@@ -246,11 +246,37 @@ async def handle_callback(self, request, provider, response):
246246 raise HTTPException (400 , detail = ERROR_MESSAGES .INVALID_CRED )
247247 provider_sub = f"{ provider } @{ sub } "
248248 email_claim = auth_manager_config .OAUTH_EMAIL_CLAIM
249- email = user_data .get (email_claim , "" ). lower ()
249+ email = user_data .get (email_claim , "" )
250250 # We currently mandate that email addresses are provided
251251 if not email :
252- log .warning (f"OAuth callback failed, email is missing: { user_data } " )
253- raise HTTPException (400 , detail = ERROR_MESSAGES .INVALID_CRED )
252+ # If the provider is GitHub,and public email is not provided, we can use the access token to fetch the user's email
253+ if provider == "github" :
254+ try :
255+ access_token = token .get ("access_token" )
256+ headers = {
257+ "Authorization" : f"Bearer { access_token } "
258+ }
259+ async with aiohttp .ClientSession () as session :
260+ async with session .get ("https://api.github.com/user/emails" , headers = headers ) as resp :
261+ if resp .ok :
262+ emails = await resp .json ()
263+ # use the primary email as the user's email
264+ primary_email = next ((e ["email" ] for e in emails if e .get ("primary" )), None )
265+ if primary_email :
266+ email = primary_email
267+ else :
268+ log .warning ("No primary email found in GitHub response" )
269+ raise HTTPException (400 , detail = ERROR_MESSAGES .INVALID_CRED )
270+ else :
271+ log .warning ("Failed to fetch GitHub email" )
272+ raise HTTPException (400 , detail = ERROR_MESSAGES .INVALID_CRED )
273+ except Exception as e :
274+ log .warning (f"Error fetching GitHub email: { e } " )
275+ raise HTTPException (400 , detail = ERROR_MESSAGES .INVALID_CRED )
276+ else :
277+ log .warning (f"OAuth callback failed, email is missing: { user_data } " )
278+ raise HTTPException (400 , detail = ERROR_MESSAGES .INVALID_CRED )
279+ email = email .lower ()
254280 if (
255281 "*" not in auth_manager_config .OAUTH_ALLOWED_DOMAINS
256282 and email .split ("@" )[- 1 ] not in auth_manager_config .OAUTH_ALLOWED_DOMAINS
0 commit comments