# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""An OAuth 2.0 client.

Tools for interacting with OAuth 2.0 protected resources.
"""

import collections
import copy
import datetime
import json
import logging
import os
import shutil
import socket
import sys
import tempfile

import six
from six.moves import http_client
from six.moves import urllib

import oauth2client
from oauth2client import _helpers
from oauth2client import clientsecrets
from oauth2client import transport
from oauth2client import util


__author__ = 'jcgregorio@google.com (Joe Gregorio)'

HAS_OPENSSL = False
HAS_CRYPTO = False
try:
    from oauth2client import crypt
    HAS_CRYPTO = True
    HAS_OPENSSL = crypt.OpenSSLVerifier is not None
except ImportError:  # pragma: NO COVER
    pass


logger = logging.getLogger(__name__)

# Expiry is stored in RFC3339 UTC format
EXPIRY_FORMAT = '%Y-%m-%dT%H:%M:%SZ'

# Which certs to use to validate id_tokens received.
ID_TOKEN_VERIFICATION_CERTS = 'https://www.googleapis.com/oauth2/v1/certs'
# This symbol previously had a typo in the name; we keep the old name
# around for now, but will remove it in the future.
ID_TOKEN_VERIFICATON_CERTS = ID_TOKEN_VERIFICATION_CERTS

# Constant to use for the out of band OAuth 2.0 flow.
OOB_CALLBACK_URN = 'urn:ietf:wg:oauth:2.0:oob'

# The value representing user credentials.
AUTHORIZED_USER = 'authorized_user'

# The value representing service account credentials.
SERVICE_ACCOUNT = 'service_account'

# The environment variable pointing the file with local
# Application Default Credentials.
GOOGLE_APPLICATION_CREDENTIALS = 'GOOGLE_APPLICATION_CREDENTIALS'
# The ~/.config subdirectory containing gcloud credentials. Intended
# to be swapped out in tests.
_CLOUDSDK_CONFIG_DIRECTORY = 'gcloud'
# The environment variable name which can replace ~/.config if set.
_CLOUDSDK_CONFIG_ENV_VAR = 'CLOUDSDK_CONFIG'

# The error message we show users when we can't find the Application
# Default Credentials.
ADC_HELP_MSG = (
    'The Application Default Credentials are not available. They are '
    'available if running in Google Compute Engine. Otherwise, the '
    'environment variable ' +
    GOOGLE_APPLICATION_CREDENTIALS +
    ' must be defined pointing to a file defining the credentials. See '
    'https://developers.google.com/accounts/docs/'
    'application-default-credentials for more information.')

_WELL_KNOWN_CREDENTIALS_FILE = 'application_default_credentials.json'

# The access token along with the seconds in which it expires.
AccessTokenInfo = collections.namedtuple(
    'AccessTokenInfo', ['access_token', 'expires_in'])

DEFAULT_ENV_NAME = 'UNKNOWN'

# If set to True _get_environment avoid GCE check (_detect_gce_environment)
NO_GCE_CHECK = os.environ.setdefault('NO_GCE_CHECK', 'False')

# Timeout in seconds to wait for the GCE metadata server when detecting the
# GCE environment.
try:
    GCE_METADATA_TIMEOUT = int(
        os.environ.setdefault('GCE_METADATA_TIMEOUT', '3'))
except ValueError:  # pragma: NO COVER
    GCE_METADATA_TIMEOUT = 3

_SERVER_SOFTWARE = 'SERVER_SOFTWARE'
_GCE_METADATA_HOST = '169.254.169.254'
_METADATA_FLAVOR_HEADER = 'Metadata-Flavor'
_DESIRED_METADATA_FLAVOR = 'Google'

# Expose utcnow() at module level to allow for
# easier testing (by replacing with a stub).
_UTCNOW = datetime.datetime.utcnow

# NOTE: These names were previously defined in this module but have been
#       moved into `oauth2client.transport`,
clean_headers = transport.clean_headers
MemoryCache = transport.MemoryCache
REFRESH_STATUS_CODES = transport.REFRESH_STATUS_CODES


class SETTINGS(object):
    """Settings namespace for globally defined values."""
    env_name = None


class Error(Exception):
    """Base error for this module."""


class FlowExchangeError(Error):
    """Error trying to exchange an authorization grant for an access token."""


class AccessTokenRefreshError(Error):
    """Error trying to refresh an expired access token."""


class HttpAccessTokenRefreshError(AccessTokenRefreshError):
    """Error (with HTTP status) trying to refresh an expired access token."""
    def __init__(self, *args, **kwargs):
        super(HttpAccessTokenRefreshError, self).__init__(*args)
        self.status = kwargs.get('status')


class TokenRevokeError(Error):
    """Error trying to revoke a token."""


class UnknownClientSecretsFlowError(Error):
    """The client secrets file called for an unknown type of OAuth 2.0 flow."""


class AccessTokenCredentialsError(Error):
    """Having only the access_token means no refresh is possible."""


class VerifyJwtTokenError(Error):
    """Could not retrieve certificates for validation."""


class NonAsciiHeaderError(Error):
    """Header names and values must be ASCII strings."""


class ApplicationDefaultCredentialsError(Error):
    """Error retrieving the Application Default Credentials."""


class OAuth2DeviceCodeError(Error):
    """Error trying to retrieve a device code."""


class CryptoUnavailableError(Error, NotImplementedError):
    """Raised when a crypto library is required, but none is available."""


def _parse_expiry(expiry):
    if expiry and isinstance(expiry, datetime.datetime):
        return expiry.strftime(EXPIRY_FORMAT)
    else:
        return None


class Credentials(object):
    """Base class for all Credentials objects.

    Subclasses must define an authorize() method that applies the credentials
    to an HTTP transport.

    Subclasses must also specify a classmethod named 'from_json' that takes a
    JSON string as input and returns an instantiated Credentials object.
    """

    NON_SERIALIZED_MEMBERS = frozenset(['store'])

    def authorize(self, http):
        """Take an httplib2.Http instance (or equivalent) and authorizes it.

        Authorizes it for the set of credentials, usually by replacing
        http.request() with a method that adds in the appropriate headers and
        then delegates to the original Http.request() method.

        Args:
            http: httplib2.Http, an http object to be used to make the refresh
                  request.
        """
        raise NotImplementedError

    def refresh(self, http):
        """Forces a refresh of the access_token.

        Args:
            http: httplib2.Http, an http object to be used to make the refresh
                  request.
        """
        raise NotImplementedError

    def revoke(self, http):
        """Revokes a refresh_token and makes the credentials void.

        Args:
            http: httplib2.Http, an http object to be used to make the revoke
                  request.
        """
        raise NotImplementedError

    def apply(self, headers):
        """Add the authorization to the headers.

        Args:
            headers: dict, the headers to add the Authorization header to.
        """
        raise NotImplementedError

    def _to_json(self, strip, to_serialize=None):
        """Utility function that creates JSON repr. of a Credentials object.

        Args:
            strip: array, An array of names of members to exclude from the
                   JSON.
            to_serialize: dict, (Optional) The properties for this object
                          that will be serialized. This allows callers to
                          modify before serializing.

        Returns:
            string, a JSON representation of this instance, suitable to pass to
            from_json().
        """
        curr_type = self.__class__
        if to_serialize is None:
            to_serialize = copy.copy(self.__dict__)
        else:
            # Assumes it is a str->str dictionary, so we don't deep copy.
            to_serialize = copy.copy(to_serialize)
        for member in strip:
            if member in to_serialize:
                del to_serialize[member]
        to_serialize['token_expiry'] = _parse_expiry(
            to_serialize.get('token_expiry'))
        # Add in information we will need later to reconstitute this instance.
        to_serialize['_class'] = curr_type.__name__
        to_serialize['_module'] = curr_type.__module__
        for key, val in to_serialize.items():
            if isinstance(val, bytes):
                to_serialize[key] = val.decode('utf-8')
            if isinstance(val, set):
                to_serialize[key] = list(val)
        return json.dumps(to_serialize)

    def to_json(self):
        """Creating a JSON representation of an instance of Credentials.

        Returns:
            string, a JSON representation of this instance, suitable to pass to
            from_json().
        """
        return self._to_json(self.NON_SERIALIZED_MEMBERS)

    @classmethod
    def new_from_json(cls, json_data):
        """Utility class method to instantiate a Credentials subclass from JSON.

        Expects the JSON string to have been produced by to_json().

        Args:
            json_data: string or bytes, JSON from to_json().

        Returns:
            An instance of the subclass of Credentials that was serialized with
            to_json().
        """
        json_data_as_unicode = _helpers._from_bytes(json_data)
        data = json.loads(json_data_as_unicode)
        # Find and call the right classmethod from_json() to restore
        # the object.
        module_name = data['_module']
        try:
            module_obj = __import__(module_name)
        except ImportError:
            # In case there's an object from the old package structure,
            # update it
            module_name = module_name.replace('.googleapiclient', '')
            module_obj = __import__(module_name)

        module_obj = __import__(module_name,
                                fromlist=module_name.split('.')[:-1])
        kls = getattr(module_obj, data['_class'])
        return kls.from_json(json_data_as_unicode)

    @classmethod
    def from_json(cls, unused_data):
        """Instantiate a Credentials object from a JSON description of it.

        The JSON should have been produced by calling .to_json() on the object.

        Args:
            unused_data: dict, A deserialized JSON object.

        Returns:
            An instance of a Credentials subclass.
        """
        return Credentials()


class Flow(object):
    """Base class for all Flow objects."""
    pass


class Storage(object):
    """Base class for all Storage objects.

    Store and retrieve a single credential. This class supports locking
    such that multiple processes and threads can operate on a single
    store.
    """
    def __init__(self, lock=None):
        """Create a Storage instance.

        Args:
            lock: An optional threading.Lock-like object. Must implement at
                  least acquire() and release(). Does not need to be
                  re-entrant.
        """
        self._lock = lock

    def acquire_lock(self):
        """Acquires any lock necessary to access this Storage.

        This lock is not reentrant.
        """
        if self._lock is not None:
            self._lock.acquire()

    def release_lock(self):
        """Release the Storage lock.

        Trying to release a lock that isn't held will result in a
        RuntimeError in the case of a threading.Lock or multiprocessing.Lock.
        """
        if self._lock is not None:
            self._lock.release()

    def locked_get(self):
        """Retrieve credential.

        The Storage lock must be held when this is called.

        Returns:
            oauth2client.client.Credentials
        """
        raise NotImplementedError

    def locked_put(self, credentials):
        """Write a credential.

        The Storage lock must be held when this is called.

        Args:
            credentials: Credentials, the credentials to store.
        """
        raise NotImplementedError

    def locked_delete(self):
        """Delete a credential.

        The Storage lock must be held when this is called.
        """
        raise NotImplementedError

    def get(self):
        """Retrieve credential.

        The Storage lock must *not* be held when this is called.

        Returns:
            oauth2client.client.Credentials
        """
        self.acquire_lock()
        try:
            return self.locked_get()
        finally:
            self.release_lock()

    def put(self, credentials):
        """Write a credential.

        The Storage lock must be held when this is called.

        Args:
            credentials: Credentials, the credentials to store.
        """
        self.acquire_lock()
        try:
            self.locked_put(credentials)
        finally:
            self.release_lock()

    def delete(self):
        """Delete credential.

        Frees any resources associated with storing the credential.
        The Storage lock must *not* be held when this is called.

        Returns:
            None
        """
        self.acquire_lock()
        try:
            return self.locked_delete()
        finally:
            self.release_lock()


def _update_query_params(uri, params):
    """Updates a URI with new query parameters.

    Args:
        uri: string, A valid URI, with potential existing query parameters.
        params: dict, A dictionary of query parameters.

    Returns:
        The same URI but with the new query parameters added.
    """
    parts = urllib.parse.urlparse(uri)
    query_params = dict(urllib.parse.parse_qsl(parts.query))
    query_params.update(params)
    new_parts = parts._replace(query=urllib.parse.urlencode(query_params))
    return urllib.parse.urlunparse(new_parts)


class OAuth2Credentials(Credentials):
    """Credentials object for OAuth 2.0.

    Credentials can be applied to an httplib2.Http object using the authorize()
    method, which then adds the OAuth 2.0 access token to each request.

    OAuth2Credentials objects may be safely pickled and unpickled.
    """

    @util.positional(8)
    def __init__(self, access_token, client_id, client_secret, refresh_token,
                 token_expiry, token_uri, user_agent, revoke_uri=None,
                 id_token=None, token_response=None, scopes=None,
                 token_info_uri=None):
        """Create an instance of OAuth2Credentials.

        This constructor is not usually called by the user, instead
        OAuth2Credentials objects are instantiated by the OAuth2WebServerFlow.

        Args:
            access_token: string, access token.
            client_id: string, client identifier.
            client_secret: string, client secret.
            refresh_token: string, refresh token.
            token_expiry: datetime, when the access_token expires.
            token_uri: string, URI of token endpoint.
            user_agent: string, The HTTP User-Agent to provide for this
                        application.
            revoke_uri: string, URI for revoke endpoint. Defaults to None; a
                        token can't be revoked if this is None.
            id_token: object, The identity of the resource owner.
            token_response: dict, the decoded response to the token request.
                            None if a token hasn't been requested yet. Stored
                            because some providers (e.g. wordpress.com) include
                            extra fields that clients may want.
            scopes: list, authorized scopes for these credentials.
          token_info_uri: string, the URI for the token info endpoint. Defaults
                          to None; scopes can not be refreshed if this is None.

        Notes:
            store: callable, A callable that when passed a Credential
                   will store the credential back to where it came from.
                   This is needed to store the latest access_token if it
                   has expired and been refreshed.
        """
        self.access_token = access_token
        self.client_id = client_id
        self.client_secret = client_secret
        self.refresh_token = refresh_token
        self.store = None
        self.token_expiry = token_expiry
        self.token_uri = token_uri
        self.user_agent = user_agent
        self.revoke_uri = revoke_uri
        self.id_token = id_token
        self.token_response = token_response
        self.scopes = set(util.string_to_scopes(scopes or []))
        self.token_info_uri = token_info_uri

        # True if the credentials have been revoked or expired and can't be
        # refreshed.
        self.invalid = False

    def authorize(self, http):
        """Authorize an httplib2.Http instance with these credentials.

        The modified http.request method will add authentication headers to
        each request and will refresh access_tokens when a 401 is received on a
        request. In addition the http.request method has a credentials
        property, http.request.credentials, which is the Credentials object
        that authorized it.

        Args:
            http: An instance of ``httplib2.Http`` or something that acts
                  like it.

        Returns:
            A modified instance of http that was passed in.

        Example::

            h = httplib2.Http()
            h = credentials.authorize(h)

        You can't create a new OAuth subclass of httplib2.Authentication
        because it never gets passed the absolute URI, which is needed for
        signing. So instead we have to overload 'request' with a closure
        that adds in the Authorization header and then calls the original
        version of 'request()'.
        """
        transport.wrap_http_for_auth(self, http)
        return http

    def refresh(self, http):
        """Forces a refresh of the access_token.

        Args:
            http: httplib2.Http, an http object to be used to make the refresh
                  request.
        """
        self._refresh(http.request)

    def revoke(self, http):
        """Revokes a refresh_token and makes the credentials void.

        Args:
            http: httplib2.Http, an http object to be used to make the revoke
                  request.
        """
        self._revoke(http.request)

    def apply(self, headers):
        """Add the authorization to the headers.

        Args:
            headers: dict, the headers to add the Authorization header to.
        """
        headers['Authorization'] = 'Bearer ' + self.access_token

    def has_scopes(self, scopes):
        """Verify that the credentials are authorized for the given scopes.

        Returns True if the credentials authorized scopes contain all of the
        scopes given.

        Args:
            scopes: list or string, the scopes to check.

        Notes:
            There are cases where the credentials are unaware of which scopes
            are authorized. Notably, credentials obtained and stored before
            this code was added will not have scopes, AccessTokenCredentials do
            not have scopes. In both cases, you can use refresh_scopes() to
            obtain the canonical set of scopes.
        """
        scopes = util.string_to_scopes(scopes)
        return set(scopes).issubset(self.scopes)

    def retrieve_scopes(self, http):
        """Retrieves the canonical list of scopes for this access token.

        Gets the scopes from the OAuth2 provider.

        Args:
            http: httplib2.Http, an http object to be used to make the refresh
                  request.

        Returns:
            A set of strings containing the canonical list of scopes.
        """
        self._retrieve_scopes(http.request)
        return self.scopes

    @classmethod
    def from_json(cls, json_data):
        """Instantiate a Credentials object from a JSON description of it.

        The JSON should have been produced by calling .to_json() on the object.

        Args:
            json_data: string or bytes, JSON to deserialize.

        Returns:
            An instance of a Credentials subclass.
        """
        data = json.loads(_helpers._from_bytes(json_data))
        if (data.get('token_expiry') and
                not isinstance(data['token_expiry'], datetime.datetime)):
            try:
                data['token_expiry'] = datetime.datetime.strptime(
                    data['token_expiry'], EXPIRY_FORMAT)
            except ValueError:
                data['token_expiry'] = None
        retval = cls(
            data['access_token'],
            data['client_id'],
            data['client_secret'],
            data['refresh_token'],
            data['token_expiry'],
            data['token_uri'],
            data['user_agent'],
            revoke_uri=data.get('revoke_uri', None),
            id_token=data.get('id_token', None),
            token_response=data.get('token_response', None),
            scopes=data.get('scopes', None),
            token_info_uri=data.get('token_info_uri', None))
        retval.invalid = data['invalid']
        return retval

    @property
    def access_token_expired(self):
        """True if the credential is expired or invalid.

        If the token_expiry isn't set, we assume the token doesn't expire.
        """
        if self.invalid:
            return True

        if not self.token_expiry:
            return False

        now = _UTCNOW()
        if now >= self.token_expiry:
            logger.info('access_token is expired. Now: %s, token_expiry: %s',
                        now, self.token_expiry)
            return True
        return False

    def get_access_token(self, http=None):
        """Return the access token and its expiration information.

        If the token does not exist, get one.
        If the token expired, refresh it.
        """
        if not self.access_token or self.access_token_expired:
            if not http:
                http = transport.get_http_object()
            self.refresh(http)
        return AccessTokenInfo(access_token=self.access_token,
                               expires_in=self._expires_in())

    def set_store(self, store):
        """Set the Storage for the credential.

        Args:
            store: Storage, an implementation of Storage object.
                   This is needed to store the latest access_token if it
                   has expired and been refreshed. This implementation uses
                   locking to check for updates before updating the
                   access_token.
        """
        self.store = store

    def _expires_in(self):
        """Return the number of seconds until this token expires.

        If token_expiry is in the past, this method will return 0, meaning the
        token has already expired.

        If token_expiry is None, this method will return None. Note that
        returning 0 in such a case would not be fair: the token may still be
        valid; we just don't know anything about it.
        """
        if self.token_expiry:
            now = _UTCNOW()
            if self.token_expiry > now:
                time_delta = self.token_expiry - now
                # TODO(orestica): return time_delta.total_seconds()
                # once dropping support for Python 2.6
                return time_delta.days * 86400 + time_delta.seconds
            else:
                return 0

    def _updateFromCredential(self, other):
        """Update this Credential from another instance."""
        self.__dict__.update(other.__getstate__())

    def __getstate__(self):
        """Trim the state down to something that can be pickled."""
        d = copy.copy(self.__dict__)
        del d['store']
        return d

    def __setstate__(self, state):
        """Reconstitute the state of the object from being pickled."""
        self.__dict__.update(state)
        self.store = None

    def _generate_refresh_request_body(self):
        """Generate the body that will be used in the refresh request."""
        body = urllib.parse.urlencode({
            'grant_type': 'refresh_token',
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token,
        })
        return body

    def _generate_refresh_request_headers(self):
        """Generate the headers that will be used in the refresh request."""
        headers = {
            'content-type': 'application/x-www-form-urlencoded',
        }

        if self.user_agent is not None:
            headers['user-agent'] = self.user_agent

        return headers

    def _refresh(self, http_request):
        """Refreshes the access_token.

        This method first checks by reading the Storage object if available.
        If a refresh is still needed, it holds the Storage lock until the
        refresh is completed.

        Args:
            http_request: callable, a callable that matches the method
                          signature of httplib2.Http.request, used to make the
                          refresh request.

        Raises:
            HttpAccessTokenRefreshError: When the refresh fails.
        """
        if not self.store:
            self._do_refresh_request(http_request)
        else:
            self.store.acquire_lock()
            try:
                new_cred = self.store.locked_get()

                if (new_cred and not new_cred.invalid and
                        new_cred.access_token != self.access_token and
                        not new_cred.access_token_expired):
                    logger.info('Updated access_token read from Storage')
                    self._updateFromCredential(new_cred)
                else:
                    self._do_refresh_request(http_request)
            finally:
                self.store.release_lock()

    def _do_refresh_request(self, http_request):
        """Refresh the access_token using the refresh_token.

        Args:
            http_request: callable, a callable that matches the method
                          signature of httplib2.Http.request, used to make the
                          refresh request.

        Raises:
            HttpAccessTokenRefreshError: When the refresh fails.
        """
        body = self._generate_refresh_request_body()
        headers = self._generate_refresh_request_headers()

        logger.info('Refreshing access_token')
        resp, content = http_request(
            self.token_uri, method='POST', body=body, headers=headers)
        content = _helpers._from_bytes(content)
        if resp.status == http_client.OK:
            d = json.loads(content)
            self.token_response = d
            self.access_token = d['access_token']
            self.refresh_token = d.get('refresh_token', self.refresh_token)
            if 'expires_in' in d:
                delta = datetime.timedelta(seconds=int(d['expires_in']))
                self.token_expiry = delta + _UTCNOW()
            else:
                self.token_expiry = None
            if 'id_token' in d:
                self.id_token = _extract_id_token(d['id_token'])
            else:
                self.id_token = None
            # On temporary refresh errors, the user does not actually have to
            # re-authorize, so we unflag here.
            self.invalid = False
            if self.store:
                self.store.locked_put(self)
        else:
            # An {'error':...} response body means the token is expired or
            # revoked, so we flag the credentials as such.
            logger.info('Failed to retrieve access token: %s', content)
            error_msg = 'Invalid response {0}.'.format(resp['status'])
            try:
                d = json.loads(content)
                if 'error' in d:
                    error_msg = d['error']
                    if 'error_description' in d:
                        error_msg += ': ' + d['error_description']
                    self.invalid = True
                    if self.store is not None:
                        self.store.locked_put(self)
            except (TypeError, ValueError):
                pass
            raise HttpAccessTokenRefreshError(error_msg, status=resp.status)

    def _revoke(self, http_request):
        """Revokes this credential and deletes the stored copy (if it exists).

        Args:
            http_request: callable, a callable that matches the method
                          signature of httplib2.Http.request, used to make the
                          revoke request.
        """
        self._do_revoke(http_request, self.refresh_token or self.access_token)

    def _do_revoke(self, http_request, token):
        """Revokes this credential and deletes the stored copy (if it exists).

        Args:
            http_request: callable, a callable that matches the method
                          signature of httplib2.Http.request, used to make the
                          refresh request.
            token: A string used as the token to be revoked. Can be either an
                   access_token or refresh_token.

        Raises:
            TokenRevokeError: If the revoke request does not return with a
                              200 OK.
        """
        logger.info('Revoking token')
        query_params = {'token': token}
        token_revoke_uri = _update_query_params(self.revoke_uri, query_params)
        resp, content = http_request(token_revoke_uri)
        if resp.status == http_client.OK:
            self.invalid = True
        else:
            error_msg = 'Invalid response {0}.'.format(resp.status)
            try:
                d = json.loads(_helpers._from_bytes(content))
                if 'error' in d:
                    error_msg = d['error']
            except (TypeError, ValueError):
                pass
            raise TokenRevokeError(error_msg)

        if self.store:
            self.store.delete()

    def _retrieve_scopes(self, http_request):
        """Retrieves the list of authorized scopes from the OAuth2 provider.

        Args:
            http_request: callable, a callable that matches the method
                          signature of httplib2.Http.request, used to make the
                          revoke request.
        """
        self._do_retrieve_scopes(http_request, self.access_token)

    def _do_retrieve_scopes(self, http_request, token):
        """Retrieves the list of authorized scopes from the OAuth2 provider.

        Args:
            http_request: callable, a callable that matches the method
                          signature of httplib2.Http.request, used to make the
                          refresh request.
            token: A string used as the token to identify the credentials to
                   the provider.

        Raises:
            Error: When refresh fails, indicating the the access token is
                   invalid.
        """
        logger.info('Refreshing scopes')
        query_params = {'access_token': token, 'fields': 'scope'}
        token_info_uri = _update_query_params(self.token_info_uri,
                                              query_params)
        resp, content = http_request(token_info_uri)
        content = _helpers._from_bytes(content)
        if resp.status == http_client.OK:
            d = json.loads(content)
            self.scopes = set(util.string_to_scopes(d.get('scope', '')))
        else:
            error_msg = 'Invalid response {0}.'.format(resp.status)
            try:
                d = json.loads(content)
                if 'error_description' in d:
                    error_msg = d['error_description']
            except (TypeError, ValueError):
                pass
            raise Error(error_msg)


class AccessTokenCredentials(OAuth2Credentials):
    """Credentials object for OAuth 2.0.

    Credentials can be applied to an httplib2.Http object using the
    authorize() method, which then signs each request from that object
    with the OAuth 2.0 access token. This set of credentials is for the
    use case where you have acquired an OAuth 2.0 access_token from
    another place such as a JavaScript client or another web
    application, and wish to use it from Python. Because only the
    access_token is present it can not be refreshed and will in time
    expire.

    AccessTokenCredentials objects may be safely pickled and unpickled.

    Usage::

        credentials = AccessTokenCredentials('<an access token>',
            'my-user-agent/1.0')
        http = httplib2.Http()
        http = credentials.authorize(http)

    Raises:
        AccessTokenCredentialsExpired: raised when the access_token expires or
                                       is revoked.
    """

    def __init__(self, access_token, user_agent, revoke_uri=None):
        """Create an instance of OAuth2Credentials

        This is one of the few types if Credentials that you should contrust,
        Credentials objects are usually instantiated by a Flow.

        Args:
            access_token: string, access token.
            user_agent: string, The HTTP User-Agent to provide for this
                        application.
            revoke_uri: string, URI for revoke endpoint. Defaults to None; a
                        token can't be revoked if this is None.
        """
        super(AccessTokenCredentials, self).__init__(
            access_token,
            None,
            None,
            None,
            None,
            None,
            user_agent,
            revoke_uri=revoke_uri)

    @classmethod
    def from_json(cls, json_data):
        data = json.loads(_helpers._from_bytes(json_data))
        retval = AccessTokenCredentials(
            data['access_token'],
            data['user_agent'])
        return retval

    def _refresh(self, http_request):
        raise AccessTokenCredentialsError(
            'The access_token is expired or invalid and can\'t be refreshed.')

    def _revoke(self, http_request):
        """Revokes the access_token and deletes the store if available.

        Args:
            http_request: callable, a callable that matches the method
                          signature of httplib2.Http.request, used to make the
                          revoke request.
        """
        self._do_revoke(http_request, self.access_token)


def _detect_gce_environment():
    """Determine if the current environment is Compute Engine.

    Returns:
        Boolean indicating whether or not the current environment is Google
        Compute Engine.
    """
    # NOTE: The explicit ``timeout`` is a workaround. The underlying
    #       issue is that resolving an unknown host on some networks will take
    #       20-30 seconds; making this timeout short fixes the issue, but
    #       could lead to false negatives in the event that we are on GCE, but
    #       the metadata resolution was particularly slow. The latter case is
    #       "unlikely".
    connection = six.moves.http_client.HTTPConnection(
        _GCE_METADATA_HOST, timeout=GCE_METADATA_TIMEOUT)

    try:
        headers = {_METADATA_FLAVOR_HEADER: _DESIRED_METADATA_FLAVOR}
        connection.request('GET', '/', headers=headers)
        response = connection.getresponse()
        if response.status == http_client.OK:
            return (response.getheader(_METADATA_FLAVOR_HEADER) ==
                    _DESIRED_METADATA_FLAVOR)
    except socket.error:  # socket.timeout or socket.error(64, 'Host is down')
        logger.info('Timeout attempting to reach GCE metadata service.')
        return False
    finally:
        connection.close()


def _in_gae_environment():
    """Detects if the code is running in the App Engine environment.

    Returns:
        True if running in the GAE environment, False otherwise.
    """
    if SETTINGS.env_name is not None:
        return SETTINGS.env_name in ('GAE_PRODUCTION', 'GAE_LOCAL')

    try:
        import google.appengine  # noqa: unused import
    except ImportError:
        pass
    else:
        server_software = os.environ.get(_SERVER_SOFTWARE, '')
        if server_software.startswith('Google App Engine/'):
            SETTINGS.env_name = 'GAE_PRODUCTION'
            return True
        elif server_software.startswith('Development/'):
            SETTINGS.env_name = 'GAE_LOCAL'
            return True

    return False


def _in_gce_environment():
    """Detect if the code is running in the Compute Engine environment.

    Returns:
        True if running in the GCE environment, False otherwise.
    """
    if SETTINGS.env_name is not None:
        return SETTINGS.env_name == 'GCE_PRODUCTION'

    if NO_GCE_CHECK != 'True' and _detect_gce_environment():
        SETTINGS.env_name = 'GCE_PRODUCTION'
        return True
    return False


class GoogleCredentials(OAuth2Credentials):
    """Application Default Credentials for use in calling Google APIs.

    The Application Default Credentials are being constructed as a function of
    the environment where the code is being run.
    More details can be found on this page:
    https://developers.google.com/accounts/docs/application-default-credentials

    Here is an example of how to use the Application Default Credentials for a
    service that requires authentication::

        from googleapiclient.discovery import build
        from oauth2client.client import GoogleCredentials

        credentials = GoogleCredentials.get_application_default()
        service = build('compute', 'v1', credentials=credentials)

        PROJECT = 'bamboo-machine-422'
        ZONE = 'us-central1-a'
        request = service.instances().list(project=PROJECT, zone=ZONE)
        response = request.execute()

        print(response)
    """

    NON_SERIALIZED_MEMBERS = (
        frozenset(['_private_key']) |
        OAuth2Credentials.NON_SERIALIZED_MEMBERS)
    """Members that aren't serialized when object is converted to JSON."""

    def __init__(self, access_token, client_id, client_secret, refresh_token,
                 token_expiry, token_uri, user_agent,
                 revoke_uri=oauth2client.GOOGLE_REVOKE_URI):
        """Create an instance of GoogleCredentials.

        This constructor is not usually called by the user, instead
        GoogleCredentials objects are instantiated by
        GoogleCredentials.from_stream() or
        GoogleCredentials.get_application_default().

        Args:
            access_token: string, access token.
            client_id: string, client identifier.
            client_secret: string, client secret.
            refresh_token: string, refresh token.
            token_expiry: datetime, when the access_token expires.
            token_uri: string, URI of token endpoint.
            user_agent: string, The HTTP User-Agent to provide for this
                        application.
            revoke_uri: string, URI for revoke endpoint. Defaults to
                        oauth2client.GOOGLE_REVOKE_URI; a token can't be
                        revoked if this is None.
        """
        super(GoogleCredentials, self).__init__(
            access_token, client_id, client_secret, refresh_token,
            token_expiry, token_uri, user_agent, revoke_uri=revoke_uri)

    def create_scoped_required(self):
        """Whether this Credentials object is scopeless.

        create_scoped(scopes) method needs to be called in order to create
        a Credentials object for API calls.
        """
        return False

    def create_scoped(self, scopes):
        """Create a Credentials object for the given scopes.

        The Credentials type is preserved.
        """
        return self

    @classmethod
    def from_json(cls, json_data):
        # TODO(issue 388): eliminate the circularity that is the reason for
        #                  this non-top-level import.
        from oauth2client import service_account
        data = json.loads(_helpers._from_bytes(json_data))

        # We handle service_account.ServiceAccountCredentials since it is a
        # possible return type of GoogleCredentials.get_application_default()
        if (data['_module'] == 'oauth2client.service_account' and
                data['_class'] == 'ServiceAccountCredentials'):
            return service_account.ServiceAccountCredentials.from_json(data)
        elif (data['_module'] == 'oauth2client.service_account' and
                data['_class'] == '_JWTAccessCredentials'):
            return service_account._JWTAccessCredentials.from_json(data)

        token_expiry = _parse_expiry(data.get('token_expiry'))
        google_credentials = cls(
            data['access_token'],
            data['client_id'],
            data['client_secret'],
            data['refresh_token'],
            token_expiry,
            data['token_uri'],
            data['user_agent'],
            revoke_uri=data.get('revoke_uri', None))
        google_credentials.invalid = data['invalid']
        return google_credentials

    @property
    def serialization_data(self):
        """Get the fields and values identifying the current credentials."""
        return {
            'type': 'authorized_user',
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'refresh_token': self.refresh_token
        }

    @staticmethod
    def _implicit_credentials_from_gae():
        """Attempts to get implicit credentials in Google App Engine env.

        If the current environment is not detected as App Engine, returns None,
        indicating no Google App Engine credentials can be detected from the
        current environment.

        Returns:
            None, if not in GAE, else an appengine.AppAssertionCredentials
            object.
        """
        if not _in_gae_environment():
            return None

        return _get_application_default_credential_GAE()

    @staticmethod
    def _implicit_credentials_from_gce():
        """Attempts to get implicit credentials in Google Compute Engine env.

        If the current environment is not detected as Compute Engine, returns
        None, indicating no Google Compute Engine credentials can be detected
        from the current environment.

        Returns:
            None, if not in GCE, else a gce.AppAssertionCredentials object.
        """
        if not _in_gce_environment():
            return None

        return _get_application_default_credential_GCE()

    @staticmethod
    def _implicit_credentials_from_files():
        """Attempts to get implicit credentials from local credential files.

        First checks if the environment variable GOOGLE_APPLICATION_CREDENTIALS
        is set with a filename and then falls back to a configuration file (the
        "well known" file) associated with the 'gcloud' command line tool.

        Returns:
            Credentials object associated with the
            GOOGLE_APPLICATION_CREDENTIALS file or the "well known" file if
            either exist. If neither file is define, returns None, indicating
            no credentials from a file can detected from the current
            environment.
        """
        credentials_filename = _get_environment_variable_file()
        if not credentials_filename:
            credentials_filename = _get_well_known_file()
            if os.path.isfile(credentials_filename):
                extra_help = (' (produced automatically when running'
                              ' "gcloud auth login" command)')
            else:
                credentials_filename = None
        else:
            extra_help = (' (pointed to by ' + GOOGLE_APPLICATION_CREDENTIALS +
                          ' environment variable)')

        if not credentials_filename:
            return

        # If we can read the credentials from a file, we don't need to know
        # what environment we are in.
        SETTINGS.env_name = DEFAULT_ENV_NAME

        try:
            return _get_application_default_credential_from_file(
                credentials_filename)
        except (ApplicationDefaultCredentialsError, ValueError) as error:
            _raise_exception_for_reading_json(credentials_filename,
                                              extra_help, error)

    @classmethod
    def _get_implicit_credentials(cls):
        """Gets credentials implicitly from the environment.

        Checks environment in order of precedence:
        - Environment variable GOOGLE_APPLICATION_CREDENTIALS pointing to
          a file with stored credentials information.
        - Stored "well known" file associated with `gcloud` command line tool.
        - Google App Engine (production and testing)
        - Google Compute Engine production environment.

        Raises:
            ApplicationDefaultCredentialsError: raised when the credentials
                                                fail to be retrieved.
        """
        # Environ checks (in order).
        environ_checkers = [
            cls._implicit_credentials_from_files,
            cls._implicit_credentials_from_gae,
            cls._implicit_credentials_from_gce,
        ]

        for checker in environ_checkers:
            credentials = checker()
            if credentials is not None:
                return credentials

        # If no credentials, fail.
        raise ApplicationDefaultCredentialsError(ADC_HELP_MSG)

    @staticmethod
    def get_application_default():
        """Get the Application Default Credentials for the current environment.

        Raises:
            ApplicationDefaultCredentialsError: raised when the credentials
                                                fail to be retrieved.
        """
        return GoogleCredentials._get_implicit_credentials()

    @staticmethod
    def from_stream(credential_filename):
        """Create a Credentials object by reading information from a file.

        It returns an object of type GoogleCredentials.

        Args:
            credential_filename: the path to the file from where the
                                 credentials are to be read

        Raises:
            ApplicationDefaultCredentialsError: raised when the credentials
                                                fail to be retrieved.
        """
        if credential_filename and os.path.isfile(credential_filename):
            try:
                return _get_application_default_credential_from_file(
                    credential_filename)
            except (ApplicationDefaultCredentialsError, ValueError) as error:
                extra_help = (' (provided as parameter to the '
                              'from_stream() method)')
                _raise_exception_for_reading_json(credential_filename,
                                                  extra_help,
                                                  error)
        else:
            raise ApplicationDefaultCredentialsError(
                'The parameter passed to the from_stream() '
                'method should point to a file.')


def _save_private_file(filename, json_contents):
    """Saves a file with read-write permissions on for the owner.

    Args:
        filename: String. Absolute path to file.
        json_contents: JSON serializable object to be saved.
    """
    temp_filename = tempfile.mktemp()
    file_desc = os.open(temp_filename, os.O_WRONLY | os.O_CREAT, 0o600)
    with os.fdopen(file_desc, 'w') as file_handle:
        json.dump(json_contents, file_handle, sort_keys=True,
                  indent=2, separators=(',', ': '))
    shutil.move(temp_filename, filename)


def save_to_well_known_file(credentials, well_known_file=None):
    """Save the provided GoogleCredentials to the well known file.

    Args:
        credentials: the credentials to be saved to the well known file;
                     it should be an instance of GoogleCredentials
        well_known_file: the name of the file where the credentials are to be
                         saved; this parameter is supposed to be used for
                         testing only
    """
    # TODO(orestica): move this method to tools.py
    # once the argparse import gets fixed (it is not present in Python 2.6)

    if well_known_file is None:
        well_known_file = _get_well_known_file()

    config_dir = os.path.dirname(well_known_file)
    if not os.path.isdir(config_dir):
        raise OSError(
            'Config directory does not exist: {0}'.format(config_dir))

    credentials_data = credentials.serialization_data
    _save_private_file(well_known_file, credentials_data)


def _get_environment_variable_file():
    application_default_credential_filename = (
        os.environ.get(GOOGLE_APPLICATION_CREDENTIALS, None))

    if application_default_credential_filename:
        if os.path.isfile(application_default_credential_filename):
            return application_default_credential_filename
        else:
            raise ApplicationDefaultCredentialsError(
                'File ' + application_default_credential_filename +
                ' (pointed by ' +
                GOOGLE_APPLICATION_CREDENTIALS +
                ' environment variable) does not exist!')


def _get_well_known_file():
    """Get the well known file produced by command 'gcloud auth login'."""
    # TODO(orestica): Revisit this method once gcloud provides a better way
    # of pinpointing the exact location of the file.
    default_config_dir = os.getenv(_CLOUDSDK_CONFIG_ENV_VAR)
    if default_config_dir is None:
        if os.name == 'nt':
            try:
                default_config_dir = os.path.join(os.environ['APPDATA'],
                                                  _CLOUDSDK_CONFIG_DIRECTORY)
            except KeyError:
                # This should never happen unless someone is really
                # messing with things.
                drive = os.environ.get('SystemDrive', 'C:')
                default_config_dir = os.path.join(drive, '\\',
                                                  _CLOUDSDK_CONFIG_DIRECTORY)
        else:
            default_config_dir = os.path.join(os.path.expanduser('~'),
                                              '.config',
                                              _CLOUDSDK_CONFIG_DIRECTORY)

    return os.path.join(default_config_dir, _WELL_KNOWN_CREDENTIALS_FILE)


def _get_application_default_credential_from_file(filename):
    """Build the Application Default Credentials from file."""
    # read the credentials from the file
    with open(filename) as file_obj:
        client_credentials = json.load(file_obj)

    credentials_type = client_credentials.get('type')
    if credentials_type == AUTHORIZED_USER:
        required_fields = set(['client_id', 'client_secret', 'refresh_token'])
    elif credentials_type == SERVICE_ACCOUNT:
        required_fields = set(['client_id', 'client_email', 'private_key_id',
                               'private_key'])
    else:
        raise ApplicationDefaultCredentialsError(
            "'type' field should be defined (and have one of the '" +
            AUTHORIZED_USER + "' or '" + SERVICE_ACCOUNT + "' values)")

    missing_fields = required_fields.difference(client_credentials.keys())

    if missing_fields:
        _raise_exception_for_missing_fields(missing_fields)

    if client_credentials['type'] == AUTHORIZED_USER:
        return GoogleCredentials(
            access_token=None,
            client_id=client_credentials['client_id'],
            client_secret=client_credentials['client_secret'],
            refresh_token=client_credentials['refresh_token'],
            token_expiry=None,
            token_uri=oauth2client.GOOGLE_TOKEN_URI,
            user_agent='Python client library')
    else:  # client_credentials['type'] == SERVICE_ACCOUNT
        from oauth2client import service_account
        return service_account._JWTAccessCredentials.from_json_keyfile_dict(
            client_credentials)


def _raise_exception_for_missing_fields(missing_fields):
    raise ApplicationDefaultCredentialsError(
        'The following field(s) must be defined: ' + ', '.join(missing_fields))


def _raise_exception_for_reading_json(credential_file,
                                      extra_help,
                                      error):
    raise ApplicationDefaultCredentialsError(
        'An error was encountered while reading json file: ' +
        credential_file + extra_help + ': ' + str(error))


def _get_application_default_credential_GAE():
    from oauth2client.contrib.appengine import AppAssertionCredentials

    return AppAssertionCredentials([])


def _get_application_default_credential_GCE():
    from oauth2client.contrib.gce import AppAssertionCredentials

    return AppAssertionCredentials()


class AssertionCredentials(GoogleCredentials):
    """Abstract Credentials object used for OAuth 2.0 assertion grants.

    This credential does not require a flow to instantiate because it
    represents a two legged flow, and therefore has all of the required
    information to generate and refresh its own access tokens. It must
    be subclassed to generate the appropriate assertion string.

    AssertionCredentials objects may be safely pickled and unpickled.
    """

    @util.positional(2)
    def __init__(self, assertion_type, user_agent=None,
                 token_uri=oauth2client.GOOGLE_TOKEN_URI,
                 revoke_uri=oauth2client.GOOGLE_REVOKE_URI,
                 **unused_kwargs):
        """Constructor for AssertionFlowCredentials.

        Args:
            assertion_type: string, assertion type that will be declared to the
                            auth server
            user_agent: string, The HTTP User-Agent to provide for this
                        application.
            token_uri: string, URI for token endpoint. For convenience defaults
                       to Google's endpoints but any OAuth 2.0 provider can be
                       used.
            revoke_uri: string, URI for revoke endpoint.
        """
        super(AssertionCredentials, self).__init__(
            None,
            None,
            None,
            None,
            None,
            token_uri,
            user_agent,
            revoke_uri=revoke_uri)
        self.assertion_type = assertion_type

    def _generate_refresh_request_body(self):
        assertion = self._generate_assertion()

        body = urllib.parse.urlencode({
            'assertion': assertion,
            'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        })

        return body

    def _generate_assertion(self):
        """Generate assertion string to be used in the access token request."""
        raise NotImplementedError

    def _revoke(self, http_request):
        """Revokes the access_token and deletes the store if available.

        Args:
            http_request: callable, a callable that matches the method
                          signature of httplib2.Http.request, used to make the
                          revoke request.
        """
        self._do_revoke(http_request, self.access_token)

    def sign_blob(self, blob):
        """Cryptographically sign a blob (of bytes).

        Args:
            blob: bytes, Message to be signed.

        Returns:
            tuple, A pair of the private key ID used to sign the blob and
            the signed contents.
        """
        raise NotImplementedError('This method is abstract.')


def _require_crypto_or_die():
    """Ensure we have a crypto library, or throw CryptoUnavailableError.

    The oauth2client.crypt module requires either PyCrypto or PyOpenSSL
    to be available in order to function, but these are optional
    dependencies.
    """
    if not HAS_CRYPTO:
        raise CryptoUnavailableError('No crypto library available')


@util.positional(2)
def verify_id_token(id_token, audience, http=None,
                    cert_uri=ID_TOKEN_VERIFICATION_CERTS):
    """Verifies a signed JWT id_token.

    This function requires PyOpenSSL and because of that it does not work on
    App Engine.

    Args:
        id_token: string, A Signed JWT.
        audience: string, The audience 'aud' that the token should be for.
        http: httplib2.Http, instance to use to make the HTTP request. Callers
              should supply an instance that has caching enabled.
        cert_uri: string, URI of the certificates in JSON format to
                  verify the JWT against.

    Returns:
        The deserialized JSON in the JWT.

    Raises:
        oauth2client.crypt.AppIdentityError: if the JWT fails to verify.
        CryptoUnavailableError: if no crypto library is available.
    """
    _require_crypto_or_die()
    if http is None:
        http = transport.get_cached_http()

    resp, content = http.request(cert_uri)
    if resp.status == http_client.OK:
        certs = json.loads(_helpers._from_bytes(content))
        return crypt.verify_signed_jwt_with_certs(id_token, certs, audience)
    else:
        raise VerifyJwtTokenError('Status code: {0}'.format(resp.status))


def _extract_id_token(id_token):
    """Extract the JSON payload from a JWT.

    Does the extraction w/o checking the signature.

    Args:
        id_token: string or bytestring, OAuth 2.0 id_token.

    Returns:
        object, The deserialized JSON payload.
    """
    if type(id_token) == bytes:
        segments = id_token.split(b'.')
    else:
        segments = id_token.split(u'.')

    if len(segments) != 3:
        raise VerifyJwtTokenError(
            'Wrong number of segments in token: {0}'.format(id_token))

    return json.loads(
        _helpers._from_bytes(_helpers._urlsafe_b64decode(segments[1])))


def _parse_exchange_token_response(content):
    """Parses response of an exchange token request.

    Most providers return JSON but some (e.g. Facebook) return a
    url-encoded string.

    Args:
        content: The body of a response

    Returns:
        Content as a dictionary object. Note that the dict could be empty,
        i.e. {}. That basically indicates a failure.
    """
    resp = {}
    content = _helpers._from_bytes(content)
    try:
        resp = json.loads(content)
    except Exception:
        # different JSON libs raise different exceptions,
        # so we just do a catch-all here
        resp = dict(urllib.parse.parse_qsl(content))

    # some providers respond with 'expires', others with 'expires_in'
    if resp and 'expires' in resp:
        resp['expires_in'] = resp.pop('expires')

    return resp


@util.positional(4)
def credentials_from_code(client_id, client_secret, scope, code,
                          redirect_uri='postmessage', http=None,
                          user_agent=None,
                          token_uri=oauth2client.GOOGLE_TOKEN_URI,
                          auth_uri=oauth2client.GOOGLE_AUTH_URI,
                          revoke_uri=oauth2client.GOOGLE_REVOKE_URI,
                          device_uri=oauth2client.GOOGLE_DEVICE_URI,
                          token_info_uri=oauth2client.GOOGLE_TOKEN_INFO_URI):
    """Exchanges an authorization code for an OAuth2Credentials object.

    Args:
        client_id: string, client identifier.
        client_secret: string, client secret.
        scope: string or iterable of strings, scope(s) to request.
        code: string, An authorization code, most likely passed down from
              the client
        redirect_uri: string, this is generally set to 'postmessage' to match
                      the redirect_uri that the client specified
        http: httplib2.Http, optional http instance to use to do the fetch
        token_uri: string, URI for token endpoint. For convenience defaults
                   to Google's endpoints but any OAuth 2.0 provider can be
                   used.
        auth_uri: string, URI for authorization endpoint. For convenience
                  defaults to Google's endpoints but any OAuth 2.0 provider
                  can be used.
        revoke_uri: string, URI for revoke endpoint. For convenience
                    defaults to Google's endpoints but any OAuth 2.0 provider
                    can be used.
        device_uri: string, URI for device authorization endpoint. For
                    convenience defaults to Google's endpoints but any OAuth
                    2.0 provider can be used.

    Returns:
        An OAuth2Credentials object.

    Raises:
        FlowExchangeError if the authorization code cannot be exchanged for an
        access token
    """
    flow = OAuth2WebServerFlow(client_id, client_secret, scope,
                               redirect_uri=redirect_uri,
                               user_agent=user_agent, auth_uri=auth_uri,
                               token_uri=token_uri, revoke_uri=revoke_uri,
                               device_uri=device_uri,
                               token_info_uri=token_info_uri)

    credentials = flow.step2_exchange(code, http=http)
    return credentials


@util.positional(3)
def credentials_from_clientsecrets_and_code(filename, scope, code,
                                            message=None,
                                            redirect_uri='postmessage',
                                            http=None,
                                            cache=None,
                                            device_uri=None):
    """Returns OAuth2Credentials from a clientsecrets file and an auth code.

    Will create the right kind of Flow based on the contents of the
    clientsecrets file or will raise InvalidClientSecretsError for unknown
    types of Flows.

    Args:
        filename: string, File name of clientsecrets.
        scope: string or iterable of strings, scope(s) to request.
        code: string, An authorization code, most likely passed down from
              the client
        message: string, A friendly string to display to the user if the
                 clientsecrets file is missing or invalid. If message is
                 provided then sys.exit will be called in the case of an error.
                 If message in not provided then
                 clientsecrets.InvalidClientSecretsError will be raised.
        redirect_uri: string, this is generally set to 'postmessage' to match
                      the redirect_uri that the client specified
        http: httplib2.Http, optional http instance to use to do the fetch
        cache: An optional cache service client that implements get() and set()
               methods. See clientsecrets.loadfile() for details.
        device_uri: string, OAuth 2.0 device authorization endpoint

    Returns:
        An OAuth2Credentials object.

    Raises:
        FlowExchangeError: if the authorization code cannot be exchanged for an
                           access token
        UnknownClientSecretsFlowError: if the file describes an unknown kind
                                       of Flow.
        clientsecrets.InvalidClientSecretsError: if the clientsecrets file is
                                                 invalid.
    """
    flow = flow_from_clientsecrets(filename, scope, message=message,
                                   cache=cache, redirect_uri=redirect_uri,
                                   device_uri=device_uri)
    credentials = flow.step2_exchange(code, http=http)
    return credentials


class DeviceFlowInfo(collections.namedtuple('DeviceFlowInfo', (
        'device_code', 'user_code', 'interval', 'verification_url',
        'user_code_expiry'))):
    """Intermediate information the OAuth2 for devices flow."""

    @classmethod
    def FromResponse(cls, response):
        """Create a DeviceFlowInfo from a server response.

        The response should be a dict containing entries as described here:

        http://tools.ietf.org/html/draft-ietf-oauth-v2-05#section-3.7.1
        """
        # device_code, user_code, and verification_url are required.
        kwargs = {
            'device_code': response['device_code'],
            'user_code': response['user_code'],
        }
        # The response may list the verification address as either
        # verification_url or verification_uri, so we check for both.
        verification_url = response.get(
            'verification_url', response.get('verification_uri'))
        if verification_url is None:
            raise OAuth2DeviceCodeError(
                'No verification_url provided in server response')
        kwargs['verification_url'] = verification_url
        # expires_in and interval are optional.
        kwargs.update({
            'interval': response.get('interval'),
            'user_code_expiry': None,
        })
        if 'expires_in' in response:
            kwargs['user_code_expiry'] = (
                _UTCNOW() +
                datetime.timedelta(seconds=int(response['expires_in'])))
        return cls(**kwargs)


def _oauth2_web_server_flow_params(kwargs):
    """Configures redirect URI parameters for OAuth2WebServerFlow."""
    params = {
        'access_type': 'offline',
        'response_type': 'code',
    }

    params.update(kwargs)

    # Check for the presence of the deprecated approval_prompt param and
    # warn appropriately.
    approval_prompt = params.get('approval_prompt')
    if approval_prompt is not None:
        logger.warning(
            'The approval_prompt parameter for OAuth2WebServerFlow is '
            'deprecated. Please use the prompt parameter instead.')

        if approval_prompt == 'force':
            logger.warning(
                'approval_prompt="force" has been adjusted to '
                'prompt="consent"')
            params['prompt'] = 'consent'
            del params['approval_prompt']

    return params


class OAuth2WebServerFlow(Flow):
    """Does the Web Server Flow for OAuth 2.0.

    OAuth2WebServerFlow objects may be safely pickled and unpickled.
    """

    @util.positional(4)
    def __init__(self, client_id,
                 client_secret=None,
                 scope=None,
                 redirect_uri=None,
                 user_agent=None,
                 auth_uri=oauth2client.GOOGLE_AUTH_URI,
                 token_uri=oauth2client.GOOGLE_TOKEN_URI,
                 revoke_uri=oauth2client.GOOGLE_REVOKE_URI,
                 login_hint=None,
                 device_uri=oauth2client.GOOGLE_DEVICE_URI,
                 token_info_uri=oauth2client.GOOGLE_TOKEN_INFO_URI,
                 authorization_header=None,
                 **kwargs):
        """Constructor for OAuth2WebServerFlow.

        The kwargs argument is used to set extra query parameters on the
        auth_uri. For example, the access_type and prompt
        query parameters can be set via kwargs.

        Args:
            client_id: string, client identifier.
            client_secret: string client secret.
            scope: string or iterable of strings, scope(s) of the credentials
                   being requested.
            redirect_uri: string, Either the string 'urn:ietf:wg:oauth:2.0:oob'
                          for a non-web-based application, or a URI that
                          handles the callback from the authorization server.
            user_agent: string, HTTP User-Agent to provide for this
                        application.
            auth_uri: string, URI for authorization endpoint. For convenience
                      defaults to Google's endpoints but any OAuth 2.0 provider
                      can be used.
            token_uri: string, URI for token endpoint. For convenience
                       defaults to Google's endpoints but any OAuth 2.0
                       provider can be used.
            revoke_uri: string, URI for revoke endpoint. For convenience
                        defaults to Google's endpoints but any OAuth 2.0
                        provider can be used.
            login_hint: string, Either an email address or domain. Passing this
                        hint will either pre-fill the email box on the sign-in
                        form or select the proper multi-login session, thereby
                        simplifying the login flow.
            device_uri: string, URI for device authorization endpoint. For
                        convenience defaults to Google's endpoints but any
                        OAuth 2.0 provider can be used.
            authorization_header: string, For use with OAuth 2.0 providers that
                                  require a client to authenticate using a
                                  header value instead of passing client_secret
                                  in the POST body.
            **kwargs: dict, The keyword arguments are all optional and required
                      parameters for the OAuth calls.
        """
        # scope is a required argument, but to preserve backwards-compatibility
        # we don't want to rearrange the positional arguments
        if scope is None:
            raise TypeError("The value of scope must not be None")
        self.client_id = client_id
        self.client_secret = client_secret
        self.scope = util.scopes_to_string(scope)
        self.redirect_uri = redirect_uri
        self.login_hint = login_hint
        self.user_agent = user_agent
        self.auth_uri = auth_uri
        self.token_uri = token_uri
        self.revoke_uri = revoke_uri
        self.device_uri = device_uri
        self.token_info_uri = token_info_uri
        self.authorization_header = authorization_header
        self.params = _oauth2_web_server_flow_params(kwargs)

    @util.positional(1)
    def step1_get_authorize_url(self, redirect_uri=None, state=None):
        """Returns a URI to redirect to the provider.

        Args:
            redirect_uri: string, Either the string 'urn:ietf:wg:oauth:2.0:oob'
                          for a non-web-based application, or a URI that
                          handles the callback from the authorization server.
                          This parameter is deprecated, please move to passing
                          the redirect_uri in via the constructor.
            state: string, Opaque state string which is passed through the
                   OAuth2 flow and returned to the client as a query parameter
                   in the callback.

        Returns:
            A URI as a string to redirect the user to begin the authorization
            flow.
        """
        if redirect_uri is not None:
            logger.warning((
                'The redirect_uri parameter for '
                'OAuth2WebServerFlow.step1_get_authorize_url is deprecated. '
                'Please move to passing the redirect_uri in via the '
                'constructor.'))
            self.redirect_uri = redirect_uri

        if self.redirect_uri is None:
            raise ValueError('The value of redirect_uri must not be None.')

        query_params = {
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'scope': self.scope,
        }
        if state is not None:
            query_params['state'] = state
        if self.login_hint is not None:
            query_params['login_hint'] = self.login_hint
        query_params.update(self.params)
        return _update_query_params(self.auth_uri, query_params)

    @util.positional(1)
    def step1_get_device_and_user_codes(self, http=None):
        """Returns a user code and the verification URL where to enter it

        Returns:
            A user code as a string for the user to authorize the application
            An URL as a string where the user has to enter the code
        """
        if self.device_uri is None:
            raise ValueError('The value of device_uri must not be None.')

        body = urllib.parse.urlencode({
            'client_id': self.client_id,
            'scope': self.scope,
        })
        headers = {
            'content-type': 'application/x-www-form-urlencoded',
        }

        if self.user_agent is not None:
            headers['user-agent'] = self.user_agent

        if http is None:
            http = transport.get_http_object()

        resp, content = http.request(self.device_uri, method='POST', body=body,
                                     headers=headers)
        content = _helpers._from_bytes(content)
        if resp.status == http_client.OK:
            try:
                flow_info = json.loads(content)
            except ValueError as exc:
                raise OAuth2DeviceCodeError(
                    'Could not parse server response as JSON: "{0}", '
                    'error: "{1}"'.format(content, exc))
            return DeviceFlowInfo.FromResponse(flow_info)
        else:
            error_msg = 'Invalid response {0}.'.format(resp.status)
            try:
                error_dict = json.loads(content)
                if 'error' in error_dict:
                    error_msg += ' Error: {0}'.format(error_dict['error'])
            except ValueError:
                # Couldn't decode a JSON response, stick with the
                # default message.
                pass
            raise OAuth2DeviceCodeError(error_msg)

    @util.positional(2)
    def step2_exchange(self, code=None, http=None, device_flow_info=None):
        """Exchanges a code for OAuth2Credentials.

        Args:
            code: string, a dict-like object, or None. For a non-device
                  flow, this is either the response code as a string, or a
                  dictionary of query parameters to the redirect_uri. For a
                  device flow, this should be None.
            http: httplib2.Http, optional http instance to use when fetching
                  credentials.
            device_flow_info: DeviceFlowInfo, return value from step1 in the
                              case of a device flow.

        Returns:
            An OAuth2Credentials object that can be used to authorize requests.

        Raises:
            FlowExchangeError: if a problem occurred exchanging the code for a
                               refresh_token.
            ValueError: if code and device_flow_info are both provided or both
                        missing.
        """
        if code is None and device_flow_info is None:
            raise ValueError('No code or device_flow_info provided.')
        if code is not None and device_flow_info is not None:
            raise ValueError('Cannot provide both code and device_flow_info.')

        if code is None:
            code = device_flow_info.device_code
        elif not isinstance(code, (six.string_types, six.binary_type)):
            if 'code' not in code:
                raise FlowExchangeError(code.get(
                    'error', 'No code was supplied in the query parameters.'))
            code = code['code']

        post_data = {
            'client_id': self.client_id,
            'code': code,
            'scope': self.scope,
        }
        if self.client_secret is not None:
            post_data['client_secret'] = self.client_secret
        if device_flow_info is not None:
            post_data['grant_type'] = 'http://oauth.net/grant_type/device/1.0'
        else:
            post_data['grant_type'] = 'authorization_code'
            post_data['redirect_uri'] = self.redirect_uri
        body = urllib.parse.urlencode(post_data)
        headers = {
            'content-type': 'application/x-www-form-urlencoded',
        }
        if self.authorization_header is not None:
            headers['Authorization'] = self.authorization_header
        if self.user_agent is not None:
            headers['user-agent'] = self.user_agent

        if http is None:
            http = transport.get_http_object()

        resp, content = http.request(self.token_uri, method='POST', body=body,
                                     headers=headers)
        d = _parse_exchange_token_response(content)
        if resp.status == http_client.OK and 'access_token' in d:
            access_token = d['access_token']
            refresh_token = d.get('refresh_token', None)
            if not refresh_token:
                logger.info(
                    'Received token response with no refresh_token. Consider '
                    "reauthenticating with prompt='consent'.")
            token_expiry = None
            if 'expires_in' in d:
                delta = datetime.timedelta(seconds=int(d['expires_in']))
                token_expiry = delta + _UTCNOW()

            extracted_id_token = None
            if 'id_token' in d:
                extracted_id_token = _extract_id_token(d['id_token'])

            logger.info('Successfully retrieved access token')
            return OAuth2Credentials(
                access_token, self.client_id, self.client_secret,
                refresh_token, token_expiry, self.token_uri, self.user_agent,
                revoke_uri=self.revoke_uri, id_token=extracted_id_token,
                token_response=d, scopes=self.scope,
                token_info_uri=self.token_info_uri)
        else:
            logger.info('Failed to retrieve access token: %s', content)
            if 'error' in d:
                # you never know what those providers got to say
                error_msg = (str(d['error']) +
                             str(d.get('error_description', '')))
            else:
                error_msg = 'Invalid response: {0}.'.format(str(resp.status))
            raise FlowExchangeError(error_msg)


@util.positional(2)
def flow_from_clientsecrets(filename, scope, redirect_uri=None,
                            message=None, cache=None, login_hint=None,
                            device_uri=None):
    """Create a Flow from a clientsecrets file.

    Will create the right kind of Flow based on the contents of the
    clientsecrets file or will raise InvalidClientSecretsError for unknown
    types of Flows.

    Args:
        filename: string, File name of client secrets.
        scope: string or iterable of strings, scope(s) to request.
        redirect_uri: string, Either the string 'urn:ietf:wg:oauth:2.0:oob' for
                      a non-web-based application, or a URI that handles the
                      callback from the authorization server.
        message: string, A friendly string to display to the user if the
                 clientsecrets file is missing or invalid. If message is
                 provided then sys.exit will be called in the case of an error.
                 If message in not provided then
                 clientsecrets.InvalidClientSecretsError will be raised.
        cache: An optional cache service client that implements get() and set()
               methods. See clientsecrets.loadfile() for details.
        login_hint: string, Either an email address or domain. Passing this
                    hint will either pre-fill the email box on the sign-in form
                    or select the proper multi-login session, thereby
                    simplifying the login flow.
        device_uri: string, URI for device authorization endpoint. For
                    convenience defaults to Google's endpoints but any
                    OAuth 2.0 provider can be used.

    Returns:
        A Flow object.

    Raises:
        UnknownClientSecretsFlowError: if the file describes an unknown kind of
                                       Flow.
        clientsecrets.InvalidClientSecretsError: if the clientsecrets file is
                                                 invalid.
    """
    try:
        client_type, client_info = clientsecrets.loadfile(filename,
                                                          cache=cache)
        if client_type in (clientsecrets.TYPE_WEB,
                           clientsecrets.TYPE_INSTALLED):
            constructor_kwargs = {
                'redirect_uri': redirect_uri,
                'auth_uri': client_info['auth_uri'],
                'token_uri': client_info['token_uri'],
                'login_hint': login_hint,
            }
            revoke_uri = client_info.get('revoke_uri')
            if revoke_uri is not None:
                constructor_kwargs['revoke_uri'] = revoke_uri
            if device_uri is not None:
                constructor_kwargs['device_uri'] = device_uri
            return OAuth2WebServerFlow(
                client_info['client_id'], client_info['client_secret'],
                scope, **constructor_kwargs)

    except clientsecrets.InvalidClientSecretsError as e:
        if message is not None:
            if e.args:
                message = ('The client secrets were invalid: '
                           '\n{0}\n{1}'.format(e, message))
            sys.exit(message)
        else:
            raise
    else:
        raise UnknownClientSecretsFlowError(
            'This OAuth 2.0 flow is unsupported: {0!r}'.format(client_type))
