Skip to content

Commit c09d1f2

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

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

auth_oidc/models/res_users.py

+40-17
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,43 @@ 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 validation_endpoint
53+
"""
54+
oauth_provider = self.env["auth.oauth.provider"].browse(provider)
55+
56+
# Parse the token to get validation data
57+
validation = oauth_provider._parse_id_token(id_token, access_token)
58+
59+
if oauth_provider.data_endpoint:
60+
data = super()._auth_oauth_rpc(oauth_provider.data_endpoint, access_token)
61+
validation.update(data)
62+
# unify subject key, pop all possible and get most sensible. When this
63+
# is reworked, BC should be dropped and only the `sub` key should be
64+
# used (here, in _generate_signup_values, and in _auth_oauth_signin)
65+
subject = next(
66+
filter(
67+
None,
68+
[
69+
validation.pop(key, None)
70+
for key in [
71+
"sub", # standard
72+
"id", # google v1 userinfo, facebook opengraph
73+
"user_id", # google tokeninfo, odoo (tokeninfo)
74+
]
75+
],
76+
),
77+
None,
78+
)
79+
if not subject:
80+
raise AccessDenied("Missing subject identity")
81+
validation["user_id"] = subject
82+
83+
return validation
84+
4885
@api.model
4986
def auth_oauth(self, provider, params):
5087
oauth_provider = self.env["auth.oauth.provider"].browse(provider)
@@ -64,23 +101,9 @@ def auth_oauth(self, provider, params):
64101
if not id_token:
65102
_logger.error("No id_token in response.")
66103
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()
104+
105+
validation = self._auth_oauth_validate(provider, id_token, access_token)
106+
84107
# retrieve and sign in user
85108
params["access_token"] = access_token
86109
login = self._auth_oauth_signin(provider, validation, params)

0 commit comments

Comments
 (0)