signature:
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
 pkce : boolean , default : False , Generate and include a " Proof Key
 for Code Exchange " ( PKCE ) with your authorization and token
 requests . This adds security for installed applications that
 cannot protect a client _ secret . See RFC 7636 for details .
 code _ verifier : bytestring or None , default : None , parameter passed
 as part of the code exchange when pkce = True . If
 None , a code _ verifier will automatically be
 generated as part of step1 _ get _ authorize _ url ( ) . See
 RFC 7636 for details .
 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 ."""

implementation:
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


signature:
def _oauth2_web_server_flow_params ( kwargs ) :
    """Configures redirect URI parameters for OAuth2WebServerFlow ."""

implementation:
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


signature:
def flow_from_clientsecrets ( filename , scope , redirect_uri = None , message = None , cache = None , login_hint = None , device_uri = None , pkce = None , code_verifier = None , prompt = 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 ."""

implementation:
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' )
        optional = ( 'revoke_uri' , 'device_uri' , 'pkce' , 'code_verifier' , 'prompt' )
        for param in optional :
            if locals ( ) [ param ] is not None :
                constructor_kwargs [ param ] = locals ( ) [ param ]
        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 ) )


signature:
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 ( ) ."""

implementation:
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 )


signature:
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 ( ) ."""

implementation:
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 )


signature:
def put ( self , credentials ) :
    """Write a credential .
 The Storage lock must be held when this is called .
 Args :
 credentials : Credentials , the credentials to store ."""

implementation:
self . acquire_lock ( )
try :
    self . locked_put ( credentials )
finally :
    self . release_lock ( )


signature:
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 ."""

implementation:
scopes = _helpers . string_to_scopes ( scopes )
return set ( scopes ) . issubset ( self . scopes )


signature:
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 ."""

implementation:
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 ) , id_token_jwt = data . get ( 'id_token_jwt' , 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


signature:
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 ."""

implementation:
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


signature:
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 ."""

implementation:
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 ( ) )


signature:
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 ."""

implementation:
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


signature:
def _generate_refresh_request_body ( self ) :
    """Generate the body that will be used in the refresh request ."""

implementation:
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


signature:
def _refresh ( self , http ) :
    """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 : an object to be used to make HTTP requests .
 Raises :
 HttpAccessTokenRefreshError : When the refresh fails ."""

implementation:
if not self . store :
    self . _do_refresh_request ( http )
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 )
    finally :
        self . store . release_lock ( )


signature:
def _do_refresh_request ( self , http ) :
    """Refresh the access _ token using the refresh _ token .
 Args :
 http : an object to be used to make HTTP requests .
 Raises :
 HttpAccessTokenRefreshError : When the refresh fails ."""

implementation:
body = self . _generate_refresh_request_body ( )
headers = self . _generate_refresh_request_headers ( )
logger . info ( 'Refreshing access_token' )
resp , content = transport . request ( http , 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' ] )
        self . id_token_jwt = d [ 'id_token' ]
    else :
        self . id_token = None
        self . id_token_jwt = 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 )


signature:
def _revoke ( self , http ) :
    """Revokes this credential and deletes the stored copy ( if it exists ) .
 Args :
 http : an object to be used to make HTTP requests ."""

implementation: self . _do_revoke ( http , self . refresh_token or self . access_token )


signature:
def _do_revoke ( self , http , token ) :
    """Revokes this credential and deletes the stored copy ( if it exists ) .
 Args :
 http : an object to be used to make HTTP requests .
 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 ."""

implementation:
logger . info ( 'Revoking token' )
query_params = { 'token' : token }
token_revoke_uri = _helpers . update_query_params ( self . revoke_uri , query_params )
resp , content = transport . request ( http , token_revoke_uri )
if resp . status == http_client . METHOD_NOT_ALLOWED :
    body = urllib . parse . urlencode ( query_params )
    resp , content = transport . request ( http , token_revoke_uri , method = 'POST' , body = body )
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 ( )


signature:
def _do_retrieve_scopes ( self , http , token ) :
    """Retrieves the list of authorized scopes from the OAuth2 provider .
 Args :
 http : an object to be used to make HTTP requests .
 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 ."""

implementation:
logger . info ( 'Refreshing scopes' )
query_params = { 'access_token' : token , 'fields' : 'scope' }
token_info_uri = _helpers . update_query_params ( self . token_info_uri , query_params )
resp , content = transport . request ( http , token_info_uri )
content = _helpers . _from_bytes ( content )
if resp . status == http_client . OK :
    d = json . loads ( content )
    self . scopes = set ( _helpers . 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 )


signature:
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 ."""

implementation:
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 )


signature:
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 ."""

implementation:
# 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 )


signature:
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 ."""

implementation:
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.' )


signature:
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"""

implementation:
# 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 )


signature:
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 ."""

implementation:
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
if self . _pkce :
    if not self . code_verifier :
        self . code_verifier = _pkce . code_verifier ( )
    challenge = _pkce . code_challenge ( self . code_verifier )
    query_params [ 'code_challenge' ] = challenge
    query_params [ 'code_challenge_method' ] = 'S256'
query_params . update ( self . params )
return _helpers . update_query_params ( self . auth_uri , query_params )


signature:
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"""

implementation:
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 = transport . request ( http , 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 )


signature:
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 ."""

implementation:
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 self . _pkce :
    post_data [ 'code_verifier' ] = self . code_verifier
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 = transport . request ( http , 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
    id_token_jwt = None
    if 'id_token' in d :
        extracted_id_token = _extract_id_token ( d [ 'id_token' ] )
        id_token_jwt = 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 , id_token_jwt = id_token_jwt , 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 )


signature:
def verify ( self , message , signature ) :
    """Verifies a message against a signature .
 Args :
 message : string or bytes , The message to verify . If string , will be
 encoded to bytes as utf - 8.
 signature : string or bytes , The signature on the message . If
 string , will be encoded to bytes as utf - 8.
 Returns :
 True if message was signed by the private key associated with the
 public key that this object was constructed with ."""

implementation:
message = _helpers . _to_bytes ( message , encoding = 'utf-8' )
try :
    return rsa . pkcs1 . verify ( message , signature , self . _pubkey )
except ( ValueError , rsa . pkcs1 . VerificationError ) :
    return False


signature:
def from_string ( cls , key_pem , is_x509_cert ) :
    """Construct an RsaVerifier instance from a string .
 Args :
 key _ pem : string , public key in PEM format .
 is _ x509 _ cert : bool , True if key _ pem is an X509 cert , otherwise it
 is expected to be an RSA key in PEM format .
 Returns :
 RsaVerifier instance .
 Raises :
 ValueError : if the key _ pem can ' t be parsed . In either case , error
 will begin with ' No PEM start marker ' . If
 ` ` is _ x509 _ cert ` ` is True , will fail to find the
 " - - - - - BEGIN CERTIFICATE - - - - - " error , otherwise fails
 to find " - - - - - BEGIN RSA PUBLIC KEY - - - - - " ."""

implementation:
key_pem = _helpers . _to_bytes ( key_pem )
if is_x509_cert :
    der = rsa . pem . load_pem ( key_pem , 'CERTIFICATE' )
    asn1_cert , remaining = decoder . decode ( der , asn1Spec = Certificate ( ) )
    if remaining != b'' :
        raise ValueError ( 'Unused bytes' , remaining )
    cert_info = asn1_cert [ 'tbsCertificate' ] [ 'subjectPublicKeyInfo' ]
    key_bytes = _bit_list_to_bytes ( cert_info [ 'subjectPublicKey' ] )
    pubkey = rsa . PublicKey . load_pkcs1 ( key_bytes , 'DER' )
else :
    pubkey = rsa . PublicKey . load_pkcs1 ( key_pem , 'PEM' )
return cls ( pubkey )


signature:
def sign ( self , message ) :
    """Signs a message .
 Args :
 message : bytes , Message to be signed .
 Returns :
 string , The signature of the message for the given key ."""

implementation:
message = _helpers . _to_bytes ( message , encoding = 'utf-8' )
return rsa . pkcs1 . sign ( message , self . _key , 'SHA-256' )


signature:
def from_string ( cls , key , password = 'notasecret' ) :
    """Construct an RsaSigner instance from a string .
 Args :
 key : string , private key in PEM format .
 password : string , password for private key file . Unused for PEM
 files .
 Returns :
 RsaSigner instance .
 Raises :
 ValueError if the key cannot be parsed as PKCS # 1 or PKCS # 8 in
 PEM format ."""

implementation:
key = _helpers . _from_bytes ( key )
# pem expects str in Py3
marker_id , key_bytes = pem . readPemBlocksFromFile ( six . StringIO ( key ) , _PKCS1_MARKER , _PKCS8_MARKER )
if marker_id == 0 :
    pkey = rsa . key . PrivateKey . load_pkcs1 ( key_bytes , format = 'DER' )
elif marker_id == 1 :
    key_info , remaining = decoder . decode ( key_bytes , asn1Spec = _PKCS8_SPEC )
    if remaining != b'' :
        raise ValueError ( 'Unused bytes' , remaining )
    pkey_info = key_info . getComponentByName ( 'privateKey' )
    pkey = rsa . key . PrivateKey . load_pkcs1 ( pkey_info . asOctets ( ) , format = 'DER' )
else :
    raise ValueError ( 'No key could be detected.' )
return cls ( pkey )


signature:
def _create_file_if_needed ( filename ) :
    """Creates the an empty file if it does not already exist .
 Returns :
 True if the file was created , False otherwise ."""

implementation:
if os . path . exists ( filename ) :
    return False
else : # Equivalent to " touch " .
    open ( filename , 'a+b' ) . close ( )
    logger . info ( 'Credential file {0} created' . format ( filename ) )
    return True


signature:
def _load_credentials_file ( credentials_file ) :
    """Load credentials from the given file handle .
 The file is expected to be in this format :
 " file _ version " : 2,
 " credentials " : {
 " key " : " base64 encoded json representation of credentials . "
 This function will warn and return empty credentials instead of raising
 exceptions .
 Args :
 credentials _ file : An open file handle .
 Returns :
 A dictionary mapping user - defined keys to an instance of
 : class : ` oauth2client . client . Credentials ` ."""

implementation:
try :
    credentials_file . seek ( 0 )
    data = json . load ( credentials_file )
except Exception :
    logger . warning ( 'Credentials file could not be loaded, will ignore and ' 'overwrite.' )
    return { }
if data . get ( 'file_version' ) != 2 :
    logger . warning ( 'Credentials file is not version 2, will ignore and ' 'overwrite.' )
    return { }
credentials = { }
for key , encoded_credential in iteritems ( data . get ( 'credentials' , { } ) ) :
    try :
        credential_json = base64 . b64decode ( encoded_credential )
        credential = client . Credentials . new_from_json ( credential_json )
        credentials [ key ] = credential
    except :
        logger . warning ( 'Invalid credential {0} in file, ignoring.' . format ( key ) )
return credentials


signature:
def _write_credentials_file ( credentials_file , credentials ) :
    """Writes credentials to a file .
 Refer to : func : ` _ load _ credentials _ file ` for the format .
 Args :
 credentials _ file : An open file handle , must be read / write .
 credentials : A dictionary mapping user - defined keys to an instance of
 : class : ` oauth2client . client . Credentials ` ."""

implementation:
data = { 'file_version' : 2 , 'credentials' : { } }
for key , credential in iteritems ( credentials ) :
    credential_json = credential . to_json ( )
    encoded_credential = _helpers . _from_bytes ( base64 . b64encode ( _helpers . _to_bytes ( credential_json ) ) )
    data [ 'credentials' ] [ key ] = encoded_credential
credentials_file . seek ( 0 )
json . dump ( data , credentials_file )
credentials_file . truncate ( )


signature:
def _get_backend ( filename ) :
    """A helper method to get or create a backend with thread locking .
 This ensures that only one backend is used per - file per - process , so that
 thread and process locks are appropriately shared .
 Args :
 filename : The full path to the credential storage file .
 Returns :
 An instance of : class : ` _ MultiprocessStorageBackend ` ."""

implementation:
filename = os . path . abspath ( filename )
with _backends_lock :
    if filename not in _backends :
        _backends [ filename ] = _MultiprocessStorageBackend ( filename )
    return _backends [ filename ]


signature:
def _load_credentials ( self ) :
    """( Re - ) loads the credentials from the file ."""

implementation:
if not self . _file :
    return
loaded_credentials = _load_credentials_file ( self . _file )
self . _credentials . update ( loaded_credentials )
logger . debug ( 'Read credential file' )


signature:
def locked_get ( self ) :
    """Retrieves the current credentials from the store .
 Returns :
 An instance of : class : ` oauth2client . client . Credentials ` or ` None ` ."""

implementation:
credential = self . _backend . locked_get ( self . _key )
if credential is not None :
    credential . set_store ( self )
return credential


signature:
def positional ( max_positional_args ) :
    """A decorator to declare that only the first N arguments my be positional .
 This decorator makes it easy to support Python 3 style keyword - only
 parameters . For example , in Python 3 it is possible to write : :
 def fn ( pos1 , * , kwonly1 = None , kwonly1 = None ) :
 All named parameters after ` ` * ` ` must be a keyword : :
 fn ( 10 , ' kw1 ' , ' kw2 ' ) # Raises exception .
 fn ( 10 , kwonly1 = ' kw1 ' ) # Ok .
 Example
 To define a function like above , do : :
 @ positional ( 1)
 def fn ( pos1 , kwonly1 = None , kwonly2 = None ) :
 If no default value is provided to a keyword argument , it becomes a
 required keyword argument : :
 @ positional ( 0)
 def fn ( required _ kw ) :
 This must be called with the keyword parameter : :
 fn ( ) # Raises exception .
 fn ( 10 ) # Raises exception .
 fn ( required _ kw = 10 ) # Ok .
 When defining instance or class methods always remember to account for
 ` ` self ` ` and ` ` cls ` ` : :
 class MyClass ( object ) :
 @ positional ( 2)
 def my _ method ( self , pos1 , kwonly1 = None ) :
 @ classmethod
 @ positional ( 2)
 def my _ method ( cls , pos1 , kwonly1 = None ) :
 The positional decorator behavior is controlled by
 ` ` _ helpers . positional _ parameters _ enforcement ` ` , which may be set to
 ` ` POSITIONAL _ EXCEPTION ` ` , ` ` POSITIONAL _ WARNING ` ` or
 ` ` POSITIONAL _ IGNORE ` ` to raise an exception , log a warning , or do
 nothing , respectively , if a declaration is violated .
 Args :
 max _ positional _ arguments : Maximum number of positional arguments . All
 parameters after the this index must be
 keyword only .
 Returns :
 A decorator that prevents using arguments after max _ positional _ args
 from being used as positional parameters .
 Raises :
 TypeError : if a key - word only argument is provided as a positional
 parameter , but only if
 _ helpers . positional _ parameters _ enforcement is set to
 POSITIONAL _ EXCEPTION ."""

implementation:
def positional_decorator ( wrapped ) :
    @ functools . wraps ( wrapped )
    def positional_wrapper ( * args , ** kwargs ) :
        if len ( args ) > max_positional_args :
            plural_s = ''
            if max_positional_args != 1 :
                plural_s = 's'
            message = ( '{function}() takes at most {args_max} positional ' 'argument{plural} ({args_given} given)' . format ( function = wrapped . __name__ , args_max = max_positional_args , args_given = len ( args ) , plural = plural_s ) )
            if positional_parameters_enforcement == POSITIONAL_EXCEPTION :
                raise TypeError ( message )
            elif positional_parameters_enforcement == POSITIONAL_WARNING :
                logger . warning ( message )
        return wrapped ( * args , ** kwargs )
    return positional_wrapper
if isinstance ( max_positional_args , six . integer_types ) :
    return positional_decorator
else :
    args , _ , _ , defaults = inspect . getargspec ( max_positional_args )
    return positional ( len ( args ) - len ( defaults ) ) ( max_positional_args )


signature:
def string_to_scopes ( scopes ) :
    """Converts stringifed scope value to a list .
 If scopes is a list then it is simply passed through . If scopes is an
 string then a list of each individual scope is returned .
 Args :
 scopes : a string or iterable of strings , the scopes .
 Returns :
 The scopes in a list ."""

implementation:
if not scopes :
    return [ ]
elif isinstance ( scopes , six . string_types ) :
    return scopes . split ( ' ' )
else :
    return scopes


signature:
def parse_unique_urlencoded ( content ) :
    """Parses unique key - value parameters from urlencoded content .
 Args :
 content : string , URL - encoded key - value pairs .
 Returns :
 dict , The key - value pairs from ` ` content ` ` .
 Raises :
 ValueError : if one of the keys is repeated ."""

implementation:
urlencoded_params = urllib . parse . parse_qs ( content )
params = { }
for key , value in six . iteritems ( urlencoded_params ) :
    if len ( value ) != 1 :
        msg = ( 'URL-encoded content contains a repeated value:' '%s -> %s' % ( key , ', ' . join ( value ) ) )
        raise ValueError ( msg )
    params [ key ] = value [ 0 ]
return params


signature:
def update_query_params ( uri , params ) :
    """Updates a URI with new query parameters .
 If a given key from ` ` params ` ` is repeated in the ` ` uri ` ` , then
 the URI will be considered invalid and an error will occur .
 If the URI is valid , then each value from ` ` params ` ` will
 replace the corresponding value in the query parameters ( if
 it exists ) .
 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 ."""

implementation:
parts = urllib . parse . urlparse ( uri )
query_params = parse_unique_urlencoded ( parts . query )
query_params . update ( params )
new_query = urllib . parse . urlencode ( query_params )
new_parts = parts . _replace ( query = new_query )
return urllib . parse . urlunparse ( new_parts )


signature:
def _add_query_parameter ( url , name , value ) :
    """Adds a query parameter to a url .
 Replaces the current value if it already exists in the URL .
 Args :
 url : string , url to add the query parameter to .
 name : string , query parameter name .
 value : string , query parameter value .
 Returns :
 Updated query parameter . Does not update the url if value is None ."""

implementation:
if value is None :
    return url
else :
    return update_query_params ( url , { name : value } )


signature:
def _apply_user_agent ( headers , user_agent ) :
    """Adds a user - agent to the headers .
 Args :
 headers : dict , request headers to add / modify user
 agent within .
 user _ agent : str , the user agent to add .
 Returns :
 dict , the original headers passed in , but modified if the
 user agent is not None ."""

implementation:
if user_agent is not None :
    if 'user-agent' in headers :
        headers [ 'user-agent' ] = ( user_agent + ' ' + headers [ 'user-agent' ] )
    else :
        headers [ 'user-agent' ] = user_agent
return headers


signature:
def clean_headers ( headers ) :
    """Forces header keys and values to be strings , i . e not unicode .
 The httplib module just concats the header keys and values in a way that
 may make the message header a unicode string , which , if it then tries to
 contatenate to a binary request body may result in a unicode decode error .
 Args :
 headers : dict , A dictionary of headers .
 Returns :
 The same dictionary but with all the keys converted to strings ."""

implementation:
clean = { }
try :
    for k , v in six . iteritems ( headers ) :
        if not isinstance ( k , six . binary_type ) :
            k = str ( k )
        if not isinstance ( v , six . binary_type ) :
            v = str ( v )
        clean [ _helpers . _to_bytes ( k ) ] = _helpers . _to_bytes ( v )
except UnicodeEncodeError :
    from oauth2client . client import NonAsciiHeaderError
    raise NonAsciiHeaderError ( k , ': ' , v )
return clean


signature:
def wrap_http_for_auth ( credentials , http ) :
    """Prepares an HTTP object ' s request method for auth .
 Wraps HTTP requests with logic to catch auth failures ( typically
 identified via a 401 status code ) . In the event of failure , tries
 to refresh the token used and then retry the original request .
 Args :
 credentials : Credentials , the credentials used to identify
 the authenticated user .
 http : httplib2 . Http , an http object to be used to make
 auth requests ."""

implementation:
orig_request_method = http . request
# The closure that will replace ' httplib2 . Http . request ' .
def new_request ( uri , method = 'GET' , body = None , headers = None , redirections = httplib2 . DEFAULT_MAX_REDIRECTS , connection_type = None ) :
    if not credentials . access_token :
        _LOGGER . info ( 'Attempting refresh to obtain ' 'initial access_token' )
        credentials . _refresh ( orig_request_method )
    # Clone and modify the request headers to add the appropriate
    # Authorization header .
    headers = _initialize_headers ( headers )
    credentials . apply ( headers )
    _apply_user_agent ( headers , credentials . user_agent )
    body_stream_position = None
    # Check if the body is a file - like stream .
    if all ( getattr ( body , stream_prop , None ) for stream_prop in _STREAM_PROPERTIES ) :
        body_stream_position = body . tell ( )
    resp , content = request ( orig_request_method , uri , method , body , clean_headers ( headers ) , redirections , connection_type )
    # A stored token may expire between the time it is retrieved and
    # the time the request is made , so we may need to try twice .
    max_refresh_attempts = 2
    for refresh_attempt in range ( max_refresh_attempts ) :
        if resp . status not in REFRESH_STATUS_CODES :
            break
        _LOGGER . info ( 'Refreshing due to a %s (attempt %s/%s)' , resp . status , refresh_attempt + 1 , max_refresh_attempts )
        credentials . _refresh ( orig_request_method )
        credentials . apply ( headers )
        if body_stream_position is not None :
            body . seek ( body_stream_position )
        resp , content = request ( orig_request_method , uri , method , body , clean_headers ( headers ) , redirections , connection_type )
    return resp , content
# Replace the request method with our own closure .
http . request = new_request
# Set credentials as a property of the request method .
http . request . credentials = credentials


signature:
def wrap_http_for_jwt_access ( credentials , http ) :
    """Prepares an HTTP object ' s request method for JWT access .
 Wraps HTTP requests with logic to catch auth failures ( typically
 identified via a 401 status code ) . In the event of failure , tries
 to refresh the token used and then retry the original request .
 Args :
 credentials : _ JWTAccessCredentials , the credentials used to identify
 a service account that uses JWT access tokens .
 http : httplib2 . Http , an http object to be used to make
 auth requests ."""

implementation:
orig_request_method = http . request
wrap_http_for_auth ( credentials , http )
# The new value of ` ` http . request ` ` set by ` ` wrap _ http _ for _ auth ` ` .
authenticated_request_method = http . request
# The closure that will replace ' httplib2 . Http . request ' .
def new_request ( uri , method = 'GET' , body = None , headers = None , redirections = httplib2 . DEFAULT_MAX_REDIRECTS , connection_type = None ) :
    if 'aud' in credentials . _kwargs : # Preemptively refresh token , this is not done for OAuth2
        if ( credentials . access_token is None or credentials . access_token_expired ) :
            credentials . refresh ( None )
        return request ( authenticated_request_method , uri , method , body , headers , redirections , connection_type )
    else : # If we don ' t have an ' aud ' ( audience ) claim ,
    # create a 1 - time token with the uri root as the audience
        headers = _initialize_headers ( headers )
        _apply_user_agent ( headers , credentials . user_agent )
        uri_root = uri . split ( '?' , 1 ) [ 0 ]
        token , unused_expiry = credentials . _create_token ( { 'aud' : uri_root } )
        headers [ 'Authorization' ] = 'Bearer ' + token
        return request ( orig_request_method , uri , method , body , clean_headers ( headers ) , redirections , connection_type )
# Replace the request method with our own closure .
http . request = new_request
# Set credentials as a property of the request method .
http . request . credentials = credentials


signature:
def request ( http , uri , method = 'GET' , body = None , headers = None , redirections = httplib2 . DEFAULT_MAX_REDIRECTS , connection_type = None ) :
    """Make an HTTP request with an HTTP object and arguments .
 Args :
 http : httplib2 . Http , an http object to be used to make requests .
 uri : string , The URI to be requested .
 method : string , The HTTP method to use for the request . Defaults
 to ' GET ' .
 body : string , The payload / body in HTTP request . By default
 there is no payload .
 headers : dict , Key - value pairs of request headers . By default
 there are no headers .
 redirections : int , The number of allowed 203 redirects for
 the request . Defaults to 5.
 connection _ type : httplib . HTTPConnection , a subclass to be used for
 establishing connection . If not set , the type
 will be determined from the ` ` uri ` ` .
 Returns :
 tuple , a pair of a httplib2 . Response with the status code and other
 headers and the bytes of the content returned ."""

implementation:
# NOTE : Allowing http or http . request is temporary ( See Issue 601 ) .
http_callable = getattr ( http , 'request' , http )
return http_callable ( uri , method = method , body = body , headers = headers , redirections = redirections , connection_type = connection_type )


signature:
def _get_flow_for_token ( csrf_token ) :
    """Retrieves the flow instance associated with a given CSRF token from
 the Flask session ."""

implementation:
flow_pickle = session . pop ( _FLOW_KEY . format ( csrf_token ) , None )
if flow_pickle is None :
    return None
else :
    return pickle . loads ( flow_pickle )


signature:
def init_app ( self , app , scopes = None , client_secrets_file = None , client_id = None , client_secret = None , authorize_callback = None , storage = None , ** kwargs ) :
    """Initialize this extension for the given app .
 Arguments :
 app : A Flask application .
 scopes : Optional list of scopes to authorize .
 client _ secrets _ file : Path to a file containing client secrets . You
 can also specify the GOOGLE _ OAUTH2 _ CLIENT _ SECRETS _ FILE config
 value .
 client _ id : If not specifying a client secrets file , specify the
 OAuth2 client id . You can also specify the
 GOOGLE _ OAUTH2 _ CLIENT _ ID config value . You must also provide a
 client secret .
 client _ secret : The OAuth2 client secret . You can also specify the
 GOOGLE _ OAUTH2 _ CLIENT _ SECRET config value .
 authorize _ callback : A function that is executed after successful
 user authorization .
 storage : A oauth2client . client . Storage subclass for storing the
 credentials . By default , this is a Flask session based storage .
 kwargs : Any additional args are passed along to the Flow
 constructor ."""

implementation:
self . app = app
self . authorize_callback = authorize_callback
self . flow_kwargs = kwargs
if storage is None :
    storage = dictionary_storage . DictionaryStorage ( session , key = _CREDENTIALS_KEY )
self . storage = storage
if scopes is None :
    scopes = app . config . get ( 'GOOGLE_OAUTH2_SCOPES' , _DEFAULT_SCOPES )
self . scopes = scopes
self . _load_config ( client_secrets_file , client_id , client_secret )
app . register_blueprint ( self . _create_blueprint ( ) )


signature:
def _load_config ( self , client_secrets_file , client_id , client_secret ) :
    """Loads oauth2 configuration in order of priority .
 Priority :
 1 . Config passed to the constructor or init _ app .
 2 . Config passed via the GOOGLE _ OAUTH2 _ CLIENT _ SECRETS _ FILE app
 config .
 3 . Config passed via the GOOGLE _ OAUTH2 _ CLIENT _ ID and
 GOOGLE _ OAUTH2 _ CLIENT _ SECRET app config .
 Raises :
 ValueError if no config could be found ."""

implementation:
if client_id and client_secret :
    self . client_id , self . client_secret = client_id , client_secret
    return
if client_secrets_file :
    self . _load_client_secrets ( client_secrets_file )
    return
if 'GOOGLE_OAUTH2_CLIENT_SECRETS_FILE' in self . app . config :
    self . _load_client_secrets ( self . app . config [ 'GOOGLE_OAUTH2_CLIENT_SECRETS_FILE' ] )
    return
try :
    self . client_id , self . client_secret = ( self . app . config [ 'GOOGLE_OAUTH2_CLIENT_ID' ] , self . app . config [ 'GOOGLE_OAUTH2_CLIENT_SECRET' ] )
except KeyError :
    raise ValueError ( 'OAuth2 configuration could not be found. Either specify the ' 'client_secrets_file or client_id and client_secret or set ' 'the app configuration variables ' 'GOOGLE_OAUTH2_CLIENT_SECRETS_FILE or ' 'GOOGLE_OAUTH2_CLIENT_ID and GOOGLE_OAUTH2_CLIENT_SECRET.' )


signature:
def _load_client_secrets ( self , filename ) :
    """Loads client secrets from the given filename ."""

implementation:
client_type , client_info = clientsecrets . loadfile ( filename )
if client_type != clientsecrets . TYPE_WEB :
    raise ValueError ( 'The flow specified in {0} is not supported.' . format ( client_type ) )
self . client_id = client_info [ 'client_id' ]
self . client_secret = client_info [ 'client_secret' ]


signature:
def _make_flow ( self , return_url = None , ** kwargs ) :
    """Creates a Web Server Flow"""

implementation:
# Generate a CSRF token to prevent malicious requests .
csrf_token = hashlib . sha256 ( os . urandom ( 1024 ) ) . hexdigest ( )
session [ _CSRF_KEY ] = csrf_token
state = json . dumps ( { 'csrf_token' : csrf_token , 'return_url' : return_url } )
kw = self . flow_kwargs . copy ( )
kw . update ( kwargs )
extra_scopes = kw . pop ( 'scopes' , [ ] )
scopes = set ( self . scopes ) . union ( set ( extra_scopes ) )
flow = client . OAuth2WebServerFlow ( client_id = self . client_id , client_secret = self . client_secret , scope = scopes , state = state , redirect_uri = url_for ( 'oauth2.callback' , _external = True ) , ** kw )
flow_key = _FLOW_KEY . format ( csrf_token )
session [ flow_key ] = pickle . dumps ( flow )
return flow


signature:
def authorize_view ( self ) :
    """Flask view that starts the authorization flow .
 Starts flow by redirecting the user to the OAuth2 provider ."""

implementation:
args = request . args . to_dict ( )
# Scopes will be passed as mutliple args , and to _ dict ( ) will only
# return one . So , we use getlist ( ) to get all of the scopes .
args [ 'scopes' ] = request . args . getlist ( 'scopes' )
return_url = args . pop ( 'return_url' , None )
if return_url is None :
    return_url = request . referrer or '/'
flow = self . _make_flow ( return_url = return_url , ** args )
auth_url = flow . step1_get_authorize_url ( )
return redirect ( auth_url )


signature:
def callback_view ( self ) :
    """Flask view that handles the user ' s return from OAuth2 provider .
 On return , exchanges the authorization code for credentials and stores
 the credentials ."""

implementation:
if 'error' in request . args :
    reason = request . args . get ( 'error_description' , request . args . get ( 'error' , '' ) )
    reason = markupsafe . escape ( reason )
    return ( 'Authorization failed: {0}' . format ( reason ) , httplib . BAD_REQUEST )
try :
    encoded_state = request . args [ 'state' ]
    server_csrf = session [ _CSRF_KEY ]
    code = request . args [ 'code' ]
except KeyError :
    return 'Invalid request' , httplib . BAD_REQUEST
try :
    state = json . loads ( encoded_state )
    client_csrf = state [ 'csrf_token' ]
    return_url = state [ 'return_url' ]
except ( ValueError , KeyError ) :
    return 'Invalid request state' , httplib . BAD_REQUEST
if client_csrf != server_csrf :
    return 'Invalid request state' , httplib . BAD_REQUEST
flow = _get_flow_for_token ( server_csrf )
if flow is None :
    return 'Invalid request state' , httplib . BAD_REQUEST
# Exchange the auth code for credentials .
try :
    credentials = flow . step2_exchange ( code )
except client . FlowExchangeError as exchange_error :
    current_app . logger . exception ( exchange_error )
    content = 'An error occurred: {0}' . format ( exchange_error )
    return content , httplib . BAD_REQUEST
# Save the credentials to the storage .
self . storage . put ( credentials )
if self . authorize_callback :
    self . authorize_callback ( credentials )
return redirect ( return_url )


signature:
def credentials ( self ) :
    """The credentials for the current user or None if unavailable ."""

implementation:
ctx = _app_ctx_stack . top
if not hasattr ( ctx , _CREDENTIALS_KEY ) :
    ctx . google_oauth2_credentials = self . storage . get ( )
return ctx . google_oauth2_credentials


signature:
def has_credentials ( self ) :
    """Returns True if there are valid credentials for the current user ."""

implementation:
if not self . credentials :
    return False
# Is the access token expired ? If so , do we have an refresh token ?
elif ( self . credentials . access_token_expired and not self . credentials . refresh_token ) :
    return False
else :
    return True


signature:
def email ( self ) :
    """Returns the user ' s email address or None if there are no credentials .
 The email address is provided by the current credentials ' id _ token .
 This should not be used as unique identifier as the user can change
 their email . If you need a unique identifier , use user _ id ."""

implementation:
if not self . credentials :
    return None
try :
    return self . credentials . id_token [ 'email' ]
except KeyError :
    current_app . logger . error ( 'Invalid id_token {0}' . format ( self . credentials . id_token ) )


signature:
def required ( self , decorated_function = None , scopes = None , ** decorator_kwargs ) :
    """Decorator to require OAuth2 credentials for a view .
 If credentials are not available for the current user , then they will
 be redirected to the authorization flow . Once complete , the user will
 be redirected back to the original page ."""

implementation:
def curry_wrapper ( wrapped_function ) :
    @ wraps ( wrapped_function )
    def required_wrapper ( * args , ** kwargs ) :
        return_url = decorator_kwargs . pop ( 'return_url' , request . url )
        requested_scopes = set ( self . scopes )
        if scopes is not None :
            requested_scopes |= set ( scopes )
        if self . has_credentials ( ) :
            requested_scopes |= self . credentials . scopes
        requested_scopes = list ( requested_scopes )
        # Does the user have credentials and does the credentials have
        # all of the needed scopes ?
        if ( self . has_credentials ( ) and self . credentials . has_scopes ( requested_scopes ) ) :
            return wrapped_function ( * args , ** kwargs )
        # Otherwise , redirect to authorization
        else :
            auth_url = self . authorize_url ( return_url , scopes = requested_scopes , ** decorator_kwargs )
            return redirect ( auth_url )
    return required_wrapper
if decorated_function :
    return curry_wrapper ( decorated_function )
else :
    return curry_wrapper


signature:
def get ( http , path , root = METADATA_ROOT , recursive = None ) :
    """Fetch a resource from the metadata server .
 Args :
 http : an object to be used to make HTTP requests .
 path : A string indicating the resource to retrieve . For example ,
 ' instance / service - accounts / default '
 root : A string indicating the full path to the metadata server root .
 recursive : A boolean indicating whether to do a recursive query of
 metadata . See
 https : / / cloud . google . com / compute / docs / metadata # aggcontents
 Returns :
 A dictionary if the metadata server returns JSON , otherwise a string .
 Raises :
 http _ client . HTTPException if an error corrured while
 retrieving metadata ."""

implementation:
url = urlparse . urljoin ( root , path )
url = _helpers . _add_query_parameter ( url , 'recursive' , recursive )
response , content = transport . request ( http , url , headers = METADATA_HEADERS )
if response . status == http_client . OK :
    decoded = _helpers . _from_bytes ( content )
    if response [ 'content-type' ] == 'application/json' :
        return json . loads ( decoded )
    else :
        return decoded
else :
    raise http_client . HTTPException ( 'Failed to retrieve {0} from the Google Compute Engine' 'metadata service. Response:\n{1}' . format ( url , response ) )


signature:
def get_token ( http , service_account = 'default' ) :
    """Fetch an oauth token for the
 Args :
 http : an object to be used to make HTTP requests .
 service _ account : An email specifying the service account this token
 should represent . Default will be a token for the " default " service
 account of the current compute engine instance .
 Returns :
 A tuple of ( access token , token expiration ) , where access token is the
 access token as a string and token expiration is a datetime object
 that indicates when the access token will expire ."""

implementation:
token_json = get ( http , 'instance/service-accounts/{0}/token' . format ( service_account ) )
token_expiry = client . _UTCNOW ( ) + datetime . timedelta ( seconds = token_json [ 'expires_in' ] )
return token_json [ 'access_token' ] , token_expiry


signature:
def xsrf_secret_key ( ) :
    """Return the secret key for use for XSRF protection .
 If the Site entity does not have a secret key , this method will also create
 one and persist it .
 Returns :
 The secret key ."""

implementation:
secret = memcache . get ( XSRF_MEMCACHE_ID , namespace = OAUTH2CLIENT_NAMESPACE )
if not secret : # Load the one and only instance of SiteXsrfSecretKey .
    model = SiteXsrfSecretKey . get_or_insert ( key_name = 'site' )
    if not model . secret :
        model . secret = _generate_new_xsrf_secret_key ( )
        model . put ( )
    secret = model . secret
    memcache . add ( XSRF_MEMCACHE_ID , secret , namespace = OAUTH2CLIENT_NAMESPACE )
return str ( secret )


signature:
def _build_state_value ( request_handler , user ) :
    """Composes the value for the ' state ' parameter .
 Packs the current request URI and an XSRF token into an opaque string that
 can be passed to the authentication server via the ' state ' parameter .
 Args :
 request _ handler : webapp . RequestHandler , The request .
 user : google . appengine . api . users . User , The current user .
 Returns :
 The state value as a string ."""

implementation:
uri = request_handler . request . url
token = xsrfutil . generate_token ( xsrf_secret_key ( ) , user . user_id ( ) , action_id = str ( uri ) )
return uri + ':' + token


signature:
def _parse_state_value ( state , user ) :
    """Parse the value of the ' state ' parameter .
 Parses the value and validates the XSRF token in the state parameter .
 Args :
 state : string , The value of the state parameter .
 user : google . appengine . api . users . User , The current user .
 Returns :
 The redirect URI , or None if XSRF token is not valid ."""

implementation:
uri , token = state . rsplit ( ':' , 1 )
if xsrfutil . validate_token ( xsrf_secret_key ( ) , token , user . user_id ( ) , action_id = uri ) :
    return uri
else :
    return None


signature:
def oauth2decorator_from_clientsecrets ( filename , scope , message = None , cache = None ) :
    """Creates an OAuth2Decorator populated from a clientsecrets file .
 Args :
 filename : string , File name of client secrets .
 scope : string or list of strings , scope ( s ) of the credentials being
 requested .
 message : string , A friendly string to display to the user if the
 clientsecrets file is missing or invalid . The message may
 contain HTML and will be presented on the web interface for
 any method that uses the decorator .
 cache : An optional cache service client that implements get ( ) and set ( )
 methods . See clientsecrets . loadfile ( ) for details .
 Returns : An OAuth2Decorator"""

implementation: return OAuth2DecoratorFromClientSecrets ( filename , scope , message = message , cache = cache )


signature:
def _refresh ( self , http ) :
    """Refreshes the access token .
 Since the underlying App Engine app _ identity implementation does its
 own caching we can skip all the storage hoops and just to a refresh
 using the API .
 Args :
 http : unused HTTP object
 Raises :
 AccessTokenRefreshError : When the refresh fails ."""

implementation:
try :
    scopes = self . scope . split ( )
    ( token , _ ) = app_identity . get_access_token ( scopes , service_account_id = self . service_account_id )
except app_identity . Error as e :
    raise client . AccessTokenRefreshError ( str ( e ) )
self . access_token = token


signature:
def service_account_email ( self ) :
    """Get the email for the current service account .
 Returns :
 string , The email associated with the Google App Engine
 service account ."""

implementation:
if self . _service_account_email is None :
    self . _service_account_email = ( app_identity . get_service_account_name ( ) )
return self . _service_account_email


signature:
def _is_ndb ( self ) :
    """Determine whether the model of the instance is an NDB model .
 Returns :
 Boolean indicating whether or not the model is an NDB or DB model ."""

implementation:
# issubclass will fail if one of the arguments is not a class , only
# need worry about new - style classes since ndb and db models are
# new - style
if isinstance ( self . _model , type ) :
    if _NDB_MODEL is not None and issubclass ( self . _model , _NDB_MODEL ) :
        return True
    elif issubclass ( self . _model , db . Model ) :
        return False
raise TypeError ( 'Model class not an NDB or DB model: {0}.' . format ( self . _model ) )


signature:
def _get_entity ( self ) :
    """Retrieve entity from datastore .
 Uses a different model method for db or ndb models .
 Returns :
 Instance of the model corresponding to the current storage object
 and stored using the key name of the storage object ."""

implementation:
if self . _is_ndb ( ) :
    return self . _model . get_by_id ( self . _key_name )
else :
    return self . _model . get_by_key_name ( self . _key_name )


signature:
def _delete_entity ( self ) :
    """Delete entity from datastore .
 Attempts to delete using the key _ name stored on the object , whether or
 not the given key is in the datastore ."""

implementation:
if self . _is_ndb ( ) :
    _NDB_KEY ( self . _model , self . _key_name ) . delete ( )
else :
    entity_key = db . Key . from_path ( self . _model . kind ( ) , self . _key_name )
    db . delete ( entity_key )


signature:
def locked_get ( self ) :
    """Retrieve Credential from datastore .
 Returns :
 oauth2client . Credentials"""

implementation:
credentials = None
if self . _cache :
    json = self . _cache . get ( self . _key_name )
    if json :
        credentials = client . Credentials . new_from_json ( json )
if credentials is None :
    entity = self . _get_entity ( )
    if entity is not None :
        credentials = getattr ( entity , self . _property_name )
        if self . _cache :
            self . _cache . set ( self . _key_name , credentials . to_json ( ) )
if credentials and hasattr ( credentials , 'set_store' ) :
    credentials . set_store ( self )
return credentials


signature:
def locked_put ( self , credentials ) :
    """Write a Credentials to the datastore .
 Args :
 credentials : Credentials , the credentials to store ."""

implementation:
entity = self . _model . get_or_insert ( self . _key_name )
setattr ( entity , self . _property_name , credentials )
entity . put ( )
if self . _cache :
    self . _cache . set ( self . _key_name , credentials . to_json ( ) )


signature:
def locked_delete ( self ) :
    """Delete Credential from datastore ."""

implementation:
if self . _cache :
    self . _cache . delete ( self . _key_name )
self . _delete_entity ( )


signature:
def oauth_required ( self , method ) :
    """Decorator that starts the OAuth 2.0 dance .
 Starts the OAuth dance for the logged in user if they haven ' t already
 granted access for this application .
 Args :
 method : callable , to be decorated method of a webapp . RequestHandler
 instance ."""

implementation:
def check_oauth ( request_handler , * args , ** kwargs ) :
    if self . _in_error :
        self . _display_error_message ( request_handler )
        return
    user = users . get_current_user ( )
    # Don ' t use @ login _ decorator as this could be used in a
    # POST request .
    if not user :
        request_handler . redirect ( users . create_login_url ( request_handler . request . uri ) )
        return
    self . _create_flow ( request_handler )
    # Store the request URI in ' state ' so we can use it later
    self . flow . params [ 'state' ] = _build_state_value ( request_handler , user )
    self . credentials = self . _storage_class ( self . _credentials_class , None , self . _credentials_property_name , user = user ) . get ( )
    if not self . has_credentials ( ) :
        return request_handler . redirect ( self . authorize_url ( ) )
    try :
        resp = method ( request_handler , * args , ** kwargs )
    except client . AccessTokenRefreshError :
        return request_handler . redirect ( self . authorize_url ( ) )
    finally :
        self . credentials = None
    return resp
return check_oauth


signature:
def _create_flow ( self , request_handler ) :
    """Create the Flow object .
 The Flow is calculated lazily since we don ' t know where this app is
 running until it receives a request , at which point redirect _ uri can be
 calculated and then the Flow object can be constructed .
 Args :
 request _ handler : webapp . RequestHandler , the request handler ."""

implementation:
if self . flow is None :
    redirect_uri = request_handler . request . relative_url ( self . _callback_path )
    # Usually / oauth2callback
    self . flow = client . OAuth2WebServerFlow ( self . _client_id , self . _client_secret , self . _scope , redirect_uri = redirect_uri , user_agent = self . _user_agent , auth_uri = self . _auth_uri , token_uri = self . _token_uri , revoke_uri = self . _revoke_uri , ** self . _kwargs )


signature:
def oauth_aware ( self , method ) :
    """Decorator that sets up for OAuth 2.0 dance , but doesn ' t do it .
 Does all the setup for the OAuth dance , but doesn ' t initiate it .
 This decorator is useful if you want to create a page that knows
 whether or not the user has granted access to this application .
 From within a method decorated with @ oauth _ aware the has _ credentials ( )
 and authorize _ url ( ) methods can be called .
 Args :
 method : callable , to be decorated method of a webapp . RequestHandler
 instance ."""

implementation:
def setup_oauth ( request_handler , * args , ** kwargs ) :
    if self . _in_error :
        self . _display_error_message ( request_handler )
        return
    user = users . get_current_user ( )
    # Don ' t use @ login _ decorator as this could be used in a
    # POST request .
    if not user :
        request_handler . redirect ( users . create_login_url ( request_handler . request . uri ) )
        return
    self . _create_flow ( request_handler )
    self . flow . params [ 'state' ] = _build_state_value ( request_handler , user )
    self . credentials = self . _storage_class ( self . _credentials_class , None , self . _credentials_property_name , user = user ) . get ( )
    try :
        resp = method ( request_handler , * args , ** kwargs )
    finally :
        self . credentials = None
    return resp
return setup_oauth


signature:
def http ( self , * args , ** kwargs ) :
    """Returns an authorized http instance .
 Must only be called from within an @ oauth _ required decorated method , or
 from within an @ oauth _ aware decorated method where has _ credentials ( )
 returns True .
 Args :
 * args : Positional arguments passed to httplib2 . Http constructor .
 * * kwargs : Positional arguments passed to httplib2 . Http constructor ."""

implementation: return self . credentials . authorize ( transport . get_http_object ( * args , ** kwargs ) )


signature:
def generate_token ( key , user_id , action_id = '' , when = None ) :
    """Generates a URL - safe token for the given user , action , time tuple .
 Args :
 key : secret key to use .
 user _ id : the user ID of the authenticated user .
 action _ id : a string identifier of the action they requested
 authorization for .
 when : the time in seconds since the epoch at which the user was
 authorized for this action . If not set the current time is used .
 Returns :
 A string XSRF protection token ."""

implementation:
digester = hmac . new ( _helpers . _to_bytes ( key , encoding = 'utf-8' ) )
digester . update ( _helpers . _to_bytes ( str ( user_id ) , encoding = 'utf-8' ) )
digester . update ( DELIMITER )
digester . update ( _helpers . _to_bytes ( action_id , encoding = 'utf-8' ) )
digester . update ( DELIMITER )
when = _helpers . _to_bytes ( str ( when or int ( time . time ( ) ) ) , encoding = 'utf-8' )
digester . update ( when )
digest = digester . digest ( )
token = base64 . urlsafe_b64encode ( digest + DELIMITER + when )
return token


signature:
def validate_token ( key , token , user_id , action_id = "" , current_time = None ) :
    """Validates that the given token authorizes the user for the action .
 Tokens are invalid if the time of issue is too old or if the token
 does not match what generateToken outputs ( i . e . the token was forged ) .
 Args :
 key : secret key to use .
 token : a string of the token generated by generateToken .
 user _ id : the user ID of the authenticated user .
 action _ id : a string identifier of the action they requested
 authorization for .
 Returns :
 A boolean - True if the user is authorized for the action , False
 otherwise ."""

implementation:
if not token :
    return False
try :
    decoded = base64 . urlsafe_b64decode ( token )
    token_time = int ( decoded . split ( DELIMITER ) [ - 1 ] )
except ( TypeError , ValueError , binascii . Error ) :
    return False
if current_time is None :
    current_time = time . time ( )
# If the token is too old it ' s not valid .
if current_time - token_time > DEFAULT_TIMEOUT_SECS :
    return False
# The given token should match the generated one with the same time .
expected_token = generate_token ( key , user_id , action_id = action_id , when = token_time )
if len ( token ) != len ( expected_token ) :
    return False
# Perform constant time comparison to avoid timing attacks
different = 0
for x , y in zip ( bytearray ( token ) , bytearray ( expected_token ) ) :
    different |= x ^ y
return not different


signature:
def _validate_clientsecrets ( clientsecrets_dict ) :
    """Validate parsed client secrets from a file .
 Args :
 clientsecrets _ dict : dict , a dictionary holding the client secrets .
 Returns :
 tuple , a string of the client type and the information parsed
 from the file ."""

implementation:
_INVALID_FILE_FORMAT_MSG = ( 'Invalid file format. See ' 'https://developers.google.com/api-client-library/' 'python/guide/aaa_client_secrets' )
if clientsecrets_dict is None :
    raise InvalidClientSecretsError ( _INVALID_FILE_FORMAT_MSG )
try :
    ( client_type , client_info ) , = clientsecrets_dict . items ( )
except ( ValueError , AttributeError ) :
    raise InvalidClientSecretsError ( _INVALID_FILE_FORMAT_MSG + ' ' 'Expected a JSON object with a single property for a "web" or ' '"installed" application' )
if client_type not in VALID_CLIENT :
    raise InvalidClientSecretsError ( 'Unknown client type: {0}.' . format ( client_type ) )
for prop_name in VALID_CLIENT [ client_type ] [ 'required' ] :
    if prop_name not in client_info :
        raise InvalidClientSecretsError ( 'Missing property "{0}" in a client type of "{1}".' . format ( prop_name , client_type ) )
for prop_name in VALID_CLIENT [ client_type ] [ 'string' ] :
    if client_info [ prop_name ] . startswith ( '[[' ) :
        raise InvalidClientSecretsError ( 'Property "{0}" is not configured.' . format ( prop_name ) )
return client_type , client_info


signature:
def loadfile ( filename , cache = None ) :
    """Loading of client _ secrets JSON file , optionally backed by a cache .
 Typical cache storage would be App Engine memcache service ,
 but you can pass in any other cache client that implements
 these methods :
 * ` ` get ( key , namespace = ns ) ` `
 * ` ` set ( key , value , namespace = ns ) ` `
 Usage : :
 # without caching
 client _ type , client _ info = loadfile ( ' secrets . json ' )
 # using App Engine memcache service
 from google . appengine . api import memcache
 client _ type , client _ info = loadfile ( ' secrets . json ' , cache = memcache )
 Args :
 filename : string , Path to a client _ secrets . json file on a filesystem .
 cache : An optional cache service client that implements get ( ) and set ( )
 methods . If not specified , the file is always being loaded from
 a filesystem .
 Raises :
 InvalidClientSecretsError : In case of a validation error or some
 I / O failure . Can happen only on cache miss .
 Returns :
 ( client _ type , client _ info ) tuple , as _ loadfile ( ) normally would .
 JSON contents is validated only during first load . Cache hits are not
 validated ."""

implementation:
_SECRET_NAMESPACE = 'oauth2client:secrets#ns'
if not cache :
    return _loadfile ( filename )
obj = cache . get ( filename , namespace = _SECRET_NAMESPACE )
if obj is None :
    client_type , client_info = _loadfile ( filename )
    obj = { client_type : client_info }
    cache . set ( filename , obj , namespace = _SECRET_NAMESPACE )
return next ( six . iteritems ( obj ) )


signature:
def _SendRecv ( ) :
    """Communicate with the Developer Shell server socket ."""

implementation:
port = int ( os . getenv ( DEVSHELL_ENV , 0 ) )
if port == 0 :
    raise NoDevshellServer ( )
sock = socket . socket ( )
sock . connect ( ( 'localhost' , port ) )
data = CREDENTIAL_INFO_REQUEST_JSON
msg = '{0}\n{1}' . format ( len ( data ) , data )
sock . sendall ( _helpers . _to_bytes ( msg , encoding = 'utf-8' ) )
header = sock . recv ( 6 ) . decode ( )
if '\n' not in header :
    raise CommunicationError ( 'saw no newline in the first 6 bytes' )
len_str , json_str = header . split ( '\n' , 1 )
to_read = int ( len_str ) - len ( json_str )
if to_read > 0 :
    json_str += sock . recv ( to_read , socket . MSG_WAITALL ) . decode ( )
return CredentialInfoResponse ( json_str )


signature:
def _refresh ( self , http ) :
    """Refreshes the access token .
 Args :
 http : unused HTTP object"""

implementation:
self . devshell_response = _SendRecv ( )
self . access_token = self . devshell_response . access_token
expires_in = self . devshell_response . expires_in
if expires_in is not None :
    delta = datetime . timedelta ( seconds = expires_in )
    self . token_expiry = client . _UTCNOW ( ) + delta
else :
    self . token_expiry = None


signature:
def locked_get ( self ) :
    """Retrieve Credential from file .
 Returns :
 oauth2client . client . Credentials"""

implementation:
credentials = None
content = keyring . get_password ( self . _service_name , self . _user_name )
if content is not None :
    try :
        credentials = client . Credentials . new_from_json ( content )
        credentials . set_store ( self )
    except ValueError :
        pass
return credentials


signature:
def locked_put ( self , credentials ) :
    """Write Credentials to file .
 Args :
 credentials : Credentials , the credentials to store ."""

implementation: keyring . set_password ( self . _service_name , self . _user_name , credentials . to_json ( ) )


signature:
def pkcs12_key_as_pem ( private_key_bytes , private_key_password ) :
    """Convert the contents of a PKCS # 12 key to PEM using pyOpenSSL .
 Args :
 private _ key _ bytes : Bytes . PKCS # 12 key in DER format .
 private _ key _ password : String . Password for PKCS # 12 key .
 Returns :
 String . PEM contents of ` ` private _ key _ bytes ` ` ."""

implementation:
private_key_password = _helpers . _to_bytes ( private_key_password )
pkcs12 = crypto . load_pkcs12 ( private_key_bytes , private_key_password )
return crypto . dump_privatekey ( crypto . FILETYPE_PEM , pkcs12 . get_privatekey ( ) )


signature:
def verify ( self , message , signature ) :
    """Verifies a message against a signature .
 Args :
 message : string or bytes , The message to verify . If string , will be
 encoded to bytes as utf - 8.
 signature : string or bytes , The signature on the message . If string ,
 will be encoded to bytes as utf - 8.
 Returns :
 True if message was signed by the private key associated with the
 public key that this object was constructed with ."""

implementation:
message = _helpers . _to_bytes ( message , encoding = 'utf-8' )
signature = _helpers . _to_bytes ( signature , encoding = 'utf-8' )
try :
    crypto . verify ( self . _pubkey , signature , message , 'sha256' )
    return True
except crypto . Error :
    return False


signature:
def from_string ( key_pem , is_x509_cert ) :
    """Construct a Verified instance from a string .
 Args :
 key _ pem : string , public key in PEM format .
 is _ x509 _ cert : bool , True if key _ pem is an X509 cert , otherwise it
 is expected to be an RSA key in PEM format .
 Returns :
 Verifier instance .
 Raises :
 OpenSSL . crypto . Error : if the key _ pem can ' t be parsed ."""

implementation:
key_pem = _helpers . _to_bytes ( key_pem )
if is_x509_cert :
    pubkey = crypto . load_certificate ( crypto . FILETYPE_PEM , key_pem )
else :
    pubkey = crypto . load_privatekey ( crypto . FILETYPE_PEM , key_pem )
return OpenSSLVerifier ( pubkey )


signature:
def sign ( self , message ) :
    """Signs a message .
 Args :
 message : bytes , Message to be signed .
 Returns :
 string , The signature of the message for the given key ."""

implementation:
message = _helpers . _to_bytes ( message , encoding = 'utf-8' )
return crypto . sign ( self . _key , message , 'sha256' )


signature:
def from_string ( key , password = b'notasecret' ) :
    """Construct a Signer instance from a string .
 Args :
 key : string , private key in PKCS12 or PEM format .
 password : string , password for the private key file .
 Returns :
 Signer instance .
 Raises :
 OpenSSL . crypto . Error if the key can ' t be parsed ."""

implementation:
key = _helpers . _to_bytes ( key )
parsed_pem_key = _helpers . _parse_pem_key ( key )
if parsed_pem_key :
    pkey = crypto . load_privatekey ( crypto . FILETYPE_PEM , parsed_pem_key )
else :
    password = _helpers . _to_bytes ( password , encoding = 'utf-8' )
    pkey = crypto . load_pkcs12 ( key , password ) . get_privatekey ( )
return OpenSSLSigner ( pkey )


signature:
def verify ( self , message , signature ) :
    """Verifies a message against a signature .
 Args :
 message : string or bytes , The message to verify . If string , will be
 encoded to bytes as utf - 8.
 signature : string or bytes , The signature on the message .
 Returns :
 True if message was signed by the private key associated with the
 public key that this object was constructed with ."""

implementation:
message = _helpers . _to_bytes ( message , encoding = 'utf-8' )
return PKCS1_v1_5 . new ( self . _pubkey ) . verify ( SHA256 . new ( message ) , signature )


signature:
def from_string ( key_pem , is_x509_cert ) :
    """Construct a Verified instance from a string .
 Args :
 key _ pem : string , public key in PEM format .
 is _ x509 _ cert : bool , True if key _ pem is an X509 cert , otherwise it
 is expected to be an RSA key in PEM format .
 Returns :
 Verifier instance ."""

implementation:
if is_x509_cert :
    key_pem = _helpers . _to_bytes ( key_pem )
    pemLines = key_pem . replace ( b' ' , b'' ) . split ( )
    certDer = _helpers . _urlsafe_b64decode ( b'' . join ( pemLines [ 1 : - 1 ] ) )
    certSeq = DerSequence ( )
    certSeq . decode ( certDer )
    tbsSeq = DerSequence ( )
    tbsSeq . decode ( certSeq [ 0 ] )
    pubkey = RSA . importKey ( tbsSeq [ 6 ] )
else :
    pubkey = RSA . importKey ( key_pem )
return PyCryptoVerifier ( pubkey )


signature:
def sign ( self , message ) :
    """Signs a message .
 Args :
 message : string , Message to be signed .
 Returns :
 string , The signature of the message for the given key ."""

implementation:
message = _helpers . _to_bytes ( message , encoding = 'utf-8' )
return PKCS1_v1_5 . new ( self . _key ) . sign ( SHA256 . new ( message ) )


signature:
def from_string ( key , password = 'notasecret' ) :
    """Construct a Signer instance from a string .
 Args :
 key : string , private key in PEM format .
 password : string , password for private key file . Unused for PEM
 files .
 Returns :
 Signer instance .
 Raises :
 NotImplementedError if the key isn ' t in PEM format ."""

implementation:
parsed_pem_key = _helpers . _parse_pem_key ( _helpers . _to_bytes ( key ) )
if parsed_pem_key :
    pkey = RSA . importKey ( parsed_pem_key )
else :
    raise NotImplementedError ( 'No key in PEM format was detected. This implementation ' 'can only use the PyCrypto library for keys in PEM ' 'format.' )
return PyCryptoSigner ( pkey )


signature:
def run_flow ( flow , storage , flags = None , http = None ) :
    """Core code for a command - line application .
 The ` ` run ( ) ` ` function is called from your application and runs
 through all the steps to obtain credentials . It takes a ` ` Flow ` `
 argument and attempts to open an authorization server page in the
 user ' s default web browser . The server asks the user to grant your
 application access to the user ' s data . If the user grants access ,
 the ` ` run ( ) ` ` function returns new credentials . The new credentials
 are also stored in the ` ` storage ` ` argument , which updates the file
 associated with the ` ` Storage ` ` object .
 It presumes it is run from a command - line application and supports the
 following flags :
 ` ` - - auth _ host _ name ` ` ( string , default : ` ` localhost ` ` )
 Host name to use when running a local web server to handle
 redirects during OAuth authorization .
 ` ` - - auth _ host _ port ` ` ( integer , default : ` ` [ 8080 , 8090 ] ` ` )
 Port to use when running a local web server to handle redirects
 during OAuth authorization . Repeat this option to specify a list
 of values .
 ` ` - - [ no ] auth _ local _ webserver ` ` ( boolean , default : ` ` True ` ` )
 Run a local web server to handle redirects during OAuth
 authorization .
 The tools module defines an ` ` ArgumentParser ` ` the already contains the
 flag definitions that ` ` run ( ) ` ` requires . You can pass that
 ` ` ArgumentParser ` ` to your ` ` ArgumentParser ` ` constructor : :
 parser = argparse . ArgumentParser (
 description = _ _ doc _ _ ,
 formatter _ class = argparse . RawDescriptionHelpFormatter ,
 parents = [ tools . argparser ] )
 flags = parser . parse _ args ( argv )
 Args :
 flow : Flow , an OAuth 2.0 Flow to step through .
 storage : Storage , a ` ` Storage ` ` to store the credential in .
 flags : ` ` argparse . Namespace ` ` , ( Optional ) The command - line flags . This
 is the object returned from calling ` ` parse _ args ( ) ` ` on
 ` ` argparse . ArgumentParser ` ` as described above . Defaults
 to ` ` argparser . parse _ args ( ) ` ` .
 http : An instance of ` ` httplib2 . Http . request ` ` or something that
 acts like it .
 Returns :
 Credentials , the obtained credential ."""

implementation:
if flags is None :
    flags = argparser . parse_args ( )
logging . getLogger ( ) . setLevel ( getattr ( logging , flags . logging_level ) )
if not flags . noauth_local_webserver :
    success = False
    port_number = 0
    for port in flags . auth_host_port :
        port_number = port
        try :
            httpd = ClientRedirectServer ( ( flags . auth_host_name , port ) , ClientRedirectHandler )
        except socket . error :
            pass
        else :
            success = True
            break
    flags . noauth_local_webserver = not success
    if not success :
        print ( _FAILED_START_MESSAGE )
if not flags . noauth_local_webserver :
    oauth_callback = 'http://{host}:{port}/' . format ( host = flags . auth_host_name , port = port_number )
else :
    oauth_callback = client . OOB_CALLBACK_URN
flow . redirect_uri = oauth_callback
authorize_url = flow . step1_get_authorize_url ( )
if not flags . noauth_local_webserver :
    import webbrowser
    webbrowser . open ( authorize_url , new = 1 , autoraise = True )
    print ( _BROWSER_OPENED_MESSAGE . format ( address = authorize_url ) )
else :
    print ( _GO_TO_LINK_MESSAGE . format ( address = authorize_url ) )
code = None
if not flags . noauth_local_webserver :
    httpd . handle_request ( )
    if 'error' in httpd . query_params :
        sys . exit ( 'Authentication request was rejected.' )
    if 'code' in httpd . query_params :
        code = httpd . query_params [ 'code' ]
    else :
        print ( 'Failed to find "code" in the query parameters ' 'of the redirect.' )
        sys . exit ( 'Try running with --noauth_local_webserver.' )
else :
    code = input ( 'Enter verification code: ' ) . strip ( )
try :
    credential = flow . step2_exchange ( code , http = http )
except client . FlowExchangeError as e :
    sys . exit ( 'Authentication has failed: {0}' . format ( e ) )
storage . put ( credential )
credential . set_store ( storage )
print ( 'Authentication successful.' )
return credential


signature:
def do_GET ( self ) :
    """Handle a GET request .
 Parses the query parameters and prints a message
 if the flow has completed . Note that we can ' t detect
 if an error occurred ."""

implementation:
self . send_response ( http_client . OK )
self . send_header ( 'Content-type' , 'text/html' )
self . end_headers ( )
parts = urllib . parse . urlparse ( self . path )
query = _helpers . parse_unique_urlencoded ( parts . query )
self . server . query_params = query
self . wfile . write ( b'<title>Authentication Status</title>' )
self . wfile . write ( b'
The authentication flow has completed.
' )
self . wfile . write ( b'' )


signature:
def oauth_required ( decorated_function = None , scopes = None , ** decorator_kwargs ) :
    """Decorator to require OAuth2 credentials for a view .
 . . code - block : : python
 : caption : views . py
 : name : views _ required _ 2
 from oauth2client . django _ util . decorators import oauth _ required
 @ oauth _ required
 def requires _ default _ scopes ( request ) :
 email = request . credentials . id _ token [ ' email ' ]
 service = build ( serviceName = ' calendar ' , version = ' v3 ' ,
 http = request . oauth . http ,
 developerKey = API _ KEY )
 events = service . events ( ) . list (
 calendarId = ' primary ' ) . execute ( ) [ ' items ' ]
 return HttpResponse (
 " email : { 0 } , calendar : { 1 } " . format ( email , str ( events ) ) )
 Args :
 decorated _ function : View function to decorate , must have the Django
 request object as the first argument .
 scopes : Scopes to require , will default .
 decorator _ kwargs : Can include ` ` return _ url ` ` to specify the URL to
 return to after OAuth2 authorization is complete .
 Returns :
 An OAuth2 Authorize view if credentials are not found or if the
 credentials are missing the required scopes . Otherwise ,
 the decorated view ."""

implementation:
def curry_wrapper ( wrapped_function ) :
    @ wraps ( wrapped_function )
    def required_wrapper ( request , * args , ** kwargs ) :
        if not ( django_util . oauth2_settings . storage_model is None or request . user . is_authenticated ( ) ) :
            redirect_str = '{0}?next={1}' . format ( django . conf . settings . LOGIN_URL , parse . quote ( request . path ) )
            return shortcuts . redirect ( redirect_str )
        return_url = decorator_kwargs . pop ( 'return_url' , request . get_full_path ( ) )
        user_oauth = django_util . UserOAuth2 ( request , scopes , return_url )
        if not user_oauth . has_credentials ( ) :
            return shortcuts . redirect ( user_oauth . get_authorize_redirect ( ) )
        setattr ( request , django_util . oauth2_settings . request_prefix , user_oauth )
        return wrapped_function ( request , * args , ** kwargs )
    return required_wrapper
if decorated_function :
    return curry_wrapper ( decorated_function )
else :
    return curry_wrapper


signature:
def oauth_enabled ( decorated_function = None , scopes = None , ** decorator_kwargs ) :
    """Decorator to enable OAuth Credentials if authorized , and setup
 the oauth object on the request object to provide helper functions
 to start the flow otherwise .
 . . code - block : : python
 : caption : views . py
 : name : views _ enabled3
 from oauth2client . django _ util . decorators import oauth _ enabled
 @ oauth _ enabled
 def optional _ oauth2 ( request ) :
 if request . oauth . has _ credentials ( ) :
 # this could be passed into a view
 # request . oauth . http is also initialized
 return HttpResponse ( " User email : { 0 } " . format (
 request . oauth . credentials . id _ token [ ' email ' ] )
 else :
 return HttpResponse ( ' Here is an OAuth Authorize link :
 < a href = " { 0 } " > Authorize < / a > ' . format (
 request . oauth . get _ authorize _ redirect ( ) ) )
 Args :
 decorated _ function : View function to decorate .
 scopes : Scopes to require , will default .
 decorator _ kwargs : Can include ` ` return _ url ` ` to specify the URL to
 return to after OAuth2 authorization is complete .
 Returns :
 The decorated view function ."""

implementation:
def curry_wrapper ( wrapped_function ) :
    @ wraps ( wrapped_function )
    def enabled_wrapper ( request , * args , ** kwargs ) :
        return_url = decorator_kwargs . pop ( 'return_url' , request . get_full_path ( ) )
        user_oauth = django_util . UserOAuth2 ( request , scopes , return_url )
        setattr ( request , django_util . oauth2_settings . request_prefix , user_oauth )
        return wrapped_function ( request , * args , ** kwargs )
    return enabled_wrapper
if decorated_function :
    return curry_wrapper ( decorated_function )
else :
    return curry_wrapper


signature:
def code_verifier ( n_bytes = 64 ) :
    """Generates a ' code _ verifier ' as described in section 4.1 of RFC 7636.
 This is a ' high - entropy cryptographic random string ' that will be
 impractical for an attacker to guess .
 Args :
 n _ bytes : integer between 31 and 96 , inclusive . default : 64
 number of bytes of entropy to include in verifier .
 Returns :
 Bytestring , representing urlsafe base64 - encoded random data ."""

implementation:
verifier = base64 . urlsafe_b64encode ( os . urandom ( n_bytes ) ) . rstrip ( b'=' )
# https : / / tools . ietf . org / html / rfc7636 # section - 4.1
# minimum length of 43 characters and a maximum length of 128 characters .
if len ( verifier ) < 43 :
    raise ValueError ( "Verifier too short. n_bytes must be > 30." )
elif len ( verifier ) > 128 :
    raise ValueError ( "Verifier too long. n_bytes must be < 97." )
else :
    return verifier


signature:
def code_challenge ( verifier ) :
    """Creates a ' code _ challenge ' as described in section 4.2 of RFC 7636
 by taking the sha256 hash of the verifier and then urlsafe
 base64 - encoding it .
 Args :
 verifier : bytestring , representing a code _ verifier as generated by
 code _ verifier ( ) .
 Returns :
 Bytestring , representing a urlsafe base64 - encoded sha256 hash digest ,
 without ' = ' padding ."""

implementation:
digest = hashlib . sha256 ( verifier ) . digest ( )
return base64 . urlsafe_b64encode ( digest ) . rstrip ( b'=' )


signature:
def _retrieve_info ( self , http ) :
    """Retrieves service account info for invalid credentials .
 Args :
 http : an object to be used to make HTTP requests ."""

implementation:
if self . invalid :
    info = _metadata . get_service_account_info ( http , service_account = self . service_account_email or 'default' )
    self . invalid = False
    self . service_account_email = info [ 'email' ]
    self . scopes = info [ 'scopes' ]


signature:
def _refresh ( self , http ) :
    """Refreshes the access token .
 Skip all the storage hoops and just refresh using the API .
 Args :
 http : an object to be used to make HTTP requests .
 Raises :
 HttpAccessTokenRefreshError : When the refresh fails ."""

implementation:
try :
    self . _retrieve_info ( http )
    self . access_token , self . token_expiry = _metadata . get_token ( http , service_account = self . service_account_email )
except http_client . HTTPException as err :
    raise client . HttpAccessTokenRefreshError ( str ( err ) )


signature:
def locked_get ( self ) :
    """Retrieve stored credential from the Django ORM .
 Returns :
 oauth2client . Credentials retrieved from the Django ORM , associated
 with the ` ` model ` ` , ` ` key _ value ` ` - > ` ` key _ name ` ` pair used to query
 for the model , and ` ` property _ name ` ` identifying the
 ` ` CredentialsProperty ` ` field , all of which are defined in the
 constructor for this Storage object ."""

implementation:
query = { self . key_name : self . key_value }
entities = self . model_class . objects . filter ( ** query )
if len ( entities ) > 0 :
    credential = getattr ( entities [ 0 ] , self . property_name )
    if getattr ( credential , 'set_store' , None ) is not None :
        credential . set_store ( self )
    return credential
else :
    return None


signature:
def locked_put ( self , credentials ) :
    """Write a Credentials to the Django datastore .
 Args :
 credentials : Credentials , the credentials to store ."""

implementation:
entity , _ = self . model_class . objects . get_or_create ( ** { self . key_name : self . key_value } )
setattr ( entity , self . property_name , credentials )
entity . save ( )


signature:
def locked_delete ( self ) :
    """Delete Credentials from the datastore ."""

implementation:
query = { self . key_name : self . key_value }
self . model_class . objects . filter ( ** query ) . delete ( )


signature:
def locked_get ( self ) :
    """Retrieve the credentials from the dictionary , if they exist .
 Returns : A : class : ` oauth2client . client . OAuth2Credentials ` instance ."""

implementation:
serialized = self . _dictionary . get ( self . _key )
if serialized is None :
    return None
credentials = client . OAuth2Credentials . from_json ( serialized )
credentials . set_store ( self )
return credentials


signature:
def locked_put ( self , credentials ) :
    """Save the credentials to the dictionary .
 Args :
 credentials : A : class : ` oauth2client . client . OAuth2Credentials `
 instance ."""

implementation:
serialized = credentials . to_json ( )
self . _dictionary [ self . _key ] = serialized