Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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_expiration_delta_expired_with_verify_expiration_on_refresh():
    class App(morepath.App):
        pass

    class Refresh(object):
        pass

    @App.path(model=Refresh, path='refresh')
    def get_refresh():
        return Refresh()

    @App.json(model=Refresh)
    def refresh(self, request):
        verify_refresh_request(request)

    refresh_nonce_handler = 'more.jwtauth.tests.handler.refresh_nonce_handler'
    expiration_delta = timedelta(seconds=-3)
    refresh_delta = timedelta(seconds=3)
    settings = {
        'master_secret': 'secret',
        'expiration_delta': expiration_delta,
        'allow_refresh': True,
        'refresh_delta': refresh_delta,
        'refresh_nonce_handler': refresh_nonce_handler,
        'verify_expiration_on_refresh': True
    }

    @App.setting_section(section="jwtauth")
    def get_jwtauth_settings():
        return settings

    identity_policy = JWTIdentityPolicy(**settings)

    exp = timegm((datetime.utcnow() + expiration_delta).utctimetuple())
    refresh_until = timegm((datetime.utcnow() + refresh_delta).utctimetuple())

    claims_set = {
        'sub': 'user',
        'exp': exp,
        'refresh_until': refresh_until,
        'nonce': '__user__'
    }

    token = identity_policy.encode_jwt(claims_set)
    headers = {'Authorization': 'JWT ' + token}

    morepath.commit(App)
    c = Client(App())

    with pytest.raises(ExpiredSignatureError) as excinfo:
        c.get('/refresh', headers=headers)
    assert 'Token has expired' in str(excinfo.value)
    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
Beispiel #7
0
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_claims_with_refresh_until_and_nonce():
    refresh_nonce_handler = 'more.jwtauth.tests.handler.refresh_nonce_handler'

    identity_policy = JWTIdentityPolicy(
        master_secret='secret',
        allow_refresh=True,
        refresh_delta=timedelta(seconds=2),
        refresh_nonce_handler=refresh_nonce_handler)

    userid = 'user'
    claims_set = identity_policy.create_claims_set(None, userid)

    now = timegm(datetime.utcnow().utctimetuple())

    assert claims_set['refresh_until'] >= now + 1
    assert claims_set['refresh_until'] <= now + 3
    assert claims_set['nonce'] == '__user__'
def test_refresh_with_invalid_refresh_nonce():
    class App(morepath.App):
        pass

    class Refresh(object):
        pass

    @App.path(model=Refresh, path='refresh')
    def get_refresh():
        return Refresh()

    @App.json(model=Refresh)
    def refresh(self, request):
        verify_refresh_request(request)

    refresh_nonce_handler = 'more.jwtauth.tests.handler.refresh_nonce_handler'
    settings = {
        'master_secret': 'secret',
        'allow_refresh': True,
        'refresh_delta': 3,
        '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 + 3,
        'nonce': '__invalid__'
    }

    token = identity_policy.encode_jwt(claims_set)
    headers = {'Authorization': 'JWT ' + token}

    morepath.commit(App)
    c = Client(App())

    with pytest.raises(InvalidTokenError) as excinfo:
        c.get('/refresh', headers=headers)
    assert 'Refresh nonce is not valid' in str(excinfo.value)
Beispiel #10
0
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
Beispiel #12
0
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) == "*****@*****.**"
Beispiel #13
0
def test_refresh_with_missing_refresh_until_claim():
    class App(morepath.App):
        pass

    class Refresh(object):
        pass

    @App.path(model=Refresh, path='refresh')
    def get_refresh():
        return Refresh()

    @App.json(model=Refresh)
    def refresh(self, request):
        verify_refresh_request(request)

    refresh_nonce_handler = 'more.jwtauth.tests.handler.refresh_nonce_handler'
    settings = {
        'master_secret': 'secret',
        'allow_refresh': True,
        'refresh_delta': 3,
        'refresh_nonce_handler': refresh_nonce_handler
    }

    @App.setting_section(section="jwtauth")
    def get_jwtauth_settings():
        return settings

    identity_policy = JWTIdentityPolicy(**settings)

    claims_set = {'sub': 'user', 'nonce': '__user__'}

    token = identity_policy.encode_jwt(claims_set)
    headers = {'Authorization': 'JWT ' + token}

    morepath.commit(App)
    c = Client(App())

    with pytest.raises(MissingRequiredClaimError) as excinfo:
        c.get('/refresh', headers=headers)
    assert 'Token is missing the "refresh_until" claim' in str(excinfo.value)
Beispiel #14
0
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)
Beispiel #15
0
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
Beispiel #16
0
def get_identity_policy(settings):
    """Crea la política de identidad (usando jwt)"""
    jwtauth_settings = settings.jwtauth.__dict__.copy()
    return JWTIdentityPolicy(**jwtauth_settings)
Beispiel #17
0
 def get_identity_policy(settings):
     jwtauth_settings = settings.jwtauth.__dict__.copy()
     return JWTIdentityPolicy(**jwtauth_settings)
Beispiel #18
0
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'
Beispiel #19
0
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'
Beispiel #20
0
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
Beispiel #21
0
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
Beispiel #22
0
def test_jwt_identity_policy_errors():
    class App(morepath.App):
        pass

    class Model(object):
        def __init__(self, id):
            self.id = id

    class Permission(object):
        pass

    @App.path(model=Model, path='{id}',
              variables=lambda model: {'id': model.id})
    def get_model(id):
        return Model(id)

    @App.permission_rule(model=Model, permission=Permission)
    def get_permission(identity, model, permission):
        return identity.userid == 'user'

    @App.view(model=Model, permission=Permission)
    def default(self, request):
        return "Model: %s" % self.id

    @App.setting_section(section="jwtauth")
    def get_jwtauth_settings():
        return {
            'master_secret': u'sëcret',
            'leeway': None
        }

    @App.identity_policy()
    def get_identity_policy(settings):
        jwtauth_settings = settings.jwtauth.__dict__.copy()
        return JWTIdentityPolicy(**jwtauth_settings)

    @App.verify_identity()
    def verify_identity(identity):
        assert identity is not NO_IDENTITY
        return True

    morepath.commit(App)

    c = Client(App())

    identity_policy = JWTIdentityPolicy(
        master_secret=u'sëcret'
    )

    response = c.get('/foo', status=403)

    headers = {'Authorization': 'Something'}
    response = c.get('/foo', headers=headers, status=403)

    headers = {'Authorization': 'JWT ' + 'nonsense'}
    response = c.get('/foo', headers=headers, status=403)

    # no userid
    claims_set = {
        'sub': None
    }
    token = identity_policy.encode_jwt(claims_set)
    headers = {'Authorization': 'JWT ' + token}
    response = c.get('/foo', headers=headers, status=403)

    claims_set = {
        'sub': 'user'
    }
    token = identity_policy.encode_jwt(claims_set)

    headers = {'Authorization': 'OtherAuthType ' + token}
    response = c.get('/foo', headers=headers, status=403)

    headers = {'Authorization': 'JWT ' + token}
    response = c.get('/foo', headers=headers)
    assert response.body == b'Model: foo'