o ag@sdZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z m Z ddlmZmZmZddlmZdZd Zd Zd d iZGd ddZdS)z oauthlib.oauth2.rfc6749 ~~~~~~~~~~~~~~~~~~~~~~~ This module is an implementation of various logic needed for consuming OAuth 2.0 RFC6749. N)generate_token)tokens)InsecureTransportErrorTokenExpiredError)parse_token_responseprepare_token_request prepare_token_revocation_request)is_secure_transport auth_headerquerybodyz Content-Typez!application/x-www-form-urlencodedc@seZdZdZdZedddddddddedddfddZeddZ d d Z d d Z d dZ  d.ddZ  d/ddZ  d0ddZ  d1ddZ d2ddZd3ddZd4ddZ  d.d d!Zd"d#Zd3d$d%Zdddedfd&d'Zd(d)Zd*d+Zd,d-ZdS)5ClientaBase OAuth2 client responsible for access token management. This class also acts as a generic interface providing methods common to all client types such as ``prepare_authorization_request`` and ``prepare_token_revocation_request``. The ``prepare_x_request`` methods are the recommended way of interacting with clients (as opposed to the abstract prepare uri/body/etc methods). They are recommended over the older set because they are easier to use (more consistent) and add a few additional security checks, such as HTTPS and state checking. Some of these methods require further implementation only provided by the specific purpose clients such as :py:class:`oauthlib.oauth2.MobileApplicationClient` and thus you should always seek to use the client class matching the OAuth workflow you need. For Python, this is usually :py:class:`oauthlib.oauth2.WebApplicationClient`. refresh_tokenBearerNcKs||_||_||_||_||_||_||_|pi|_| |_| |_ | |_ | |_ | |_ ||_ ||_d|_d|_d|_||jdS)aeInitialize a client with commonly used attributes. :param client_id: Client identifier given by the OAuth provider upon registration. :param default_token_placement: Tokens can be supplied in the Authorization header (default), the URL query component (``query``) or the request body (``body``). :param token_type: OAuth 2 token type. Defaults to Bearer. Change this if you specify the ``access_token`` parameter and know it is of a different token type, such as a MAC, JWT or SAML token. Can also be supplied as ``token_type`` inside the ``token`` dict parameter. :param access_token: An access token (string) used to authenticate requests to protected resources. Can also be supplied inside the ``token`` dict parameter. :param refresh_token: A refresh token (string) used to refresh expired tokens. Can also be supplied inside the ``token`` dict parameter. :param mac_key: Encryption key used with MAC tokens. :param mac_algorithm: Hashing algorithm for MAC tokens. :param token: A dict of token attributes such as ``access_token``, ``token_type`` and ``expires_at``. :param scope: A list of default scopes to request authorization for. :param state: A CSRF protection string used during authorization. :param redirect_url: The redirection endpoint on the client side to which the user returns after authorization. :param state_generator: A no argument state generation callable. Defaults to :py:meth:`oauthlib.common.generate_token`. :param code_verifier: PKCE parameter. A cryptographically random string that is used to correlate the authorization request to the token request. :param code_challenge: PKCE parameter. A challenge derived from the code verifier that is sent in the authorization request, to be verified against later. :param code_challenge_method: PKCE parameter. A method that was used to derive code challenge. Defaults to "plain" if not present in the request. N) client_iddefault_token_placement token_type access_tokenrmac_key mac_algorithmtokenscopestate_generatorstate redirect_url code_verifiercode_challengecode_challenge_methodcode expires_in _expires_atpopulate_token_attributes)selfrrrrrrrrrrrrrrrkwargsr$F/usr/lib/python3/dist-packages/oauthlib/oauth2/rfc6749/clients/base.py__init__8s&@ zClient.__init__cCs|j|jdS)aOSupported token types and their respective methods Additional tokens can be supported by extending this dictionary. The Bearer token spec is stable and safe to use. The MAC token spec is not yet stable and support for MAC tokens is experimental and currently matching version 00 of the spec. )rMAC)_add_bearer_token_add_mac_token)r"r$r$r% token_typess zClient.token_typescOtd)z,Abstract method used to create request URIs.*Must be implemented by inheriting classes.NotImplementedErrorr"argsr#r$r$r%prepare_request_urizClient.prepare_request_uricOr+)z.Abstract method used to create request bodies.r,r-r/r$r$r%prepare_request_bodyr2zClient.prepare_request_bodycOr+)z4Abstract method used to parse redirection responses.r,r-r/r$r$r%parse_request_uri_responser2z!Client.parse_request_uri_responseGETcKst|st|p |j}dd|jD}|j|vr$td|j|js1|j ds1td|j r>|j t kr>t ||j|||||fi|S)acAdd token to the request uri, body or authorization header. The access token type provides the client with the information required to successfully utilize the access token to make a protected resource request (along with type-specific attributes). The client MUST NOT use an access token if it does not understand the token type. For example, the "bearer" token type defined in [`I-D.ietf-oauth-v2-bearer`_] is utilized by simply including the access token string in the request: .. code-block:: http GET /resource/1 HTTP/1.1 Host: example.com Authorization: Bearer mF_9.B5f-4.1JqM while the "mac" token type defined in [`I-D.ietf-oauth-v2-http-mac`_] is utilized by issuing a MAC key together with the access token which is used to sign certain components of the HTTP requests: .. code-block:: http GET /resource/1 HTTP/1.1 Host: example.com Authorization: MAC id="h480djs93hd8", nonce="274312:dj83hs9s", mac="kDZvddkndxvhGRXZhvuDjEWhGeE=" .. _`I-D.ietf-oauth-v2-bearer`: https://tools.ietf.org/html/rfc6749#section-12.2 .. _`I-D.ietf-oauth-v2-http-mac`: https://tools.ietf.org/html/rfc6749#section-12.2 cSsi|] \}}||qSr$)lower).0kvr$r$r% sz$Client.add_token..zUnsupported token type: %srzMissing access token.)r rrr*itemsrr6 ValueErrorrrgetr timer)r"uri http_methodr headerstoken_placementr#case_insensitive_token_typesr$r$r% add_tokens"# zClient.add_tokencKsbt|st|p ||_|p|j|_|dur|jn|}|j|f|j||jd|}|tdfS)a>Prepare the authorization request. This is the first step in many OAuth flows in which the user is redirected to a certain authorization URL. This method adds required parameters to the authorization URL. :param authorization_url: Provider authorization endpoint URL. :param state: CSRF protection string. Will be automatically created if not provided. The generated state is available via the ``state`` attribute. Clients should verify that the state is unchanged and present in the authorization response. This verification is done automatically if using the ``authorization_response`` parameter with ``prepare_token_request``. :param redirect_url: Redirect URL to which the user will be returned after authorization. Must be provided unless previously setup with the provider. If provided then it must also be provided in the token request. :param scope: List of scopes to request. Must be equal to or a subset of the scopes granted when obtaining the refresh token. If none is provided, the ones provided in the constructor are used. :param kwargs: Additional parameters to included in the request. :returns: The prepared request tuple with (url, headers, body). N) redirect_urirr)r rrrrrr1FORM_ENC_HEADERS)r"authorization_urlrrrr#auth_urlr$r$r%prepare_authorization_requests  z$Client.prepare_authorization_requestrFcKsXt|st|p |j}|r|j||d|p|j|_|jd||jd|}|t|fS)aPrepare a token creation request. Note that these requests usually require client authentication, either by including client_id or a set of provider specific authentication credentials. :param token_url: Provider token creation endpoint URL. :param authorization_response: The full redirection URL string, i.e. the location to which the user was redirected after successfull authorization. Used to mine credentials needed to obtain a token in this step, such as authorization code. :param redirect_url: The redirect_url supplied with the authorization request (if there was one). :param state: :param body: Existing request body (URL encoded string) to embed parameters into. This may contain extra paramters. Default ''. :param kwargs: Additional parameters to included in the request. :returns: The prepared request tuple with (url, headers, body). )r)r rENr$)r rrr4rr3rG)r" token_urlauthorization_responserrr r#r$r$r%r s   zClient.prepare_token_requestcKsBt|st|dur|jn|}|jd|||d|}|t|fS)aPrepare an access token refresh request. Expired access tokens can be replaced by new access tokens without going through the OAuth dance if the client obtained a refresh token. This refresh token and authentication credentials can be used to obtain a new access token, and possibly a new refresh token. :param token_url: Provider token refresh endpoint URL. :param refresh_token: Refresh token string. :param body: Existing request body (URL encoded string) to embed parameters into. This may contain extra paramters. Default ''. :param scope: List of scopes to request. Must be equal to or a subset of the scopes granted when obtaining the refresh token. If none is provided, the ones provided in the constructor are used. :param kwargs: Additional parameters to included in the request. :returns: The prepared request tuple with (url, headers, body). N)r rrr$)r rrprepare_refresh_bodyrG)r"rKrr rr#r$r$r%prepare_refresh_token_request1s z$Client.prepare_refresh_token_requestrcKs(t|stt||f|||d|S)aBPrepare a token revocation request. :param revocation_url: Provider token revocation endpoint URL. :param token: The access or refresh token to be revoked (string). :param token_type_hint: ``"access_token"`` (default) or ``"refresh_token"``. This is optional and if you wish to not pass it you must provide ``token_type_hint=None``. :param body: :param callback: A jsonp callback such as ``package.callback`` to be invoked upon receiving the response. Not that it should not include a () suffix. :param kwargs: Additional parameters to included in the request. :returns: The prepared request tuple with (url, headers, body). Note that JSONP request may use GET requests as the parameters will be added to the request URL query as opposed to the request body. An example of a revocation request .. code-block: http POST /revoke HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token An example of a jsonp revocation request .. code-block: http GET /revoke?token=agabcdefddddafdd&callback=package.myCallback HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW and an error response .. code-block: http package.myCallback({"error":"unsupported_token_type"}); Note that these requests usually require client credentials, client_id in the case for public clients and provider specific authentication credentials for confidential clients. )token_type_hintr callback)r rr)r"revocation_urlrrOr rPr#r$r$r%rSs6z'Client.prepare_token_revocation_requestcKs2|dur|jn|}t||d|_||j|jS)ajParse the JSON response body. If the access token request is valid and authorized, the authorization server issues an access token as described in `Section 5.1`_. A refresh token SHOULD NOT be included. If the request failed client authentication or is invalid, the authorization server returns an error response as described in `Section 5.2`_. :param body: The response body from the token request. :param scope: Scopes originally requested. If none is provided, the ones provided in the constructor are used. :return: Dictionary of token parameters. :raises: Warning if scope has changed. OAuth2Error if response is invalid. These response are json encoded and could easily be parsed without the assistance of OAuthLib. However, there are a few subtle issues to be aware of regarding the response which are helpfully addressed through the raising of various errors. A successful response should always contain **access_token** The access token issued by the authorization server. Often a random string. **token_type** The type of the token issued as described in `Section 7.1`_. Commonly ``Bearer``. While it is not mandated it is recommended that the provider include **expires_in** The lifetime in seconds of the access token. For example, the value "3600" denotes that the access token will expire in one hour from the time the response was generated. If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value. **scope** Providers may supply this in all responses but are required to only if it has changed since the authorization request. .. _`Section 5.1`: https://tools.ietf.org/html/rfc6749#section-5.1 .. _`Section 5.2`: https://tools.ietf.org/html/rfc6749#section-5.2 .. _`Section 7.1`: https://tools.ietf.org/html/rfc6749#section-7.1 N)r)rrrr!)r"r rr#r$r$r%parse_request_body_responses/ z"Client.parse_request_body_responsecKs6|p|j}|dur |jn|}t|jf|||d|S)aPrepare an access token request, using a refresh token. If the authorization server issued a refresh token to the client, the client makes a refresh request to the token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format in the HTTP request entity-body: grant_type REQUIRED. Value MUST be set to "refresh_token". refresh_token REQUIRED. The refresh token issued to the client. scope OPTIONAL. The scope of the access request as described by Section 3.3. The requested scope MUST NOT include any scope not originally granted by the resource owner, and if omitted is treated as equal to the scope originally granted by the resource owner. Note that if none is provided, the ones provided in the constructor are used if any. N)r rr)rrrrefresh_token_key)r"r rrr#r$r$r%rMs  zClient.prepare_refresh_bodycCsZ|tkr t|j|}n|tkrt|j|}n|tkr$t|j|}ntd|||fS)zDAdd a bearer token to the request uri, body or authorization header.Invalid token placement.) AUTH_HEADERrprepare_bearer_headersr URI_QUERYprepare_bearer_uriBODYprepare_bearer_bodyr<)r"r?r@r rArBr$r$r%r(s zClient._add_bearer_tokencCsVd}|dks td|dkstdtd}t|}t||s&td||_|S)aCreate PKCE **code_verifier** used in computing **code_challenge**. :param length: REQUIRED. The length of the code_verifier. The client first creates a code verifier, "code_verifier", for each OAuth 2.0 [RFC6749] Authorization Request, in the following manner: code_verifier = high-entropy cryptographic random STRING using the unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" from Section 2.3 of [RFC3986], with a minimum length of 43 characters and a maximum length of 128 characters. .. _`Section 4.1`: https://tools.ietf.org/html/rfc7636#section-4.1 N+z*Length must be greater than or equal to 43z(Length must be less than or equal to 128z^[A-Zaa-z0-9-._~]z)code_verifier contains invalid characters)r<recompilesecrets token_urlsafesearchr)r"lengthrallowed_charactersr$r$r%create_code_verifiers   zClient.create_code_verifiercCsd}|dkr td|dkrd}||_|}||_|dkrFt}||jdd|}t t |}| dd d d  d d }||_|S) aDCreate PKCE **code_challenge** derived from the **code_verifier**. :param code_verifier: REQUIRED. The **code_verifier** generated from create_code_verifier(). :param code_challenge_method: OPTIONAL. The method used to derive the **code_challenge**. Acceptable values include "S256". DEFAULT is "plain". The client then creates a code challenge derived from the code verifier by using one of the following transformations on the code verifier: plain code_challenge = code_verifier S256 code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) If the client is capable of using "S256", it MUST use "S256", as "S256" is Mandatory To Implement (MTI) on the server. Clients are permitted to use "plain" only if they cannot support "S256" for some technical reason and know via out-of-band configuration that the server supports "plain". The plain transformation is for compatibility with existing deployments and for constrained environments that can't use the S256 transformation. .. _`Section 4.2`: https://tools.ietf.org/html/rfc7636#section-4.2 NzInvalid code_verifierplainS256ascii)encoding+-/_=rF) r<rrhashlibsha256updateencodedigestbytesdecodebase64urlsafe_b64encodereplace)r"rrrh sha256_valr$r$r%create_code_challenges zClient.create_code_challengecKsB|tkrtdtj|j||j|f||||jd|}|||fS)zAdd a MAC token to the request authorization header. Warning: MAC token support is experimental as the spec is not yet stable. rT)rAr exthash_algorithm)rUr<rprepare_mac_headerrrr)r"r?r@r rArBr{r#r$r$r%r)Bs  zClient._add_mac_tokencCstdt||S)Nz=Please switch to the public method populate_token_attributes.)warningswarnDeprecationWarningr!r"responser$r$r%_populate_attributesPs zClient._populate_attributescCsd|vr |d|_dSdS)z2Add attributes from an auth code response to self.rN)r=rrr$r$r%populate_code_attributesUszClient.populate_code_attributescCsd|vr |d|_d|vr|d|_d|vr|d|_d|vr2|d|_tt|j|_d|vrHz t|d|_Wnd|_Yd|vrR|d|_d|vr^|d|_ dSdS) z6Add attributes from a token exchange response to self.rrrr expires_atNrr) r=rrrrr>intr rrrr$r$r%r![s&     z Client.populate_token_attributes)r5NNN)NNN)NNNrF)NrFN)rrFN)N)rFNN)__name__ __module__ __qualname____doc__rSrUrr&propertyr*r1r3r4rDrJrrNrrRrMr(rdrzr)rrr!r$r$r$r%r $sd T  6 + ( # = 4  !4  r )rr>r~r_r]rnruoauthlib.commonroauthlib.oauth2.rfc6749roauthlib.oauth2.rfc6749.errorsrr"oauthlib.oauth2.rfc6749.parametersrrroauthlib.oauth2.rfc6749.utilsr rUrWrYrGr r$r$r$r%s$