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
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
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
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
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)