• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""OAuth 2.0 Async Credentials.
16
17This module provides credentials based on OAuth 2.0 access and refresh tokens.
18These credentials usually access resources on behalf of a user (resource
19owner).
20
21Specifically, this is intended to use access tokens acquired using the
22`Authorization Code grant`_ and can refresh those tokens using a
23optional `refresh token`_.
24
25Obtaining the initial access and refresh token is outside of the scope of this
26module. Consult `rfc6749 section 4.1`_ for complete details on the
27Authorization Code grant flow.
28
29.. _Authorization Code grant: https://tools.ietf.org/html/rfc6749#section-1.3.1
30.. _refresh token: https://tools.ietf.org/html/rfc6749#section-6
31.. _rfc6749 section 4.1: https://tools.ietf.org/html/rfc6749#section-4.1
32"""
33
34from google.auth import _credentials_async as credentials
35from google.auth import _helpers
36from google.auth import exceptions
37from google.oauth2 import _reauth_async as reauth
38from google.oauth2 import credentials as oauth2_credentials
39
40
41class Credentials(oauth2_credentials.Credentials):
42    """Credentials using OAuth 2.0 access and refresh tokens.
43
44    The credentials are considered immutable. If you want to modify the
45    quota project, use :meth:`with_quota_project` or ::
46
47        credentials = credentials.with_quota_project('myproject-123)
48    """
49
50    @_helpers.copy_docstring(credentials.Credentials)
51    async def refresh(self, request):
52        if (
53            self._refresh_token is None
54            or self._token_uri is None
55            or self._client_id is None
56            or self._client_secret is None
57        ):
58            raise exceptions.RefreshError(
59                "The credentials do not contain the necessary fields need to "
60                "refresh the access token. You must specify refresh_token, "
61                "token_uri, client_id, and client_secret."
62            )
63
64        (
65            access_token,
66            refresh_token,
67            expiry,
68            grant_response,
69            rapt_token,
70        ) = await reauth.refresh_grant(
71            request,
72            self._token_uri,
73            self._refresh_token,
74            self._client_id,
75            self._client_secret,
76            scopes=self._scopes,
77            rapt_token=self._rapt_token,
78            enable_reauth_refresh=self._enable_reauth_refresh,
79        )
80
81        self.token = access_token
82        self.expiry = expiry
83        self._refresh_token = refresh_token
84        self._id_token = grant_response.get("id_token")
85        self._rapt_token = rapt_token
86
87        if self._scopes and "scope" in grant_response:
88            requested_scopes = frozenset(self._scopes)
89            granted_scopes = frozenset(grant_response["scope"].split())
90            scopes_requested_but_not_granted = requested_scopes - granted_scopes
91            if scopes_requested_but_not_granted:
92                raise exceptions.RefreshError(
93                    "Not all requested scopes were granted by the "
94                    "authorization server, missing scopes {}.".format(
95                        ", ".join(scopes_requested_but_not_granted)
96                    )
97                )
98
99
100class UserAccessTokenCredentials(oauth2_credentials.UserAccessTokenCredentials):
101    """Access token credentials for user account.
102
103    Obtain the access token for a given user account or the current active
104    user account with the ``gcloud auth print-access-token`` command.
105
106    Args:
107        account (Optional[str]): Account to get the access token for. If not
108            specified, the current active account will be used.
109        quota_project_id (Optional[str]): The project ID used for quota
110            and billing.
111
112    """
113