1""" 
    2oauthlib.openid.connect.core.request_validator 
    3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    4""" 
    5import logging 
    6 
    7from oauthlib.oauth2.rfc6749.request_validator import ( 
    8    RequestValidator as OAuth2RequestValidator, 
    9) 
    10 
    11log = logging.getLogger(__name__) 
    12 
    13 
    14class RequestValidator(OAuth2RequestValidator): 
    15 
    16    def get_authorization_code_scopes(self, client_id, code, redirect_uri, request): 
    17        """ Extracts scopes from saved authorization code. 
    18 
    19        The scopes returned by this method is used to route token requests 
    20        based on scopes passed to Authorization Code requests. 
    21 
    22        With that the token endpoint knows when to include OpenIDConnect 
    23        id_token in token response only based on authorization code scopes. 
    24 
    25        Only code param should be sufficient to retrieve grant code from 
    26        any storage you are using, `client_id` and `redirect_uri` can have a 
    27        blank value `""` don't forget to check it before using those values 
    28        in a select query if a database is used. 
    29 
    30        :param client_id: Unicode client identifier 
    31        :param code: Unicode authorization code grant 
    32        :param redirect_uri: Unicode absolute URI 
    33        :return: A list of scope 
    34 
    35        Method is used by: 
    36            - Authorization Token Grant Dispatcher 
    37        """ 
    38        raise NotImplementedError('Subclasses must implement this method.') 
    39 
    40    def get_authorization_code_nonce(self, client_id, code, redirect_uri, request): 
    41        """ Extracts nonce from saved authorization code. 
    42 
    43        If present in the Authentication Request, Authorization 
    44        Servers MUST include a nonce Claim in the ID Token with the 
    45        Claim Value being the nonce value sent in the Authentication 
    46        Request. Authorization Servers SHOULD perform no other 
    47        processing on nonce values used. The nonce value is a 
    48        case-sensitive string. 
    49 
    50        Only code param should be sufficient to retrieve grant code from 
    51        any storage you are using. However, `client_id` and `redirect_uri` 
    52        have been validated and can be used also. 
    53 
    54        :param client_id: Unicode client identifier 
    55        :param code: Unicode authorization code grant 
    56        :param redirect_uri: Unicode absolute URI 
    57        :return: Unicode nonce 
    58 
    59        Method is used by: 
    60            - Authorization Token Grant Dispatcher 
    61        """ 
    62        raise NotImplementedError('Subclasses must implement this method.') 
    63 
    64    def get_jwt_bearer_token(self, token, token_handler, request): 
    65        """Get JWT Bearer token or OpenID Connect ID token 
    66 
    67        If using OpenID Connect this SHOULD call `oauthlib.oauth2.RequestValidator.get_id_token` 
    68 
    69        :param token: A Bearer token dict 
    70        :param token_handler: the token handler (BearerToken class) 
    71        :param request: OAuthlib request. 
    72        :type request: oauthlib.common.Request 
    73        :return: The JWT Bearer token or OpenID Connect ID token (a JWS signed JWT) 
    74 
    75        Method is used by JWT Bearer and OpenID Connect tokens: 
    76            - JWTToken.create_token 
    77        """ 
    78        raise NotImplementedError('Subclasses must implement this method.') 
    79 
    80    def get_id_token(self, token, token_handler, request): 
    81        """Get OpenID Connect ID token 
    82 
    83        This method is OPTIONAL and is NOT RECOMMENDED. 
    84        `finalize_id_token` SHOULD be implemented instead. However, if you 
    85        want a full control over the minting of the `id_token`, you 
    86        MAY want to override `get_id_token` instead of using 
    87        `finalize_id_token`. 
    88 
    89        In the OpenID Connect workflows when an ID Token is requested this method is called. 
    90        Subclasses should implement the construction, signing and optional encryption of the 
    91        ID Token as described in the OpenID Connect spec. 
    92 
    93        In addition to the standard OAuth2 request properties, the request may also contain 
    94        these OIDC specific properties which are useful to this method: 
    95 
    96            - nonce, if workflow is implicit or hybrid and it was provided 
    97            - claims, if provided to the original Authorization Code request 
    98 
    99        The token parameter is a dict which may contain an ``access_token`` entry, in which 
    100        case the resulting ID Token *should* include a calculated ``at_hash`` claim. 
    101 
    102        Similarly, when the request parameter has a ``code`` property defined, the ID Token 
    103        *should* include a calculated ``c_hash`` claim. 
    104 
    105        http://openid.net/specs/openid-connect-core-1_0.html (sections `3.1.3.6`_, `3.2.2.10`_, `3.3.2.11`_) 
    106 
    107        .. _`3.1.3.6`: http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken 
    108        .. _`3.2.2.10`: http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDToken 
    109        .. _`3.3.2.11`: http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken 
    110 
    111        :param token: A Bearer token dict 
    112        :param token_handler: the token handler (BearerToken class) 
    113        :param request: OAuthlib request. 
    114        :type request: oauthlib.common.Request 
    115        :return: The ID Token (a JWS signed JWT) 
    116        """ 
    117        return None 
    118 
    119    def finalize_id_token(self, id_token, token, token_handler, request): 
    120        """Finalize OpenID Connect ID token & Sign or Encrypt. 
    121 
    122        In the OpenID Connect workflows when an ID Token is requested 
    123        this method is called.  Subclasses should implement the 
    124        construction, signing and optional encryption of the ID Token 
    125        as described in the OpenID Connect spec. 
    126 
    127        The `id_token` parameter is a dict containing a couple of OIDC 
    128        technical fields related to the specification. Prepopulated 
    129        attributes are: 
    130 
    131        - `aud`, equals to `request.client_id`. 
    132        - `iat`, equals to current time. 
    133        - `nonce`, if present, is equals to the `nonce` from the 
    134          authorization request. 
    135        - `at_hash`, hash of `access_token`, if relevant. 
    136        - `c_hash`, hash of `code`, if relevant. 
    137 
    138        This method MUST provide required fields as below: 
    139 
    140        - `iss`, REQUIRED. Issuer Identifier for the Issuer of the response. 
    141        - `sub`, REQUIRED. Subject Identifier 
    142        - `exp`, REQUIRED. Expiration time on or after which the ID 
    143          Token MUST NOT be accepted by the RP when performing 
    144          authentication with the OP. 
    145 
    146        Additional claims must be added, note that `request.scope` 
    147        should be used to determine the list of claims. 
    148 
    149        More information can be found at `OpenID Connect Core#Claims`_ 
    150 
    151        .. _`OpenID Connect Core#Claims`: https://openid.net/specs/openid-connect-core-1_0.html#Claims 
    152 
    153        :param id_token: A dict containing technical fields of id_token 
    154        :param token: A Bearer token dict 
    155        :param token_handler: the token handler (BearerToken class) 
    156        :param request: OAuthlib request. 
    157        :type request: oauthlib.common.Request 
    158        :return: The ID Token (a JWS signed JWT or JWE encrypted JWT) 
    159        """ 
    160        raise NotImplementedError('Subclasses must implement this method.') 
    161 
    162    def validate_jwt_bearer_token(self, token, scopes, request): 
    163        """Ensure the JWT Bearer token or OpenID Connect ID token are valids and authorized access to scopes. 
    164 
    165        If using OpenID Connect this SHOULD call `oauthlib.oauth2.RequestValidator.get_id_token` 
    166 
    167        If not using OpenID Connect this can `return None` to avoid 5xx rather 401/3 response. 
    168 
    169        OpenID connect core 1.0 describe how to validate an id_token: 
    170            - http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation 
    171            - http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDTValidation 
    172            - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation 
    173            - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation2 
    174 
    175        :param token: Unicode Bearer token 
    176        :param scopes: List of scopes (defined by you) 
    177        :param request: OAuthlib request. 
    178        :type request: oauthlib.common.Request 
    179        :rtype: True or False 
    180 
    181        Method is indirectly used by all core OpenID connect JWT token issuing grant types: 
    182            - Authorization Code Grant 
    183            - Implicit Grant 
    184            - Hybrid Grant 
    185        """ 
    186        raise NotImplementedError('Subclasses must implement this method.') 
    187 
    188    def validate_id_token(self, token, scopes, request): 
    189        """Ensure the id token is valid and authorized access to scopes. 
    190 
    191        OpenID connect core 1.0 describe how to validate an id_token: 
    192            - http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation 
    193            - http://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDTValidation 
    194            - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation 
    195            - http://openid.net/specs/openid-connect-core-1_0.html#HybridIDTValidation2 
    196 
    197        :param token: Unicode Bearer token 
    198        :param scopes: List of scopes (defined by you) 
    199        :param request: OAuthlib request. 
    200        :type request: oauthlib.common.Request 
    201        :rtype: True or False 
    202 
    203        Method is indirectly used by all core OpenID connect JWT token issuing grant types: 
    204            - Authorization Code Grant 
    205            - Implicit Grant 
    206            - Hybrid Grant 
    207        """ 
    208        raise NotImplementedError('Subclasses must implement this method.') 
    209 
    210    def validate_silent_authorization(self, request): 
    211        """Ensure the logged in user has authorized silent OpenID authorization. 
    212 
    213        Silent OpenID authorization allows access tokens and id tokens to be 
    214        granted to clients without any user prompt or interaction. 
    215 
    216        :param request: OAuthlib request. 
    217        :type request: oauthlib.common.Request 
    218        :rtype: True or False 
    219 
    220        Method is used by: 
    221            - OpenIDConnectAuthCode 
    222            - OpenIDConnectImplicit 
    223            - OpenIDConnectHybrid 
    224        """ 
    225        raise NotImplementedError('Subclasses must implement this method.') 
    226 
    227    def validate_silent_login(self, request): 
    228        """Ensure session user has authorized silent OpenID login. 
    229 
    230        If no user is logged in or has not authorized silent login, this 
    231        method should return False. 
    232 
    233        If the user is logged in but associated with multiple accounts and 
    234        not selected which one to link to the token then this method should 
    235        raise an oauthlib.oauth2.AccountSelectionRequired error. 
    236 
    237        :param request: OAuthlib request. 
    238        :type request: oauthlib.common.Request 
    239        :rtype: True or False 
    240 
    241        Method is used by: 
    242            - OpenIDConnectAuthCode 
    243            - OpenIDConnectImplicit 
    244            - OpenIDConnectHybrid 
    245        """ 
    246        raise NotImplementedError('Subclasses must implement this method.') 
    247 
    248    def validate_user_match(self, id_token_hint, scopes, claims, request): 
    249        """Ensure client supplied user id hint matches session user. 
    250 
    251        If the sub claim or id_token_hint is supplied then the session 
    252        user must match the given ID. 
    253 
    254        :param id_token_hint: User identifier string. 
    255        :param scopes: List of OAuth 2 scopes and OpenID claims (strings). 
    256        :param claims: OpenID Connect claims dict. 
    257        :param request: OAuthlib request. 
    258        :type request: oauthlib.common.Request 
    259        :rtype: True or False 
    260 
    261        Method is used by: 
    262            - OpenIDConnectAuthCode 
    263            - OpenIDConnectImplicit 
    264            - OpenIDConnectHybrid 
    265        """ 
    266        raise NotImplementedError('Subclasses must implement this method.') 
    267 
    268    def get_userinfo_claims(self, request): 
    269        """Return the UserInfo claims in JSON or Signed or Encrypted. 
    270 
    271        The UserInfo Claims MUST be returned as the members of a JSON object 
    272         unless a signed or encrypted response was requested during Client 
    273         Registration. The Claims defined in Section 5.1 can be returned, as can 
    274         additional Claims not specified there. 
    275 
    276        For privacy reasons, OpenID Providers MAY elect to not return values for 
    277        some requested Claims. 
    278 
    279        If a Claim is not returned, that Claim Name SHOULD be omitted from the 
    280        JSON object representing the Claims; it SHOULD NOT be present with a 
    281        null or empty string value. 
    282 
    283        The sub (subject) Claim MUST always be returned in the UserInfo 
    284        Response. 
    285 
    286        Upon receipt of the UserInfo Request, the UserInfo Endpoint MUST return 
    287        the JSON Serialization of the UserInfo Response as in Section 13.3 in 
    288        the HTTP response body unless a different format was specified during 
    289        Registration [OpenID.Registration]. 
    290 
    291        If the UserInfo Response is signed and/or encrypted, then the Claims are 
    292        returned in a JWT and the content-type MUST be application/jwt. The 
    293        response MAY be encrypted without also being signed. If both signing and 
    294        encryption are requested, the response MUST be signed then encrypted, 
    295        with the result being a Nested JWT, as defined in [JWT]. 
    296 
    297        If signed, the UserInfo Response SHOULD contain the Claims iss (issuer) 
    298        and aud (audience) as members. The iss value SHOULD be the OP's Issuer 
    299        Identifier URL. The aud value SHOULD be or include the RP's Client ID 
    300        value. 
    301 
    302        :param request: OAuthlib request. 
    303        :type request: oauthlib.common.Request 
    304        :rtype: Claims as a dict OR JWT/JWS/JWE as a string 
    305 
    306        Method is used by: 
    307            UserInfoEndpoint 
    308        """ 
    309 
    310    def refresh_id_token(self, request): 
    311        """Whether the id token should be refreshed. Default, True 
    312 
    313        :param request: OAuthlib request. 
    314        :type request: oauthlib.common.Request 
    315        :rtype: True or False 
    316 
    317        Method is used by: 
    318            RefreshTokenGrant 
    319        """ 
    320        return True