Skip to content

Commit bc39e7b

Browse files
committed
[IMP] auth_oidc: split validation in _auth_oauth_validate
1 parent 7f29f85 commit bc39e7b

File tree

1 file changed

+42
-17
lines changed

1 file changed

+42
-17
lines changed

auth_oidc/models/res_users.py

+42-17
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,45 @@ def _auth_oauth_get_tokens_auth_code_flow(self, oauth_provider, params):
4545
# https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse
4646
return response_json.get("access_token"), response_json.get("id_token")
4747

48+
@api.model
49+
def _auth_oauth_validate(self, provider, id_token, access_token):
50+
"""
51+
return the validation data corresponding to the access token
52+
Mostly the same as auth_oauth ResUsers._auth_oauth_validate, minus the
53+
validation_endpoint
54+
"""
55+
oauth_provider = self.env["auth.oauth.provider"].browse(provider)
56+
57+
# Parse the token to get validation data
58+
validation = oauth_provider._parse_id_token(id_token, access_token)
59+
60+
if oauth_provider.data_endpoint:
61+
data = super()._auth_oauth_rpc(oauth_provider.data_endpoint, access_token)
62+
validation.update(data)
63+
# unify subject key, pop all possible and get most sensible. When this
64+
# is reworked, BC should be dropped and only the `sub` key should be
65+
# used (here, in _generate_signup_values, and in _auth_oauth_signin)
66+
subject = next(
67+
filter(
68+
None,
69+
[
70+
validation.pop(key, None)
71+
for key in [
72+
"sub", # standard
73+
"id", # google v1 userinfo, facebook opengraph
74+
"user_id", # google tokeninfo, odoo (tokeninfo)
75+
]
76+
],
77+
),
78+
None,
79+
)
80+
if not subject:
81+
_logger.error("Access Denied: missing subject identity")
82+
raise AccessDenied()
83+
validation["user_id"] = subject
84+
85+
return validation
86+
4887
@api.model
4988
def auth_oauth(self, provider, params):
5089
oauth_provider = self.env["auth.oauth.provider"].browse(provider)
@@ -64,23 +103,9 @@ def auth_oauth(self, provider, params):
64103
if not id_token:
65104
_logger.error("No id_token in response.")
66105
raise AccessDenied()
67-
validation = oauth_provider._parse_id_token(id_token, access_token)
68-
if oauth_provider.data_endpoint:
69-
data = requests.get(
70-
oauth_provider.data_endpoint,
71-
headers={"Authorization": "Bearer %s" % access_token},
72-
timeout=10,
73-
).json()
74-
validation.update(data)
75-
# required check
76-
if "sub" in validation and "user_id" not in validation:
77-
# set user_id for auth_oauth, user_id is not an OpenID Connect standard
78-
# claim:
79-
# https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
80-
validation["user_id"] = validation["sub"]
81-
elif not validation.get("user_id"):
82-
_logger.error("user_id claim not found in id_token (after mapping).")
83-
raise AccessDenied()
106+
107+
validation = self._auth_oauth_validate(provider, id_token, access_token)
108+
84109
# retrieve and sign in user
85110
params["access_token"] = access_token
86111
login = self._auth_oauth_signin(provider, validation, params)

0 commit comments

Comments
 (0)