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 test_update(): sdb = SessionDB(BASE_URL) 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")')
class TestSessionDB(object): @pytest.fixture(autouse=True) def create_sdb(self): self.sdb = SessionDB("https://example.com/") def test_setitem(self): sid = self.sdb.token.key(areq=AREQ) code = self.sdb.token(sid=sid) self.sdb[sid] = {"indo": "china"} info = self.sdb[sid] assert info == {"indo": "china"} info = self.sdb[code] assert info == {"indo": "china"} def test_getitem_key_error(self): with pytest.raises(KeyError): self.sdb["abcdefghijklmnop"] def test_update(self): sid = self.sdb.token.key(areq=AREQ) code = self.sdb.token(sid=sid) self.sdb[sid] = {"indo": "china"} self.sdb.update(sid, "indo", "nebue") self.sdb.update(code, "indo", "second") def test_update_non_existing(self): sid = self.sdb.token.key(areq=AREQ) code = self.sdb.token(sid=sid) # can't update non-existing with pytest.raises(KeyError): self.sdb.update(sid, "indo", "nebue") self.sdb.update(code, "indo", "nebue") self.sdb.update("abcdefghijklmnop", "indo", "bar") 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_expires_at', 'expires_in', 'token_type', 'state', 'redirect_uri', 'code_used', 'client_id', 'scope', 'oauth_state', 'access_token_scope', '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_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', 'token_expires_at', 'expires_in', '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', 'token_expires_at', 'expires_in', '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["token_expires_at"] != dict2["token_expires_at"] assert dict1["access_token"] != dict2["access_token"] with pytest.raises(WrongTokenType): 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) # Purge session DB self.sdb._db = {} # Our refresh token shoudl still work 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))]): rtoken = dict1['refresh_token'] dict2 = self.sdb.refresh_token(rtoken, AREQ['client_id']) assert dict1["token_expires_at"] != dict2["token_expires_at"] assert dict1["access_token"] != 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) tokens = self.sdb.upgrade_to_token(grant, issue_refresh=True) assert not self.sdb.is_valid(grant) access_token = tokens["access_token"] assert self.sdb.is_valid(access_token) refresh_token = tokens["refresh_token"] assert self.sdb.is_valid(refresh_token, AREQ['client_id']) refreshed_tokens = self.sdb.refresh_token(refresh_token, AREQ['client_id']) access_token2 = refreshed_tokens["access_token"] assert self.sdb.is_valid(access_token2) # replace refresh_token refreshed_tokens["refresh_token"] = access_token2 assert not self.sdb.is_valid(refresh_token) # mess with the time-line refreshed_tokens["token_expires_at"] = utc_time_sans_frac() - 86400 assert not self.sdb.is_valid(access_token2) # replace access_token refreshed_tokens["access_token"] = access_token assert not self.sdb.is_valid(access_token2) ae = AuthnEvent("another:user", "salt") sid = self.sdb.create_authz_session(ae, AREQ) grant = self.sdb[sid]["code"] self.sdb.update(grant, "token_expires_at", utc_time_sans_frac() - 86400) assert not 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) refreshed_tokens = self.sdb.refresh_token(refresh_token, AREQ['client_id']) access_token = refreshed_tokens["access_token"] assert self.sdb.is_valid(access_token) self.sdb.revoke_refresh_token(refresh_token) assert not self.sdb.is_valid(refresh_token) with pytest.raises(ExpiredToken): self.sdb.refresh_token(refresh_token, AREQ['client_id']) 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'
class TestSessionDB(object): @pytest.fixture(autouse=True) def create_sdb(self): self.sdb = SessionDB("https://example.com/") def test_setitem(self): sid = self.sdb.token.key(areq=AREQ) code = self.sdb.token(sid=sid) self.sdb[sid] = {"indo": "china"} info = self.sdb[sid] assert info == {"indo": "china"} info = self.sdb[code] assert info == {"indo": "china"} def test_getitem_key_error(self): with pytest.raises(KeyError): self.sdb["abcdefghijklmnop"] def test_update(self): sid = self.sdb.token.key(areq=AREQ) code = self.sdb.token(sid=sid) self.sdb[sid] = {"indo": "china"} self.sdb.update(sid, "indo", "nebue") self.sdb.update(code, "indo", "second") def test_update_non_existing(self): sid = self.sdb.token.key(areq=AREQ) code = self.sdb.token(sid=sid) # can't update non-existing with pytest.raises(KeyError): self.sdb.update(sid, "indo", "nebue") self.sdb.update(code, "indo", "nebue") self.sdb.update("abcdefghijklmnop", "indo", "bar") 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("sub", "salt") sid = self.sdb.create_authz_session(ae1, AREQ) grant = self.sdb[sid]["code"] _dict = self.sdb.upgrade_to_token(grant) assert _eq(_dict.keys(), [ 'authn_event', 'code', 'authzreq', 'revoked', 'access_token', 'token_expires_at', 'expires_in', 'token_type', 'state', 'redirect_uri', 'code_used', 'client_id', 'scope', 'oauth_state', 'refresh_token', 'access_token_scope' ]) # 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) grant = self.sdb[sid]["code"] _dict = self.sdb.upgrade_to_token(grant, id_token="id_token", oidreq=OIDR) assert _eq(list(_dict.keys()), [ 'authn_event', 'code', 'authzreq', 'revoked', 'oidreq', 'access_token', 'id_token', 'token_expires_at', 'expires_in', 'token_type', 'state', 'redirect_uri', 'code_used', 'client_id', 'scope', 'oauth_state', 'refresh_token', 'access_token_scope' ]) assert _dict["id_token"] == "id_token" assert isinstance(_dict["oidreq"], OpenIDRequest) def test_refresh_token(self): ae = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae, AREQ) 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).copy() rtoken = dict1["refresh_token"] dict2 = self.sdb.refresh_token(rtoken) assert dict1["token_expires_at"] != dict2["token_expires_at"] assert dict1["access_token"] != dict2["access_token"] with pytest.raises(WrongTokenType): self.sdb.refresh_token(dict2["access_token"]) def test_is_valid(self): ae1 = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae1, AREQ) grant = self.sdb[sid]["code"] assert self.sdb.is_valid(grant) tokens = self.sdb.upgrade_to_token(grant) assert not self.sdb.is_valid(grant) access_token = tokens["access_token"] assert self.sdb.is_valid(access_token) refresh_token = tokens["refresh_token"] assert self.sdb.is_valid(refresh_token) refreshed_tokens = self.sdb.refresh_token(refresh_token) access_token2 = refreshed_tokens["access_token"] assert self.sdb.is_valid(access_token2) # replace refresh_token refreshed_tokens["refresh_token"] = access_token2 assert not self.sdb.is_valid(refresh_token) # mess with the time-line refreshed_tokens["token_expires_at"] = utc_time_sans_frac() - 86400 assert not self.sdb.is_valid(access_token2) # replace access_token refreshed_tokens["access_token"] = access_token assert not self.sdb.is_valid(access_token2) ae = AuthnEvent("another:user", "salt") sid = self.sdb.create_authz_session(ae, AREQ) grant = self.sdb[sid]["code"] self.sdb.update(grant, "token_expires_at", utc_time_sans_frac() - 86400) assert not self.sdb.is_valid(grant) def test_revoke_token(self): ae1 = AuthnEvent("sub", "salt") sid = self.sdb.create_authz_session(ae1, AREQ) grant = self.sdb[sid]["code"] tokens = self.sdb.upgrade_to_token(grant) 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) refreshed_tokens = self.sdb.refresh_token(refresh_token) access_token = refreshed_tokens["access_token"] assert self.sdb.is_valid(access_token) self.sdb.revoke_token(refresh_token) assert not self.sdb.is_valid(refresh_token) with pytest.raises(ExpiredToken): self.sdb.refresh_token(refresh_token) 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'