gavinzli commited on
Commit
6ac95c8
·
1 Parent(s): fc3e805

Refactor Google OAuth2 callback to improve error handling and logging

Browse files
Files changed (1) hide show
  1. app/router/auth.py +48 -74
app/router/auth.py CHANGED
@@ -1,12 +1,12 @@
1
  """Module for defining the main routes of the API."""
2
  import os
3
  import json
 
4
  import pickle
5
- from fastapi import APIRouter, Request, HTTPException
6
  from fastapi.responses import JSONResponse
7
  from google_auth_oauthlib.flow import InstalledAppFlow
8
  from googleapiclient.discovery import build
9
- from oauthlib.oauth2.rfc6749.errors import InvalidGrantError
10
 
11
  router = APIRouter(tags=["auth"])
12
 
@@ -45,79 +45,53 @@ async def get_auth_url():
45
  return JSONResponse({"url": auth_url})
46
 
47
  @router.get("/auth/google/callback")
48
- async def google_callback(state: str = None, code: str = None, scope: str = None, request: Request = None):
49
- try:
50
- # Validate state (optional, for CSRF protection)
51
- if state:
52
- raise HTTPException(status_code=400, detail="Invalid state parameter")
53
-
54
- flow = InstalledAppFlow.from_client_config(CLIENT_CONFIG, SCOPES)
55
- flow.redirect_uri = REDIRECT_URI
56
- flow.fetch_token(code=code)
57
- credentials = flow.credentials
58
- request.state.session["credential"] = json.loads(credentials.to_json())
59
-
60
- service = build("gmail", "v1", credentials=credentials)
61
- profile = service.users().getProfile(userId="me").execute()
62
-
63
- # Ensure cache directory exists
64
- os.makedirs("cache", exist_ok=True)
65
- with open(f"cache/{profile['emailAddress']}.pickle", "wb") as token:
66
- pickle.dump(credentials, token)
67
-
68
- return JSONResponse(profile)
69
- except InvalidGrantError:
70
- raise HTTPException(status_code=400, detail="Invalid or expired authorization code")
71
- except Exception as e:
72
- raise HTTPException(status_code=500, detail=f"Authentication failed: {str(e)}")
73
-
74
- # @router.get("/auth/google/callback")
75
- # async def google_callback(code: str, request: Request):
76
- # """
77
- # Handles the Google OAuth2 callback by exchanging the authorization code for credentials,
78
- # retrieving the user's Gmail profile, and saving the credentials to a file.
79
 
80
- # Args:
81
- # code (str): The authorization code returned by Google's OAuth2 server.
82
- # request (Request): The incoming HTTP request object.
83
 
84
- # Returns:
85
- # JSONResponse: A JSON response containing the user's Gmail profile information.
86
 
87
- # Side Effects:
88
- # - Saves the user's credentials to a pickle file named after their email address.
89
- # - Stores the credentials in the session state of the request.
90
 
91
- # Dependencies:
92
- # - google_auth_oauthlib.flow.InstalledAppFlow: Used to handle the OAuth2 flow.
93
- # - googleapiclient.discovery.build: Used to build the Gmail API service.
94
- # - json: Used to serialize and deserialize credentials.
95
- # - pickle: Used to save credentials to a file.
96
- # """
97
- # flow = InstalledAppFlow.from_client_config(CLIENT_CONFIG, SCOPES)
98
- # flow.redirect_uri = REDIRECT_URI
99
- # flow.fetch_token(code=code)
100
- # credentials = flow.credentials
101
- # request.state.session["credential"] = json.loads(credentials.to_json())
102
- # # cred_dict = (request.state.session.get("credential"))
103
- # # cred = Credentials(
104
- # # token=cred_dict["token"],
105
- # # refresh_token=cred_dict["refresh_token"],
106
- # # token_uri=cred_dict["token_uri"],
107
- # # client_id=cred_dict["client_id"],
108
- # # client_secret=cred_dict["client_secret"],
109
- # # scopes=cred_dict["scopes"],
110
- # # )
111
- # # service = build("gmail", "v1", credentials=Credentials(
112
- # # token=cred_dict["token"],
113
- # # refresh_token=cred_dict["refresh_token"],
114
- # # token_uri=cred_dict["token_uri"],
115
- # # client_id=cred_dict["client_id"],
116
- # # client_secret=cred_dict["client_secret"],
117
- # # scopes=cred_dict["scopes"],
118
- # # ))
119
- # service = build("gmail", "v1", credentials=credentials)
120
- # profile = service.users().getProfile(userId="me").execute()
121
- # with open(f"cache/{profile['emailAddress']}.pickle", "wb") as token:
122
- # pickle.dump(credentials, token)
123
- # return JSONResponse(profile)
 
 
1
  """Module for defining the main routes of the API."""
2
  import os
3
  import json
4
+ import logging
5
  import pickle
6
+ from fastapi import APIRouter, Request
7
  from fastapi.responses import JSONResponse
8
  from google_auth_oauthlib.flow import InstalledAppFlow
9
  from googleapiclient.discovery import build
 
10
 
11
  router = APIRouter(tags=["auth"])
12
 
 
45
  return JSONResponse({"url": auth_url})
46
 
47
  @router.get("/auth/google/callback")
48
+ async def google_callback(code: str, request: Request):
49
+ """
50
+ Handles the Google OAuth2 callback by exchanging the authorization code for credentials,
51
+ retrieving the user's Gmail profile, and saving the credentials to a file.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
+ Args:
54
+ code (str): The authorization code returned by Google's OAuth2 server.
55
+ request (Request): The incoming HTTP request object.
56
 
57
+ Returns:
58
+ JSONResponse: A JSON response containing the user's Gmail profile information.
59
 
60
+ Side Effects:
61
+ - Saves the user's credentials to a pickle file named after their email address.
62
+ - Stores the credentials in the session state of the request.
63
 
64
+ Dependencies:
65
+ - google_auth_oauthlib.flow.InstalledAppFlow: Used to handle the OAuth2 flow.
66
+ - googleapiclient.discovery.build: Used to build the Gmail API service.
67
+ - json: Used to serialize and deserialize credentials.
68
+ - pickle: Used to save credentials to a file.
69
+ """
70
+ logging.info("code: %s", code)
71
+ flow = InstalledAppFlow.from_client_config(CLIENT_CONFIG, SCOPES)
72
+ flow.redirect_uri = REDIRECT_URI
73
+ flow.fetch_token(code=code)
74
+ credentials = flow.credentials
75
+ request.state.session["credential"] = json.loads(credentials.to_json())
76
+ # cred_dict = (request.state.session.get("credential"))
77
+ # cred = Credentials(
78
+ # token=cred_dict["token"],
79
+ # refresh_token=cred_dict["refresh_token"],
80
+ # token_uri=cred_dict["token_uri"],
81
+ # client_id=cred_dict["client_id"],
82
+ # client_secret=cred_dict["client_secret"],
83
+ # scopes=cred_dict["scopes"],
84
+ # )
85
+ # service = build("gmail", "v1", credentials=Credentials(
86
+ # token=cred_dict["token"],
87
+ # refresh_token=cred_dict["refresh_token"],
88
+ # token_uri=cred_dict["token_uri"],
89
+ # client_id=cred_dict["client_id"],
90
+ # client_secret=cred_dict["client_secret"],
91
+ # scopes=cred_dict["scopes"],
92
+ # ))
93
+ service = build("gmail", "v1", credentials=credentials)
94
+ profile = service.users().getProfile(userId="me").execute()
95
+ with open(f"cache/{profile['emailAddress']}.pickle", "wb") as token:
96
+ pickle.dump(credentials, token)
97
+ return JSONResponse(profile)