diff --git a/api/blueprints/mail/oauth_callback.py b/api/blueprints/mail/oauth_callback.py index aa45995..6f70050 100644 --- a/api/blueprints/mail/oauth_callback.py +++ b/api/blueprints/mail/oauth_callback.py @@ -151,7 +151,8 @@ async def mail_callback( # Generate the tokens from the callback: tokens = await current_app.gmail_client.get_authorization_tokens( - redirect_url = request.url + redirect_url = request.url, + scopes = inbound_data["scope"] ) if tokens: diff --git a/utils_v2/goog/base.py b/utils_v2/goog/base.py index f371bdf..1e83a47 100644 --- a/utils_v2/goog/base.py +++ b/utils_v2/goog/base.py @@ -137,11 +137,11 @@ class AsyncGoogleBase: self._client_id = self._oauth_json["web"]["client_id"] self._client_secret = self._oauth_json["web"]["client_secret"] self._redirect_url = redirect_url - self._flow = InstalledAppFlow.from_client_config( - self._oauth_json, - scopes = scopes, - redirect_uri = self._redirect_url - ) + # self._flow = InstalledAppFlow.from_client_config( + # self._oauth_json, + # scopes = scopes, + # redirect_uri = self._redirect_url + # ) def enable_debug(self): self._printer.enable() @@ -161,6 +161,7 @@ class AsyncGoogleBase: async def get_authorization_url( self, + scopes: List[str], state: str = None, access_type: Literal["online", "offline"] = "offline", approval_prompt: Literal["auto", "force", "consent"] = "force", @@ -172,6 +173,7 @@ class AsyncGoogleBase: TO get the OAuth2.0 authorization URL for one user. DOCUMENTATION: 1. https://developers.google.com/identity/protocols/oauth2/web-server + :param scopes: The set of permission you want the user to give. :param state: A unique identifier for your user. If not supplied, a random string will be generated. :param access_type: Set the value to offline if your application needs to refresh access tokens when the user is not present at the browser. @@ -189,8 +191,15 @@ class AsyncGoogleBase: :return: """ + # Create a flow: + flow = InstalledAppFlow.from_client_config( + self._oauth_json, + scopes = scopes, + redirect_uri = self._redirect_url + ) + # Get an authorization URL: - auth_url, state = self._flow.authorization_url( + auth_url, state = flow.authorization_url( access_type = access_type, approval_prompt = approval_prompt, include_granted_scopes = include_granted_scopes, @@ -203,6 +212,7 @@ class AsyncGoogleBase: async def get_authorization_tokens( self, + scopes: List[str], redirect_url: str ) -> GoogleAuthTokens: @@ -210,13 +220,22 @@ class AsyncGoogleBase: When the user accepts or declines an authorization request, Google sends you an alert on your redirect URL. Pass the URL as it is to this method to generate the authorization tokens that you can store in the database and reuse for this user's activities. + :param scopes: The set of permissions the user granted. :param redirect_url: The exact URL that was hit (with the query params) that Google hit when the user did something on your authorization URL. Fortunately, this URL is readily available in Quart and Flask by calling 'request.url'. :return: The authorization tokens. """ - credentials = self._flow.fetch_token(authorization_response = redirect_url) + # Create a flow: + flow = InstalledAppFlow.from_client_config( + self._oauth_json, + scopes = scopes, + redirect_uri = self._redirect_url + ) + + # Get the credentials: + credentials = flow.fetch_token(authorization_response = redirect_url) ttl = credentials["expires_in"] - 60 return GoogleAuthTokens( accessToken = credentials.get("access_token"),