def test_construct_accesstoken_request(self): # Client 1 starts the chain of event client_1 = Client(config=CONF) _context_1 = client_1.client_get("service_context") _state = _context_1.state.create_state('issuer') auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state=_state) _context_1.state.store_item(auth_request, 'auth_request', _state) # Client 2 carries on client_2 = Client(config=CONF) _state_dump = _context_1.dump() _context2 = client_2.client_get("service_context") _context2.load(_state_dump) auth_response = AuthorizationResponse(code='access_code') _context2.state.store_item(auth_response, 'auth_response', _state) msg = client_2.client_get("service", 'accesstoken').construct(request_args={}, state=_state) assert isinstance(msg, AccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'code': 'access_code', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'authorization_code', 'redirect_uri': 'https://example.com/cli/authz_cb', 'state': _state }
class TestDPoPWithoutUserinfo: @pytest.fixture(autouse=True) def create_client(self): config = { 'client_id': 'client_id', 'client_secret': 'a longesh password', 'redirect_uris': ['https://example.com/cli/authz_cb'], 'behaviour': { 'response_types': ['code'] }, 'add_ons': { "dpop": { "function": "oidcrp.oauth2.add_on.dpop.add_support", "kwargs": { "signing_algorithms": ["ES256", "ES512"] } } } } self.client = Client(keyjar=CLI_KEY, config=config, services=DEFAULT_OAUTH2_SERVICES) self.client.client_get("service_context").provider_info = { "authorization_endpoint": "https://example.com/auth", "token_endpoint": "https://example.com/token", "dpop_signing_alg_values_supported": ["RS256", "ES256"] } def test_add_header(self): token_serv = self.client.client_get("service", "accesstoken") req_args = { "grant_type": "authorization_code", "code": "SplxlOBeZQQYbYS6WxSbIA", "redirect_uri": "https://client/example.com/cb" } headers = token_serv.get_headers(request=req_args, http_method="POST") assert headers assert "dpop" in headers # Now for the content of the DPoP proof _jws = factory(headers["dpop"]) _payload = _jws.jwt.payload() assert _payload["htu"] == "https://example.com/token" assert _payload["htm"] == "POST" _header = _jws.jwt.headers assert "jwk" in _header assert _header["typ"] == "dpop+jwt" assert _header["alg"] == "ES256" assert _header["jwk"]["kty"] == "EC" assert _header["jwk"]["crv"] == "P-256"
class TestPushedAuth: @pytest.fixture(autouse=True) def create_client(self): config = { 'client_id': 'client_id', 'client_secret': 'a longesh password', 'redirect_uris': ['https://example.com/cli/authz_cb'], 'behaviour': {'response_types': ['code']}, 'add_ons': { "pushed_authorization": { "function": "oidcrp.oauth2.add_on.pushed_authorization.add_support", "kwargs": { "body_format": "jws", "signing_algorithm": "RS256", "http_client": None, "merge_rule": "lax" } } } } self.entity = Client(keyjar=CLI_KEY, config=config, services=DEFAULT_OAUTH2_SERVICES) self.entity.client_get("service_context").provider_info = { "pushed_authorization_request_endpoint": "https://as.example.com/push" } def test_authorization(self): auth_service = self.entity.client_get("service","authorization") req_args = {'foo': 'bar', "response_type": "code"} with responses.RequestsMock() as rsps: _resp = { "request_uri": "urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", "expires_in": 3600 } rsps.add("GET", auth_service.client_get("service_context").provider_info[ "pushed_authorization_request_endpoint"], body=json.dumps(_resp), status=200) _req = auth_service.construct(request_args=req_args, state='state') assert set(_req.keys()) == {"request_uri", "response_type", "client_id"}
class TestClient2(object): @pytest.fixture(autouse=True) def create_client(self): self.redirect_uri = "http://example.com/redirect" KEYSPEC = [ { "type": "RSA", "use": ["sig"] }, { "type": "EC", "crv": "P-256", "use": ["sig"] }, ] conf = { 'redirect_uris': ['https://example.com/cli/authz_cb'], 'client_id': 'client_1', 'client_secret': 'abcdefghijklmnop', 'rp_keys': { 'private_path': 'private/jwks.json', 'key_defs': KEYSPEC, 'public_path': 'static/jwks.json', # this will create the jwks files if they are absent 'read_only': False } } rp_conf = RPConfiguration(conf) self.client = Client(config=rp_conf) assert self.client def test_keyjar(self): req_args = { 'state': 'ABCDE', 'redirect_uri': 'https://example.com/auth_cb', 'response_type': ['code'] } _context = self.client.client_get("service_context") assert len(_context.keyjar) == 1 # one issuer assert len(_context.keyjar[""]) == 2 assert len(_context.keyjar.get("sig")) == 2
def test_construct_refresh_token_request(self): # Client 1 starts the chain event client_1 = Client(config=CONF) _state = client_1.client_get("service_context").state.create_state( 'issuer') auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state=_state) client_1.client_get("service_context").state.store_item( auth_request, 'auth_request', _state) # Client 2 carries on client_2 = Client(config=CONF) _state_dump = client_1.client_get("service_context").dump() client_2.client_get("service_context").load(_state_dump) auth_response = AuthorizationResponse(code='access_code') client_2.client_get("service_context").state.store_item( auth_response, 'auth_response', _state) token_response = AccessTokenResponse(refresh_token="refresh_with_me", access_token="access") client_2.client_get("service_context").state.store_item( token_response, 'token_response', _state) # Next up is Client 1 _state_dump = client_2.client_get("service_context").dump() client_1.client_get("service_context").load(_state_dump) req_args = {} msg = client_1.client_get("service", 'refresh_token').construct( request_args=req_args, state=_state) assert isinstance(msg, RefreshAccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'refresh_token', 'refresh_token': 'refresh_with_me' }
class TestClient(object): @pytest.fixture(autouse=True) def create_client(self): self.redirect_uri = "http://example.com/redirect" conf = { 'redirect_uris': ['https://example.com/cli/authz_cb'], 'client_id': 'client_1', 'client_secret': 'abcdefghijklmnop' } self.client = Client(config=conf) def test_construct_authorization_request(self): req_args = { 'state': 'ABCDE', 'redirect_uri': 'https://example.com/auth_cb', 'response_type': ['code'] } self.client.client_get("service_context").state.create_state( 'issuer', key='ABCDE') msg = self.client.client_get( "service", 'authorization').construct(request_args=req_args) assert isinstance(msg, AuthorizationRequest) assert msg['client_id'] == 'client_1' assert msg['redirect_uri'] == 'https://example.com/auth_cb' def test_construct_accesstoken_request(self): # Bind access code to state req_args = {} _context = self.client.client_get("service_context") _context.state.create_state('issuer', 'ABCDE') auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state='ABCDE') _context.state.store_item(auth_request, 'auth_request', 'ABCDE') auth_response = AuthorizationResponse(code='access_code') self.client.client_get("service_context").state.store_item( auth_response, 'auth_response', 'ABCDE') msg = self.client.client_get("service", 'accesstoken').construct( request_args=req_args, state='ABCDE') assert isinstance(msg, AccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'authorization_code', 'state': 'ABCDE', 'code': 'access_code', 'redirect_uri': 'https://example.com/cli/authz_cb' } def test_construct_refresh_token_request(self): _context = self.client.client_get("service_context") _context.state.create_state('issuer', 'ABCDE') auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state='state') _context.state.store_item(auth_request, 'auth_request', 'ABCDE') auth_response = AuthorizationResponse(code='access_code') _context.state.store_item(auth_response, 'auth_response', 'ABCDE') token_response = AccessTokenResponse(refresh_token="refresh_with_me", access_token="access") _context.state.store_item(token_response, 'token_response', 'ABCDE') req_args = {} msg = self.client.client_get("service", 'refresh_token').construct( request_args=req_args, state='ABCDE') assert isinstance(msg, RefreshAccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'refresh_token', 'refresh_token': 'refresh_with_me' } def test_error_response(self): err = ResponseMessage(error='Illegal') http_resp = MockResponse(400, err.to_urlencoded()) resp = self.client.parse_request_response( self.client.client_get("service", 'authorization'), http_resp) assert resp['error'] == 'Illegal' assert resp['status_code'] == 400 def test_error_response_500(self): err = ResponseMessage(error='Illegal') http_resp = MockResponse(500, err.to_urlencoded()) with pytest.raises(ParseError): self.client.parse_request_response( self.client.client_get("service", 'authorization'), http_resp) def test_error_response_2(self): err = ResponseMessage(error='Illegal') http_resp = MockResponse( 400, err.to_json(), headers={'content-type': 'application/x-www-form-urlencoded'}) with pytest.raises(OidcServiceError): self.client.parse_request_response( self.client.client_get("service", 'authorization'), http_resp)