コード例 #1
0
    def test_register(self):
        registration_endpoint = self.PROVIDER_BASEURL + '/register'
        responses.add(responses.POST, registration_endpoint, json=self.CLIENT_METADATA.to_dict())

        provider_metadata = self.PROVIDER_METADATA.copy(registration_endpoint=registration_endpoint)
        unregistered = ProviderConfiguration(provider_metadata=provider_metadata,
                                             client_registration_info=ClientRegistrationInfo())
        facade = PyoidcFacade(unregistered, self.REDIRECT_URI)
        facade.register()
        assert facade.is_registered() is True
コード例 #2
0
    def test_token_request_handles_error_response(self):
        token_endpoint = self.PROVIDER_BASEURL + '/token'
        token_response = TokenErrorResponse(error='invalid_request', error_description='test error description')
        responses.add(responses.POST, token_endpoint, json=token_response.to_dict(), status=400)

        provider_metadata = self.PROVIDER_METADATA.copy(token_endpoint=token_endpoint)
        facade = PyoidcFacade(ProviderConfiguration(provider_metadata=provider_metadata,
                                                    client_metadata=self.CLIENT_METADATA),
                              self.REDIRECT_URI)
        assert facade.token_request('1234') == token_response
コード例 #3
0
 def test_no_userinfo_request_is_made_if_no_userinfo_endpoint_is_configured(
         self):
     facade = PyoidcFacade(
         ProviderConfiguration(
             provider_metadata=self.PROVIDER_METADATA,
             client_metadata=self.CLIENT_METADATA,
         ),
         self.REDIRECT_URI,
     )
     assert facade.userinfo_request("test_token") is None
コード例 #4
0
 def test_parse_authentication_response(self):
     facade = PyoidcFacade(ProviderConfiguration(provider_metadata=self.PROVIDER_METADATA,
                                                 client_metadata=self.CLIENT_METADATA),
                           self.REDIRECT_URI)
     auth_code = 'auth_code-1234'
     state = 'state-1234'
     auth_response = AuthorizationResponse(**{'state': state, 'code': auth_code})
     parsed_auth_response = facade.parse_authentication_response(auth_response.to_dict())
     assert isinstance(parsed_auth_response, AuthorizationResponse)
     assert parsed_auth_response.to_dict() == auth_response.to_dict()
コード例 #5
0
 def test_no_userinfo_request_is_made_if_no_access_token(self):
     provider_metadata = self.PROVIDER_METADATA.copy(
         userinfo_endpoint=self.PROVIDER_BASEURL + "/userinfo")
     facade = PyoidcFacade(
         ProviderConfiguration(
             provider_metadata=provider_metadata,
             client_metadata=self.CLIENT_METADATA,
         ),
         self.REDIRECT_URI,
     )
     assert facade.userinfo_request(None) is None
コード例 #6
0
    def test_configurable_userinfo_endpoint_method_is_used(self, userinfo_http_method):
        userinfo_endpoint = self.PROVIDER_BASEURL + '/userinfo'
        userinfo_response = OpenIDSchema(sub='user1')
        responses.add(userinfo_http_method, userinfo_endpoint, json=userinfo_response.to_dict())

        provider_metadata = self.PROVIDER_METADATA.copy(userinfo_endpoint=userinfo_endpoint)
        facade = PyoidcFacade(ProviderConfiguration(provider_metadata=provider_metadata,
                                                    client_metadata=self.CLIENT_METADATA,
                                                    userinfo_http_method=userinfo_http_method),
                              self.REDIRECT_URI)
        assert facade.userinfo_request('test_token') == userinfo_response
コード例 #7
0
 def test_parse_authentication_response_handles_error_response(self):
     facade = PyoidcFacade(
         ProviderConfiguration(provider_metadata=self.PROVIDER_METADATA,
                               client_metadata=self.CLIENT_METADATA),
         REDIRECT_URI)
     error_response = AuthorizationErrorResponse(**{
         'error': 'invalid_request',
         'state': 'state-1234'
     })
     parsed_auth_response = facade.parse_authentication_response(
         error_response)
     assert isinstance(parsed_auth_response, AuthorizationErrorResponse)
     assert parsed_auth_response.to_dict() == error_response.to_dict()
コード例 #8
0
    def test_token_request(self):
        token_endpoint = self.PROVIDER_BASEURL + "/token"
        now = int(time.time())
        id_token_claims = {
            "iss": self.PROVIDER_METADATA["issuer"],
            "sub": "test_user",
            "aud": [self.CLIENT_METADATA["client_id"]],
            "exp": now + 1,
            "iat": now,
            "nonce": "test_nonce",
        }
        id_token_jwt, id_token_signing_key = signed_id_token(id_token_claims)
        token_response = AccessTokenResponse(access_token="test_access_token",
                                             token_type="Bearer",
                                             id_token=id_token_jwt)
        responses.add(responses.POST,
                      token_endpoint,
                      json=token_response.to_dict())

        provider_metadata = self.PROVIDER_METADATA.copy(
            token_endpoint=token_endpoint)
        facade = PyoidcFacade(
            ProviderConfiguration(
                provider_metadata=provider_metadata,
                client_metadata=self.CLIENT_METADATA,
            ),
            self.REDIRECT_URI,
        )

        auth_code = "auth_code-1234"
        responses.add(
            responses.GET,
            self.PROVIDER_METADATA["jwks_uri"],
            json={"keys": [id_token_signing_key.serialize()]},
        )
        with self.app.app_context():
            token_response = facade.token_request(auth_code)

        assert isinstance(token_response, AccessTokenResponse)
        expected_token_response = token_response.to_dict()
        expected_token_response["id_token"] = id_token_claims
        expected_token_response["id_token_jwt"] = id_token_jwt
        assert token_response.to_dict() == expected_token_response

        token_request = dict(parse_qsl(responses.calls[0].request.body))
        expected_token_request = {
            "grant_type": "authorization_code",
            "code": auth_code,
            "redirect_uri": self.FULL_REDIRECT_URI
        }
        assert token_request == expected_token_request
コード例 #9
0
 def test_should_detect_nonce_mismatch(self, client_mock):
     client = PyoidcFacade(
         ProviderConfiguration(
             provider_metadata=ProviderMetadata(issuer=self.ISSUER),
             client_metadata=ClientMetadata(client_id=self.CLIENT_ID)),
         redirect_uri='https://client.example.com/redirect')
     client.exchange_authorization_code = MagicMock(
         return_value=self.TOKEN_RESPONSE)
     auth_request = {
         'state': self.AUTH_RESPONSE['state'],
         'nonce': 'other_nonce'
     }
     with pytest.raises(InvalidIdTokenError):
         AuthResponseHandler(client).process_auth_response(
             self.AUTH_RESPONSE, auth_request)
コード例 #10
0
    def test_token_request(self):
        token_endpoint = self.PROVIDER_BASEURL + '/token'
        now = int(time.time())
        id_token_claims = {
            'iss': self.PROVIDER_METADATA['issuer'],
            'sub': 'test_user',
            'aud': [self.CLIENT_METADATA['client_id']],
            'exp': now + 1,
            'iat': now,
            'nonce': 'test_nonce'
        }
        id_token_jwt, id_token_signing_key = signed_id_token(id_token_claims)
        token_response = AccessTokenResponse(access_token='test_access_token',
                                             token_type='Bearer',
                                             id_token=id_token_jwt)
        responses.add(responses.POST,
                      token_endpoint,
                      json=token_response.to_dict())

        provider_metadata = self.PROVIDER_METADATA.copy(
            token_endpoint=token_endpoint)
        facade = PyoidcFacade(
            ProviderConfiguration(provider_metadata=provider_metadata,
                                  client_metadata=self.CLIENT_METADATA),
            self.REDIRECT_URI)

        auth_code = 'auth_code-1234'
        responses.add(responses.GET,
                      self.PROVIDER_METADATA['jwks_uri'],
                      json={'keys': [id_token_signing_key.serialize()]})
        token_response = facade.token_request(auth_code)

        assert isinstance(token_response, AccessTokenResponse)
        expected_token_response = token_response.to_dict()
        expected_token_response['id_token'] = id_token_claims
        expected_token_response['id_token_jwt'] = id_token_jwt
        assert token_response.to_dict() == expected_token_response

        token_request = dict(parse_qsl(responses.calls[0].request.body))
        expected_token_request = {
            'grant_type': 'authorization_code',
            'code': auth_code,
            'redirect_uri': self.REDIRECT_URI
        }
        assert token_request == expected_token_request
コード例 #11
0
    def test_token_request(self, request_func, expected_token_request):
        token_endpoint = self.PROVIDER_BASEURL + '/token'
        now = int(time.time())
        id_token_claims = {
            'iss': self.PROVIDER_METADATA['issuer'],
            'sub': 'test_user',
            'aud': [self.CLIENT_METADATA['client_id']],
            'exp': now + 1,
            'iat': now,
            'nonce': 'test_nonce'
        }
        id_token_jwt, id_token_signing_key = signed_id_token(id_token_claims)
        token_response = AccessTokenResponse(access_token='test_access_token',
                                             refresh_token='refresh-token',
                                             token_type='Bearer',
                                             id_token=id_token_jwt,
                                             expires_in=now + 1)

        responses.add(responses.POST,
                      token_endpoint,
                      json=token_response.to_dict())

        provider_metadata = self.PROVIDER_METADATA.copy(
            token_endpoint=token_endpoint)
        facade = PyoidcFacade(
            ProviderConfiguration(provider_metadata=provider_metadata,
                                  client_metadata=self.CLIENT_METADATA),
            REDIRECT_URI)
        grant = Grant(resp=token_response)
        grant.grant_expiration_time = now + grant.exp_in
        facade._client.grant = {'test-state': grant}

        responses.add(responses.GET,
                      self.PROVIDER_METADATA['jwks_uri'],
                      json={'keys': [id_token_signing_key.serialize()]})
        token_response = request_func(facade)

        assert isinstance(token_response, AccessTokenResponse)
        expected_token_response = token_response.to_dict()
        expected_token_response['id_token'] = id_token_claims
        expected_token_response['id_token_jwt'] = id_token_jwt
        assert token_response.to_dict() == expected_token_response

        token_request = dict(parse_qsl(responses.calls[0].request.body))
        assert token_request == expected_token_request
コード例 #12
0
 def test_client_credentials_grant(self, scope, extra_args):
     token_endpoint = f'{self.PROVIDER_BASEURL}/token'
     provider_metadata = self.PROVIDER_METADATA.copy(
         token_endpoint=token_endpoint)
     facade = PyoidcFacade(
         ProviderConfiguration(provider_metadata=provider_metadata,
                               client_metadata=self.CLIENT_METADATA),
         REDIRECT_URI)
     client_credentials_grant_response = {
         'access_token': 'access_token',
         'expires_in': 60,
         'not-before-policy': 0,
         'refresh_expires_in': 0,
         'scope': 'read write',
         'token_type': 'Bearer'
     }
     responses.add(responses.POST,
                   token_endpoint,
                   json=client_credentials_grant_response)
     assert client_credentials_grant_response == facade.client_credentials_grant(
         scope=scope, **extra_args).to_dict()
コード例 #13
0
 def test_parse_authentication_response_preserves_id_token_jwt(self):
     facade = PyoidcFacade(ProviderConfiguration(provider_metadata=self.PROVIDER_METADATA,
                                                 client_metadata=self.CLIENT_METADATA),
                           self.REDIRECT_URI)
     state = 'state-1234'
     now = int(time.time())
     id_token, id_token_signing_key = signed_id_token({
         'iss': self.PROVIDER_METADATA['issuer'],
         'sub': 'test_sub',
         'aud': 'client1',
         'exp': now + 1,
         'iat': now
     })
     responses.add(responses.GET,
                   self.PROVIDER_METADATA['jwks_uri'],
                   json={'keys': [id_token_signing_key.serialize()]})
     auth_response = AuthorizationResponse(**{'state': state, 'id_token': id_token})
     parsed_auth_response = facade.parse_authentication_response(auth_response)
     assert isinstance(parsed_auth_response, AuthorizationResponse)
     assert parsed_auth_response['state'] == state
     assert parsed_auth_response['id_token_jwt'] == id_token
コード例 #14
0
    def test_token_request_handles_error_response(self):
        token_endpoint = self.PROVIDER_BASEURL + '/token'
        token_response = TokenErrorResponse(
            error='invalid_request',
            error_description='test error description')
        responses.add(responses.POST,
                      token_endpoint,
                      json=token_response.to_dict(),
                      status=400)

        provider_metadata = self.PROVIDER_METADATA.copy(
            token_endpoint=token_endpoint)
        facade = PyoidcFacade(
            ProviderConfiguration(provider_metadata=provider_metadata,
                                  client_metadata=self.CLIENT_METADATA),
            REDIRECT_URI)
        state = 'test-state'
        grant = Grant()
        grant.grant_expiration_time = int(time.time()) + grant.exp_in
        facade._client.grant = {state: grant}
        assert facade.exchange_authorization_code('1234',
                                                  state) == token_response
コード例 #15
0
    def test_token_request_handles_error_response(self):
        token_endpoint = self.PROVIDER_BASEURL + "/token"
        token_response = TokenErrorResponse(
            error="invalid_request",
            error_description="test error description")
        responses.add(responses.POST,
                      token_endpoint,
                      json=token_response.to_dict(),
                      status=400)

        provider_metadata = self.PROVIDER_METADATA.copy(
            token_endpoint=token_endpoint)
        facade = PyoidcFacade(
            ProviderConfiguration(
                provider_metadata=provider_metadata,
                client_metadata=self.CLIENT_METADATA,
            ),
            self.REDIRECT_URI,
        )

        with self.app.app_context():
            assert facade.token_request("1234") == token_response
コード例 #16
0
 def test_parse_authentication_response_preserves_id_token_jwt(self):
     facade = PyoidcFacade(
         ProviderConfiguration(
             provider_metadata=self.PROVIDER_METADATA,
             client_metadata=self.CLIENT_METADATA,
         ),
         self.REDIRECT_URI,
     )
     state = "state-1234"
     now = int(time.time())
     id_token, id_token_signing_key = signed_id_token({
         "iss":
         self.PROVIDER_METADATA["issuer"],
         "sub":
         "test_sub",
         "aud":
         "client1",
         "exp":
         now + 1,
         "iat":
         now,
     })
     responses.add(
         responses.GET,
         self.PROVIDER_METADATA["jwks_uri"],
         json={"keys": [id_token_signing_key.serialize()]},
     )
     auth_response = AuthorizationResponse(**{
         "state": state,
         "id_token": id_token
     })
     parsed_auth_response = facade.parse_authentication_response(
         auth_response)
     assert isinstance(parsed_auth_response, AuthorizationResponse)
     assert parsed_auth_response["state"] == state
     assert parsed_auth_response["id_token_jwt"] == id_token
コード例 #17
0
 def test_no_registered_client_metadata_is_handled(self):
     config = ProviderConfiguration(
         provider_metadata=self.PROVIDER_METADATA,
         client_registration_info=ClientRegistrationInfo())
     facade = PyoidcFacade(config, REDIRECT_URI)
     assert not facade._client.registration_response
コード例 #18
0
 def test_registered_client_metadata_is_forwarded_to_pyoidc(self):
     config = ProviderConfiguration(
         provider_metadata=self.PROVIDER_METADATA,
         client_metadata=self.CLIENT_METADATA)
     facade = PyoidcFacade(config, REDIRECT_URI)
     assert facade._client.registration_response
コード例 #19
0
 def test_token_request_handles_missing_provider_token_endpoint(self):
     facade = PyoidcFacade(
         ProviderConfiguration(provider_metadata=self.PROVIDER_METADATA,
                               client_metadata=self.CLIENT_METADATA),
         REDIRECT_URI)
     assert facade.exchange_authorization_code('1234') is None
コード例 #20
0
 def test_no_userinfo_request_is_made_if_no_userinfo_http_method_is_configured(self):
     facade = PyoidcFacade(ProviderConfiguration(provider_metadata=self.PROVIDER_METADATA,
                                                 client_metadata=self.CLIENT_METADATA,
                                                 userinfo_http_method=None),
                           self.REDIRECT_URI)
     assert facade.userinfo_request('test_token') is None