class TestEndpoint(object): @pytest.fixture(autouse=True) def create_endpoint(self): conf = { "issuer": "https://example.com/", "password": "******", "token_expires_in": 600, "grant_expires_in": 300, "refresh_token_expires_in": 86400, "verify_ssl": False, "capabilities": CAPABILITIES, "jwks": { "uri_path": "static/jwks.json", "key_defs": KEYDEFS }, "id_token": { "class": IDToken, "kwargs": { "default_claims": { "email": { "essential": True }, "email_verified": { "essential": True }, } }, }, "endpoint": { "authorization": { "path": "{}/authorization", "class": Authorization, "kwargs": { "response_types_supported": [" ".join(x) for x in RESPONSE_TYPES_SUPPORTED], "response_modes_supported": ["query", "fragment", "form_post"], "claims_parameter_supported": True, "request_parameter_supported": True, "request_uri_parameter_supported": True, "request_cls": JWTSecuredAuthorizationRequest, }, } }, "authentication": { "anon": { "acr": "http://www.swamid.se/policy/assurance/al1", "class": "oidcendpoint.user_authn.user.NoAuthn", "kwargs": { "user": "******" }, } }, "userinfo": { "class": UserInfo, "kwargs": { "db": USERINFO_db } }, "template_dir": "template", "cookie_dealer": { "class": CookieDealer, "kwargs": { "sign_key": "ghsNKDDLshZTPn974nOsIGhedULrsqnsGoBFBLwUKuJhE2ch", "default_values": { "name": "oidcop", "domain": "127.0.0.1", "path": "/", "max_age": 3600, }, }, }, } endpoint_context = EndpointContext(conf) _clients = yaml.safe_load(io.StringIO(client_yaml)) endpoint_context.cdb = _clients["clients"] endpoint_context.keyjar.import_jwks( endpoint_context.keyjar.export_jwks(True, ""), conf["issuer"]) self.endpoint = endpoint_context.endpoint["authorization"] self.rp_keyjar = KeyJar() self.rp_keyjar.add_symmetric("client_1", "hemligtkodord1234567890") self.endpoint.endpoint_context.keyjar.add_symmetric( "client_1", "hemligtkodord1234567890") def test_parse_request_parameter(self): _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256") _jws = _jwt.pack( AUTH_REQ_DICT, aud=self.endpoint.endpoint_context.provider_info["issuer"]) # ----------------- _req = self.endpoint.parse_request({ "request": _jws, "redirect_uri": AUTH_REQ.get("redirect_uri"), "response_type": AUTH_REQ.get("response_type"), "client_id": AUTH_REQ.get("client_id"), "scope": AUTH_REQ.get("scope"), }) assert "__verified_request" in _req def test_parse_request_uri(self): _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256") _jws = _jwt.pack( AUTH_REQ_DICT, aud=self.endpoint.endpoint_context.provider_info["issuer"]) request_uri = "https://client.example.com/req" # ----------------- with responses.RequestsMock() as rsps: rsps.add("GET", request_uri, body=_jws, status=200) _req = self.endpoint.parse_request({ "request_uri": request_uri, "redirect_uri": AUTH_REQ.get("redirect_uri"), "response_type": AUTH_REQ.get("response_type"), "client_id": AUTH_REQ.get("client_id"), "scope": AUTH_REQ.get("scope"), }) assert "__verified_request" in _req
class TestUserAuthn(object): @pytest.fixture(autouse=True) def create_endpoint_context(self): conf = { "issuer": "https://example.com/", "password": "******", "token_expires_in": 600, "grant_expires_in": 300, "refresh_token_expires_in": 86400, "verify_ssl": False, "endpoint": { "authorization": { "path": "{}/authorization", "class": Authorization, "kwargs": { "response_types_supported": [" ".join(x) for x in RESPONSE_TYPES_SUPPORTED], "response_modes_supported": ["query", "fragment", "form_post"], "claims_parameter_supported": True, "request_parameter_supported": True, "request_uri_parameter_supported": True, }, } }, "keys": {"uri_path": "static/jwks.json", "key_defs": KEYDEFS}, "authentication": { "anon": {"acr": UNSPECIFIED, "class": NoAuthn, "kwargs": {"user": "******"},}, }, "cookie_handler": { "class": "oidcop.cookie_handler.CookieHandler", "kwargs": { "sign_key": "ghsNKDDLshZTPn974nOsIGhedULrsqnsGoBFBLwUKuJhE2ch", "name": { "session": "oidc_op", "register": "oidc_op_reg", "session_management": "oidc_op_sman", }, }, }, "template_dir": "template", } server = Server(OPConfiguration(conf=conf, base_path=BASEDIR), cwd=BASEDIR) endpoint_context = server.endpoint_context _clients = yaml.safe_load(io.StringIO(client_yaml)) endpoint_context.cdb = _clients["oidc_clients"] endpoint_context.keyjar.import_jwks( endpoint_context.keyjar.export_jwks(True, ""), conf["issuer"] ) self.endpoint = server.server_get("endpoint", "authorization") self.rp_keyjar = KeyJar() self.rp_keyjar.add_symmetric("client_1", "hemligtkodord1234567890") endpoint_context.keyjar.add_symmetric("client_1", "hemligtkodord1234567890") def test_sso(self): request = self.endpoint.parse_request(AUTH_REQ_DICT) redirect_uri = request["redirect_uri"] cinfo = self.endpoint.server_get("endpoint_context").cdb[request["client_id"]] info = self.endpoint.setup_auth(request, redirect_uri, cinfo, cookie=None) # info = self.endpoint.process_request(request) assert "user" in info res = self.endpoint.authz_part2(request, info["session_id"], cookie="") assert res cookies_1 = res["cookie"] # second login - from 2nd client request = self.endpoint.parse_request(AUTH_REQ_2.to_dict()) redirect_uri = request["redirect_uri"] cinfo = self.endpoint.server_get("endpoint_context").cdb[request["client_id"]] info = self.endpoint.setup_auth(request, redirect_uri, cinfo, cookie=None) sid2 = info["session_id"] assert set(info.keys()) == {"session_id", "identity", "user"} assert info["user"] == "diana" res = self.endpoint.authz_part2(request, info["session_id"], cookie="") cookies_2 = res["cookie"] # third login - from 3rd client request = self.endpoint.parse_request(AUTH_REQ_3.to_dict()) redirect_uri = request["redirect_uri"] cinfo = self.endpoint.server_get("endpoint_context").cdb[request["client_id"]] info = self.endpoint.setup_auth(request, redirect_uri, cinfo, cookie=None) assert set(info.keys()) == {"session_id", "identity", "user"} assert info["user"] == "diana" res = self.endpoint.authz_part2(request, info["session_id"], cookie="") cookies_3 = res["cookie"] # fourth login - from 1st client request = self.endpoint.parse_request(AUTH_REQ_4.to_dict()) redirect_uri = request["redirect_uri"] cinfo = self.endpoint.server_get("endpoint_context").cdb[request["client_id"]] info = self.endpoint.setup_auth(request, redirect_uri, cinfo, cookie=cookies_1) assert set(info.keys()) == {"session_id", "identity", "user"} assert info["user"] == "diana" self.endpoint.authz_part2(request, info["session_id"], cookie="") # Fifth login - from 2nd client - wrong cookie request = self.endpoint.parse_request(AUTH_REQ_2.to_dict()) redirect_uri = request["redirect_uri"] cinfo = self.endpoint.server_get("endpoint_context").cdb[request["client_id"]] info = self.endpoint.setup_auth(request, redirect_uri, cinfo, cookie=cookies_1) # No valid login cookie so new session assert info["session_id"] != sid2 user_session_info = self.endpoint.server_get("endpoint_context").session_manager.get( ["diana"] ) assert len(user_session_info.subordinate) == 3 assert set(user_session_info.subordinate) == { "client_1", "client_2", "client_3", } # Should be one grant for each of client_2 and client_3 and # 2 grants for client_1 csi1 = self.endpoint.server_get("endpoint_context").session_manager.get( ["diana", "client_1"] ) csi2 = self.endpoint.server_get("endpoint_context").session_manager.get( ["diana", "client_2"] ) csi3 = self.endpoint.server_get("endpoint_context").session_manager.get( ["diana", "client_3"] ) assert len(csi1.subordinate) == 2 assert len(csi2.subordinate) == 1 assert len(csi3.subordinate) == 1
class TestEndpoint(object): @pytest.fixture(autouse=True) def create_endpoint(self): conf = { "issuer": "https://example.com/", "password": "******", "token_expires_in": 600, "grant_expires_in": 300, "refresh_token_expires_in": 86400, "verify_ssl": False, "capabilities": CAPABILITIES, "jwks": {"uri_path": "static/jwks.json", "key_defs": KEYDEFS}, "id_token": { "class": IDToken, "kwargs": { "default_claims": { "email": {"essential": True}, "email_verified": {"essential": True}, } }, }, "endpoint": { "authorization": { "path": "{}/authorization", "class": Authorization, "kwargs": { "response_types_supported": [ " ".join(x) for x in RESPONSE_TYPES_SUPPORTED ], "response_modes_supported": ["query", "fragment", "form_post"], "claims_parameter_supported": True, "request_parameter_supported": True, "request_uri_parameter_supported": True, }, } }, "authentication": { "anon": { "acr": "http://www.swamid.se/policy/assurance/al1", "class": "oidcendpoint.user_authn.user.NoAuthn", "kwargs": {"user": "******"}, } }, "userinfo": {"class": UserInfo, "kwargs": {"db": USERINFO_db}}, "template_dir": "template", "cookie_dealer": { "class": CookieDealer, "kwargs": { "sign_key": "ghsNKDDLshZTPn974nOsIGhedULrsqnsGoBFBLwUKuJhE2ch", "default_values": { "name": "oidcop", "domain": "127.0.0.1", "path": "/", "max_age": 3600, }, }, }, } endpoint_context = EndpointContext(conf) _clients = yaml.safe_load(io.StringIO(client_yaml)) endpoint_context.cdb = _clients["clients"] endpoint_context.keyjar.import_jwks( endpoint_context.keyjar.export_jwks(True, ""), conf["issuer"] ) self.endpoint = endpoint_context.endpoint["authorization"] self.rp_keyjar = KeyJar() self.rp_keyjar.add_symmetric("client_1", "hemligtkodord1234567890") self.endpoint.endpoint_context.keyjar.add_symmetric( "client_1", "hemligtkodord1234567890" ) def test_init(self): assert self.endpoint def test_parse(self): _req = self.endpoint.parse_request(AUTH_REQ_DICT) assert isinstance(_req, AuthorizationRequest) assert set(_req.keys()) == set(AUTH_REQ.keys()) def test_process_request(self): _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) assert set(_resp.keys()) == { "response_args", "fragment_enc", "return_uri", "cookie", } def test_do_response_code(self): _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) _msg = parse_qs(msg["response"]) assert _msg part = urlparse(msg["response"]) assert part.fragment == "" assert part.query _query = parse_qs(part.query) assert _query assert "code" in _query def test_do_response_code_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "code token" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(response_msg=_resp) assert isinstance(msg, dict) assert msg["response"]["error"] == "invalid_request" def test_verify_uri_unknown_client(self): request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(UnknownClient): verify_uri(self.endpoint.endpoint_context, request, "redirect_uri") def test_verify_uri_fragment(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = {"redirect_uri": ["https://rp.example.com/auth_cb"]} request = {"redirect_uri": "https://rp.example.com/cb#foobar"} with pytest.raises(URIError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_noregistered(self): _ec = self.endpoint.endpoint_context request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_unregistered(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/auth_cb", {})] } request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(RedirectURIError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_match(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_mismatch(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb?foo=bar&foo=kex"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb?foo=bar&level=low"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_missing(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [ ("https://rp.example.com/cb", {"foo": ["bar"], "state": ["low"]}) ] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_missing_val(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar", "low"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_no_registered_qp(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_get_uri(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = { "redirect_uri": "https://rp.example.com/cb", "client_id": "client_id", } assert get_uri(_ec, request, "redirect_uri") == "https://rp.example.com/cb" def test_get_uri_no_redirect_uri(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"client_id": "client_id"} assert get_uri(_ec, request, "redirect_uri") == "https://rp.example.com/cb" def test_get_uri_no_registered(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"client_id": "client_id"} with pytest.raises(ParameterError): get_uri(_ec, request, "post_logout_redirect_uri") def test_get_uri_more_then_one_registered(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [ ("https://rp.example.com/cb", {}), ("https://rp.example.org/authz_cb", {"foo": "bar"}), ] } request = {"client_id": "client_id"} with pytest.raises(ParameterError): get_uri(_ec, request, "redirect_uri") def test_create_authn_response(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) _ec = self.endpoint.endpoint_context _ec.sdb["session_id"] = SessionInfo( authn_req=request, uid="diana", sub="abcdefghijkl", authn_event={ "authn_info": "loa1", "uid": "diana", "authn_time": utc_time_sans_frac(), }, ) _ec.cdb["client_id"] = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "ES256", } resp = create_authn_response(self.endpoint, request, "session_id") assert isinstance(resp["response_args"], AuthorizationErrorResponse) def test_setup_auth(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } kaka = self.endpoint.endpoint_context.cookie_dealer.create_cookie( "value", "sso" ) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, kaka) assert set(res.keys()) == {"authn_event", "identity", "user"} def test_setup_auth_error(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } item = self.endpoint.endpoint_context.authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].fail = ToOld res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].file = "" def test_setup_auth_user(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } _ec = self.endpoint.endpoint_context _ec.sdb["session_id"] = SessionInfo( authn_req=request, uid="diana", sub="abcdefghijkl", authn_event={ "authn_info": "loa1", "uid": "diana", "authn_time": utc_time_sans_frac(), }, ) item = _ec.authn_broker.db["anon"] item["method"].user = b64e( as_bytes(json.dumps({"uid": "krall", "sid": "session_id"})) ) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"authn_event", "identity", "user"} assert res["identity"]["uid"] == "krall" def test_setup_auth_session_revoked(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } _ec = self.endpoint.endpoint_context _ec.sdb["session_id"] = SessionInfo( authn_req=request, uid="diana", sub="abcdefghijkl", authn_event={ "authn_info": "loa1", "uid": "diana", "authn_time": utc_time_sans_frac(), }, revoked=True, ) item = _ec.authn_broker.db["anon"] item["method"].user = b64e( as_bytes(json.dumps({"uid": "krall", "sid": "session_id"})) ) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"args", "function"} def test_response_mode_form_post(self): request = {"response_mode": "form_post"} info = { "response_args": AuthorizationResponse(foo="bar"), "return_uri": "https://example.com/cb", } info = self.endpoint.response_mode(request, **info) assert set(info.keys()) == {"response_args", "return_uri", "response_msg", "content_type", "response_placement"} assert info["response_msg"] == FORM_POST.format( action="https://example.com/cb", inputs='<input type="hidden" name="foo" value="bar"/>', ) def test_response_mode_fragment(self): request = {"response_mode": "fragment"} self.endpoint.response_mode(request, fragment_enc=True) with pytest.raises(InvalidRequest): self.endpoint.response_mode(request, fragment_enc=False) info = self.endpoint.response_mode(request) assert set(info.keys()) == {"fragment_enc"}
class TestEndpoint(object): @pytest.fixture(autouse=True) def create_endpoint(self): conf = { "issuer": "https://example.com/", "password": "******", "token_expires_in": 600, "grant_expires_in": 300, "refresh_token_expires_in": 86400, "verify_ssl": False, "capabilities": CAPABILITIES, "jwks": { "uri_path": "static/jwks.json", "key_defs": KEYDEFS }, "id_token": { "class": IDToken, "kwargs": { "default_claims": { "email": { "essential": True }, "email_verified": { "essential": True }, } }, }, "endpoint": { "provider_config": { "path": "{}/.well-known/openid-configuration", "class": ProviderConfiguration, "kwargs": {}, }, "registration": { "path": "{}/registration", "class": Registration, "kwargs": {}, }, "authorization": { "path": "{}/authorization", "class": Authorization, "kwargs": { "response_types_supported": [" ".join(x) for x in RESPONSE_TYPES_SUPPORTED], "response_modes_supported": ["query", "fragment", "form_post"], "claims_parameter_supported": True, "request_parameter_supported": True, "request_uri_parameter_supported": True, }, }, "token": { "path": "token", "class": AccessToken, "kwargs": { "client_authn_method": [ "client_secret_post", "client_secret_basic", "client_secret_jwt", "private_key_jwt", ] }, }, "userinfo": { "path": "userinfo", "class": userinfo.UserInfo, "kwargs": { "db_file": "users.json", "claim_types_supported": [ "normal", "aggregated", "distributed", ], }, }, }, "authentication": { "anon": { "acr": "http://www.swamid.se/policy/assurance/al1", "class": "oidcendpoint.user_authn.user.NoAuthn", "kwargs": { "user": "******" }, } }, "userinfo": { "class": UserInfo, "kwargs": { "db": USERINFO_db } }, "template_dir": "template", "cookie_dealer": { "class": CookieDealer, "kwargs": { "sign_key": "ghsNKDDLshZTPn974nOsIGhedULrsqnsGoBFBLwUKuJhE2ch", "default_values": { "name": "oidcop", "domain": "127.0.0.1", "path": "/", "max_age": 3600, }, }, }, "login_hint2acrs": { "class": LoginHint2Acrs, "kwargs": { "scheme_map": { "email": [INTERNETPROTOCOLPASSWORD] } }, }, } endpoint_context = EndpointContext(conf) _clients = yaml.safe_load(io.StringIO(client_yaml)) endpoint_context.cdb = _clients["oidc_clients"] endpoint_context.keyjar.import_jwks( endpoint_context.keyjar.export_jwks(True, ""), conf["issuer"]) self.endpoint = endpoint_context.endpoint["authorization"] self.rp_keyjar = KeyJar() self.rp_keyjar.add_symmetric("client_1", "hemligtkodord1234567890") self.endpoint.endpoint_context.keyjar.add_symmetric( "client_1", "hemligtkodord1234567890") def test_init(self): assert self.endpoint def test_parse(self): _req = self.endpoint.parse_request(AUTH_REQ_DICT) assert isinstance(_req, AuthorizationRequest) assert set(_req.keys()) == set(AUTH_REQ.keys()) def test_process_request(self): _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) assert set(_resp.keys()) == { "response_args", "fragment_enc", "return_uri", "cookie", } def test_do_response_code(self): _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) _msg = parse_qs(msg["response"]) assert _msg part = urlparse(msg["response"]) assert part.fragment == "" assert part.query _query = parse_qs(part.query) assert _query assert "code" in _query def test_do_response_id_token_no_nonce(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "id_token" _pr_resp = self.endpoint.parse_request(_orig_req) # Missing nonce assert isinstance(_pr_resp, ResponseMessage) def test_do_response_id_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "id_token" _orig_req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) part = urlparse(msg["response"]) assert part.query == "" assert part.fragment _frag_msg = parse_qs(part.fragment) assert _frag_msg assert "id_token" in _frag_msg assert "code" not in _frag_msg assert "token" not in _frag_msg def test_do_response_id_token_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "id_token token" _orig_req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(response_msg=_resp) assert isinstance(msg, dict) assert msg["response"]["error"] == "invalid_request" def test_do_response_code_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "code token" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(response_msg=_resp) assert isinstance(msg, dict) assert msg["response"]["error"] == "invalid_request" def test_do_response_code_id_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "code id_token" _orig_req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) part = urlparse(msg["response"]) assert part.query == "" assert part.fragment _frag_msg = parse_qs(part.fragment) assert _frag_msg assert "id_token" in _frag_msg assert "code" in _frag_msg assert "access_token" not in _frag_msg def test_do_response_code_id_token_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "code id_token token" _orig_req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) part = urlparse(msg["response"]) assert part.query == "" assert part.fragment _frag_msg = parse_qs(part.fragment) assert _frag_msg assert "id_token" in _frag_msg assert "code" in _frag_msg assert "access_token" in _frag_msg def test_id_token_claims(self): _req = AUTH_REQ_DICT.copy() _req["claims"] = CLAIMS _req["response_type"] = "code id_token token" _req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_req) _resp = self.endpoint.process_request(_pr_resp) idt = verify_id_token(_resp["response_args"], keyjar=self.endpoint.endpoint_context.keyjar) assert idt # from claims assert "given_name" in _resp["response_args"]["__verified_id_token"] # from config assert "email" in _resp["response_args"]["__verified_id_token"] def test_re_authenticate(self): request = {"prompt": "login"} authn = UserAuthnMethod(self.endpoint.endpoint_context) assert re_authenticate(request, authn) def test_id_token_acr(self): _req = AUTH_REQ_DICT.copy() _req["claims"] = { "id_token": { "acr": { "value": "http://www.swamid.se/policy/assurance/al1" } } } _req["response_type"] = "code id_token token" _req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_req) _resp = self.endpoint.process_request(_pr_resp) res = verify_id_token(_resp["response_args"], keyjar=self.endpoint.endpoint_context.keyjar) assert res res = _resp["response_args"][verified_claim_name("id_token")] assert res["acr"] == "http://www.swamid.se/policy/assurance/al1" def test_verify_uri_unknown_client(self): request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(UnknownClient): verify_uri(self.endpoint.endpoint_context, request, "redirect_uri") def test_verify_uri_fragment(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uri": ["https://rp.example.com/auth_cb"] } request = {"redirect_uri": "https://rp.example.com/cb#foobar"} with pytest.raises(URIError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_noregistered(self): _ec = self.endpoint.endpoint_context request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_unregistered(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/auth_cb", {})] } request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(RedirectURIError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_match(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", { "foo": ["bar"] })] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_mismatch(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", { "foo": ["bar"] })] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb?foo=bar&foo=kex"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = { "redirect_uri": "https://rp.example.com/cb?foo=bar&level=low" } with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_missing(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", { "foo": ["bar"], "state": ["low"] })] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_missing_val(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", { "foo": ["bar", "low"] })] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_no_registered_qp(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_get_uri(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {})] } request = { "redirect_uri": "https://rp.example.com/cb", "client_id": "client_id", } assert get_uri(_ec, request, "redirect_uri") == "https://rp.example.com/cb" def test_get_uri_no_redirect_uri(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {})] } request = {"client_id": "client_id"} assert get_uri(_ec, request, "redirect_uri") == "https://rp.example.com/cb" def test_get_uri_no_registered(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {})] } request = {"client_id": "client_id"} with pytest.raises(ParameterError): get_uri(_ec, request, "post_logout_redirect_uri") def test_get_uri_more_then_one_registered(self): _ec = self.endpoint.endpoint_context _ec.cdb["client_id"] = { "redirect_uris": [ ("https://rp.example.com/cb", {}), ("https://rp.example.org/authz_cb", { "foo": "bar" }), ] } request = {"client_id": "client_id"} with pytest.raises(ParameterError): get_uri(_ec, request, "redirect_uri") def test_create_authn_response(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) _ec = self.endpoint.endpoint_context _ec.sdb["session_id"] = SessionInfo( authn_req=request, uid="diana", sub="abcdefghijkl", authn_event={ "authn_info": "loa1", "uid": "diana", "authn_time": utc_time_sans_frac(), }, ) _ec.cdb["client_id"] = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "ES256", } resp = create_authn_response(self.endpoint, request, "session_id") assert isinstance(resp["response_args"], AuthorizationErrorResponse) def test_setup_auth(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } kaka = self.endpoint.endpoint_context.cookie_dealer.create_cookie( "value", "sso") res = self.endpoint.setup_auth(request, redirect_uri, cinfo, kaka) assert set(res.keys()) == {"authn_event", "identity", "user"} def test_setup_auth_error(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } item = self.endpoint.endpoint_context.authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].fail = ToOld res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].file = "" def test_setup_auth_user(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } _ec = self.endpoint.endpoint_context _ec.sdb["session_id"] = SessionInfo( authn_req=request, uid="diana", sub="abcdefghijkl", authn_event={ "authn_info": "loa1", "uid": "diana", "authn_time": utc_time_sans_frac(), }, ) item = _ec.authn_broker.db["anon"] item["method"].user = b64e( as_bytes(json.dumps({ "uid": "krall", "sid": "session_id" }))) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"authn_event", "identity", "user"} assert res["identity"]["uid"] == "krall" def test_setup_auth_session_revoked(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } _ec = self.endpoint.endpoint_context _ec.sdb["session_id"] = SessionInfo( authn_req=request, uid="diana", sub="abcdefghijkl", authn_event={ "authn_info": "loa1", "uid": "diana", "authn_time": utc_time_sans_frac(), }, revoked=True, ) item = _ec.authn_broker.db["anon"] item["method"].user = b64e( as_bytes(json.dumps({ "uid": "krall", "sid": "session_id" }))) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"args", "function"} def test_response_mode_form_post(self): request = {"response_mode": "form_post"} info = { "response_args": AuthorizationResponse(foo="bar"), "return_uri": "https://example.com/cb", } info = self.endpoint.response_mode(request, **info) assert set(info.keys()) == { "response_args", "return_uri", "response_msg", "content_type", "response_placement" } assert info["response_msg"] == FORM_POST.format( action="https://example.com/cb", inputs='<input type="hidden" name="foo" value="bar"/>', ) def test_do_response_code_form_post(self): _req = AUTH_REQ_DICT.copy() _req["response_mode"] = "form_post" _pr_resp = self.endpoint.parse_request(_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert ('Content-type', 'text/html') in msg["http_headers"] assert "response_placement" in msg def test_response_mode_fragment(self): request = {"response_mode": "fragment"} self.endpoint.response_mode(request, fragment_enc=True) with pytest.raises(InvalidRequest): self.endpoint.response_mode(request, fragment_enc=False) info = self.endpoint.response_mode(request) assert set(info.keys()) == {"fragment_enc"} def test_check_session_iframe(self): self.endpoint.endpoint_context.provider_info[ "check_session_iframe"] = "https://example.com/csi" _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) assert "session_state" in _resp["response_args"] def test_setup_auth_login_hint(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", login_hint="tel:0907865204", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } item = self.endpoint.endpoint_context.authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} assert "login_hint" in res["args"] def test_setup_auth_login_hint2acrs(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", login_hint="email:foo@bar", ) redirect_uri = request["redirect_uri"] method_spec = { "acr": INTERNETPROTOCOLPASSWORD, "kwargs": { "user": "******" }, "class": NoAuthn, } self.endpoint.endpoint_context.authn_broker["foo"] = init_method( method_spec, None) item = self.endpoint.endpoint_context.authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication item = self.endpoint.endpoint_context.authn_broker.db["foo"] item["method"].fail = NoSuchAuthentication res = self.endpoint.pick_authn_method(request, redirect_uri) assert set(res.keys()) == {"method", "acr"} assert res["acr"] == INTERNETPROTOCOLPASSWORD assert isinstance(res["method"], NoAuthn) assert res["method"].user == "knoll" def test_post_logout_uri(self): pass def test_parse_request(self): _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256") _jws = _jwt.pack( AUTH_REQ_DICT, aud=self.endpoint.endpoint_context.provider_info["issuer"]) # ----------------- _req = self.endpoint.parse_request({ "request": _jws, "redirect_uri": AUTH_REQ.get("redirect_uri"), "response_type": AUTH_REQ.get("response_type"), "client_id": AUTH_REQ.get("client_id"), "scope": AUTH_REQ.get("scope"), }) assert "__verified_request" in _req def test_parse_request_uri(self): _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256") _jws = _jwt.pack( AUTH_REQ_DICT, aud=self.endpoint.endpoint_context.provider_info["issuer"]) request_uri = "https://client.example.com/req" # ----------------- with responses.RequestsMock() as rsps: rsps.add("GET", request_uri, body=_jws, status=200) _req = self.endpoint.parse_request({ "request_uri": request_uri, "redirect_uri": AUTH_REQ.get("redirect_uri"), "response_type": AUTH_REQ.get("response_type"), "client_id": AUTH_REQ.get("client_id"), "scope": AUTH_REQ.get("scope"), }) assert "__verified_request" in _req
class TestEndpoint(object): @pytest.fixture(autouse=True) def create_endpoint(self): conf = { "issuer": "https://example.com/", "password": "******", "verify_ssl": False, "capabilities": CAPABILITIES, "keys": {"uri_path": "static/jwks.json", "key_defs": KEYDEFS}, "token_handler_args": { "jwks_file": "private/token_jwks.json", "code": {"kwargs": {"lifetime": 600}}, "token": { "class": "oidcop.token.jwt_token.JWTToken", "kwargs": { "lifetime": 3600, "add_claims_by_scope": True, "aud": ["https://example.org/appl"], }, }, "refresh": { "class": "oidcop.token.jwt_token.JWTToken", "kwargs": {"lifetime": 3600, "aud": ["https://example.org/appl"],}, }, "id_token": { "class": "oidcop.token.id_token.IDToken", "kwargs": { "base_claims": { "email": {"essential": True}, "email_verified": {"essential": True}, "given_name": {"essential": True}, "nickname": None, } }, }, }, "endpoint": { "provider_config": { "path": "{}/.well-known/openid-configuration", "class": ProviderConfiguration, "kwargs": {}, }, "registration": {"path": "{}/registration", "class": Registration, "kwargs": {},}, "authorization": { "path": "{}/authorization", "class": Authorization, "kwargs": { "response_types_supported": [" ".join(x) for x in RESPONSE_TYPES_SUPPORTED], "response_modes_supported": ["query", "fragment", "form_post"], "claims_parameter_supported": True, "request_parameter_supported": True, "request_uri_parameter_supported": True, }, }, "token": { "path": "token", "class": Token, "kwargs": { "client_authn_method": [ "client_secret_post", "client_secret_basic", "client_secret_jwt", "private_key_jwt", ] }, }, "userinfo": { "path": "userinfo", "class": userinfo.UserInfo, "kwargs": { "db_file": "users.json", "claim_types_supported": ["normal", "aggregated", "distributed",], }, }, }, "authentication": { "anon": { "acr": "http://www.swamid.se/policy/assurance/al1", "class": "oidcop.user_authn.user.NoAuthn", "kwargs": {"user": "******"}, } }, "userinfo": {"class": UserInfo, "kwargs": {"db": USERINFO_db}}, "template_dir": "template", "authz": { "class": AuthzHandling, "kwargs": { "grant_config": { "usage_rules": { "authorization_code": { "supports_minting": ["access_token", "refresh_token", "id_token",], "max_usage": 1, }, "access_token": {}, "refresh_token": { "supports_minting": ["access_token", "refresh_token"], }, }, "expires_in": 43200, } }, }, "cookie_handler": { "class": CookieHandler, "kwargs": { "sign_key": "ghsNKDDLshZTPn974nOsIGhedULrsqnsGoBFBLwUKuJhE2ch", "name": { "session": "oidc_op", "register": "oidc_op_reg", "session_management": "oidc_op_sman", }, }, }, "login_hint2acrs": { "class": LoginHint2Acrs, "kwargs": {"scheme_map": {"email": [INTERNETPROTOCOLPASSWORD]}}, }, } server = Server(OPConfiguration(conf=conf, base_path=BASEDIR), cwd=BASEDIR) endpoint_context = server.endpoint_context _clients = yaml.safe_load(io.StringIO(client_yaml)) endpoint_context.cdb = _clients["oidc_clients"] endpoint_context.keyjar.import_jwks( endpoint_context.keyjar.export_jwks(True, ""), conf["issuer"] ) self.endpoint = server.server_get("endpoint", "authorization") self.session_manager = endpoint_context.session_manager self.user_id = "diana" self.rp_keyjar = KeyJar() self.rp_keyjar.add_symmetric("client_1", "hemligtkodord1234567890") endpoint_context.keyjar.add_symmetric("client_1", "hemligtkodord1234567890") def test_init(self): assert self.endpoint def _create_session(self, auth_req, sub_type="public", sector_identifier=""): if sector_identifier: authz_req = auth_req.copy() authz_req["sector_identifier_uri"] = sector_identifier else: authz_req = auth_req client_id = authz_req["client_id"] ae = create_authn_event(self.user_id) return self.session_manager.create_session( ae, authz_req, self.user_id, client_id=client_id, sub_type=sub_type ) def test_parse(self): _req = self.endpoint.parse_request(AUTH_REQ_DICT) assert isinstance(_req, AuthorizationRequest) assert set(_req.keys()) == set(AUTH_REQ.keys()) def test_process_request(self): _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) assert set(_resp.keys()) == { "response_args", "fragment_enc", "return_uri", "cookie", "session_id", } def test_do_response_code(self): _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) _msg = parse_qs(msg["response"]) assert _msg part = urlparse(msg["response"]) assert part.fragment == "" assert part.query _query = parse_qs(part.query) assert _query assert "code" in _query def test_do_response_id_token_no_nonce(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "id_token" _pr_resp = self.endpoint.parse_request(_orig_req) # Missing nonce assert isinstance(_pr_resp, ResponseMessage) def test_do_response_id_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "id_token" _orig_req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) part = urlparse(msg["response"]) assert part.query == "" assert part.fragment _frag_msg = parse_qs(part.fragment) assert _frag_msg assert "id_token" in _frag_msg assert "code" not in _frag_msg assert "token" not in _frag_msg def test_do_response_id_token_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "id_token token" _orig_req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_orig_req) assert isinstance(_pr_resp, AuthorizationErrorResponse) assert _pr_resp["error"] == "invalid_request" def test_do_response_code_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "code token" _pr_resp = self.endpoint.parse_request(_orig_req) assert isinstance(_pr_resp, AuthorizationErrorResponse) assert _pr_resp["error"] == "invalid_request" def test_do_response_code_id_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "code id_token" _orig_req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) part = urlparse(msg["response"]) assert part.query == "" assert part.fragment _frag_msg = parse_qs(part.fragment) assert _frag_msg assert "id_token" in _frag_msg assert "code" in _frag_msg assert "access_token" not in _frag_msg def test_do_response_code_id_token_token(self): _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "code id_token token" _orig_req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_orig_req) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) part = urlparse(msg["response"]) assert part.query == "" assert part.fragment _frag_msg = parse_qs(part.fragment) assert _frag_msg assert "id_token" in _frag_msg assert "code" in _frag_msg assert "access_token" in _frag_msg def test_id_token_claims(self): _req = AUTH_REQ_DICT.copy() _req["claims"] = CLAIMS _req["response_type"] = "code id_token token" _req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_req) _resp = self.endpoint.process_request(_pr_resp) idt = verify_id_token( _resp["response_args"], keyjar=self.endpoint.server_get("endpoint_context").keyjar, ) assert idt # from config assert "given_name" in _resp["response_args"]["__verified_id_token"] assert "nickname" in _resp["response_args"]["__verified_id_token"] # Could have gotten email but didn't ask for it assert "email" in _resp["response_args"]["__verified_id_token"] def test_re_authenticate(self): request = {"prompt": "login"} authn = UserAuthnMethod(self.endpoint.server_get("endpoint_context")) assert re_authenticate(request, authn) def test_id_token_acr(self): _req = AUTH_REQ_DICT.copy() _req["claims"] = { "id_token": {"acr": {"value": "http://www.swamid.se/policy/assurance/al1"}} } _req["response_type"] = "code id_token token" _req["nonce"] = "rnd_nonce" _pr_resp = self.endpoint.parse_request(_req) _resp = self.endpoint.process_request(_pr_resp) res = verify_id_token( _resp["response_args"], keyjar=self.endpoint.server_get("endpoint_context").keyjar, ) assert res res = _resp["response_args"][verified_claim_name("id_token")] assert res["acr"] == "http://www.swamid.se/policy/assurance/al1" def test_verify_uri_unknown_client(self): request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(UnknownClient): verify_uri(self.endpoint.server_get("endpoint_context"), request, "redirect_uri") def test_verify_uri_fragment(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = {"redirect_uri": ["https://rp.example.com/auth_cb"]} request = {"redirect_uri": "https://rp.example.com/cb#foobar"} with pytest.raises(URIError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_noregistered(self): _ec = self.endpoint.server_get("endpoint_context") request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(KeyError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_unregistered(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/auth_cb", {})]} request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(RedirectURIError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_match(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"]})]} request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_mismatch(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"]})]} request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb?foo=bar&foo=kex"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb?foo=bar&level=low"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_missing(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"], "state": ["low"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_qp_missing_val(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar", "low"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_verify_uri_no_registered_qp(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_ec, request, "redirect_uri", "client_id") def test_get_uri(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = { "redirect_uri": "https://rp.example.com/cb", "client_id": "client_id", } assert get_uri(_ec, request, "redirect_uri") == "https://rp.example.com/cb" def test_get_uri_no_redirect_uri(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"client_id": "client_id"} assert get_uri(_ec, request, "redirect_uri") == "https://rp.example.com/cb" def test_get_uri_no_registered(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"client_id": "client_id"} with pytest.raises(ParameterError): get_uri(_ec, request, "post_logout_redirect_uri") def test_get_uri_more_then_one_registered(self): _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = { "redirect_uris": [ ("https://rp.example.com/cb", {}), ("https://rp.example.org/authz_cb", {"foo": "bar"}), ] } request = {"client_id": "client_id"} with pytest.raises(ParameterError): get_uri(_ec, request, "redirect_uri") def test_create_authn_response(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) _ec = self.endpoint.server_get("endpoint_context") _ec.cdb["client_id"] = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "ES256", } session_id = self._create_session(request) resp = self.endpoint.create_authn_response(request, session_id) assert isinstance(resp["response_args"], AuthorizationResponse) def test_setup_auth(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } kaka = self.endpoint.server_get("endpoint_context").cookie_handler.make_cookie_content( "value", "sso" ) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, [kaka]) assert set(res.keys()) == {"session_id", "identity", "user"} def test_setup_auth_error(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } item = self.endpoint.server_get("endpoint_context").authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].fail = ToOld res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].file = "" def test_setup_auth_user(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } _ec = self.endpoint.server_get("endpoint_context") session_id = self._create_session(request) item = _ec.authn_broker.db["anon"] item["method"].user = b64e(as_bytes(json.dumps({"uid": "krall", "sid": session_id}))) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"session_id", "identity", "user"} assert res["identity"]["uid"] == "krall" def test_setup_auth_session_revoked(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } _ec = self.endpoint.server_get("endpoint_context") session_id = self._create_session(request) item = _ec.authn_broker.db["anon"] item["method"].user = b64e(as_bytes(json.dumps({"uid": "krall", "sid": session_id}))) grant = _ec.session_manager[session_id] grant.revoked = True res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"args", "function"} def test_check_session_iframe(self): self.endpoint.server_get("endpoint_context").provider_info[ "check_session_iframe" ] = "https://example.com/csi" _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) assert "session_state" in _resp["response_args"] def test_setup_auth_login_hint(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", login_hint="tel:0907865204", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } item = self.endpoint.server_get("endpoint_context").authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} assert "login_hint" in res["args"] def test_setup_auth_login_hint2acrs(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", login_hint="email:foo@bar", ) redirect_uri = request["redirect_uri"] method_spec = { "acr": INTERNETPROTOCOLPASSWORD, "kwargs": {"user": "******"}, "class": NoAuthn, } self.endpoint.server_get("endpoint_context").authn_broker["foo"] = init_method( method_spec, None ) item = self.endpoint.server_get("endpoint_context").authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication item = self.endpoint.server_get("endpoint_context").authn_broker.db["foo"] item["method"].fail = NoSuchAuthentication res = self.endpoint.pick_authn_method(request, redirect_uri) assert set(res.keys()) == {"method", "acr"} assert res["acr"] == INTERNETPROTOCOLPASSWORD assert isinstance(res["method"], NoAuthn) assert res["method"].user == "knoll" def test_post_logout_uri(self): pass def test_parse_request(self): _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256") _jws = _jwt.pack( AUTH_REQ_DICT, aud=self.endpoint.server_get("endpoint_context").provider_info["issuer"], ) # ----------------- _req = self.endpoint.parse_request( { "request": _jws, "redirect_uri": AUTH_REQ.get("redirect_uri"), "response_type": AUTH_REQ.get("response_type"), "client_id": AUTH_REQ.get("client_id"), "scope": AUTH_REQ.get("scope"), } ) assert "__verified_request" in _req def test_parse_request_uri(self): _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256") _jws = _jwt.pack( AUTH_REQ_DICT, aud=self.endpoint.server_get("endpoint_context").provider_info["issuer"], ) request_uri = "https://client.example.com/req" # ----------------- with responses.RequestsMock() as rsps: rsps.add("GET", request_uri, body=_jws, status=200) _req = self.endpoint.parse_request( { "request_uri": request_uri, "redirect_uri": AUTH_REQ.get("redirect_uri"), "response_type": AUTH_REQ.get("response_type"), "client_id": AUTH_REQ.get("client_id"), "scope": AUTH_REQ.get("scope"), } ) assert "__verified_request" in _req def test_verify_response_type(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token token"], state="state", nonce="nonce", scope="openid", ) client_info = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", "policy_uri": "https://example.com/policy.html", } assert self.endpoint.verify_response_type(request, client_info) is False client_info["response_types"] = [ "code", "code id_token", "id_token", "id_token token", ] assert self.endpoint.verify_response_type(request, client_info) is True @pytest.mark.parametrize("exp_in", [360, "360", 0]) def test_mint_token_exp_at(self, exp_in): grant = Grant() grant.usage_rules = {"authorization_code": {"expires_in": exp_in}} DUMMY_SESSION_ID = self.session_manager.encrypted_session_id( "user_id", "client_id", "grant.id" ) code = self.endpoint.mint_token("authorization_code", grant, DUMMY_SESSION_ID) if exp_in in [360, "360"]: assert code.expires_at else: assert code.expires_at == 0 def test_do_request_uri(self): request = AuthorizationRequest( redirect_uri="https://rp.example.com/cb", request_uri="https://example.com/request", ) orig_request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token token"], state="state", nonce="nonce", scope="openid", ) _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256") _jws = _jwt.pack( orig_request.to_dict(), aud=self.endpoint.server_get("endpoint_context").provider_info["issuer"], ) endpoint_context = self.endpoint.server_get("endpoint_context") endpoint_context.cdb["client_1"]["request_uris"] = [("https://example.com/request", {})] with responses.RequestsMock() as rsps: rsps.add( "GET", request["request_uri"], body=_jws, adding_headers={"Content-Type": "application/jose"}, status=200, ) self.endpoint._do_request_uri(request, "client_1", endpoint_context) request["request_uri"] = "https://example.com/request#1" with responses.RequestsMock() as rsps: rsps.add( "GET", request["request_uri"], body=_jws, adding_headers={"Content-Type": "application/jose"}, status=200, ) self.endpoint._do_request_uri(request, "client_1", endpoint_context) request["request_uri"] = "https://example.com/another" with pytest.raises(ValueError): self.endpoint._do_request_uri(request, "client_1", endpoint_context) endpoint_context.provider_info["request_uri_parameter_supported"] = False with pytest.raises(ServiceError): self.endpoint._do_request_uri(request, "client_1", endpoint_context) def test_post_parse_request(self): endpoint_context = self.endpoint.server_get("endpoint_context") msg = self.endpoint._post_parse_request(None, "client_1", endpoint_context) assert "error" in msg request = AuthorizationRequest( client_id="client_X", response_type=["code"], state="state", nonce="nonce", scope="openid", ) msg = self.endpoint._post_parse_request(request, "client_X", endpoint_context) assert "error" in msg assert msg["error_description"] == "unknown client" request["client_id"] = "client_1" endpoint_context.cdb["client_1"]["redirect_uris"] = [ ("https://example.com/cb", ""), ("https://example.com/2nd_cb", ""), ] msg = self.endpoint._post_parse_request(request, "client_1", endpoint_context) assert "error" in msg assert msg["error"] == "invalid_request" @pytest.mark.parametrize("response_mode", ["form_post", "fragment", "query"]) def test_response_mode(self, response_mode): request = AuthorizationRequest( client_id="client_1", response_type=["code"], redirect_uri="https://example.com/cb", state="state", scope="openid", response_mode=response_mode, ) response_args = AuthorizationResponse(scope="openid", code="abcdefghijklmnop") if response_mode == "fragment": info = self.endpoint.response_mode( request, response_args, request["redirect_uri"], fragment_enc=True ) else: info = self.endpoint.response_mode(request, response_args, request["redirect_uri"]) if response_mode == "form_post": assert set(info.keys()) == { "response_msg", "content_type", "response_placement", } elif response_mode == "fragment": assert set(info.keys()) == {"response_args", "return_uri", "fragment_enc"} elif response_mode == "query": assert set(info.keys()) == {"response_args", "return_uri"} def test_post_authentication(self): request = AuthorizationRequest( client_id="client_1", response_type=["code"], redirect_uri="https://example.com/cb", state="state", scope="openid", ) session_id = self._create_session(request) resp = self.endpoint.post_authentication(request, session_id) assert resp def test_do_request_user(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) assert self.endpoint.do_request_user(request) == {} # With login_hint request["login_hint"] = "mail:[email protected]" assert self.endpoint.do_request_user(request) == {} endpoint_context = self.endpoint.server_get("endpoint_context") # userinfo _userinfo = init_user_info( {"class": "oidcop.user_info.UserInfo", "kwargs": {"db_file": full_path("users.json")},}, "", ) # login_hint endpoint_context.login_hint_lookup = init_service( {"class": "oidcop.login_hint.LoginHintLookup"}, None ) endpoint_context.login_hint_lookup.userinfo = _userinfo # With login_hint and login_hint_lookup assert self.endpoint.do_request_user(request) == {"req_user": "******"}
class TestEndpoint(object): @pytest.fixture(autouse=True) def create_endpoint(self): conf = { "issuer": "https://example.com/", "password": "******", "verify_ssl": False, "capabilities": CAPABILITIES, "keys": {"uri_path": "static/jwks.json", "key_defs": KEYDEFS}, "token_handler_args": { "jwks_def": { "private_path": "private/token_jwks.json", "read_only": False, "key_defs": [{"type": "oct", "bytes": "24", "use": ["enc"], "kid": "code"}], }, "code": {"kwargs": {"lifetime": 600}}, "token": { "class": "oidcop.token.jwt_token.JWTToken", "kwargs": { "lifetime": 3600, "add_claims_by_scope": True, "aud": ["https://example.org/appl"], }, }, "refresh": { "class": "oidcop.token.jwt_token.JWTToken", "kwargs": {"lifetime": 3600, "aud": ["https://example.org/appl"],}, }, "id_token": { "class": "oidcop.token.id_token.IDToken", "kwargs": { "base_claims": { "email": {"essential": True}, "email_verified": {"essential": True}, } }, }, }, "endpoint": { "authorization": { "path": "{}/authorization", "class": Authorization, "kwargs": { "response_types_supported": [" ".join(x) for x in RESPONSE_TYPES_SUPPORTED], "response_modes_supported": ["query", "fragment", "form_post"], "claims_parameter_supported": True, "request_parameter_supported": True, "request_uri_parameter_supported": True, }, } }, "authentication": { "anon": { "acr": "http://www.swamid.se/policy/assurance/al1", "class": "oidcop.user_authn.user.NoAuthn", "kwargs": {"user": "******"}, } }, "userinfo": {"class": UserInfo, "kwargs": {"db": USERINFO_db}}, "template_dir": "template", "cookie_handler": { "class": CookieHandler, "kwargs": { "keys": {"key_defs": COOKIE_KEYDEFS}, "name": { "session": "oidc_op", "register": "oidc_op_reg", "session_management": "oidc_op_sman", }, }, }, "authz": { "class": AuthzHandling, "kwargs": { "grant_config": { "usage_rules": { "authorization_code": { "supports_minting": ["access_token", "refresh_token", "id_token",], "max_usage": 1, }, "access_token": {}, "refresh_token": { "supports_minting": ["access_token", "refresh_token", "id_token",], }, }, "expires_in": 43200, } }, }, } server = Server(ASConfiguration(conf=conf, base_path=BASEDIR), cwd=BASEDIR) endpoint_context = server.endpoint_context _clients = yaml.safe_load(io.StringIO(client_yaml)) endpoint_context.cdb = _clients["clients"] endpoint_context.keyjar.import_jwks( endpoint_context.keyjar.export_jwks(True, ""), conf["issuer"] ) self.endpoint = server.server_get("endpoint", "authorization") self.session_manager = endpoint_context.session_manager self.user_id = "diana" self.rp_keyjar = KeyJar() self.rp_keyjar.add_symmetric("client_1", "hemligtkodord1234567890") self.endpoint.server_get("endpoint_context").keyjar.add_symmetric( "client_1", "hemligtkodord1234567890" ) def _create_session(self, auth_req, sub_type="public", sector_identifier=""): if sector_identifier: areq = auth_req.copy() areq["sector_identifier_uri"] = sector_identifier else: areq = auth_req client_id = areq["client_id"] ae = create_authn_event(self.user_id) return self.session_manager.create_session( ae, areq, self.user_id, client_id=client_id, sub_type=sub_type ) def test_init(self): assert self.endpoint def test_parse(self): _req = self.endpoint.parse_request(AUTH_REQ_DICT) assert isinstance(_req, AuthorizationRequest) assert set(_req.keys()) == set(AUTH_REQ.keys()) def test_process_request(self): _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) assert set(_resp.keys()) == { "response_args", "fragment_enc", "return_uri", "cookie", "session_id", } def test_do_response_code(self): _pr_resp = self.endpoint.parse_request(AUTH_REQ_DICT) _resp = self.endpoint.process_request(_pr_resp) msg = self.endpoint.do_response(**_resp) assert isinstance(msg, dict) _msg = parse_qs(msg["response"]) assert _msg part = urlparse(msg["response"]) assert part.fragment == "" assert part.query _query = parse_qs(part.query) assert _query assert "code" in _query def test_do_response_code_token(self): """UnAuthorized Client """ _orig_req = AUTH_REQ_DICT.copy() _orig_req["response_type"] = "code token" msg = "" _pr_resp = self.endpoint.parse_request(_orig_req) assert isinstance(_pr_resp, AuthorizationErrorResponse) assert _pr_resp["error"] == "invalid_request" def test_verify_uri_unknown_client(self): request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(UnknownClient): verify_uri(self.endpoint.server_get("endpoint_context"), request, "redirect_uri") def test_verify_uri_fragment(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = {"redirect_uri": ["https://rp.example.com/auth_cb"]} request = {"redirect_uri": "https://rp.example.com/cb#foobar"} with pytest.raises(URIError): verify_uri(_context, request, "redirect_uri", "client_id") def test_verify_uri_noregistered(self): _context = self.endpoint.server_get("endpoint_context") request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(KeyError): verify_uri(_context, request, "redirect_uri", "client_id") def test_verify_uri_unregistered(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/auth_cb", {})]} request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(RedirectURIError): verify_uri(_context, request, "redirect_uri", "client_id") def test_verify_uri_qp_match(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} verify_uri(_context, request, "redirect_uri", "client_id") def test_verify_uri_qp_mismatch(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_context, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb?foo=bar&foo=kex"} with pytest.raises(ValueError): verify_uri(_context, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(ValueError): verify_uri(_context, request, "redirect_uri", "client_id") request = {"redirect_uri": "https://rp.example.com/cb?foo=bar&level=low"} with pytest.raises(ValueError): verify_uri(_context, request, "redirect_uri", "client_id") def test_verify_uri_qp_missing(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"], "state": ["low"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} with pytest.raises(ValueError): verify_uri(_context, request, "redirect_uri", "client_id") def test_verify_uri_qp_missing_val(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = { "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar", "low"]})] } request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"} with pytest.raises(ValueError): verify_uri(_context, request, "redirect_uri", "client_id") def test_verify_uri_no_registered_qp(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_context, request, "redirect_uri", "client_id") def test_verify_uri_wrong_uri_type(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"} with pytest.raises(ValueError): verify_uri(_context, request, "post_logout_redirect_uri", "client_id") def test_verify_uri_none_registered(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = { "post_logout_redirect_uri": [("https://rp.example.com/plrc", {})] } request = {"redirect_uri": "https://rp.example.com/cb"} with pytest.raises(ValueError): verify_uri(_context, request, "redirect_uri", "client_id") def test_get_uri(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = { "redirect_uri": "https://rp.example.com/cb", "client_id": "client_id", } assert get_uri(_context, request, "redirect_uri") == "https://rp.example.com/cb" def test_get_uri_no_redirect_uri(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"client_id": "client_id"} assert get_uri(_context, request, "redirect_uri") == "https://rp.example.com/cb" def test_get_uri_no_registered(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]} request = {"client_id": "client_id"} with pytest.raises(ParameterError): get_uri(_context, request, "post_logout_redirect_uri") def test_get_uri_more_then_one_registered(self): _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = { "redirect_uris": [ ("https://rp.example.com/cb", {}), ("https://rp.example.org/authz_cb", {"foo": "bar"}), ] } request = {"client_id": "client_id"} with pytest.raises(ParameterError): get_uri(_context, request, "redirect_uri") def test_create_authn_response(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) self.endpoint.server_get("endpoint_context").cdb["client_id"] = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "ES256", } session_id = self._create_session(request) resp = self.endpoint.create_authn_response(request, session_id) assert isinstance(resp["response_args"], AuthorizationErrorResponse) def test_setup_auth(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } kaka = self.endpoint.server_get("endpoint_context").cookie_handler.make_cookie_content( "value", "sso" ) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, [kaka]) assert set(res.keys()) == {"session_id", "identity", "user"} def test_setup_auth_error(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } item = self.endpoint.server_get("endpoint_context").authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].fail = ToOld res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].file = "" def test_setup_auth_invalid_scope(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid THAT-BLOODY_SCOPE", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } _context = self.endpoint.server_get("endpoint_context") _context.cdb["client_id"] = cinfo kaka = _context.cookie_handler.make_cookie_content("value", "sso") # force to 400 Http Error message if the release scope policy is heavy! _context.conf["capabilities"]["deny_unknown_scopes"] = True excp = None try: res = self.endpoint.process_request(request, http_info={"headers": {"cookie": [kaka]}}) except UnAuthorizedClientScope as e: excp = e assert excp assert isinstance(excp, UnAuthorizedClientScope) def test_setup_auth_user(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } session_id = self._create_session(request) item = self.endpoint.server_get("endpoint_context").authn_broker.db["anon"] item["method"].user = b64e(as_bytes(json.dumps({"uid": "krall", "sid": session_id}))) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"session_id", "identity", "user"} assert res["identity"]["uid"] == "krall" def test_setup_auth_session_revoked(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } session_id = self._create_session(request) _context = self.endpoint.server_get("endpoint_context") _mngr = _context.session_manager _csi = _mngr[session_id] _csi.revoked = True item = _context.authn_broker.db["anon"] item["method"].user = b64e(as_bytes(json.dumps({"uid": "krall", "sid": session_id}))) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"args", "function"} def test_response_mode_form_post(self): request = {"response_mode": "form_post"} info = { "response_args": AuthorizationResponse(foo="bar"), "return_uri": "https://example.com/cb", } info = self.endpoint.response_mode(request, **info) assert set(info.keys()) == { "response_msg", "content_type", "response_placement", } assert info["response_msg"] == FORM_POST.format( action="https://example.com/cb", inputs='<input type="hidden" name="foo" value="bar"/>', ) def test_response_mode_fragment(self): request = {"response_mode": "fragment"} self.endpoint.response_mode(request, fragment_enc=True) with pytest.raises(InvalidRequest): self.endpoint.response_mode(request, fragment_enc=False) info = self.endpoint.response_mode(request) assert set(info.keys()) == {"return_uri", "response_args", "fragment_enc"} def test_req_user(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None, req_user="******") assert "function" in res def test_req_user_no_prompt(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", prompt="none", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None, req_user="******") assert "error" in res