def _RefreshGrant(request, token_uri, refresh_token, client_id, client_secret, scopes=None, rapt_token=None): """Prepares the request to send to auth server to refresh tokens.""" body = [ ('grant_type', google_auth_client._REFRESH_GRANT_TYPE), # pylint: disable=protected-access ('client_id', client_id), ('client_secret', client_secret), ('refresh_token', refresh_token), ] if scopes: body.append(('scope', ' '.join(scopes))) if rapt_token: body.append(('rapt', rapt_token)) response_data = _TokenEndpointRequestWithRetry(request, token_uri, body) try: access_token = response_data['access_token'] except KeyError as caught_exc: new_exc = google_auth_exceptions.RefreshError( 'No access token in response.', response_data) six.raise_from(new_exc, caught_exc) refresh_token = response_data.get('refresh_token', refresh_token) expiry = google_auth_client._parse_expiry(response_data) # pylint: disable=protected-access return access_token, refresh_token, expiry, response_data
def _handle_refresh_token_response(self, response): if 'access_token' in response: self.token = response['access_token'] else: msg = '[{request_id}] No access token in response.' logging.error(msg) raise exceptions.GCPAuthError(msg) self.expiry = _client._parse_expiry(response)
async def refresh_grant(session: ClientSession, token_uri, refresh_token, client_id, client_secret): """Implements the OAuth 2.0 refresh token grant. For more details, see `rfc678 section 6`_. Args: request (google.auth.transport.Request): A callable used to make HTTP requests. token_uri (str): The OAuth 2.0 authorizations server's token endpoint URI. refresh_token (str): The refresh token to use to get a new access token. client_id (str): The OAuth 2.0 application's client ID. client_secret (str): The Oauth 2.0 appliaction's client secret. Returns: Tuple[str, Optional[str], Optional[datetime], Mapping[str, str]]: The access token, new refresh token, expiration, and additional data returned by the token endpoint. Raises: google.auth.exceptions.RefreshError: If the token endpoint returned an error. .. _rfc6748 section 6: https://tools.ietf.org/html/rfc6749#section-6 """ body = { 'grant_type': _REFRESH_GRANT_TYPE, 'client_id': client_id, 'client_secret': client_secret, 'refresh_token': refresh_token, } response_data = await _token_endpoint_request(session, token_uri, body) try: access_token = response_data['access_token'] except KeyError: raise exceptions.RefreshError('No access token in response.', response_data) refresh_token = response_data.get('refresh_token', refresh_token) expiry = _parse_expiry(response_data) return access_token, refresh_token, expiry, response_data
async def refresh_token(self): """Refresh oauth access token attached to this HTTP session. Raises: :exc:`.GCPAuthError`: if no token was found in the response. :exc:`.GCPHTTPError`: if any exception occurred, specifically a :exc:`.GCPHTTPResponseError`, if the exception is associated with a response status code. """ url, headers, body = self._setup_token_request() request_id = uuid.uuid4() logging.debug( _utils.REQ_LOG_FMT.format(request_id=request_id, method='POST', url=url, kwargs=None)) async with self._session.post(url, headers=headers, data=body) as resp: log_kw = { 'request_id': request_id, 'method': 'POST', 'url': resp.url, 'status': resp.status, 'reason': resp.reason, } logging.debug(_utils.RESP_LOG_FMT.format(**log_kw)) # avoid leaky abstractions and wrap http errors with our own try: resp.raise_for_status() except aiohttp.ClientResponseError as e: msg = f'[{request_id}] Issue connecting to {resp.url}: {e}' logging.error(msg, exc_info=e) raise exceptions.GCPHTTPResponseError(msg, resp.status) response = await resp.json() try: self.token = response['access_token'] except KeyError: msg = '[{request_id}] No access token in response.' logging.error(msg) raise exceptions.GCPAuthError(msg) self.expiry = _client._parse_expiry(response)
async def jwt_grant(session: ClientSession, token_uri, assertion): """Implements the JWT Profile for OAuth 2.0 Authorization Grants. For more details, see `rfc7523 section 4`_. Args: request (google.auth.transport.Request): A callable used to make HTTP requests. token_uri (str): The OAuth 2.0 authorizations server's token endpoint URI. assertion (str): The OAuth 2.0 assertion. Returns: Tuple[str, Optional[datetime], Mapping[str, str]]: The access token, expiration, and additional data returned by the token endpoint. Raises: google.auth.exceptions.RefreshError: If the token endpoint returned an error. .. _rfc7523 section 4: https://tools.ietf.org/html/rfc7523#section-4 """ body = { 'assertion': assertion, 'grant_type': _JWT_GRANT_TYPE, } response_data = await _token_endpoint_request(session, token_uri, body) try: access_token = response_data['access_token'] except KeyError: raise exceptions.RefreshError('No access token in response.', response_data) expiry = _parse_expiry(response_data) return access_token, expiry, response_data
def test__parse_expiry_none(): assert _client._parse_expiry({}) is None
def test__parse_expiry(unused_utcnow): result = _client._parse_expiry({'expires_in': 500}) assert result == datetime.datetime.min + datetime.timedelta(seconds=500)