@@ -45,6 +45,45 @@ 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
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
+
48
87
@api .model
49
88
def auth_oauth (self , provider , params ):
50
89
oauth_provider = self .env ["auth.oauth.provider" ].browse (provider )
@@ -64,23 +103,9 @@ def auth_oauth(self, provider, params):
64
103
if not id_token :
65
104
_logger .error ("No id_token in response." )
66
105
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
+
84
109
# retrieve and sign in user
85
110
params ["access_token" ] = access_token
86
111
login = self ._auth_oauth_signin (provider , validation , params )
0 commit comments