def create_sdb(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[""] = [kb] self.sdb = SessionDB( "https://example.com/", db=DictSessionBackend(), code_factory=DefaultToken("supersecret", "verybadpassword", typ="A", lifetime=600), token_factory=JWTToken( "T", keyjar=kj, lt_pattern={ "code": 3600, "token": 900 }, iss="https://example.com/as", sign_alg="RS256", ), refresh_token_factory=JWTToken( "R", keyjar=kj, lt_pattern={"": 24 * 3600}, iss="https://example.com/as", token_storage={}, ), )
def __init__(self, jwt_keys=None, name=""): Server.__init__(self, jwt_keys=jwt_keys) self.sdb = SessionDB() self.name = name self.client = {} self.registration_expires_in = 3600 self.host = ""
def test_token(): sdb = SessionDB() sid = sdb.token.key(areq=AREQ) assert len(sid) == 28 sdb = SessionDB({"a": "b"}) sid = sdb.token.key(areq=AREQ) assert len(sid) == 28
def __init__(self, name=""): Server.__init__(self) self.sdb = SessionDB() self.name = name self.client = {} self.registration_expires_in = 3600 self.host = "" self.webfinger = WebFinger()
def test_token(): sdb = SessionDB(BASE_URL) sid = sdb.token.key(areq=AREQ) assert len(sid) == 56 sdb = SessionDB(BASE_URL, {"a": "b"}) sid = sdb.token.key(areq=AREQ) assert len(sid) == 56
def test_type_and_key(): sdb = SessionDB() sid = sdb.token.key(areq=AREQ) code = sdb.token(sid=sid) print sid part = sdb.token.type_and_key(code) print part assert part[0] == "A" assert part[1] == sid
def test_type_and_key(): sdb = SessionDB(BASE_URL) sid = sdb.token.key(areq=AREQ) code = sdb.token(sid=sid) print sid part = sdb.token.type_and_key(code) print part assert part[0] == "A" assert part[1] == sid
def __init__(self, name=""): Server.__init__(self) self.sdb = SessionDB(name) self.name = name self.client = {} self.registration_expires_in = 3600 self.host = "" self.webfinger = WebFinger() self.userinfo_signed_response_alg = ""
def test_create_authz_session(): sdb = SessionDB() sid = sdb.create_authz_session("sub", AREQ) info = sdb[sid] print info assert info["oauth_state"] == "authz" sdb = SessionDB() # Missing nonce property sid = sdb.create_authz_session("sub", OAUTH2_AREQ) info = sdb[sid] print info assert info["oauth_state"] == "authz" sid2 = sdb.create_authz_session("sub", AREQN) info = sdb[sid2] print info assert info["nonce"] == "something" sid3 = sdb.create_authz_session("sub", AREQN, id_token="id_token") info = sdb[sid3] print info assert info["id_token"] == "id_token" sid4 = sdb.create_authz_session("sub", AREQN, oidreq=OIDR) info = sdb[sid4] print info assert "id_token" not in info assert "oidreq" in info
def test_sub_to_authn_event(): sdb = SessionDB(BASE_URL) ae2 = AuthnEvent("sub") sid = sdb.create_authz_session(ae2, AREQ) sub = sdb.do_sub(sid) # given the sub find out weather the authn event is still valid sids = sdb.sub2sid[sub] ae = sdb[sids[0]]["authn_event"] assert ae.valid()
def test_sub_to_authn_event(): sdb = SessionDB(BASE_URL) ae2 = AuthnEvent("sub", time_stamp=time.time()) sid = sdb.create_authz_session(ae2, AREQ) sub = sdb.do_sub(sid) # given the sub find out weather the authn event is still valid sids = sdb.get_sids_by_sub(sub) ae = sdb[sids[0]]["authn_event"] assert ae.valid()
def test_upgrade_to_token(): sdb = SessionDB() sid = sdb.create_authz_session("sub", AREQ) grant = sdb[sid]["code"] _dict = sdb.upgrade_to_token(grant) print _dict.keys() assert _eq(_dict.keys(), ['code', 'authzreq', 'token_type', 'local_sub', 'client_id', 'oauth_state', 'refresh_token', 'revoked', 'sub', 'access_token', 'token_expires_at', 'expires_in', 'state', 'redirect_uri', 'code_used', 'scope', 'access_token_scope']) raises(Exception, 'sdb.upgrade_to_token(grant)') raises(Exception, 'sdb.upgrade_to_token(_dict["access_token"]') sdb = SessionDB() sid = sdb.create_authz_session("another_user_id", AREQ) grant = sdb[sid]["code"] _dict = sdb.upgrade_to_token(grant, id_token="id_token", oidreq=OIDR) print _dict.keys() assert _eq(_dict.keys(), ['code', 'authzreq', 'id_token', 'token_type', 'local_sub', 'client_id', 'oauth_state', 'refresh_token', 'revoked', 'sub', 'oidreq', 'access_token', 'token_expires_at', 'expires_in', 'state', 'redirect_uri', 'code_used', 'scope', 'access_token_scope']) assert _dict["id_token"] == "id_token" assert _dict["oidreq"].type() == "OpenIDRequest" _ = _dict["access_token"] raises(Exception, 'sdb.upgrade_to_token(token)')
def test_setitem(): sdb = SessionDB() sid = sdb.token.key(areq=AREQ) code = sdb.token(sid=sid) sdb[sid] = {"indo": "china"} info = sdb[sid] assert info == {"indo": "china"} info = sdb[code] assert info == {"indo": "china"} raises(KeyError, 'sdb["abcdefghijklmnop"]')
def test_new_token(): sdb = SessionDB(BASE_URL) sid = sdb.token.key(areq=AREQ) assert len(sid) == 56 code2 = sdb.token('T', sid=sid) assert len(sid) == 56 code3 = sdb.token(ttype="", prev=code2) assert code2 != code3 sid2 = sdb.token.key(areq=AREQ, user="******") assert len(sid2) == 56 assert sid != sid2
def test_new_token(): sdb = SessionDB() sid = sdb.token.key(areq=AREQ) assert len(sid) == 28 code2 = sdb.token('T', sid=sid) assert len(sid) == 28 code3 = sdb.token(ttype="", prev=code2) assert code2 != code3 sid2 = sdb.token.key(areq=AREQ, user="******") assert len(sid2) == 28 assert sid != sid2
def test_setitem(): sdb = SessionDB(BASE_URL) sid = sdb.token.key(areq=AREQ) code = sdb.token(sid=sid) sdb[sid] = {"indo": "china"} info = sdb[sid] assert info == {"indo": "china"} info = sdb[code] assert info == {"indo": "china"} raises(KeyError, 'sdb["abcdefghijklmnop"]')
def test_session_state_in_auth_req_for_session_support(self): provider = Provider(SERVER_INFO["issuer"], SessionDB(SERVER_INFO["issuer"]), CDB, AUTHN_BROKER, USERINFO, AUTHZ, verify_client, SYMKEY, urlmap=URLMAP, keyjar=KEYJAR) provider.capabilities.update( {"check_session_iframe": "https://op.example.com/check_session"}) req_args = { "scope": ["openid"], "redirect_uri": "http://localhost:8087/authz", "response_type": ["code"], "client_id": "number5" } areq = AuthorizationRequest(**req_args) resp = provider.authorization_endpoint(request=areq.to_urlencoded()) aresp = self.cons.parse_response(AuthorizationResponse, resp.message, sformat="urlencoded") assert "session_state" in aresp
def test_refresh_token(): sdb = SessionDB() sid = sdb.create_authz_session("sub", AREQ) grant = sdb[sid]["code"] _dict = sdb.upgrade_to_token(grant) dict1 = _dict.copy() rtoken = _dict["refresh_token"] time.sleep(1) dict2 = sdb.refresh_token(rtoken) print dict2 assert dict1["token_expires_at"] != dict2["token_expires_at"] assert dict1["access_token"] != dict2["access_token"] raises(Exception, 'sdb.refresh_token(dict2["access_token"])')
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://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request
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_srv2(): cc = ClaimsClient(client_id="client_1") cc.client_secret = "hemlig" req = cc.construct_UserClaimsRequest( request_args={ "sub": "diana", "claims_names": ["gender", "birthdate"] }) srv = ClaimsServer("pyoicserv", SessionDB(), CDB, USERINFO, verify_client, keyjar=KEYJAR, dist_claims_mode=ClaimsMode(USER2MODE)) srv.keyjar[""] = keybundle_from_local_file("rsa.key", "rsa", ["ver", "sig"]) assert srv resp = srv.claims_endpoint(req.to_urlencoded(), "") print resp.message ucr = UserClaimsResponse().deserialize(resp.message, "json") ucr.verify(keyjar=srv.keyjar) print ucr assert _eq(ucr["claims_names"], ["gender", "birthdate"]) assert "jwt" in ucr
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_faulty_idtoken_from_accesstoken_endpoint(): consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, CLIENT_CONFIG, SERVER_INFO) consumer.keyjar = CLIKEYS mfos = MITMServer("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.client_secret = "hemlig" consumer.secret_type = "basic" consumer.config["response_type"] = ["id_token"] args = { "client_id": consumer.client_id, "response_type": consumer.config["response_type"], "scope": ["openid"], } result = consumer.do_authorization_request(state=_state, request_args=args) consumer._backup("state0") assert result.status_code == 302 # assert result.location.startswith(consumer.redirect_uri[0]) _, query = result.headers["location"].split("?") print query try: consumer.parse_authz(query=query) except BadSignature: pass else: assert False
def test_refresh_token(): sdb = SessionDB() sid = sdb.create_authz_session("user_id", AREQ) grant = sdb[sid]["code"] _dict = sdb.update_to_token(grant) dict1 = _dict.copy() rtoken = _dict["refresh_token"] time.sleep(1) dict2 = sdb.refresh_token(rtoken) print dict2 assert dict1["issued"] != dict2["issued"] assert dict1["access_token"] != dict2["access_token"] raises(Exception, 'sdb.refresh_token(dict2["access_token"])')
def create_provider(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[''] = [kb] _sdb = SessionDB("https://example.com/", db={}, code_factory=DefaultToken('supersecret', 'verybadpassword', typ='A', lifetime=600), token_factory=JWTToken('T', keyjar=kj, lt_pattern={ 'code': 3600, 'token': 900 }, iss='https://example.com/as', sign_alg='RS256'), refresh_token_factory=JWTToken( 'R', keyjar=kj, lt_pattern={'': 24 * 3600}, iss='https://example.com/as')) # name, sdb, cdb, authn_broker, authz, client_authn, self.provider = Provider("as", _sdb, CDB, AUTHN_BROKER, AUTHZ, verify_client, baseurl='https://example.com/as')
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_refresh_token(): sdb = SessionDB(BASE_URL) ae = AuthnEvent("sub") sid = sdb.create_authz_session(ae, AREQ) grant = sdb[sid]["code"] _dict = sdb.upgrade_to_token(grant) dict1 = _dict.copy() rtoken = _dict["refresh_token"] time.sleep(1) dict2 = sdb.refresh_token(rtoken) print dict2 assert dict1["token_expires_at"] != dict2["token_expires_at"] assert dict1["access_token"] != dict2["access_token"] raises(Exception, 'sdb.refresh_token(dict2["access_token"])')
def __init__(self, db, base_url, instance=None, refresh_db=None, refresh_token_expires_in=86400, token_factory=None, code_factory=None, refresh_token_factory=None): SSIXADBBase.__init__(self, db) SessionDBBase.__init__(self, base_url, self, refresh_db, refresh_token_expires_in, token_factory, code_factory, refresh_token_factory) self.instance = instance # Overwrite uid2sid store self.uid2sid = UidToSidDB(db, self.instance)
def test_create_authz_session(): sdb = SessionDB() sid = sdb.create_authz_session("user_id", AREQ) info = sdb[sid] print info assert info["oauth_state"] == "authz" sdb = SessionDB() # Missing nonce property sid = sdb.create_authz_session("user_id", OAUTH2_AREQ) info = sdb[sid] print info assert info["oauth_state"] == "authz" sid2 = sdb.create_authz_session("user_id", AREQN) info = sdb[sid2] print info assert info["nonce"] == "something" sid3 = sdb.create_authz_session("user_id", AREQN, id_token="id_token") info = sdb[sid3] print info assert info["id_token"] == "id_token" sid4 = sdb.create_authz_session("user_id", AREQN, oidreq=OIDR) info = sdb[sid4] print info assert "id_token" not in info assert "oidreq" in info
def test_server_authorization_endpoint_id_token(): provider = provider_init bib = { "scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code", "id_token"], "client_id": "a1b2c3", "nonce": "Nonce", "prompt": ["none"] } req = AuthorizationRequest(**bib) AREQ = AuthorizationRequest(response_type="code", client_id="client_1", redirect_uri="http://example.com/authz", scope=["openid"], state="state000") sdb = SessionDB() sid = sdb.create_authz_session("userX", AREQ) _info = sdb[sid] _user_info = IdToken(iss="https://foo.example.om", sub="foo", aud=bib["client_id"], exp=epoch_in_a_while(minutes=10), acr="2", nonce=bib["nonce"]) print provider.keyjar.issuer_keys print _user_info.to_dict() idt = provider.id_token_as_signed_jwt(_info, access_token="access_token", user_info=_user_info) req["id_token"] = idt QUERY_STRING = req.to_urlencoded() resp = provider.authorization_endpoint(request=QUERY_STRING) print resp assert "error=login_required" in resp.message
def test_create_authz_session_with_sector_id(): sdb = SessionDB(seed="foo") sid5 = sdb.create_authz_session("user_id", AREQN, oidreq=OIDR, sector_id="http://example.com/") info_1 = sdb[sid5] print info_1 assert "id_token" not in info_1 assert "oidreq" in info_1 assert info_1["user_id"] != "user_id" sid6 = sdb.create_authz_session("user_id", AREQN, oidreq=OIDR, sector_id="http://example.org/") info_2 = sdb[sid6] print info_2 assert info_2["user_id"] != "user_id" assert info_2["user_id"] != info_1["user_id"]
def create_claims_server(self, keyjar): self.srv = ClaimsServer("pyoicserv", SessionDB("https://example.com"), TestClaimsServer.CDB, UserInfo(USERDB), verify_client, keyjar=keyjar, dist_claims_mode=ClaimsMode( TestClaimsServer.USER2MODE))
def test_provider_key_setup(): provider = Provider("pyoicserv", SessionDB(SERVER_INFO["issuer"]), None, None, None, None, None, "") provider.baseurl = "http://www.example.com/" provider.key_setup("static", sig={"format": "jwk", "alg": "RSA"}) keys = provider.keyjar.get_signing_key("RSA") assert len(keys) == 1 assert provider.jwks_uri == "http://www.example.com/static/jwks"
def setup_op(self, oper_id, test_id, com_args, op_arg, test_conf, events): op = self.provider_cls(sdb=SessionDB(com_args["baseurl"]), **com_args) op.events = events op.oper_id = oper_id op.test_id = test_id for _authn in com_args["authn_broker"]: _authn.srv = op for key, val in list(op_arg.items()): if key == 'keyjar': init_keyjar(op, val, com_args) else: setattr(op, key, val) write_jwks_uri(op, op_arg, self.folder) if op.baseurl.endswith("/"): div = "" else: div = "/" op.name = op.baseurl = "{}{}{}/{}".format(op.baseurl, div, oper_id, test_id) _tc = test_conf[test_id] if not _tc: raise UnknownTestID(test_id) try: _capa = _tc['capabilities'] except KeyError: pass else: op.capabilities.update(_capa) # update jwx for _typ in ["signing_alg", "encryption_alg", "encryption_enc"]: for item in ["id_token", "userinfo"]: cap_param = '{}_{}_values_supported'.format(item, _typ) try: op.jwx_def[_typ][item] = _capa[cap_param][0] except KeyError: pass try: op.claims_type = _tc["claims"] except KeyError: pass try: op.behavior_type = _tc["behavior"] op.server.behavior_type = _tc["behavior"] except KeyError: pass return op
def create_sdb(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[''] = [kb] self.sdb = SessionDB( "https://example.com/", token_factory=JWTToken('T', keyjar=kj, lt_pattern={ 'code': 3600, 'token': 900 }, iss='https://example.com/as', sign_alg='RS256'), refresh_token_factory=JWTToken('R', keyjar=kj, lt_pattern={'': 24 * 3600}, iss='https://example.com/as'))
def test_provider_key_setup(self, tmpdir): path = tmpdir.strpath provider = Provider("pyoicserv", SessionDB(SERVER_INFO["issuer"]), None, None, None, None, None, "") provider.baseurl = "http://www.example.com" provider.key_setup(path, path, sig={"format": "jwk", "alg": "RSA"}) keys = provider.keyjar.get_signing_key("RSA") assert len(keys) == 1 assert provider.jwks_uri == "http://www.example.com/{}/jwks".format( path)
def create_sdb(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[""] = [kb] self.sdb = SessionDB( "https://example.com/", token_factory=JWTToken( "T", keyjar=kj, lifetime={"code": 3600, "token": 900}, iss="https://example.com/as", sign_alg="RS256" ), refresh_token_factory=JWTToken("R", keyjar=kj, lifetime={"": 24 * 3600}, iss="https://example.com/as"), )
def provider(): issuer = "https://op.foo.com" client_db = {} session_db = SessionDB(issuer), verification_function = verify_client authz_handler = AuthzHandling() symkey = None user_info_store = None authn_broker = None return Provider(issuer, session_db, client_db, authn_broker, user_info_store, authz_handler, verification_function, symkey)
def create_sdb(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[''] = [kb] self.sdb = SessionDB( "https://example.com/", token_factory=JWTToken('T', {'code': 3600, 'token': 900}, 'https://example.com/as', 'RS256', kj), refresh_token_factory=JWTToken( 'R', {'': 24*3600}, 'https://example.com/as', 'RS256', kj) )
def test_server_authorization_endpoint_id_token(): provider = provider_init bib = {"scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code", "id_token"], "client_id": "a1b2c3", "nonce": "Nonce", "prompt": ["none"]} req = AuthorizationRequest(**bib) AREQ = AuthorizationRequest(response_type="code", client_id="client_1", redirect_uri="http://example.com/authz", scope=["openid"], state="state000") sdb = SessionDB() sid = sdb.create_authz_session("username", AREQ) _info = sdb[sid] _user_info = IdToken(iss="https://foo.example.om", sub="foo", aud=bib["client_id"], exp=epoch_in_a_while(minutes=10), acr="2", nonce=bib["nonce"]) print provider.keyjar.issuer_keys print _user_info.to_dict() idt = provider.id_token_as_signed_jwt(_info, access_token="access_token", user_info=_user_info) req["id_token"] = idt environ = BASE_ENVIRON.copy() environ["QUERY_STRING"] = req.to_urlencoded() resp = provider.authorization_endpoint(environ, start_response) print resp line = resp[0] assert "error=login_required" in line
def test_update_to_token(): sdb = SessionDB() sid = sdb.create_authz_session("user_id", AREQ) grant = sdb[sid]["code"] _dict = sdb.update_to_token(grant) print _dict.keys() assert _eq(_dict.keys(), ['code', 'authzreq', 'token_type', 'local_sub', 'client_id', 'oauth_state', 'refresh_token', 'revoked', 'sub', 'access_token', 'token_expires_at', 'expires_in', 'state', 'redirect_uri', 'code_used', 'scope', 'access_token_scope']) raises(Exception, 'sdb.update_to_token(grant)') raises(Exception, 'sdb.update_to_token(_dict["access_token"]') sdb = SessionDB() sid = sdb.create_authz_session("another_user_id", AREQ) grant = sdb[sid]["code"] _dict = sdb.update_to_token(grant, id_token="id_token", oidreq=OIDR) print _dict.keys() assert _eq(_dict.keys(), ['code', 'authzreq', 'id_token', 'token_type', 'local_sub', 'client_id', 'oauth_state', 'refresh_token', 'revoked', 'sub', 'oidreq', 'access_token', 'token_expires_at', 'expires_in', 'state', 'redirect_uri', 'code_used', 'scope', 'access_token_scope']) assert _dict["id_token"] == "id_token" assert _dict["oidreq"].type() == "OpenIDRequest" _ = _dict["access_token"] raises(Exception, 'sdb.update_to_token(token)')
def main(base, cookie_handler): as_conf = { "version": "1.0", "issuer": base, "pat_profiles_supported": ["bearer"], "aat_profiles_supported": ["bearer"], "rpt_profiles_supported": ["bearer"], "pat_grant_types_supported": ["authorization_code"], "aat_grant_types_supported": ["authorization_code"], "claim_profiles_supported": ["openid"], #"dynamic_client_endpoint": "%s/dynamic_client_endpoint" % BASE, #"token_endpoint": "%s/token_endpoint" % BASE, #"user_endpoint": "%s/user_endpoint" % BASE, #"resource_set_registration_endpoint": "%s/rsr_endpoint" % BASE, #"introspection_endpoint": "%s/introspection_endpoint" % BASE, #"permission_registration_endpoint": "%s/pr_endpoint" % BASE, #"rpt_endpoint": "%s/rpt_endpoint" % BASE, #"authorization_request_endpoint": "%s/ar_endpoint" % BASE, #"userinfo_endpoint": "%s/user_info_endpoint" % BASE # ------------ The OIDC provider config ----------------------- } base_url = "http://%s" % socket.gethostname() ab = AuthnBroker() ab.add("linda", DummyAuthn(None, "linda")) #AB.add("hans", DummyAuthn(None, "*****@*****.**")) ab.add( "UserPwd", UsernamePasswordMako(None, "login2.mako", LOOKUP, PASSWD, "%s/authorization" % base), 10, base_url) ab.add("BasicAuthn", BasicAuthnExtra(None, PASSWD), 10, base_url) AUTHZSRV = authzsrv.OidcDynRegUmaAS(base, SessionDB(base_url), CDB, ab, USERINFO, AUTHZ, verify_client, "1234567890", keyjar=None, configuration=as_conf, base_url=base) cookie_handler.init_srv(AUTHZSRV) jwks = keyjar_init(AUTHZSRV, KEYS, "a%d") fp = open("static/jwk_as.json", "w") fp.write(json.dumps(jwks)) fp.close() return AUTHZSRV
def create_sdb(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[''] = [kb] self.sdb = SessionDB( "https://example.com/", token_factory=JWTToken('T', keyjar=kj, lt_pattern={'code': 3600, 'token': 900}, iss='https://example.com/as', sign_alg='RS256'), refresh_token_factory=JWTToken( 'R', keyjar=kj, lt_pattern={'': 24 * 3600}, iss='https://example.com/as') )
def create_sdb(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[''] = [kb] self.sdb = SessionDB( "https://example.com/", db={}, code_factory=DefaultToken( 'supersecret', 'verybadpassword', typ='A', lifetime=600), token_factory=JWTToken('T', keyjar=kj, lt_pattern={'code': 3600, 'token': 900}, iss='https://example.com/as', sign_alg='RS256'), refresh_token_factory=JWTToken( 'R', keyjar=kj, lt_pattern={'': 24 * 3600}, iss='https://example.com/as') )
def test_create_authz_session(): sdb = SessionDB(BASE_URL) ae = AuthnEvent("uid") sid = sdb.create_authz_session(ae, AREQ) sdb.do_sub(sid) info = sdb[sid] print info assert info["oauth_state"] == "authz" sdb = SessionDB(BASE_URL) ae = AuthnEvent("sub") # Missing nonce property sid = sdb.create_authz_session(ae, OAUTH2_AREQ) info = sdb[sid] print info assert info["oauth_state"] == "authz" ae = AuthnEvent("sub") sid2 = sdb.create_authz_session(ae, AREQN) info = sdb[sid2] print info assert info["nonce"] == "something" sid3 = sdb.create_authz_session(ae, AREQN, id_token="id_token") info = sdb[sid3] print info assert info["id_token"] == "id_token" sid4 = sdb.create_authz_session(ae, AREQN, oidreq=OIDR) info = sdb[sid4] print info assert "id_token" not in info assert "oidreq" in info
def test_create_authz_session_with_sector_id(): sdb = SessionDB(BASE_URL, seed="foo") ae = AuthnEvent("sub") sid5 = sdb.create_authz_session(ae, AREQN, oidreq=OIDR) sdb.do_sub(sid5, "http://example.com/si.jwt", "pairwise") info_1 = sdb[sid5] print info_1 assert "id_token" not in info_1 assert "oidreq" in info_1 assert info_1["sub"] != "sub" user_id1 = info_1["sub"] sdb.do_sub(sid5, "http://example.net/si.jwt", "pairwise") info_2 = sdb[sid5] print info_2 assert info_2["sub"] != "sub" assert info_2["sub"] != user_id1
def test_create_authz_session_with_sector_id(): sdb = SessionDB(seed="foo") uid = "user_id" sid5 = sdb.create_authz_session(uid, AREQN, oidreq=OIDR) sdb.do_userid(sid5, uid, "http://example.com/si.jwt", "pairwise") info_1 = sdb[sid5] print info_1 assert "id_token" not in info_1 assert "oidreq" in info_1 assert info_1["sub"] != "user_id" user_id1 = info_1["sub"] sdb.do_userid(sid5, uid, "http://example.net/si.jwt", "pairwise") info_2 = sdb[sid5] print info_2 assert info_2["sub"] != "user_id" assert info_2["sub"] != user_id1
def test_update(): sdb = SessionDB() sid = sdb.token.key(areq=AREQ) code = sdb.token(sid=sid) raises(KeyError, 'sdb.update(sid, "indo", "nebue")') raises(KeyError, 'sdb.update(code, "indo", "nebue")') sdb[sid] = {"indo": "china"} sdb.update(sid, "indo", "nebue") sdb.update(code, "indo", "second") raises(KeyError, 'sdb.update("abcdefghijklmnop", "indo", "bar")') #noinspection PyUnusedLocal sid2 = sdb.token.key(areq=AREQ) raises(KeyError, 'sdb.update(sid2, "indo", "bar")')
def create_sdb(self): self.sdb = SessionDB("https://example.com/")
class TestSessionDB(object): @pytest.fixture(autouse=True) def create_sdb(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[''] = [kb] self.sdb = SessionDB( "https://example.com/", token_factory=JWTToken('T', keyjar=kj, lt_pattern={'code': 3600, 'token': 900}, iss='https://example.com/as', sign_alg='RS256'), refresh_token_factory=JWTToken( 'R', keyjar=kj, lt_pattern={'': 24 * 3600}, iss='https://example.com/as') ) def test_create_authz_session(self): ae = AuthnEvent("uid", "salt") sid = self.sdb.create_authz_session(ae, AREQ) self.sdb.do_sub(sid, "client_salt") info = self.sdb[sid] assert info["oauth_state"] == "authz" def test_create_authz_session_without_nonce(self): ae = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae, AREQ) info = self.sdb[sid] assert info["oauth_state"] == "authz" def test_create_authz_session_with_nonce(self): ae = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae, AREQN) info = self.sdb[sid] assert info["nonce"] == "something" def test_create_authz_session_with_id_token(self): ae = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae, AREQN, id_token="id_token") info = self.sdb[sid] assert info["id_token"] == "id_token" def test_create_authz_session_with_oidreq(self): ae = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae, AREQN, oidreq=OIDR) info = self.sdb[sid] assert "id_token" not in info assert "oidreq" in info def test_create_authz_session_with_sector_id(self): ae = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae, AREQN, oidreq=OIDR) self.sdb.do_sub(sid, "client_salt", "http://example.com/si.jwt", "pairwise") info_1 = self.sdb[sid].copy() assert "id_token" not in info_1 assert "oidreq" in info_1 assert info_1["sub"] != "sub" self.sdb.do_sub(sid, "client_salt", "http://example.net/si.jwt", "pairwise") info_2 = self.sdb[sid] assert info_2["sub"] != "sub" assert info_2["sub"] != info_1["sub"] def test_upgrade_to_token(self): ae1 = AuthnEvent("uid", "salt") sid = self.sdb.create_authz_session(ae1, AREQ) self.sdb[sid]['sub'] = 'sub' grant = self.sdb[sid]["code"] _dict = self.sdb.upgrade_to_token(grant) #print(_dict.keys()) assert _eq(list(_dict.keys()), ['authn_event', 'code', 'authzreq', 'revoked', 'access_token', 'token_type', 'state', 'redirect_uri', 'code_used', 'client_id', 'scope', 'oauth_state', 'access_token_scope', 'sub', 'response_type']) # can't update again with pytest.raises(AccessCodeUsed): self.sdb.upgrade_to_token(grant) self.sdb.upgrade_to_token(_dict["access_token"]) def test_upgrade_to_token_refresh(self): ae1 = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae1, AREQO) self.sdb.do_sub(sid, ae1.salt) grant = self.sdb[sid]["code"] _dict = self.sdb.upgrade_to_token(grant, issue_refresh=True) #print(_dict.keys()) assert _eq(_dict.keys(), ['authn_event', 'code', 'authzreq', 'revoked', 'access_token', 'response_type', 'token_type', 'state', 'redirect_uri', 'code_used', 'client_id', 'scope', 'oauth_state', 'access_token_scope', 'refresh_token', 'sub']) # can't update again with pytest.raises(AccessCodeUsed): self.sdb.upgrade_to_token(grant) self.sdb.upgrade_to_token(_dict["access_token"]) def test_upgrade_to_token_with_id_token_and_oidreq(self): ae2 = AuthnEvent("another_user_id", "salt") sid = self.sdb.create_authz_session(ae2, AREQ) self.sdb[sid]['sub'] = 'sub' grant = self.sdb[sid]["code"] _dict = self.sdb.upgrade_to_token(grant, id_token="id_token", oidreq=OIDR) #print(_dict.keys()) assert _eq(list(_dict.keys()), ['authn_event', 'code', 'authzreq', 'revoked', 'oidreq', 'access_token', 'id_token', 'response_type', 'token_type', 'state', 'redirect_uri', 'code_used', 'client_id', 'scope', 'oauth_state', 'access_token_scope', 'sub']) assert _dict["id_token"] == "id_token" assert isinstance(_dict["oidreq"], OpenIDRequest) def test_refresh_token(self): ae = AuthnEvent("uid", "salt") sid = self.sdb.create_authz_session(ae, AREQ) self.sdb[sid]['sub'] = 'sub' grant = self.sdb[sid]["code"] # with mock.patch("time.gmtime", side_effect=[ # time.struct_time((1970, 1, 1, 10, 39, 0, 0, 0, 0)), # time.struct_time((1970, 1, 1, 10, 40, 0, 0, 0, 0))]): dict1 = self.sdb.upgrade_to_token(grant, issue_refresh=True).copy() rtoken = dict1["refresh_token"] dict2 = self.sdb.refresh_token(rtoken, AREQ['client_id']) assert dict1["access_token"] != dict2["access_token"] with pytest.raises(ExpiredToken): self.sdb.refresh_token(dict2["access_token"], AREQ['client_id']) def test_refresh_token_cleared_session(self): ae = AuthnEvent('uid', 'salt') sid = self.sdb.create_authz_session(ae, AREQ) self.sdb[sid]['sub'] = 'sub' grant = self.sdb[sid]['code'] dict1 = self.sdb.upgrade_to_token(grant, issue_refresh=True) ac1 = dict1['access_token'] rtoken = dict1['refresh_token'] dict2 = self.sdb.refresh_token(rtoken, AREQ['client_id']) assert ac1 != dict2["access_token"] def test_is_valid(self): ae1 = AuthnEvent("uid", "salt") sid = self.sdb.create_authz_session(ae1, AREQ) self.sdb[sid]['sub'] = 'sub' grant = self.sdb[sid]["code"] assert self.sdb.is_valid(grant) sinfo = self.sdb.upgrade_to_token(grant, issue_refresh=True) assert not self.sdb.is_valid(grant) access_token = sinfo["access_token"] assert self.sdb.access_token.valid(access_token) refresh_token = sinfo["refresh_token"] sinfo = self.sdb.refresh_token(refresh_token, AREQ['client_id']) access_token2 = sinfo["access_token"] assert self.sdb.is_valid(access_token2) # The old access code should be invalid try: self.sdb.is_valid(access_token) except KeyError: pass def test_valid_grant(self): ae = AuthnEvent("another:user", "salt") sid = self.sdb.create_authz_session(ae, AREQ) grant = self.sdb[sid]["code"] assert self.sdb.is_valid(grant) def test_revoke_token(self): ae1 = AuthnEvent("uid", "salt") sid = self.sdb.create_authz_session(ae1, AREQ) self.sdb[sid]['sub'] = 'sub' grant = self.sdb[sid]["code"] tokens = self.sdb.upgrade_to_token(grant, issue_refresh=True) access_token = tokens["access_token"] refresh_token = tokens["refresh_token"] assert self.sdb.is_valid(access_token) self.sdb.revoke_token(access_token) assert not self.sdb.is_valid(access_token) sinfo = self.sdb.refresh_token(refresh_token, AREQ['client_id']) access_token = sinfo["access_token"] assert self.sdb.is_valid(access_token) self.sdb.revoke_refresh_token(refresh_token) assert not self.sdb.is_valid(refresh_token) try: self.sdb.refresh_token(refresh_token, AREQ['client_id']) except ExpiredToken: pass assert self.sdb.is_valid(access_token) ae2 = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae2, AREQ) grant = self.sdb[sid]["code"] self.sdb.revoke_token(grant) assert not self.sdb.is_valid(grant) def test_sub_to_authn_event(self): ae = AuthnEvent("sub", "salt", time_stamp=time.time()) sid = self.sdb.create_authz_session(ae, AREQ) sub = self.sdb.do_sub(sid, "client_salt") # given the sub find out whether the authn event is still valid sids = self.sdb.get_sids_by_sub(sub) ae = self.sdb[sids[0]]["authn_event"] assert ae.valid() def test_do_sub_deterministic(self): ae = AuthnEvent("tester", "random_value") sid = self.sdb.create_authz_session(ae, AREQ) self.sdb.do_sub(sid, "other_random_value") info = self.sdb[sid] assert info["sub"] == \ '179670cdee6375c48e577317b2abd7d5cd26a5cdb1cfb7ef84af3d703c71d013' self.sdb.do_sub(sid, "other_random_value", sector_id='http://example.com', subject_type="pairwise") info2 = self.sdb[sid] assert info2["sub"] == \ 'aaa50d80f8780cf1c4beb39e8e126556292f5091b9e39596424fefa2b99d9c53' self.sdb.do_sub(sid, "another_random_value", sector_id='http://other.example.com', subject_type="pairwise") info2 = self.sdb[sid] assert info2["sub"] == \ '62fb630e29f0d41b88e049ac0ef49a9c3ac5418c029d6e4f5417df7e9443976b'
def test_is_valid(): sdb = SessionDB(BASE_URL) ae1 = AuthnEvent("sub") sid = sdb.create_authz_session(ae1, AREQ) grant = sdb[sid]["code"] assert sdb.is_valid(grant) _dict = sdb.upgrade_to_token(grant) assert sdb.is_valid(grant) is False token1 = _dict["access_token"] assert sdb.is_valid(token1) rtoken = _dict["refresh_token"] assert sdb.is_valid(rtoken) dict2 = sdb.refresh_token(rtoken) token2 = dict2["access_token"] assert sdb.is_valid(token2) # replace refresh_token dict2["refresh_token"] = token2 assert sdb.is_valid(rtoken) is False # mess with the time-line dict2["token_expires_at"] = utc_time_sans_frac() - 86400 assert sdb.is_valid(token2) is False # replace access_token dict2["access_token"] = token1 assert sdb.is_valid(token2) is False ae = AuthnEvent("another:user") sid = sdb.create_authz_session(ae, AREQ) grant = sdb[sid]["code"] gdict = sdb[grant] gdict["token_expires_at"] = utc_time_sans_frac() - 86400 assert sdb.is_valid(grant) is False
def test_revoke_token(): sdb = SessionDB(BASE_URL) ae1 = AuthnEvent("sub") sid = sdb.create_authz_session(ae1, AREQ) grant = sdb[sid]["code"] _dict = sdb.upgrade_to_token(grant) token = _dict["access_token"] rtoken = _dict["refresh_token"] assert sdb.is_valid(token) sdb.revoke_token(token) assert sdb.is_valid(token) is False dict2 = sdb.refresh_token(rtoken) token = dict2["access_token"] assert sdb.is_valid(token) sdb.revoke_token(rtoken) assert sdb.is_valid(rtoken) is False raises(ExpiredToken, 'sdb.refresh_token(rtoken)') assert sdb.is_valid(token) # --- new token ---- sdb = SessionDB(BASE_URL) ae2 = AuthnEvent("sub") sid = sdb.create_authz_session(ae2, AREQ) grant = sdb[sid]["code"] sdb.revoke_token(grant) assert sdb.is_valid(grant) is False
class MyFakeOICServer(Server): def __init__(self, jwt_keys=None, name=""): Server.__init__(self, jwt_keys=jwt_keys) self.sdb = SessionDB() self.name = name self.client = {} self.registration_expires_in = 3600 self.host = "" #noinspection PyUnusedLocal def http_request(self, path, method="GET", **kwargs): part = urlparse.urlparse(path) path = part[2] query = part[4] self.host = "%s://%s" % (part.scheme, part.netloc) response = Response response.status_code = 500 response.text = "" if path == ENDPOINT["authorization_endpoint"]: assert method == "GET" response = self.authorization_endpoint(query) elif path == ENDPOINT["token_endpoint"]: assert method == "POST" response = self.token_endpoint(kwargs["data"]) elif path == ENDPOINT["user_info_endpoint"]: assert method == "POST" response = self.userinfo_endpoint(kwargs["data"]) elif path == ENDPOINT["refresh_session_endpoint"]: assert method == "GET" response = self.refresh_session_endpoint(query) elif path == ENDPOINT["check_session_endpoint"]: assert method == "GET" response = self.check_session_endpoint(query) elif path == ENDPOINT["end_session_endpoint"]: assert method == "GET" response = self.end_session_endpoint(query) elif path == ENDPOINT["registration_endpoint"]: if method == "POST": response = self.registration_endpoint(kwargs["data"]) elif path == "/.well-known/simple-web-discovery": assert method == "GET" response = self.issuer(query) elif path == "/swd_server": assert method == "GET" response = self.swd_server(query) elif path == "/.well-known/openid-configuration"\ or path == "/providerconf/.well-known/openid-configuration": assert method == "GET" response = self.openid_conf() return response def authorization_endpoint(self, query): req = self.parse_authorization_request(query=query) sid = self.sdb.create_authz_session(user_id="user", areq=req) _info = self.sdb[sid] if "code" in req["response_type"]: if "token" in req["response_type"]: grant = _info["code"] _dict = self.sdb.update_to_token(grant) _dict["oauth_state"]="authz", _dict = by_schema(AuthorizationResponse(), **_dict) resp = AuthorizationResponse(**_dict) #resp.code = grant else: resp = AuthorizationResponse(state=req["state"], code=_info["code"]) else: # "implicit" in req.response_type: grant = _info["code"] params = AccessTokenResponse.c_param.keys() _dict = dict([(k,v) for k, v in self.sdb.update_to_token(grant).items() if k in params]) try: del _dict["refresh_token"] except KeyError: pass if "id_token" in req["response_type"]: _dict["id_token"] = self.make_id_token(_info, issuer=self.name, access_token=_dict["access_token"]) resp = AccessTokenResponse(**_dict) location = resp.request(req["redirect_uri"]) response= Response() response.headers = {"location":location} response.status_code = 302 response.text = "" return response def token_endpoint(self, data): if "grant_type=refresh_token" in data: req = self.parse_refresh_token_request(body=data) _info = self.sdb.refresh_token(req["refresh_token"]) elif "grant_type=authorization_code": req = self.parse_token_request(body=data) _info = self.sdb.update_to_token(req["code"]) else: response = TokenErrorResponse(error="unsupported_grant_type") return response, "" resp = AccessTokenResponse(**by_schema(AccessTokenResponse, **_info)) response = Response() response.headers = {"content-type":"application/json"} response.text = resp.to_json() return response def userinfo_endpoint(self, data): _ = self.parse_user_info_request(data) _info = { "name": "Melody Gardot", "nickname": "Mel", "email": "*****@*****.**", "verified": True, } resp = OpenIDSchema(**_info) response = Response() response.headers = {"content-type":"application/json"} response.text = resp.to_json() return response def registration_endpoint(self, data): req = self.parse_registration_request(data) client_secret = rndstr() expires = utc_time_sans_frac() + self.registration_expires_in if req["type"] == "client_associate": client_id = rndstr(10) self.client[client_id] = { "client_secret": client_secret, "info": req.to_dict(), "expires": expires } else: client_id = req.client_id _cinfo = self.client[req.client_id] _cinfo["info"].update(req.to_dict()) _cinfo["client_secret"] = client_secret _cinfo["expires"] = expires resp = RegistrationResponseCARS(client_id=client_id, client_secret=client_secret, expires_at=expires) response = Response() response.headers = {"content-type":"application/json"} response.text = resp.to_json() return response def check_session_endpoint(self, query): try: idtoken = self.parse_check_session_request(query=query) except Exception: raise response = Response() response.text = idtoken.to_json() response.headers = {"content-type":"application/json"} return response #noinspection PyUnusedLocal def refresh_session_endpoint(self, query): try: req = self.parse_refresh_session_request(query=query) except Exception: raise resp = RegistrationResponseCARS(client_id="anonymous", client_secret="hemligt") response = Response() response.headers = {"content-type":"application/json"} response.text = resp.to_json() return response def end_session_endpoint(self, query): try: req = self.parse_end_session_request(query=query) except Exception: raise # redirect back resp = EndSessionResponse(state=req["state"]) url = resp.request(req["redirect_url"]) response = Response() response.headers= {"location":url} response.status_code = 302 # redirect response.text = "" return response #noinspection PyUnusedLocal def add_credentials(self, user, passwd): return def issuer(self, query): request = self.parse_issuer_request(query) if request["principal"] == "*****@*****.**": resp = IssuerResponse(locations="http://example.com/") elif request["principal"] == "*****@*****.**": swd = SWDServiceRedirect(location="https://example.net/swd_server") resp = IssuerResponse(SWD_service_redirect=swd, expires=time_sans_frac() + 600) else: resp = None if resp is None: response = Response() response.status = 401 return response, "" else: response = Response() response.headers = {"content-type":"application/json"} response.text = resp.to_json() return response def swd_server(self, query): request = self.parse_issuer_request(query) if request["principal"] == "*****@*****.**": resp = IssuerResponse(locations="http://example.net/providerconf") else: resp = None if resp is None: response = Response() response.status_code = 401 response.text = "" return response else: response = Response() response.headers = {"content-type":"application/json"} response.text = resp.to_json() return response def openid_conf(self): endpoint = {} for point, path in ENDPOINT.items(): endpoint[point] = "%s%s" % (self.host, path) resp = ProviderConfigurationResponse( issuer=self.name, scopes_supported=["openid", "profile", "email", "address"], identifiers_supported=["public", "PPID"], flows_supported=["code", "token", "code token", "id_token", "code id_token", "token id_token"], **endpoint) response = Response() response.headers = {"content-type":"application/json"} response.text = resp.to_json() return response
class MyFakeOICServer(Server): def __init__(self, name=""): Server.__init__(self) self.sdb = SessionDB() self.name = name self.client = {} self.registration_expires_in = 3600 self.host = "" self.webfinger = WebFinger() #noinspection PyUnusedLocal def http_request(self, path, method="GET", **kwargs): part = urlparse(path) path = part[2] query = part[4] self.host = "%s://%s" % (part.scheme, part.netloc) response = Response response.status_code = 500 response.text = "" if path == ENDPOINT["authorization_endpoint"]: assert method == "GET" response = self.authorization_endpoint(query) elif path == ENDPOINT["token_endpoint"]: assert method == "POST" response = self.token_endpoint(kwargs["data"]) elif path == ENDPOINT["user_info_endpoint"]: assert method == "POST" response = self.userinfo_endpoint(kwargs["data"]) elif path == ENDPOINT["refresh_session_endpoint"]: assert method == "GET" response = self.refresh_session_endpoint(query) elif path == ENDPOINT["check_session_endpoint"]: assert method == "GET" response = self.check_session_endpoint(query) elif path == ENDPOINT["end_session_endpoint"]: assert method == "GET" response = self.end_session_endpoint(query) elif path == ENDPOINT["registration_endpoint"]: if method == "POST": response = self.registration_endpoint(kwargs["data"]) elif path == "/.well-known/webfinger": assert method == "GET" qdict = parse_qs(query) response.status_code = 200 response.text = self.webfinger.response(qdict["resource"][0], "%s/" % self.name) elif path == "/.well-known/openid-configuration": assert method == "GET" response = self.openid_conf() return response def authorization_endpoint(self, query): req = self.parse_authorization_request(query=query) sid = self.sdb.create_authz_session(sub="user", areq=req) _info = self.sdb[sid] _info["sub"] = _info["local_sub"] if "code" in req["response_type"]: if "token" in req["response_type"]: grant = _info["code"] _dict = self.sdb.upgrade_to_token(grant) _dict["oauth_state"] = "authz", _dict = by_schema(AuthorizationResponse(), **_dict) resp = AuthorizationResponse(**_dict) #resp.code = grant else: resp = AuthorizationResponse(state=req["state"], code=_info["code"]) else: # "implicit" in req.response_type: grant = _info["code"] params = AccessTokenResponse.c_param.keys() _dict = dict([(k, v) for k, v in self.sdb.upgrade_to_token(grant).items() if k in params]) try: del _dict["refresh_token"] except KeyError: pass if "id_token" in req["response_type"]: _idt = self.make_id_token(_info, issuer=self.name, access_token=_dict["access_token"]) alg = "RS256" ckey = self.keyjar.get_signing_key(alg2keytype(alg), _info["client_id"]) _dict["id_token"] = _idt.to_jwt(key=ckey, algorithm=alg) resp = AccessTokenResponse(**_dict) location = resp.request(req["redirect_uri"]) response = Response() response.headers = {"location": location} response.status_code = 302 response.text = "" return response def token_endpoint(self, data): if "grant_type=refresh_token" in data: req = self.parse_refresh_token_request(body=data) _info = self.sdb.refresh_token(req["refresh_token"]) elif "grant_type=authorization_code": req = self.parse_token_request(body=data) _info = self.sdb.upgrade_to_token(req["code"]) else: response = TokenErrorResponse(error="unsupported_grant_type") return response, "" resp = AccessTokenResponse(**by_schema(AccessTokenResponse, **_info)) response = Response() response.headers = {"content-type": "application/json"} response.text = resp.to_json() return response def userinfo_endpoint(self, data): _ = self.parse_user_info_request(data) _info = { "sub": "melgar", "name": "Melody Gardot", "nickname": "Mel", "email": "*****@*****.**", "verified": True, } resp = OpenIDSchema(**_info) response = Response() response.headers = {"content-type": "application/json"} response.text = resp.to_json() return response def registration_endpoint(self, data): try: req = self.parse_registration_request(data, "json") except ValueError: req = self.parse_registration_request(data) client_secret = rndstr() expires = utc_time_sans_frac() + self.registration_expires_in kwargs = {} if "client_id" not in req: client_id = rndstr(10) registration_access_token = rndstr(20) _client_info = req.to_dict() kwargs.update(_client_info) _client_info.update({ "client_secret": client_secret, "info": req.to_dict(), "expires": expires, "registration_access_token": registration_access_token, "registration_client_uri": "register_endpoint" }) self.client[client_id] = _client_info kwargs["registration_access_token"] = registration_access_token kwargs["registration_client_uri"] = "register_endpoint" try: del kwargs["operation"] except KeyError: pass else: client_id = req.client_id _cinfo = self.client[req.client_id] _cinfo["info"].update(req.to_dict()) _cinfo["client_secret"] = client_secret _cinfo["expires"] = expires resp = RegistrationResponse(client_id=client_id, client_secret=client_secret, client_secret_expires_at=expires, **kwargs) response = Response() response.headers = {"content-type": "application/json"} response.text = resp.to_json() return response def check_session_endpoint(self, query): try: idtoken = self.parse_check_session_request(query=query) except Exception: raise response = Response() response.text = idtoken.to_json() response.headers = {"content-type": "application/json"} return response #noinspection PyUnusedLocal def refresh_session_endpoint(self, query): try: req = self.parse_refresh_session_request(query=query) except Exception: raise resp = RegistrationResponse(client_id="anonymous", client_secret="hemligt") response = Response() response.headers = {"content-type": "application/json"} response.text = resp.to_json() return response def end_session_endpoint(self, query): try: req = self.parse_end_session_request(query=query) except Exception: raise # redirect back resp = EndSessionResponse(state=req["state"]) url = resp.request(req["redirect_url"]) response = Response() response.headers = {"location": url} response.status_code = 302 # redirect response.text = "" return response #noinspection PyUnusedLocal def add_credentials(self, user, passwd): return def openid_conf(self): endpoint = {} for point, path in ENDPOINT.items(): endpoint[point] = "%s%s" % (self.host, path) signing_algs = jws.SIGNER_ALGS.keys() resp = ProviderConfigurationResponse( issuer=self.name, scopes_supported=["openid", "profile", "email", "address"], identifiers_supported=["public", "PPID"], flows_supported=["code", "token", "code token", "id_token", "code id_token", "token id_token"], subject_types_supported=["pairwise", "public"], response_types_supported=["code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token"], jwks_uri="http://example.com/oidc/jwks", id_token_signing_alg_values_supported=signing_algs, grant_types_supported=["authorization_code", "implicit"], **endpoint) response = Response() response.headers = {"content-type": "application/json"} response.text = resp.to_json() return response
def test_is_valid(): sdb = SessionDB() sid = sdb.create_authz_session("user_id", AREQ) grant = sdb[sid]["code"] assert sdb.is_valid(grant) _dict = sdb.update_to_token(grant) assert sdb.is_valid(grant) is False token1 = _dict["access_token"] assert sdb.is_valid(token1) rtoken = _dict["refresh_token"] assert sdb.is_valid(rtoken) dict2 = sdb.refresh_token(rtoken) token2 = dict2["access_token"] assert sdb.is_valid(token2) # replace refresh_token dict2["refresh_token"] = token2 assert sdb.is_valid(rtoken) is False # mess with the time-line dict2["expires_at"] = utc_time_sans_frac() - 86400 # like yesterday assert sdb.is_valid(token2) is False # replace access_token dict2["access_token"] = token1 assert sdb.is_valid(token2) is False sid = sdb.create_authz_session("another:user", AREQ) grant = sdb[sid]["code"] gdict = sdb[grant] gdict["expires_at"] = utc_time_sans_frac() - 86400 # like yesterday assert sdb.is_valid(grant) is False
def test_revoke_token(): sdb = SessionDB() sid = sdb.create_authz_session("user_id", AREQ) grant = sdb[sid]["code"] _dict = sdb.update_to_token(grant) token = _dict["access_token"] rtoken = _dict["refresh_token"] assert sdb.is_valid(token) sdb.revoke_token(token) assert sdb.is_valid(token) is False dict2 = sdb.refresh_token(rtoken) token = dict2["access_token"] assert sdb.is_valid(token) sdb.revoke_token(rtoken) assert sdb.is_valid(rtoken) is False raises(ExpiredToken, 'sdb.refresh_token(rtoken)') assert sdb.is_valid(token) # --- new token ---- sdb = SessionDB() sid = sdb.create_authz_session("user_id", AREQ) grant = sdb[sid]["code"] sdb.revoke_token(grant) assert sdb.is_valid(grant) is False