def test_get_userid_without_userid(): identity_policy = JWTIdentityPolicy(master_secret='secret') claims_set = {} token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert identity_policy.get_userid(claims_set_decoded) is None
def test_encode_decode_with_unicode(): identity_policy = JWTIdentityPolicy(master_secret='sëcret') claims_set = { 'sub': 'user' } token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert claims_set_decoded == claims_set
def test_create_claim_and_encode_decode_expired(): identity_policy = JWTIdentityPolicy( master_secret='secret', expiration_delta=datetime.timedelta(seconds=-2) ) userid = 'user' claims_set = identity_policy.create_claims_set(userid) token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert claims_set_decoded is None
def test_encode_decode_with_issuer(): identity_policy = JWTIdentityPolicy(master_secret='secret', issuer='Issuer_App') userid = 'user' extra_claims = { 'iss': 'Invalid_Issuer_App' } claims_set = identity_policy.create_claims_set(userid, extra_claims) token = identity_policy.encode_jwt(claims_set) with pytest.raises(InvalidIssuerError): claims_set_decoded = identity_policy.decode_jwt(token) extra_claims = { 'iss': 'Issuer_App' } claims_set = identity_policy.create_claims_set(userid, extra_claims) token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert claims_set_decoded == claims_set
def test_create_claim_and_encode_decode_expired_but_with_leeway(): identity_policy = JWTIdentityPolicy( master_secret='secret', expiration_delta=datetime.timedelta(seconds=-2), leeway=3 ) userid = 'user' claims_set = identity_policy.create_claims_set(userid) token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert identity_policy.get_userid(claims_set_decoded) == userid
def test_encode_decode_with_es256(): identity_policy = JWTIdentityPolicy( algorithm='ES256', private_key_file='more/jwtauth/tests/keys/testkey_ec', public_key_file='more/jwtauth/tests/keys/testkey_ec.pub' ) claims_set = { 'sub': 'user' } token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert claims_set_decoded == claims_set
def test_create_claim_and_encode_decode_and_get_userid_and_get_extra_claims(): identity_policy = JWTIdentityPolicy(master_secret='secret') userid = 'user' extra_claims = { 'email': '*****@*****.**', 'role': 'admin' } claims_set = identity_policy.create_claims_set(userid, extra_claims) token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert userid == identity_policy.get_userid(claims_set_decoded) assert extra_claims == identity_policy.get_extra_claims(claims_set_decoded)
def test_encode_decode_with_ps384(self): identity_policy = JWTIdentityPolicy( algorithm='PS384', private_key_file=relative('keys/testkey_rsa'), public_key_file=relative('keys/testkey_rsa.pub') ) claims_set = { 'sub': 'user' } token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert claims_set_decoded == claims_set
def test_refresh_token(): app = App() c = Client(app) response = c.post( "/login", json.dumps({"email": "*****@*****.**", "password": "******"}) ) headers = {"Authorization": response.headers["Authorization"]} response = c.get("/refresh", headers=headers) jwtauth_settings = app.settings.jwtauth.__dict__.copy() identity_policy = JWTIdentityPolicy(**jwtauth_settings) authtype, token = response.headers["Authorization"].split(" ", 1) claims_set_decoded = identity_policy.decode_jwt(token) assert identity_policy.get_userid(claims_set_decoded) == "*****@*****.**" with db_session: # set new nonce to invalid current tokens for this user User[2].nonce = uuid4().hex response = c.get("/refresh", headers=headers, status=403) assert response.json == {"validationError": "Could not refresh your token"} now = timegm(datetime.utcnow().utctimetuple()) with db_session: nonce = User.get(email="*****@*****.**").nonce claims_set = { "sub": "*****@*****.**", "uid": "/users/2", "refresh_until": now - 3, "nonce": nonce, "exp": now + 3, } token = identity_policy.encode_jwt(claims_set) headers = {"Authorization": "JWT " + token} response = c.get("/refresh", headers=headers, status=403) assert response.json == {"validationError": "Your session has expired"}
def test_encode_decode_with_es256_as_bytes(self): with open(relative('keys/testkey_ec'), 'r') as key_priv_file: private_key = key_priv_file.read() with open(relative('keys/testkey_ec.pub'), 'r') as key_pub_file: public_key = key_pub_file.read() identity_policy = JWTIdentityPolicy( algorithm='ES256', private_key=private_key, public_key=public_key ) claims_set = { 'sub': 'user' } token = identity_policy.encode_jwt(claims_set) claims_set_decoded = identity_policy.decode_jwt(token) assert claims_set_decoded == claims_set
def test_login(): app = App() c = Client(app) response = c.post( "/login", json.dumps({"email": "*****@*****.**", "password": "******"}), status=403, ) assert response.json == {"validationError": "Invalid email or password"} response = c.post( "/login", json.dumps({"email": "*****@*****.**", "password": "******"}), status=403, ) assert response.json == {"validationError": "Invalid email or password"} response = c.post( "/login", json.dumps({"email": "test@example", "password": "******"}), status=403, ) assert response.json == {"validationError": "Invalid email or password"} response = c.post( "/login", json.dumps({"email": "*****@*****.**", "password": "******"}), status=422, ) assert response.json == {"password": ["min length is 5"]} response = c.post( "/login", json.dumps({"email": "*****@*****.**", "password": "******"}) ) jwtauth_settings = app.settings.jwtauth.__dict__.copy() identity_policy = JWTIdentityPolicy(**jwtauth_settings) authtype, token = response.headers["Authorization"].split(" ", 1) claims_set_decoded = identity_policy.decode_jwt(token) assert identity_policy.get_userid(claims_set_decoded) == "*****@*****.**"
def test_refresh_without_refresh_nonce_handler_setting(): class App(morepath.App): pass class Refresh(object): pass @App.identity_policy() def get_identity_policy(settings): jwtauth_settings = settings.jwtauth.__dict__.copy() return JWTIdentityPolicy(**jwtauth_settings) @App.path(model=Refresh, path='refresh') def get_refresh(): return Refresh() @App.json(model=Refresh) def refresh(self, request): userid = verify_refresh_request(request) @request.after def remember(response): identity = Identity(userid) request.app.remember_identity(response, request, identity) return {'userid': userid} settings = { 'master_secret': 'secret', 'allow_refresh': True, 'refresh_delta': 3 } @App.setting_section(section="jwtauth") def get_jwtauth_settings(): return settings identity_policy = JWTIdentityPolicy(**settings) now = timegm(datetime.utcnow().utctimetuple()) claims_set = { 'sub': 'user', 'refresh_until': now + 3, } token = identity_policy.encode_jwt(claims_set) headers = {'Authorization': 'JWT ' + token} morepath.commit(App) c = Client(App()) r = c.get('/refresh', headers=headers) assert r.json == { 'userid': 'user', } authtype, token = r.headers['Authorization'].split(' ', 1) claims_set_decoded = identity_policy.decode_jwt(token) assert identity_policy.get_userid(claims_set_decoded) == 'user'
def test_refresh_token_with_extra_claims(): class App(morepath.App): pass class Refresh(object): pass @App.identity_policy() def get_identity_policy(settings): jwtauth_settings = settings.jwtauth.__dict__.copy() return JWTIdentityPolicy(**jwtauth_settings) @App.path(model=Refresh, path='refresh') def get_refresh(): return Refresh() @App.json(model=Refresh) def refresh(self, request): userid = verify_refresh_request(request) updated_extra_claims = { 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'father' } @request.after def remember(response): identity = Identity(userid, **updated_extra_claims) request.app.remember_identity(response, request, identity) return { 'userid': 'user', 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'father' } refresh_nonce_handler = 'more.jwtauth.tests.handler.refresh_nonce_handler' refresh_delta = 3600 settings = { 'master_secret': 'secret', 'allow_refresh': True, 'refresh_delta': refresh_delta, 'refresh_nonce_handler': refresh_nonce_handler } @App.setting_section(section="jwtauth") def get_jwtauth_settings(): return settings identity_policy = JWTIdentityPolicy(**settings) now = timegm(datetime.utcnow().utctimetuple()) claims_set = { 'sub': 'user', 'refresh_until': now + refresh_delta, 'nonce': '__user__', 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'wizard' } token = identity_policy.encode_jwt(claims_set) headers = {'Authorization': 'JWT ' + token} morepath.commit(App) app = App() c = Client(app) r = c.get('/refresh', headers=headers) assert r.json == { 'userid': 'user', 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'father' } authtype, token = r.headers['Authorization'].split(' ', 1) claims_set_decoded = identity_policy.decode_jwt(token) assert identity_policy.get_userid(claims_set_decoded) == 'user' extra_claims = { 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'father' } assert identity_policy.get_extra_claims(claims_set_decoded) == extra_claims
def test_login_with_extra_claims(): class App(morepath.App): pass @App.setting_section(section="jwtauth") def get_jwtauth_settings(): return { 'master_secret': 'secret', } @App.identity_policy() def get_identity_policy(settings): jwtauth_settings = settings.jwtauth.__dict__.copy() return JWTIdentityPolicy(**jwtauth_settings) class Login(object): pass @App.path(model=Login, path='login') def get_login(): return Login() @App.json(model=Login, request_method='POST') def login(self, request): username = request.POST['username'] password = request.POST['password'] fullname = request.POST['fullname'] email = request.POST['email'] role = request.POST['role'] if not user_has_password(username, password): raise HTTPProxyAuthenticationRequired('Invalid username/password') @request.after def remember(response): identity = Identity(username, fullname=fullname, email=email, role=role) morepath.remember_identity(response, request, identity, lookup=request.lookup) return { 'username': username, 'fullname': fullname, 'email': email, 'role': role } def user_has_password(username, password): return username == 'user' and password == 'password' morepath.commit(App) c = Client(App()) params = { 'username': '******', 'password': '******', 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'wizard' } r = c.post('/login', params, status=407) params = { 'username': '******', 'password': '******', 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'wizard' } r = c.post('/login', params) assert r.json == { 'username': '******', 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'wizard' } identity_policy = JWTIdentityPolicy( master_secret='secret', ) authtype, token = r.headers['Authorization'].split(' ', 1) claims_set_decoded = identity_policy.decode_jwt(token) assert identity_policy.get_userid(claims_set_decoded) == 'user' extra_claims = { 'fullname': 'Harry Potter', 'email': '*****@*****.**', 'role': 'wizard' } assert identity_policy.get_extra_claims(claims_set_decoded) == extra_claims
def test_login(): class App(morepath.App): pass @App.setting_section(section="jwtauth") def get_jwtauth_settings(): return { 'master_secret': 'secret', 'expiration_delta': None, } @App.identity_policy() def get_identity_policy(settings): jwtauth_settings = settings.jwtauth.__dict__.copy() return JWTIdentityPolicy(**jwtauth_settings) class Login(object): pass @App.path(model=Login, path='login') def get_login(): return Login() @App.json(model=Login, request_method='POST') def login(self, request): username = request.POST['username'] password = request.POST['password'] if not user_has_password(username, password): raise HTTPProxyAuthenticationRequired('Invalid username/password') @request.after def remember(response): identity = Identity(username) morepath.remember_identity(response, request, identity, lookup=request.lookup) return { 'username': username, } def user_has_password(username, password): return username == 'user' and password == 'password' morepath.commit(App) c = Client(App()) r = c.post('/login', 'username=user&password=false', status=407) r = c.post('/login', 'username=not_exists&password=password', status=407) r = c.post('/login', 'username=user&password=password') assert r.json == { 'username': '******', } identity_policy = JWTIdentityPolicy( master_secret='secret', expiration_delta=None ) claims_set = { 'sub': 'user' } expected_token = identity_policy.encode_jwt(claims_set) assert r.headers['Authorization'] == '%s %s' % ('JWT', expected_token) authtype, token = r.headers['Authorization'].split(' ', 1) claims_set_decoded = identity_policy.decode_jwt(token) assert identity_policy.get_userid(claims_set_decoded) == 'user'