@@ -45,6 +45,43 @@ def _auth_oauth_get_tokens_auth_code_flow(self, oauth_provider, params):
45
45
# https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse
46
46
return response_json .get ("access_token" ), response_json .get ("id_token" )
47
47
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
+
48
85
@api .model
49
86
def auth_oauth (self , provider , params ):
50
87
oauth_provider = self .env ["auth.oauth.provider" ].browse (provider )
@@ -64,23 +101,9 @@ def auth_oauth(self, provider, params):
64
101
if not id_token :
65
102
_logger .error ("No id_token in response." )
66
103
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
+
84
107
# retrieve and sign in user
85
108
params ["access_token" ] = access_token
86
109
login = self ._auth_oauth_signin (provider , validation , params )
0 commit comments