def test_userinfo(): consumer = Consumer(SessionDB(), CONFIG, CLIENT_CONFIG, SERVER_INFO) consumer.keyjar = CLIKEYS mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS consumer.http_request = mfos.http_request consumer.redirect_uris = ["http://example.com/authz"] consumer.state = "state0" consumer.nonce = rndstr() consumer.secret_type = "basic" consumer.set_client_secret("hemligt") consumer.keyjar = CLIKEYS args = { "client_id": consumer.client_id, "response_type": "code", "scope": ["openid"], } result = consumer.do_authorization_request(state=consumer.state, request_args=args) assert result.status_code == 302 assert result.headers["location"].startswith(consumer.redirect_uris[0]) _, query = result.headers["location"].split("?") consumer.parse_response(AuthorizationResponse, info=query, sformat="urlencoded") consumer.complete() result = consumer.get_user_info() print result assert result.type() == "OpenIDSchema" assert _eq(result.keys(), ['name', 'email', 'verified', 'nickname', 'sub'])
def test_userinfo(): consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, CLIENT_CONFIG, SERVER_INFO) consumer.keyjar = CLIKEYS mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS consumer.http_request = mfos.http_request consumer.redirect_uris = ["http://example.com/authz"] _state = "state0" consumer.nonce = rndstr() consumer.secret_type = "basic" consumer.set_client_secret("hemligt") consumer.keyjar = CLIKEYS args = { "client_id": consumer.client_id, "response_type": "code", "scope": ["openid"], } result = consumer.do_authorization_request(state=_state, request_args=args) assert result.status_code == 302 assert result.headers["location"].startswith(consumer.redirect_uris[0]) _, query = result.headers["location"].split("?") consumer.parse_response(AuthorizationResponse, info=query, sformat="urlencoded") consumer.complete(_state) result = consumer.get_user_info(_state) print result assert result.type() == "OpenIDSchema" assert _eq(result.keys(), ['name', 'email', 'verified', 'nickname', 'sub'])
def test_complete_secret_auth(): consumer = Consumer(SessionDB(), CONFIG, CLIENT_CONFIG, SERVER_INFO) mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS consumer.http_request = mfos.http_request consumer.redirect_uris = ["http://example.com/authz"] consumer.state = "state0" consumer.nonce = rndstr() consumer.client_secret = "hemlig" consumer.secret_type = "basic" del consumer.config["password"] args = { "client_id": consumer.client_id, "response_type": "code", "scope": ["openid"], } result = consumer.do_authorization_request(state=consumer.state, request_args=args) assert result.status_code == 302 assert result.headers["location"].startswith(consumer.redirect_uris[0]) _, query = result.headers["location"].split("?") consumer.parse_response(AuthorizationResponse, info=query, sformat="urlencoded") resp = consumer.complete() print resp assert resp.type() == "AccessTokenResponse" print resp.keys() assert _eq(resp.keys(), ['token_type', 'state', 'access_token', 'scope', 'expires_in', 'refresh_token']) assert resp["state"] == consumer.state
def test_sign_userinfo(): consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, CLIENT_CONFIG, SERVER_INFO) consumer.keyjar = CLIKEYS mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS mfos.userinfo_signed_response_alg = "RS256" consumer.http_request = mfos.http_request consumer.redirect_uris = ["http://example.com/authz"] _state = "state0" consumer.nonce = rndstr() consumer.secret_type = "basic" consumer.set_client_secret("hemligt") consumer.keyjar = CLIKEYS consumer.client_prefs = {"userinfo_signed_response_alg": "RS256"} consumer.provider_info = { "userinfo_endpoint": "http://localhost:8088/userinfo", "issuer": "http://localhost:8088/"} del consumer.config["request_method"] args = { "client_id": consumer.client_id, "response_type": "code", "scope": ["openid"], } sid, location = consumer.begin("openid", "code") print location result = consumer.do_authorization_request(state=_state, request_args=args) assert result.status_code == 302 assert result.headers["location"].startswith(consumer.redirect_uris[0]) _, query = result.headers["location"].split("?") consumer.parse_response(AuthorizationResponse, info=query, sformat="urlencoded") consumer.complete(_state) result = consumer.get_user_info(_state) print result assert result.type() == "OpenIDSchema" assert _eq(result.keys(), ['name', 'email', 'verified', 'nickname', 'sub'])
class TestOICConsumer(): def setup_class(self): self.consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, CLIENT_CONFIG, SERVER_INFO) self.consumer.behaviour = { "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"] } self.consumer.client_secret = CLIENT_SECRET def test_init(self): assert self.consumer def test_backup_keys(self): keys = self.consumer.__dict__.keys() print keys _dict = self.consumer.dictionary() print _dict.keys() dkeys = [key for key in keys if key not in _dict.keys()] print dkeys assert _eq(dkeys, IGNORE) def test_backup_restore(self): _dict = self.consumer.__dict__.items() self.consumer._backup("sid") self.consumer.restore("sid") assert _dict == self.consumer.__dict__.items() self.consumer.authorization_endpoint = AUTHZ_URL assert _dict != self.consumer.__dict__.items() self.consumer.restore("sid") assert _dict == self.consumer.__dict__.items() def test_backup_restore_update(self): self.consumer.authorization_endpoint = AUTHZ_URL self.consumer.token_endpoint = "http://example.com/token" self.consumer.userinfo_endpoint = "http://example.com/userinfo" self.consumer._backup("sid") self.consumer.authorization_endpoint = AUTHZ_ORG_URL self.consumer.token_endpoint = "http://example.org/token" self.consumer.userinfo_endpoint = "" assert self.consumer.authorization_endpoint == AUTHZ_ORG_URL assert self.consumer.token_endpoint == "http://example.org/token" assert self.consumer.userinfo_endpoint == "" self.consumer.update("sid") assert self.consumer.authorization_endpoint == AUTHZ_ORG_URL assert self.consumer.token_endpoint == "http://example.org/token" assert self.consumer.userinfo_endpoint == "http://example.com/userinfo" def test_begin(self): self.consumer.authorization_endpoint = AUTHZ_URL self.consumer.keyjar[""].append(KC_RSA) # self.consumer.keyjar.set_sign_key(rsapub, "rsa") #self.consumer.keyjar.set_verify_key(rsapub, "rsa") srv = Server() srv.keyjar = SRVKEYS print "redirect_uris", self.consumer.redirect_uris print "config", self.consumer.config sid, location = self.consumer.begin("openid", "code") print location authreq = srv.parse_authorization_request(url=location) print authreq.keys() assert _eq(authreq.keys(), [ 'request', 'state', 'max_age', 'claims', 'response_type', 'client_id', 'scope', 'redirect_uri' ]) assert authreq["state"] == sid assert authreq["scope"] == self.consumer.config["scope"] assert authreq["client_id"] == self.consumer.client_id def test_begin_file(self): tempdir = tempfile.mkdtemp() self.consumer.config["request_method"] = "file" self.consumer.config["temp_dir"] = tempdir self.consumer.config["temp_path"] = tempdir self.consumer.config["authz_page"] = "/authz" srv = Server() srv.keyjar = SRVKEYS sid, location = self.consumer.begin("openid", "code", path="http://localhost:8087") print location # vkeys = {".":srv.keyjar.get_verify_key()} authreq = srv.parse_authorization_request(url=location) print authreq.keys() assert _eq(authreq.keys(), [ 'max_age', 'state', 'redirect_uri', 'response_type', 'client_id', 'scope', 'claims', 'request_uri' ]) assert authreq["state"] == sid assert authreq["scope"] == self.consumer.config["scope"] assert authreq["client_id"] == self.consumer.client_id assert authreq["redirect_uri"].startswith( "http://localhost:8087/authz") # Cleanup the file we have created shutil.rmtree(tempdir) def test_complete(self): mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request _state = "state0" self.consumer.nonce = rndstr() self.consumer.redirect_uris = ["https://example.com/cb"] args = { "client_id": self.consumer.client_id, "response_type": "code", "scope": ["openid"], } result = self.consumer.do_authorization_request(state=_state, request_args=args) assert result.status_code == 302 print "redirect_uris", self.consumer.redirect_uris print result.headers["location"] assert result.headers["location"].startswith( self.consumer.redirect_uris[0]) _, query = result.headers["location"].split("?") # vkeys = {".": self.consumer.keyjar.get_verify_key()} self.consumer.parse_response(AuthorizationResponse, info=query, sformat="urlencoded") resp = self.consumer.complete(_state) print resp assert resp.type() == "AccessTokenResponse" print resp.keys() assert _eq(resp.keys(), [ 'token_type', 'state', 'access_token', 'scope', 'expires_in', 'refresh_token' ]) assert resp["state"] == _state def test_parse_authz(self): mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request _state = "state0" self.consumer.nonce = rndstr() args = { "client_id": self.consumer.client_id, "response_type": "code", "scope": ["openid"], } result = self.consumer.do_authorization_request(state=_state, request_args=args) print self.consumer.sdb["state0"].keys() part = self.consumer.parse_authz(query=result.headers["location"]) print part atr = part[0] assert part[1] is None assert part[2] is None assert atr.type() == "AuthorizationResponse" assert atr["state"] == _state assert "code" in atr def test_parse_authz_implicit(self): mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request self.consumer.config["response_type"] = ["token"] _state = "statxxx" args = { "client_id": self.consumer.client_id, "response_type": "implicit", "scope": ["openid"], "redirect_uri": "http://localhost:8088/cb" } result = self.consumer.do_authorization_request(state=_state, request_args=args) part = self.consumer.parse_authz(query=result.headers["location"]) print part assert part[0] is None atr = part[1] assert part[2] is None assert atr.type() == "AccessTokenResponse" assert atr["state"] == _state assert "access_token" in atr
class TestOICConsumer(): @pytest.fixture(autouse=True) def setup_consumer(self): client_id = "client_1" client_config = { "client_id": client_id, "client_authn_method": CLIENT_AUTHN_METHOD, #'config': {} } self.consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, client_config, SERVER_INFO) self.consumer.behaviour = { "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"]} self.consumer.client_secret = "abcdefghijklmnop" self.consumer.keyjar = CLIKEYS self.consumer.redirect_uris = ["https://example.com/cb"] self.consumer.authorization_endpoint = "http://example.com/authorization" self.consumer.token_endpoint = "http://example.com/token" self.consumer.userinfo_endpoint = "http://example.com/userinfo" self.consumer.client_secret = "hemlig" self.consumer.secret_type = "basic" mfos = MyFakeOICServer("http://*****:*****@connect-op.heroku.com" res = c.discover(principal) assert isinstance(res, ProviderConfigurationResponse) assert _eq(res.keys(), ['registration_endpoint', 'scopes_supported', 'identifiers_supported', 'token_endpoint', 'flows_supported', 'version', 'userinfo_endpoint', 'authorization_endpoint', 'x509_url', 'issuer']) assert res.version == "3.0" assert _eq(res.flows_supported, ['code', 'token', 'id_token', 'code token', 'code id_token', 'id_token token']) def test_discover(self): c = Consumer(None, None) mfos = MyFakeOICServer("http://*****:*****@example.com" res = c.discover(principal) assert res == "http://*****:*****@example.com" res = c.discover(principal) info = c.provider_config(res) assert isinstance(info, ProviderConfigurationResponse) assert _eq(info.keys(), ['registration_endpoint', 'jwks_uri', 'check_session_endpoint', 'refresh_session_endpoint', 'register_endpoint', 'subject_types_supported', 'token_endpoint_auth_methods_supported', 'id_token_signing_alg_values_supported', 'grant_types_supported', 'user_info_endpoint', 'claims_parameter_supported', 'request_parameter_supported', 'discovery_endpoint', 'issuer', 'authorization_endpoint', 'scopes_supported', 'require_request_uri_registration', 'identifiers_supported', 'token_endpoint', 'request_uri_parameter_supported', 'version', 'response_types_supported', 'end_session_endpoint', 'flows_supported']) assert info["end_session_endpoint"] == "http://example.com/end_session" def test_client_register(self): c = Consumer(None, None) c.application_type = "web" c.application_name = "My super service" c.redirect_uris = ["http://example.com/authz"] c.contact = ["*****@*****.**"] mfos = MyFakeOICServer("http://example.com") mfos.keyjar = SRVKEYS c.http_request = mfos.http_request location = c.discover("*****@*****.**") info = c.provider_config(location) c.register(info["registration_endpoint"]) assert c.client_id is not None assert c.client_secret is not None assert c.registration_expires > utc_time_sans_frac() def _faulty_id_token(self): idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject', 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073, 'iat': 1420822473, 'aud': 'TestClient'} idts = IdToken(**idval) _signed_jwt = idts.to_jwt(key=[SYMKey(key="TestPassword")], algorithm="HS256") # Mess with the signed id_token p = _signed_jwt.split(".") p[2] = "aaa" return ".".join(p) def test_faulty_id_token(self): _faulty_signed_jwt = self._faulty_id_token() with pytest.raises(BadSignature): IdToken().from_jwt(_faulty_signed_jwt, key=[SYMKey(key="TestPassword")]) # What if no verification key is given ? # Should also result in an exception with pytest.raises(MissingSigningKey): _ = IdToken().from_jwt(_faulty_signed_jwt) def test_faulty_id_token_in_access_token_response(self): c = Consumer(None, None) c.keyjar.add_symmetric("", "TestPassword", ["sig"]) _info = {"access_token": "accessTok", "id_token": self._faulty_id_token(), "token_type": "Bearer"} _json = json.dumps(_info) with pytest.raises(BadSignature): c.parse_response(AccessTokenResponse, _json, sformat="json") def test_faulty_idtoken_from_accesstoken_endpoint(self): mfos = MITMServer("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request _state = "state0" self.consumer.consumer_config["response_type"] = ["id_token"] args = { "client_id": self.consumer.client_id, "response_type": self.consumer.consumer_config["response_type"], "scope": ["openid"], } result = self.consumer.do_authorization_request(state=_state, request_args=args) self.consumer._backup("state0") assert result.status_code == 302 query = urlparse(result.headers["location"]).query with pytest.raises(BadSignature): self.consumer.parse_authz(query=query)
class TestOICConsumer(): @pytest.fixture(autouse=True) def setup_consumer(self, fake_oic_server, session_db_factory): client_id = "client_1" client_config = { "client_id": client_id, "client_authn_method": CLIENT_AUTHN_METHOD, # 'config': {} } self.consumer = Consumer(session_db_factory(SERVER_INFO["issuer"]), CONFIG, client_config, SERVER_INFO) self.consumer.behaviour = { "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"] } self.consumer.client_secret = "abcdefghijklmnop" self.consumer.keyjar = CLIKEYS self.consumer.redirect_uris = ["https://example.com/cb"] self.consumer.authorization_endpoint = \ "http://example.com/authorization" self.consumer.token_endpoint = "http://example.com/token" self.consumer.userinfo_endpoint = "http://example.com/userinfo" self.consumer.client_secret = "hemlig" self.consumer.secret_type = "basic" mfos = fake_oic_server("http://*****:*****@connect-op.heroku.com" res = c.discover(principal) assert isinstance(res, ProviderConfigurationResponse) assert _eq(res.keys(), [ 'registration_endpoint', 'scopes_supported', 'identifiers_supported', 'token_endpoint', 'flows_supported', 'version', 'userinfo_endpoint', 'authorization_endpoint', 'x509_url', 'issuer' ]) assert res.version == "3.0" assert _eq(res.flows_supported, [ 'code', 'token', 'id_token', 'code token', 'code id_token', 'id_token token' ]) def test_discover(self, fake_oic_server): c = Consumer(None, None) mfos = fake_oic_server("https://*****:*****@example.com" res = c.discover(principal) assert res == "https://*****:*****@example.com" res = c.discover(principal) info = c.provider_config(res) assert isinstance(info, ProviderConfigurationResponse) assert _eq(info.keys(), [ 'registration_endpoint', 'jwks_uri', 'check_session_endpoint', 'refresh_session_endpoint', 'register_endpoint', 'subject_types_supported', 'token_endpoint_auth_methods_supported', 'id_token_signing_alg_values_supported', 'grant_types_supported', 'user_info_endpoint', 'claims_parameter_supported', 'request_parameter_supported', 'discovery_endpoint', 'issuer', 'authorization_endpoint', 'scopes_supported', 'require_request_uri_registration', 'identifiers_supported', 'token_endpoint', 'request_uri_parameter_supported', 'version', 'response_types_supported', 'end_session_endpoint', 'flows_supported' ]) assert info[ "end_session_endpoint"] == "https://example.com/end_session" def test_client_register(self, fake_oic_server): c = Consumer(None, None) c.application_type = "web" c.application_name = "My super service" c.redirect_uris = ["https://example.com/authz"] c.contact = ["*****@*****.**"] mfos = fake_oic_server("https://example.com") mfos.keyjar = SRVKEYS c.http_request = mfos.http_request location = c.discover("*****@*****.**") info = c.provider_config(location) c.register(info["registration_endpoint"]) assert c.client_id is not None assert c.client_secret is not None assert c.registration_expires > utc_time_sans_frac() def _faulty_id_token(self): idval = { 'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject', 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073, 'iat': 1420822473, 'aud': 'TestClient' } idts = IdToken(**idval) _signed_jwt = idts.to_jwt(key=[SYMKey(key="TestPassword")], algorithm="HS256") # Mess with the signed id_token p = _signed_jwt.split(".") p[2] = "aaa" return ".".join(p) def test_faulty_id_token(self): _faulty_signed_jwt = self._faulty_id_token() with pytest.raises(BadSignature): IdToken().from_jwt(_faulty_signed_jwt, key=[SYMKey(key="TestPassword")]) # What if no verification key is given ? # Should also result in an exception with pytest.raises(MissingSigningKey): IdToken().from_jwt(_faulty_signed_jwt) def test_faulty_id_token_in_access_token_response(self): c = Consumer(None, None) c.keyjar.add_symmetric("", "TestPassword", ["sig"]) _info = { "access_token": "accessTok", "id_token": self._faulty_id_token(), "token_type": "Bearer" } _json = json.dumps(_info) with pytest.raises(BadSignature): c.parse_response(AccessTokenResponse, _json, sformat="json") def test_faulty_idtoken_from_accesstoken_endpoint(self, mitm_server): mfos = mitm_server("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request _state = "state0" self.consumer.consumer_config["response_type"] = ["id_token"] args = { "client_id": self.consumer.client_id, "response_type": self.consumer.consumer_config["response_type"], "scope": ["openid"], } result = self.consumer.do_authorization_request(state=_state, request_args=args) self.consumer._backup("state0") assert result.status_code == 302 query = urlparse(result.headers["location"]).query with pytest.raises(BadSignature): self.consumer.parse_authz(query=query)
class TestOICConsumer(): def setup_class(self): self.consumer = Consumer(SessionDB(), CONFIG, CLIENT_CONFIG, SERVER_INFO) self.consumer.client_secret = CLIENT_SECRET def test_init(self): assert self.consumer def test_backup_keys(self): keys = self.consumer.__dict__.keys() print keys _dict = self.consumer.dictionary() print _dict.keys() dkeys = [key for key in keys if key not in _dict.keys()] print dkeys assert _eq(dkeys, IGNORE) def test_backup_restore(self): _dict = self.consumer.__dict__.items() self.consumer._backup("sid") self.consumer.restore("sid") assert _dict == self.consumer.__dict__.items() self.consumer.authorization_endpoint = AUTHZ_URL assert _dict != self.consumer.__dict__.items() self.consumer.restore("sid") assert _dict == self.consumer.__dict__.items() def test_backup_restore_update(self): self.consumer.authorization_endpoint = AUTHZ_URL self.consumer.token_endpoint = "http://example.com/token" self.consumer.userinfo_endpoint = "http://example.com/userinfo" self.consumer._backup("sid") self.consumer.authorization_endpoint = AUTHZ_ORG_URL self.consumer.token_endpoint = "http://example.org/token" self.consumer.userinfo_endpoint = "" assert self.consumer.authorization_endpoint == AUTHZ_ORG_URL assert self.consumer.token_endpoint == "http://example.org/token" assert self.consumer.userinfo_endpoint == "" self.consumer.update("sid") assert self.consumer.authorization_endpoint == AUTHZ_ORG_URL assert self.consumer.token_endpoint == "http://example.org/token" assert self.consumer.userinfo_endpoint == "http://example.com/userinfo" def test_begin(self): self.consumer.authorization_endpoint = AUTHZ_URL self.consumer.keyjar[""].append(KC_RSA) #self.consumer.keyjar.set_sign_key(rsapub, "rsa") #self.consumer.keyjar.set_verify_key(rsapub, "rsa") srv = Server() srv.keyjar = SRVKEYS print "redirect_uris", self.consumer.redirect_uris print "config", self.consumer.config location = self.consumer.begin("openid", "code") print location authreq = srv.parse_authorization_request(url=location) print authreq.keys() assert _eq(authreq.keys(), ['request', 'state', 'max_age', 'claims', 'response_type', 'client_id', 'scope', 'redirect_uri']) assert authreq["state"] == self.consumer.state assert authreq["scope"] == self.consumer.config["scope"] assert authreq["client_id"] == self.consumer.client_id def test_begin_file(self): self.consumer.config["request_method"] = "file" self.consumer.config["temp_dir"] = "./file" self.consumer.config["temp_path"] = "/tmp/" self.consumer.config["authz_page"] = "/authz" srv = Server() srv.keyjar = SRVKEYS location = self.consumer.begin("openid", "code", path="http://localhost:8087") print location #vkeys = {".":srv.keyjar.get_verify_key()} authreq = srv.parse_authorization_request(url=location) print authreq.keys() assert _eq(authreq.keys(), ['max_age', 'state', 'redirect_uri', 'response_type', 'client_id', 'scope', 'claims', 'request_uri']) assert authreq["state"] == self.consumer.state assert authreq["scope"] == self.consumer.config["scope"] assert authreq["client_id"] == self.consumer.client_id assert authreq["redirect_uri"].startswith("http://localhost:8087/authz") def test_complete(self): mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request self.consumer.state = "state0" self.consumer.nonce = rndstr() self.consumer.redirect_uris = ["https://example.com/cb"] args = { "client_id": self.consumer.client_id, "response_type": "code", "scope": ["openid"], } result = self.consumer.do_authorization_request( state=self.consumer.state, request_args=args) assert result.status_code == 302 print "redirect_uris", self.consumer.redirect_uris print result.headers["location"] assert result.headers["location"].startswith( self.consumer.redirect_uris[0]) _, query = result.headers["location"].split("?") #vkeys = {".": self.consumer.keyjar.get_verify_key()} self.consumer.parse_response(AuthorizationResponse, info=query, sformat="urlencoded") resp = self.consumer.complete() print resp assert resp.type() == "AccessTokenResponse" print resp.keys() assert _eq(resp.keys(), ['token_type', 'state', 'access_token', 'scope', 'expires_in', 'refresh_token']) assert resp["state"] == self.consumer.state def test_parse_authz(self): mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request self.consumer.state = "state0" self.consumer.nonce = rndstr() args = { "client_id": self.consumer.client_id, "response_type": "code", "scope": ["openid"], } result = self.consumer.do_authorization_request( state=self.consumer.state, request_args=args) print self.consumer.sdb.keys() print self.consumer.sdb["state0"].keys() part = self.consumer.parse_authz(query=result.headers["location"]) print part atr = part[0] assert part[1] is None assert part[2] is None assert atr.type() == "AuthorizationResponse" assert atr["state"] == "state0" assert "code" in atr def test_parse_authz_implicit(self): self.consumer.config["response_type"] = "implicit" args = { "client_id": self.consumer.client_id, "response_type": "implicit", "scope": ["openid"], } result = self.consumer.do_authorization_request( state=self.consumer.state, request_args=args) part = self.consumer.parse_authz(query=result.headers["location"]) print part assert part[0] is None atr = part[1] assert part[2] is None assert atr.type() == "AccessTokenResponse" assert atr["state"] == "state0" assert "access_token" in atr
class TestOICConsumer: @pytest.fixture(autouse=True) def setup_consumer(self, session_db_factory): client_id = "client_1" client_config = { "client_id": client_id, "client_authn_method": CLIENT_AUTHN_METHOD, } self.consumer = Consumer(DictSessionBackend(), CONFIG, client_config, SERVER_INFO) self.consumer.behaviour = { "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"] } self.consumer.keyjar = CLIKEYS self.consumer.redirect_uris = ["https://example.com/cb"] self.consumer.authorization_endpoint = "https://example.com/authorization" self.consumer.token_endpoint = "https://example.com/token" self.consumer.userinfo_endpoint = "https://example.com/userinfo" # type: ignore self.consumer.client_secret = "hemlig" self.consumer.secret_type = "basic" def test_backup_keys(self): keys = self.consumer.__dict__.keys() _dict = self.consumer.dictionary() dkeys = [key for key in keys if key not in _dict.keys()] assert _eq(dkeys, IGNORE) def test_backup_restore(self): authz_org_url = "http://example.org/authorization" _dict = sorted(list(self.consumer.__dict__.items())) self.consumer._backup("sid") self.consumer.restore("sid") assert sorted(_dict) == sorted(list(self.consumer.__dict__.items())) self.consumer.authorization_endpoint = authz_org_url assert _dict != sorted(list(self.consumer.__dict__.items())) self.consumer.restore("sid") assert _dict == sorted(list(self.consumer.__dict__.items())) def test_backup_restore_update(self): authz_org_url = "http://example.org/authorization" self.consumer._backup("sid") self.consumer.authorization_endpoint = authz_org_url self.consumer.token_endpoint = "https://example.org/token" self.consumer.userinfo_endpoint = "" # type: ignore assert self.consumer.authorization_endpoint == authz_org_url assert self.consumer.token_endpoint == "https://example.org/token" assert self.consumer.userinfo_endpoint == "" # type: ignore self.consumer.update("sid") assert self.consumer.authorization_endpoint == authz_org_url assert self.consumer.token_endpoint == "https://example.org/token" assert (self.consumer.userinfo_endpoint # type: ignore == "https://example.com/userinfo") def test_begin(self): srv = Server() srv.keyjar = SRVKEYS sid, location = self.consumer.begin("openid", "code") authreq = srv.parse_authorization_request(url=location) assert _eq( list(authreq.keys()), [ "state", "max_age", "claims", "response_type", "client_id", "scope", "redirect_uri", ], ) assert authreq["state"] == sid assert authreq["scope"] == self.consumer.consumer_config["scope"] assert authreq["client_id"] == self.consumer.client_id def test_begin_file(self, tmpdir): path = tmpdir.strpath external_path = "/exported" self.consumer.consumer_config["request_method"] = "file" self.consumer.consumer_config["temp_dir"] = path self.consumer.consumer_config["temp_path"] = external_path self.consumer.consumer_config["authz_page"] = "/authz" srv = Server() srv.keyjar = SRVKEYS sid, location = self.consumer.begin("openid", "code", path="http://*****:*****@example.com", "nickname": "Ilja", "verified": True, }, ) result = self.consumer.do_authorization_request(state=_state, request_args=args) parsed = urlparse(result.headers["location"]) self.consumer.parse_response(AuthorizationResponse, info=parsed.query, sformat="urlencoded") self.consumer.complete(_state) result = self.consumer.get_user_info(_state) assert isinstance(result, OpenIDSchema) assert _eq(result.keys(), ["name", "email", "verified", "nickname", "sub"]) def test_sign_userinfo(self): _state = "state0" self.consumer.client_prefs = {"userinfo_signed_response_alg": "RS256"} del self.consumer.consumer_config["request_method"] args = { "client_id": self.consumer.client_id, "response_type": "code", "scope": ["openid"], } location = "https://example.com/cb?code=code&state=state0" with responses.RequestsMock() as rsps: rsps.add( responses.GET, "https://example.com/authorization", status=302, headers={"location": location}, ) rsps.add( responses.POST, "https://example.com/token", content_type="application/json", json={ "access_token": "some_token", "token_type": "bearer", "state": "state0", "scope": "openid", }, ) rsps.add( responses.POST, "https://example.com/userinfo", content_type="application/json", json={ "name": "Ilja", "sub": "some_sub", "email": "*****@*****.**", "nickname": "Ilja", "verified": True, }, ) self.consumer.begin("openid", "code") result = self.consumer.do_authorization_request(state=_state, request_args=args) parsed = urlparse(result.headers["location"]) self.consumer.parse_response(AuthorizationResponse, info=parsed.query, sformat="urlencoded") self.consumer.complete(_state) result = self.consumer.get_user_info(_state) assert isinstance(result, OpenIDSchema) assert _eq(result.keys(), ["name", "email", "verified", "nickname", "sub"]) def test_get_userinfo_claims(self): _state = "state0" args = { "client_id": self.consumer.client_id, "response_type": "code", "scope": ["openid"], } location = "https://example.com/cb?code=code&state=state0" with responses.RequestsMock() as rsps: rsps.add( responses.GET, "https://example.com/authorization", status=302, headers={"location": location}, ) rsps.add( responses.POST, "https://example.com/token", content_type="application/json", json={ "access_token": "some_token", "token_type": "bearer", "state": "state0", "scope": "openid", }, ) rsps.add( responses.POST, "https://example.com/userinfo", content_type="application/json", json={ "name": "Ilja", "sub": "some_sub", "email": "*****@*****.**", "nickname": "Ilja", "verified": True, }, ) result = self.consumer.do_authorization_request(state=_state, request_args=args) parsed = urlparse(result.headers["location"]) self.consumer.parse_response(AuthorizationResponse, info=parsed.query, sformat="urlencoded") response = self.consumer.complete(_state) result = self.consumer.get_userinfo_claims( response["access_token"], self.consumer.userinfo_endpoint, # type: ignore ) assert isinstance(result, OpenIDSchema) assert _eq(result.keys(), ["name", "email", "verified", "nickname", "sub"]) def real_test_discover(self): c = Consumer(None, None) principal = "*****@*****.**" res = c.discover(principal) assert isinstance(res, ProviderConfigurationResponse) assert _eq( res.keys(), [ "registration_endpoint", "scopes_supported", "identifiers_supported", "token_endpoint", "flows_supported", "version", "userinfo_endpoint", "authorization_endpoint", "x509_url", "issuer", ], ) assert res.version == "3.0" # type: ignore assert _eq( res.flows_supported, # type: ignore [ "code", "token", "id_token", "code token", "code id_token", "id_token token", ], ) def test_discover(self): c = Consumer(None, None) webfinger = { "subject": "acct:[email protected]", "links": [{ "rel": "http://openid.net/specs/connect/1.0/issuer", "href": "https://*****:*****@example.com" with responses.RequestsMock() as rsps: rsps.add( responses.GET, "https://example.com/.well-known/webfinger" "?resource=acct%3Afoo%40example.com&rel=http%3A%2F%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer", json=webfinger, ) res = c.discover(principal) assert res == "https://localhost:8088/" def test_client_register(self): c = Consumer(None, None) c.redirect_uris = ["https://example.com/authz"] reg_resp = { "client_id": "some_client", "client_secret": "super_secret", "client_secret_expires_at": 123456789, "redirect_uris": ["https://example.com/authz"], } with responses.RequestsMock() as rsps: rsps.add(responses.POST, "https://example.com/register/", json=reg_resp) c.register("https://example.com/register/") assert json.loads(rsps.calls[0].request.body) == { "application_type": "web", "response_types": ["code"], "redirect_uris": ["https://example.com/authz"], "grant_types": ["authorization_code"], } assert c.client_id == "some_client" assert c.client_secret == "super_secret" assert c.registration_expires == 123456789 def test_client_register_token(self): c = Consumer(None, None) c.redirect_uris = ["https://example.com/authz"] client_info = { "client_id": "clientid", "redirect_uris": ["https://example.com/authz"], } with responses.RequestsMock() as rsps: rsps.add( rsps.POST, "https://provider.example.com/registration/", json=client_info, ) c.register( "https://provider.example.com/registration/", registration_token="initial_registration_token", ) header = rsps.calls[0].request.headers["Authorization"] assert header == "Bearer aW5pdGlhbF9yZWdpc3RyYXRpb25fdG9rZW4=" def test_client_register_token_b64(self): c = Consumer(None, None) c.redirect_uris = ["https://example.com/authz"] client_info = { "client_id": "clientid", "redirect_uris": ["https://example.com/authz"], } registration_token = ( "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6IC" "JlYjc1N2M3Yy00MWRlLTRmZDYtOTkwNy1hNGFiMDY1ZjEzMmEifQ.eyJqdGkiOiI2ZWY0MDZi" "MC02YzA3LTQ0NzctOWU1YS1hY2FiZjNiMWNiMjgiLCJleHAiOjAsIm5iZiI6MCwiaWF0Ijox" "NTczNzMxNjg5LCJpc3MiOiJodHRwczovL29wZW5pZC1wcm92aWRlci5leGFtcGxlLmNvbS9h" "dXRoL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOiJodHRwczovL29wZW5pZC1wcm92aWRlci5leGFt" "cGxlLmNvbS9hdXRoL3JlYWxtcy9tYXN0ZXIiLCJ0eXAiOiJJbml0aWFsQWNjZXNzVG9rZW4i" "fQ.0XTlit_JcxPZeIy8A4BzrHn1NvegVP7ws8KI0ySFex8") with responses.RequestsMock() as rsps: rsps.add( rsps.POST, "https://provider.example.com/registration/", json=client_info, ) c.register( "https://provider.example.com/registration/", registration_token=registration_token, ) header = rsps.calls[0].request.headers["Authorization"] assert header == "Bearer " + registration_token def _faulty_id_token(self): idval = { "nonce": "KUEYfRM2VzKDaaKD", "sub": "EndUserSubject", "iss": "https://alpha.cloud.nds.rub.de", "exp": 1420823073, "iat": 1420822473, "aud": "TestClient", } idts = IdToken(**idval) _signed_jwt = idts.to_jwt(key=[SYMKey(key="TestPassword")], algorithm="HS256") # Mess with the signed id_token p = _signed_jwt.split(".") p[2] = "aaa" return ".".join(p) def test_faulty_id_token(self): _faulty_signed_jwt = self._faulty_id_token() with pytest.raises(BadSignature): IdToken().from_jwt(_faulty_signed_jwt, key=[SYMKey(key="TestPassword")]) # What if no verification key is given ? # Should also result in an exception with pytest.raises(MissingSigningKey): IdToken().from_jwt(_faulty_signed_jwt) def test_faulty_id_token_in_access_token_response(self): c = Consumer(None, None) c.keyjar.add_symmetric("", "TestPassword", ["sig"]) _info = { "access_token": "accessTok", "id_token": self._faulty_id_token(), "token_type": "Bearer", } _json = json.dumps(_info) with pytest.raises(ValueError): c.parse_response(AccessTokenResponse, _json, sformat="json") def test_faulty_idtoken_from_accesstoken_endpoint(self): _state = "state0" self.consumer.consumer_config["response_type"] = ["id_token"] args = { "client_id": self.consumer.client_id, "response_type": self.consumer.consumer_config["response_type"], "scope": ["openid"], } location = ( "https://example.com/cb?state=state0&id_token=eyJhbGciOiJSUzI1NiJ9" ".eyJpc3MiOiAiaHR0cDovL2xvY2FsaG9zdDo4MDg4IiwgInN1YiI6ICJhNWRkMjRiMmYwOGE2ODZmZDM4NmMyMmM" "zZmY4ZWUyODFlZjJmYmZmMWZkZTcwMDg2NjhjZGEzZGVjZmE0NjY5IiwgImF1ZCI6IFsiY2xpZW50XzEiXSwgImV" "4cCI6IDE1NzIwOTk5NjAsICJhY3IiOiAiMiIsICJpYXQiOiAxNTcyMDEzNTYwLCAibm9uY2UiOiAibmdFTGZVdmN" "PMWoyaXNWcXkwQWNwM0NOYlZnMGdFRDEifQ.aaa") with responses.RequestsMock() as rsps: rsps.add( responses.GET, "https://example.com/authorization", status=302, headers={"location": location}, ) result = self.consumer.do_authorization_request(state=_state, request_args=args) self.consumer._backup("state0") assert result.status_code == 302 query = urlparse(result.headers["location"]).query with pytest.raises(BadSignature): self.consumer.parse_authz(query=query) def test_get_session_management_id(self): now = utc_time_sans_frac() smid = "session_management_id" idval = { "nonce": "KUEYfRM2VzKDaaKD", "sub": "EndUserSubject", "iss": "https://example.com", "exp": now + 3600, "iat": now, "aud": self.consumer.client_id, "sid": smid, } idts = IdToken(**idval) _signed_jwt = idts.to_jwt(key=KC_RSA.keys(), algorithm="RS256") _state = "state" self.consumer.sdb[_state] = { "redirect_uris": ["https://example.org/cb"] } resp = AuthorizationResponse(id_token=_signed_jwt, state=_state) self.consumer.consumer_config["response_type"] = ["id_token"] self.consumer.parse_authz(resp.to_urlencoded()) assert self.consumer.sso_db["state"]["smid"] == smid assert session_get(self.consumer.sso_db, "smid", smid) == [_state]
class TestOICConsumer: @pytest.fixture(autouse=True) def setup_consumer(self, session_db_factory): client_id = "client_1" client_config = { "client_id": client_id, "client_authn_method": CLIENT_AUTHN_METHOD, } self.consumer = Consumer( session_db_factory(SERVER_INFO["issuer"]), CONFIG, client_config, SERVER_INFO, ) self.consumer.behaviour = { "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"] } self.consumer.keyjar = CLIKEYS self.consumer.redirect_uris = ["https://example.com/cb"] self.consumer.authorization_endpoint = "https://example.com/authorization" self.consumer.token_endpoint = "https://example.com/token" self.consumer.userinfo_endpoint = "https://example.com/userinfo" self.consumer.client_secret = "hemlig" self.consumer.secret_type = "basic" def test_backup_keys(self): keys = self.consumer.__dict__.keys() _dict = self.consumer.dictionary() dkeys = [key for key in keys if key not in _dict.keys()] assert _eq(dkeys, IGNORE) def test_backup_restore(self): authz_org_url = "http://example.org/authorization" _dict = sorted(list(self.consumer.__dict__.items())) self.consumer._backup("sid") self.consumer.restore("sid") assert sorted(_dict) == sorted(list(self.consumer.__dict__.items())) self.consumer.authorization_endpoint = authz_org_url assert _dict != sorted(list(self.consumer.__dict__.items())) self.consumer.restore("sid") assert _dict == sorted(list(self.consumer.__dict__.items())) def test_backup_restore_update(self): authz_org_url = "http://example.org/authorization" self.consumer._backup("sid") self.consumer.authorization_endpoint = authz_org_url self.consumer.token_endpoint = "https://example.org/token" self.consumer.userinfo_endpoint = "" assert self.consumer.authorization_endpoint == authz_org_url assert self.consumer.token_endpoint == "https://example.org/token" assert self.consumer.userinfo_endpoint == "" self.consumer.update("sid") assert self.consumer.authorization_endpoint == authz_org_url assert self.consumer.token_endpoint == "https://example.org/token" assert self.consumer.userinfo_endpoint == "https://example.com/userinfo" def test_begin(self): srv = Server() srv.keyjar = SRVKEYS sid, location = self.consumer.begin("openid", "code") authreq = srv.parse_authorization_request(url=location) assert _eq( list(authreq.keys()), [ "state", "max_age", "claims", "response_type", "client_id", "scope", "redirect_uri", ], ) assert authreq["state"] == sid assert authreq["scope"] == self.consumer.consumer_config["scope"] assert authreq["client_id"] == self.consumer.client_id def test_begin_file(self, tmpdir): path = tmpdir.strpath external_path = "/exported" self.consumer.consumer_config["request_method"] = "file" self.consumer.consumer_config["temp_dir"] = path self.consumer.consumer_config["temp_path"] = external_path self.consumer.consumer_config["authz_page"] = "/authz" srv = Server() srv.keyjar = SRVKEYS sid, location = self.consumer.begin( "openid", "code", path="http://*****:*****@example.com", "nickname": "Ilja", "verified": True, }, ) result = self.consumer.do_authorization_request( state=_state, request_args=args ) parsed = urlparse(result.headers["location"]) self.consumer.parse_response( AuthorizationResponse, info=parsed.query, sformat="urlencoded" ) self.consumer.complete(_state) result = self.consumer.get_user_info(_state) assert isinstance(result, OpenIDSchema) assert _eq(result.keys(), ["name", "email", "verified", "nickname", "sub"]) def test_sign_userinfo(self): _state = "state0" self.consumer.client_prefs = {"userinfo_signed_response_alg": "RS256"} del self.consumer.consumer_config["request_method"] args = { "client_id": self.consumer.client_id, "response_type": "code", "scope": ["openid"], } location = "https://example.com/cb?code=code&state=state0" with responses.RequestsMock() as rsps: rsps.add( responses.GET, "https://example.com/authorization", status=302, headers={"location": location}, ) rsps.add( responses.POST, "https://example.com/token", content_type="application/json", json={ "access_token": "some_token", "token_type": "bearer", "state": "state0", "scope": "openid", }, ) rsps.add( responses.POST, "https://example.com/userinfo", content_type="application/json", json={ "name": "Ilja", "sub": "some_sub", "email": "*****@*****.**", "nickname": "Ilja", "verified": True, }, ) self.consumer.begin("openid", "code") result = self.consumer.do_authorization_request( state=_state, request_args=args ) parsed = urlparse(result.headers["location"]) self.consumer.parse_response( AuthorizationResponse, info=parsed.query, sformat="urlencoded" ) self.consumer.complete(_state) result = self.consumer.get_user_info(_state) assert isinstance(result, OpenIDSchema) assert _eq(result.keys(), ["name", "email", "verified", "nickname", "sub"]) def test_get_userinfo_claims(self): _state = "state0" args = { "client_id": self.consumer.client_id, "response_type": "code", "scope": ["openid"], } location = "https://example.com/cb?code=code&state=state0" with responses.RequestsMock() as rsps: rsps.add( responses.GET, "https://example.com/authorization", status=302, headers={"location": location}, ) rsps.add( responses.POST, "https://example.com/token", content_type="application/json", json={ "access_token": "some_token", "token_type": "bearer", "state": "state0", "scope": "openid", }, ) rsps.add( responses.POST, "https://example.com/userinfo", content_type="application/json", json={ "name": "Ilja", "sub": "some_sub", "email": "*****@*****.**", "nickname": "Ilja", "verified": True, }, ) result = self.consumer.do_authorization_request( state=_state, request_args=args ) parsed = urlparse(result.headers["location"]) self.consumer.parse_response( AuthorizationResponse, info=parsed.query, sformat="urlencoded" ) response = self.consumer.complete(_state) result = self.consumer.get_userinfo_claims( response["access_token"], self.consumer.userinfo_endpoint ) assert isinstance(result, OpenIDSchema) assert _eq(result.keys(), ["name", "email", "verified", "nickname", "sub"]) def real_test_discover(self): c = Consumer(None, None) principal = "*****@*****.**" res = c.discover(principal) assert isinstance(res, ProviderConfigurationResponse) assert _eq( res.keys(), [ "registration_endpoint", "scopes_supported", "identifiers_supported", "token_endpoint", "flows_supported", "version", "userinfo_endpoint", "authorization_endpoint", "x509_url", "issuer", ], ) assert res.version == "3.0" # type: ignore assert _eq( res.flows_supported, # type: ignore [ "code", "token", "id_token", "code token", "code id_token", "id_token token", ], ) def test_discover(self): c = Consumer(None, None) webfinger = { "subject": "acct:[email protected]", "links": [ { "rel": "http://openid.net/specs/connect/1.0/issuer", "href": "https://*****:*****@example.com" with responses.RequestsMock() as rsps: rsps.add( responses.GET, "https://example.com/.well-known/webfinger" "?resource=acct%3Afoo%40example.com&rel=http%3A%2F%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer", json=webfinger, ) res = c.discover(principal) assert res == "https://localhost:8088/" def test_client_register(self): c = Consumer(None, None) c.redirect_uris = ["https://example.com/authz"] reg_resp = { "client_id": "some_client", "client_secret": "super_secret", "client_secret_expires_at": 123456789, "redirect_uris": ["https://example.com/authz"], } with responses.RequestsMock() as rsps: rsps.add(responses.POST, "https://example.com/register/", json=reg_resp) c.register("https://example.com/register/") assert json.loads(rsps.calls[0].request.body) == { "application_type": "web", "response_types": ["code"], "redirect_uris": ["https://example.com/authz"], "grant_types": ["authorization_code"], } assert c.client_id == "some_client" assert c.client_secret == "super_secret" assert c.registration_expires == 123456789 def test_client_register_token(self): c = Consumer(None, None) c.redirect_uris = ["https://example.com/authz"] client_info = { "client_id": "clientid", "redirect_uris": ["https://example.com/authz"], } with responses.RequestsMock() as rsps: rsps.add( rsps.POST, "https://provider.example.com/registration/", json=client_info, ) c.register( "https://provider.example.com/registration/", registration_token="initial_registration_token", ) header = rsps.calls[0].request.headers["Authorization"] assert header == "Bearer aW5pdGlhbF9yZWdpc3RyYXRpb25fdG9rZW4=" def _faulty_id_token(self): idval = { "nonce": "KUEYfRM2VzKDaaKD", "sub": "EndUserSubject", "iss": "https://alpha.cloud.nds.rub.de", "exp": 1420823073, "iat": 1420822473, "aud": "TestClient", } idts = IdToken(**idval) _signed_jwt = idts.to_jwt(key=[SYMKey(key="TestPassword")], algorithm="HS256") # Mess with the signed id_token p = _signed_jwt.split(".") p[2] = "aaa" return ".".join(p) def test_faulty_id_token(self): _faulty_signed_jwt = self._faulty_id_token() with pytest.raises(BadSignature): IdToken().from_jwt(_faulty_signed_jwt, key=[SYMKey(key="TestPassword")]) # What if no verification key is given ? # Should also result in an exception with pytest.raises(MissingSigningKey): IdToken().from_jwt(_faulty_signed_jwt) def test_faulty_id_token_in_access_token_response(self): c = Consumer(None, None) c.keyjar.add_symmetric("", "TestPassword", ["sig"]) _info = { "access_token": "accessTok", "id_token": self._faulty_id_token(), "token_type": "Bearer", } _json = json.dumps(_info) with pytest.raises(ValueError): c.parse_response(AccessTokenResponse, _json, sformat="json") def test_faulty_idtoken_from_accesstoken_endpoint(self, mitm_server): mfos = mitm_server("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request _state = "state0" self.consumer.consumer_config["response_type"] = ["id_token"] args = { "client_id": self.consumer.client_id, "response_type": self.consumer.consumer_config["response_type"], "scope": ["openid"], } result = self.consumer.do_authorization_request(state=_state, request_args=args) self.consumer._backup("state0") assert result.status_code == 302 query = urlparse(result.headers["location"]).query with pytest.raises(BadSignature): self.consumer.parse_authz(query=query)