def test_link3(): link = Link(rel="http://webfinger.net/rel/profile-page", href="http://www.example.com/~bob/") assert set(link.keys()) == {'rel', 'href'} assert link['rel'] == "http://webfinger.net/rel/profile-page" assert link['href'] == "http://www.example.com/~bob/"
def test_link1(): link = Link(rel="http://webfinger.net/rel/avatar", type="image/jpeg", href="http://www.example.com/~bob/bob.jpg") assert set(link.keys()) == {'rel', 'type', 'href'} assert link['rel'] == "http://webfinger.net/rel/avatar" assert link['type'] == "image/jpeg" assert link['href'] == "http://www.example.com/~bob/bob.jpg"
def test_jrd(): jrd = JRD(subject="acct:[email protected]", aliases=["http://www.example.com/~bob/"], properties={"http://example.com/ns/role/": "employee"}, links=[ Link(rel="http://webfinger.net/rel/avatar", type="image/jpeg", href="http://www.example.com/~bob/bob.jpg"), Link(rel="http://webfinger.net/rel/profile-page", href="http://www.example.com/~bob/") ]) assert set(jrd.keys()) == {'subject', 'aliases', 'properties', 'links'}
def test_link2(): link = Link(rel="blog", type="text/html", href="http://blogs.example.com/bob/", titles={ "en-us": "The Magical World of Bob", "fr": "Le monde magique de Bob" }) assert set(link.keys()) == {'rel', 'type', 'href', 'titles'} assert link['rel'] == "blog" assert link['type'] == "text/html" assert link['href'] == "http://blogs.example.com/bob/" assert set(link['titles'].keys()) == {'en-us', 'fr'}
def test_dynamic_setup(self): user_id = 'acct:[email protected]' _link = Link(rel="http://openid.net/specs/connect/1.0/issuer", href="https://server.example.com") webfinger_response = JRD(subject=user_id, links=[_link]) self.mock_op.register_get_response( '/.well-known/webfinger', webfinger_response.to_json(), 200, {'content-type': "application/json"}) resp = { "authorization_endpoint": "https://server.example.com/connect/authorize", "issuer": "https://server.example.com", "subject_types_supported": ['public'], "token_endpoint": "https://server.example.com/connect/token", "token_endpoint_auth_methods_supported": ["client_secret_basic", "private_key_jwt"], "userinfo_endpoint": "https://server.example.com/connect/user", "check_id_endpoint": "https://server.example.com/connect/check_id", "refresh_session_endpoint": "https://server.example.com/connect/refresh_session", "end_session_endpoint": "https://server.example.com/connect/end_session", "jwks_uri": "https://server.example.com/jwk.json", "registration_endpoint": "https://server.example.com/connect/register", "scopes_supported": ["openid", "profile", "email", "address", "phone"], "response_types_supported": ["code", "code id_token", "token id_token"], "acrs_supported": ["1", "2", "http://id.incommon.org/assurance/bronze"], "user_id_types_supported": ["public", "pairwise"], "userinfo_algs_supported": ["HS256", "RS256", "A128CBC", "A128KW", "RSA1_5"], "id_token_signing_alg_values_supported": ["HS256", "RS256", "A128CBC", "A128KW", "RSA1_5"], "request_object_algs_supported": ["HS256", "RS256", "A128CBC", "A128KW", "RSA1_5"] } pcr = ProviderConfigurationResponse(**resp) self.mock_op.register_get_response( '/.well-known/openid-configuration', pcr.to_json(), 200, {'content-type': "application/json"}) self.mock_op.register_post_response( '/connect/register', registration_callback, 200, {'content-type': "application/json"}) auth_query = self.rph.begin(user_id=user_id) assert auth_query
def do_response(self, response_args=None, request=None, **kwargs): """ **Placeholder for the time being** :param response_args: :param request: :param kwargs: request arguments :return: Response information """ links = [Link(href=h, rel=OIC_ISSUER) for h in kwargs["hrefs"]] _response = JRD(subject=kwargs["subject"], links=links) info = { "response": _response.to_json(), "http_headers": [("Content-type", "application/json")], } return info
def do_response(self, response_args=None, request=None, **kwargs): """ **Placeholder for the time being** :param endpoint_context: :py:class:`oidcendpoint.endpoint_context.EndpointContext` instance :param kwargs: request arguments :return: Response information """ links = [Link(href=h, rel=OIC_ISSUER) for h in kwargs['hrefs']] _response = JRD(subject=kwargs['subject'], links=links) info = { 'response': _response.to_json(), 'http_headers': [('Content-type', 'application/json')] } return info
def test_conversation(): service_context = ServiceContext( RP_KEYJAR, { "client_preferences": { "application_type": "web", "application_name": "rphandler", "contacts": ["*****@*****.**"], "response_types": ["code"], "scope": ["openid", "profile", "email", "address", "phone"], "token_endpoint_auth_method": "client_secret_basic", }, "redirect_uris": ["{}/authz_cb".format(RP_BASEURL)], "jwks_uri": "{}/static/jwks.json".format(RP_BASEURL) }) service_spec = DEFAULT_SERVICES.copy() service_spec['WebFinger'] = {'class': WebFinger} service = init_services(service_spec, state_db=InMemoryStateDataBase(), service_context=service_context) assert set(service.keys()) == { 'accesstoken', 'authorization', 'webfinger', 'registration', 'refresh_token', 'userinfo', 'provider_info' } service_context.service = service # ======================== WebFinger ======================== info = service['webfinger'].get_request_parameters( request_args={'resource': '*****@*****.**'}) assert info[ 'url'] == 'https://example.org/.well-known/webfinger?rel=http' \ '%3A%2F' \ '%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer' \ '&resource' \ '=acct%3Afoobar%40example.org' webfinger_response = json.dumps({ "subject": "acct:[email protected]", "links": [{ "rel": "http://openid.net/specs/connect/1.0/issuer", "href": "https://example.org/op" }], "expires": "2018-02-04T11:08:41Z" }) response = service['webfinger'].parse_response(webfinger_response) assert isinstance(response, JRD) assert set(response.keys()) == {'subject', 'links', 'expires'} assert response['links'] == [ Link(rel='http://openid.net/specs/connect/1.0/issuer', href='https://example.org/op') ] service['webfinger'].update_service_context(resp=response) assert service_context.issuer == OP_BASEURL # =================== Provider info discovery ==================== info = service['provider_info'].get_request_parameters() assert info[ 'url'] == 'https://example.org/op/.well-known/openid' \ '-configuration' provider_info_response = json.dumps({ "version": "3.0", "token_endpoint_auth_methods_supported": [ "client_secret_post", "client_secret_basic", "client_secret_jwt", "private_key_jwt" ], "claims_parameter_supported": True, "request_parameter_supported": True, "request_uri_parameter_supported": True, "require_request_uri_registration": True, "grant_types_supported": [ "authorization_code", "implicit", "urn:ietf:params:oauth:grant-type:jwt-bearer", "refresh_token" ], "response_types_supported": [ "code", "id_token", "id_token token", "code id_token", "code token", "code id_token token" ], "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["public", "pairwise"], "claim_types_supported": ["normal", "aggregated", "distributed"], "claims_supported": [ "birthdate", "address", "nickname", "picture", "website", "email", "gender", "sub", "phone_number_verified", "given_name", "profile", "phone_number", "updated_at", "middle_name", "name", "locale", "email_verified", "preferred_username", "zoneinfo", "family_name" ], "scopes_supported": [ "openid", "profile", "email", "address", "phone", "offline_access", "openid" ], "userinfo_signing_alg_values_supported": [ "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256", "HS384", "HS512", "PS256", "PS384", "PS512", "none" ], "id_token_signing_alg_values_supported": [ "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256", "HS384", "HS512", "PS256", "PS384", "PS512", "none" ], "request_object_signing_alg_values_supported": [ "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256", "HS384", "HS512", "PS256", "PS384", "PS512", "none" ], "token_endpoint_auth_signing_alg_values_supported": [ "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256", "HS384", "HS512", "PS256", "PS384", "PS512" ], "userinfo_encryption_alg_values_supported": [ "RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW", "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW" ], "id_token_encryption_alg_values_supported": [ "RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW", "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW" ], "request_object_encryption_alg_values_supported": [ "RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW", "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW" ], "userinfo_encryption_enc_values_supported": [ "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A192GCM", "A256GCM" ], "id_token_encryption_enc_values_supported": [ "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A192GCM", "A256GCM" ], "request_object_encryption_enc_values_supported": [ "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A192GCM", "A256GCM" ], "acr_values_supported": ["PASSWORD"], "issuer": OP_BASEURL, "jwks_uri": "{}/static/jwks_tE2iLbOAqXhe8bqh.json".format(OP_BASEURL), "authorization_endpoint": "{}/authorization".format(OP_BASEURL), "token_endpoint": "{}/token".format(OP_BASEURL), "userinfo_endpoint": "{}/userinfo".format(OP_BASEURL), "registration_endpoint": "{}/registration".format(OP_BASEURL), "end_session_endpoint": "{}/end_session".format(OP_BASEURL) }) resp = service['provider_info'].parse_response(provider_info_response) assert isinstance(resp, ProviderConfigurationResponse) service['provider_info'].update_service_context(resp) assert service_context.provider_info['issuer'] == OP_BASEURL assert service_context.provider_info[ 'authorization_endpoint'] == \ 'https://example.org/op/authorization' assert service_context.provider_info[ 'registration_endpoint'] == 'https://example.org/op/registration' # =================== Client registration ==================== info = service['registration'].get_request_parameters() assert info['url'] == 'https://example.org/op/registration' _body = json.loads(info['body']) assert _body == { "application_type": "web", "response_types": ["code"], "contacts": ["*****@*****.**"], "jwks_uri": "https://example.com/rp/static/jwks.json", "redirect_uris": ["{}/authz_cb".format(RP_BASEURL)], 'token_endpoint_auth_method': 'client_secret_basic', "grant_types": ["authorization_code"] } assert info['headers'] == {'Content-Type': 'application/json'} now = int(time.time()) op_client_registration_response = json.dumps({ "client_id": "zls2qhN1jO6A", "client_secret": "c8434f28cf9375d9a7", "registration_access_token": "NdGrGR7LCuzNtixvBFnDphGXv7wRcONn", "registration_client_uri": "{}/registration?client_id=zls2qhN1jO6A".format(RP_BASEURL), "client_secret_expires_at": now + 3600, "client_id_issued_at": now, "application_type": "web", "response_types": ["code"], "contacts": ["*****@*****.**"], "redirect_uris": ["{}/authz_cb".format(RP_BASEURL)], "token_endpoint_auth_method": "client_secret_basic", "grant_types": ["authorization_code"] }) response = service['registration'].parse_response( op_client_registration_response) service['registration'].update_service_context(response) assert service_context.client_id == 'zls2qhN1jO6A' assert service_context.client_secret == 'c8434f28cf9375d9a7' assert isinstance(service_context.registration_response, RegistrationResponse) assert set(service_context.registration_response.keys()) == { 'client_secret_expires_at', 'contacts', 'client_id', 'token_endpoint_auth_method', 'redirect_uris', 'response_types', 'client_id_issued_at', 'client_secret', 'application_type', 'registration_client_uri', 'registration_access_token', 'grant_types' } # =================== Authorization ==================== STATE = 'Oh3w3gKlvoM2ehFqlxI3HIK5' NONCE = 'UvudLKz287YByZdsY3AJoPAlEXQkJ0dK' info = service['authorization'].get_request_parameters(request_args={ 'state': STATE, 'nonce': NONCE }) p = urlparse(info['url']) _query = parse_qs(p.query) assert set(_query.keys()) == { 'state', 'nonce', 'response_type', 'scope', 'client_id', 'redirect_uri' } assert _query['scope'] == ['openid'] assert _query['nonce'] == [NONCE] assert _query['state'] == [STATE] op_authz_resp = { 'state': STATE, 'scope': 'openid', 'code': 'Z0FBQUFBQmFkdFFjUVpFWE81SHU5N1N4N01', 'iss': OP_BASEURL, 'client_id': 'zls2qhN1jO6A' } _authz_rep = AuthorizationResponse(**op_authz_resp) _resp = service['authorization'].parse_response(_authz_rep.to_urlencoded()) service['authorization'].update_service_context(_resp, key=STATE) _item = service['authorization'].get_item(AuthorizationResponse, 'auth_response', STATE) assert _item['code'] == 'Z0FBQUFBQmFkdFFjUVpFWE81SHU5N1N4N01' # =================== Access token ==================== request_args = { 'state': STATE, 'redirect_uri': service_context.redirect_uris[0] } info = service['accesstoken'].get_request_parameters( request_args=request_args) assert info['url'] == 'https://example.org/op/token' _qp = parse_qs(info['body']) assert _qp == { 'grant_type': ['authorization_code'], 'redirect_uri': ['https://example.com/rp/authz_cb'], 'client_id': ['zls2qhN1jO6A'], 'state': ['Oh3w3gKlvoM2ehFqlxI3HIK5'], 'code': ['Z0FBQUFBQmFkdFFjUVpFWE81SHU5N1N4N01'] } assert info['headers'] == { 'Authorization': 'Basic ' 'emxzMnFoTjFqTzZBOmM4NDM0ZjI4Y2Y5Mzc1ZDlhNw==', 'Content-Type': 'application/x-www-form-urlencoded' } # create the IdToken _jwt = JWT(OP_KEYJAR, OP_BASEURL, lifetime=3600, sign=True, sign_alg='RS256') payload = { 'sub': '1b2fc9341a16ae4e30082965d537', 'acr': 'PASSWORD', 'auth_time': 1517736988, 'nonce': NONCE } _jws = _jwt.pack(payload=payload, recv='zls2qhN1jO6A') _resp = { "state": "Oh3w3gKlvoM2ehFqlxI3HIK5", "scope": "openid", "access_token": "Z0FBQUFBQmFkdFF", "token_type": "Bearer", 'expires_in': 600, "id_token": _jws } service_context.issuer = OP_BASEURL _resp = service['accesstoken'].parse_response(json.dumps(_resp), state=STATE) assert isinstance(_resp, AccessTokenResponse) assert set(_resp['__verified_id_token'].keys()) == { 'iss', 'nonce', 'acr', 'auth_time', 'aud', 'iat', 'exp', 'sub' } service['accesstoken'].update_service_context(_resp, key=STATE) _item = service['authorization'].get_item(AccessTokenResponse, 'token_response', STATE) assert set(_item.keys()) == { 'state', 'scope', 'access_token', 'token_type', 'id_token', '__verified_id_token', 'expires_in', '__expires_at' } assert _item['token_type'] == 'Bearer' assert _item['access_token'] == 'Z0FBQUFBQmFkdFF' # =================== User info ==================== info = service['userinfo'].get_request_parameters(state=STATE) assert info['url'] == 'https://example.org/op/userinfo' assert info['headers'] == {'Authorization': 'Bearer Z0FBQUFBQmFkdFF'} op_resp = {"sub": "1b2fc9341a16ae4e30082965d537"} _resp = service['userinfo'].parse_response(json.dumps(op_resp), state=STATE) service['userinfo'].update_service_context(_resp, key=STATE) assert isinstance(_resp, OpenIDSchema) assert _resp.to_dict() == {'sub': '1b2fc9341a16ae4e30082965d537'} _item = service['authorization'].get_item(OpenIDSchema, 'user_info', STATE) assert _item.to_dict() == {'sub': '1b2fc9341a16ae4e30082965d537'}