def test_jwt_required(app):
    url = "/protected"

    test_client = app.test_client()
    with app.test_request_context():
        access_token = create_access_token("username")
        fresh_access_token = create_access_token("username", fresh=True)
        refresh_token = create_refresh_token("username")

    # Access and fresh access should be able to access this
    for token in (access_token, fresh_access_token):
        response = test_client.get(url, headers=make_headers(token))
        assert response.status_code == 200
        assert response.get_json() == {"foo": "bar"}

    # Test accessing jwt_required with no jwt in the request
    response = test_client.get(url, headers=None)
    assert response.status_code == 401
    assert response.get_json() == {"msg": "Missing Authorization Header"}

    # Test refresh token access to jwt_required
    response = test_client.get(url, headers=make_headers(refresh_token))
    assert response.status_code == 422
    assert response.get_json() == {
        "msg": "Only non-refresh tokens are allowed"
    }
def test_jwt_required(app):
    url = '/protected'

    test_client = app.test_client()
    with app.test_request_context():
        access_token = create_access_token('username')
        fresh_access_token = create_access_token('username', fresh=True)
        refresh_token = create_refresh_token('username')

    # Access and fresh access should be able to access this
    for token in (access_token, fresh_access_token):
        response = test_client.get(url, headers=make_headers(token))
        json_data = json.loads(response.get_data(as_text=True))
        assert response.status_code == 200
        assert json_data == {'foo': 'bar'}

    # Test accessing jwt_required with no jwt in the request
    response = test_client.get(url, headers=None)
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 401
    assert json_data == {'msg': 'Missing Authorization Header'}

    # Test refresh token access to jwt_required
    response = test_client.get(url, headers=make_headers(refresh_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 422
    assert json_data == {'msg': 'Only access tokens can access this endpoint'}
def test_refresh_jwt_required(app):
    url = '/refresh_protected'

    test_client = app.test_client()
    with app.test_request_context():
        access_token = create_access_token('username')
        fresh_access_token = create_access_token('username', fresh=True)
        refresh_token = create_refresh_token('username')

    response = test_client.get(url, headers=make_headers(fresh_access_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 422
    assert json_data == {'msg': 'Only refresh tokens can access this endpoint'}

    response = test_client.get(url, headers=make_headers(access_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 422
    assert json_data == {'msg': 'Only refresh tokens can access this endpoint'}

    response = test_client.get(url, headers=None)
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 401
    assert json_data == {'msg': 'Missing Authorization Header'}

    response = test_client.get(url, headers=make_headers(refresh_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 200
    assert json_data == {'foo': 'bar'}
def test_jwt_optional(app):
    url = '/optional_protected'

    test_client = app.test_client()
    with app.test_request_context():
        access_token = create_access_token('username')
        fresh_access_token = create_access_token('username', fresh=True)
        expired_token = create_access_token(
            'username', expires_delta=timedelta(minutes=-1))
        refresh_token = create_refresh_token('username')

    response = test_client.get(url, headers=make_headers(fresh_access_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 200
    assert json_data == {'foo': 'baz'}

    response = test_client.get(url, headers=make_headers(access_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 200
    assert json_data == {'foo': 'baz'}

    response = test_client.get(url, headers=make_headers(refresh_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 422
    assert json_data == {'msg': 'Only access tokens can access this endpoint'}

    response = test_client.get(url, headers=None)
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 200
    assert json_data == {'foo': 'bar'}

    response = test_client.get(url, headers=make_headers(expired_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 401
    assert json_data == {'msg': 'Token has expired'}
示例#5
0
def test_jwt_optional(app, delta_func):
    url = "/optional_protected"

    test_client = app.test_client()
    with app.test_request_context():
        access_token = create_access_token("username")
        fresh_access_token = create_access_token("username", fresh=True)
        refresh_token = create_refresh_token("username")
        expired_token = create_access_token(
            identity="username", expires_delta=delta_func(minutes=-1))

    response = test_client.get(url, headers=make_headers(fresh_access_token))
    assert response.status_code == 200
    assert response.get_json() == {"foo": "baz"}

    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 200
    assert response.get_json() == {"foo": "baz"}

    response = test_client.get(url, headers=make_headers(refresh_token))
    assert response.status_code == 422
    assert response.get_json() == {"msg": "Only access tokens are allowed"}

    response = test_client.get(url, headers=None)
    assert response.status_code == 200
    assert response.get_json() == {"foo": "bar"}

    response = test_client.get(url, headers=make_headers(expired_token))
    assert response.status_code == 401
    assert response.get_json() == {"msg": "Token has expired"}
async def test_jwt_invalid_issuer(app):
    url = "/protected"
    test_client = app.test_client()

    # No issuer claim expected or provided - OK
    access_token = await encode_token(app, {"identity": "me"})
    response = await test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 200

    # Issuer claim expected and not provided - not OK
    app.config["JWT_DECODE_ISSUER"] = "my_issuer"
    access_token = await encode_token(app, {"identity": "me"})
    response = await test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 422
    assert await response.get_json() == {
        "msg": 'Token is missing the "iss" claim'
    }

    # Issuer claim still expected and wrong one provided - not OK
    access_token = await encode_token(app, {
        "iss": "different_issuer",
        "identity": "me"
    })
    response = await test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 422
    assert await response.get_json() == {"msg": "Invalid issuer"}
def test_jwt_optional(app):
    url = '/optional_protected'

    test_client = app.test_client()
    with app.test_request_context():
        access_token = create_access_token('username')
        fresh_access_token = create_access_token('username', fresh=True)
        refresh_token = create_refresh_token('username')
        expired_token = create_access_token(
            identity='username', expires_delta=timedelta(minutes=-1))

    response = test_client.get(url, headers=make_headers(fresh_access_token))
    assert response.status_code == 200
    assert response.get_json() == {'foo': 'baz'}

    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 200
    assert response.get_json() == {'foo': 'baz'}

    response = test_client.get(url, headers=make_headers(refresh_token))
    assert response.status_code == 422
    assert response.get_json() == {'msg': 'Only access tokens are allowed'}

    response = test_client.get(url, headers=None)
    assert response.status_code == 200
    assert response.get_json() == {'foo': 'bar'}

    response = test_client.get(url, headers=make_headers(expired_token))
    assert response.status_code == 401
    assert response.get_json() == {'msg': 'Token has expired'}
async def test_refresh_jwt_required(app):
    url = "/refresh_protected"

    test_client = app.test_client()
    async with app.test_request_context("/protected"):
        access_token = create_access_token("username")
        fresh_access_token = create_access_token("username", fresh=True)
        refresh_token = create_refresh_token("username")

    response = await test_client.get(url,
                                     headers=make_headers(fresh_access_token))
    assert response.status_code == 422
    assert await response.get_json() == {
        "msg": "Only refresh tokens are allowed"
    }

    response = await test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 422
    assert await response.get_json() == {
        "msg": "Only refresh tokens are allowed"
    }

    response = await test_client.get(url, headers=None)
    assert response.status_code == 401
    assert await response.get_json() == {"msg": "Missing Authorization Header"}

    response = await test_client.get(url, headers=make_headers(refresh_token))
    assert response.status_code == 200
    assert await response.get_json() == {"foo": "bar"}
def test_revoked_token_of_different_type(app):
    jwt = get_jwt_manager(app)
    test_client = app.test_client()

    @jwt.token_in_blacklist_loader
    def check_blacklisted(decrypted_token):
        return True

    with app.test_request_context():
        access_token = create_access_token('username')
        refresh_token = create_refresh_token('username')

    app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access']
    response = test_client.get('/refresh_protected',
                               headers=make_headers(refresh_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert json_data == {'foo': 'bar'}
    assert response.status_code == 200

    app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['refresh']
    response = test_client.get('/protected',
                               headers=make_headers(access_token))
    json_data = json.loads(response.get_data(as_text=True))
    assert json_data == {'foo': 'bar'}
    assert response.status_code == 200
def test_override_jwt_location(app):
    app.config["JWT_TOKEN_LOCATION"] = ["cookies"]

    @app.route("/protected_other")
    @jwt_required(locations="headers")
    def protected_other():
        return jsonify(foo="bar")

    @app.route("/protected_invalid")
    @jwt_required(locations="INVALID_LOCATION")
    def protected_invalid():
        return jsonify(foo="bar")

    test_client = app.test_client()
    with app.test_request_context():
        access_token = create_access_token("username")

    url = "/protected_other"
    response = test_client.get(url, headers=make_headers(access_token))
    assert response.get_json() == {"foo": "bar"}
    assert response.status_code == 200

    url = "/protected"
    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 401
    assert response.get_json() == {
        "msg": 'Missing cookie "access_token_cookie"'
    }

    url = "/protected_invalid"
    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 500
def test_jwt_invalid_audience(app):
    url = '/protected'
    jwtM = get_jwt_manager(app)
    test_client = app.test_client()

    # No audience claim expected or provided - OK
    access_token = encode_token(app, {'identity': 'me'})
    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 200

    # Audience claim expected and not provided - not OK
    app.config['JWT_DECODE_AUDIENCE'] = 'my_audience'
    access_token = encode_token(app, {'identity': 'me'})
    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 422
    assert response.get_json() == {'msg': 'Token is missing the "aud" claim'}

    # Audience claim still expected and wrong one provided - not OK
    access_token = encode_token(app, {
        'aud': 'different_audience',
        'identity': 'me'
    })
    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 422
    assert response.get_json() == {'msg': 'Invalid audience'}
示例#12
0
 def test_last_action_is_refreshed(self, app, client, user_factory):
     """With every authenticated API request, the last_action column is refreshed."""
     user = user_factory.get()
     client.get("/whoami", headers=make_headers("GET", user))
     last_action_old = user.last_action
     client.get("/whoami", headers=make_headers("GET", user))
     last_action_new = user.last_action
     assert last_action_old < last_action_new
def test_no_user_lookup_loader_specified(app, url):
    test_client = app.test_client()
    with app.test_request_context():
        access_token = create_access_token("username")

    response = test_client.get(url, headers=make_headers(access_token))
    assert "@jwt.user_lookup_loader" in response.get_json()["error"]
示例#14
0
async def test_token_from_complex_object(app):
    class TestObject:
        def __init__(self, username):
            self.username = username

    jwt = get_jwt_manager(app)

    @jwt.user_claims_loader
    def add_claims(test_obj):
        return {"username": test_obj.username}

    @jwt.user_identity_loader
    def add_claims(test_obj):
        return test_obj.username

    async with app.test_request_context("/protected"):
        access_token = create_access_token(TestObject("username"))

        # Make sure the changes appear in the token
        decoded_token = decode_token(access_token)
        assert decoded_token["identity"] == "username"
        assert decoded_token["user_claims"] == {"username": "******"}

    test_client = app.test_client()
    response = await test_client.get("/protected",
                                     headers=make_headers(access_token))
    assert await response.get_json() == {"username": "******"}
    assert response.status_code == 200
def test_token_from_complex_object(app):
    class TestObject:
        def __init__(self, username):
            self.username = username

    jwt = get_jwt_manager(app)

    @jwt.user_claims_loader
    def add_claims(test_obj):
        return {'username': test_obj.username}

    @jwt.user_identity_loader
    def add_claims(test_obj):
        return test_obj.username

    with app.test_request_context():
        access_token = create_access_token(TestObject('username'))

        # Make sure the changes appear in the token
        decoded_token = decode_token(access_token)
        assert decoded_token['identity'] == 'username'
        assert decoded_token['user_claims'] == {'username': '******'}

    test_client = app.test_client()
    response = test_client.get('/protected', headers=make_headers(access_token))
    assert response.get_json() == {'username': '******'}
    assert response.status_code == 200
def test_jwt_missing_claims(app):
    url = '/protected'
    test_client = app.test_client()
    token = encode_token(app, {'foo': 'bar'})

    response = test_client.get(url, headers=make_headers(token))
    assert response.status_code == 422
    assert response.get_json() == {'msg': 'Missing claim: identity'}
示例#17
0
def test_malformed_token(app):
    url = '/protected'
    test_client = app.test_client()

    access_token = 'foobarbaz'
    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 422
    assert response.get_json() == {'msg': 'Not enough segments'}
示例#18
0
def test_malformed_token(app):
    url = "/protected"
    test_client = app.test_client()

    access_token = "foobarbaz"
    response = test_client.get(url, headers=make_headers(access_token))
    assert response.status_code == 422
    assert response.get_json() == {"msg": "Not enough segments"}
示例#19
0
def test_jwt_missing_claims(app):
    url = "/protected"
    test_client = app.test_client()
    token = encode_token(app, {"foo": "bar"})

    response = test_client.get(url, headers=make_headers(token))
    assert response.status_code == 422
    assert response.get_json() == {"msg": "Missing claim: sub"}
def test_user_claims_in_access_token_specified_at_creation(app):
    with app.test_request_context():
        access_token = create_access_token('username', user_claims={'foo': 'bar'})

    test_client = app.test_client()
    response = test_client.get('/protected', headers=make_headers(access_token))
    assert response.get_json() == {'foo': 'bar'}
    assert response.status_code == 200
示例#21
0
async def test_jwt_header_in_access_token_specified_at_creation(app):
    async with app.test_request_context("/protected"):
        access_token = create_access_token("username", headers={"foo": "bar"})

    test_client = app.test_client()
    response = await test_client.get("/protected", headers=make_headers(access_token))
    assert (await response.get_json()).get("foo") == "bar"
    assert response.status_code == 200
示例#22
0
def test_no_blacklist_callback_method_provided(app):
    app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access']

    with app.test_request_context():
        access_token = create_access_token('username')

    test_client = app.test_client()
    response = test_client.get('/protected', headers=make_headers(access_token))
    assert response.status_code == 500
示例#23
0
 def test_same_auth_token(self, app, client, user_factory):
     """Can log in and get back the same auth token if there's already a valid one."""
     user = user_factory.get()
     client.post("/auth/login",
                 headers=make_headers('POST'),
                 data=json.dumps({
                     "email": user.email,
                     "password": "******"
                 }))
     current_token = user.current_auth_token
     client.post("/auth/login",
                 headers=make_headers('POST'),
                 data=json.dumps({
                     "email": user.email,
                     "password": "******"
                 }))
     db.session.refresh(user)
     assert current_token == user.current_auth_token
def test_no_blacklist_callback_method_provided(app):
    app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access']

    with app.test_request_context():
        access_token = create_access_token('username')

    with pytest.raises(RuntimeError):
        test_client = app.test_client()
        test_client.get('/protected', headers=make_headers(access_token))
def test_jwt_missing_claims(app):
    url = '/protected'
    test_client = app.test_client()
    token = encode_token(app, {'foo': 'bar'})

    response = test_client.get(url, headers=make_headers(token))
    json_data = json.loads(response.get_data(as_text=True))
    assert response.status_code == 422
    assert json_data == {'msg': 'Missing claim: jti'}
def test_invalid_jwt(app):
    url = '/protected'
    jwtM = get_jwt_manager(app)
    test_client = app.test_client()
    invalid_token = "aaaaa.bbbbb.ccccc"

    # Test default response
    response = test_client.get(url, headers=make_headers(invalid_token))
    assert response.status_code == 422
    assert response.get_json() == {'msg': 'Invalid header padding'}

    # Test custom response
    @jwtM.invalid_token_loader
    def custom_response(err_str):
        return jsonify(msg='foobar'), 201

    response = test_client.get(url, headers=make_headers(invalid_token))
    assert response.status_code == 201
    assert response.get_json() == {'msg': 'foobar'}
def test_jwt_header_in_refresh_token_specified_at_creation(app):
    with app.test_request_context():
        refresh_token = create_refresh_token('username',
                                             headers={'foo': 'bar'})

    test_client = app.test_client()
    response = test_client.get('/protected2',
                               headers=make_headers(refresh_token))
    assert response.get_json().get("foo") == "bar"
    assert response.status_code == 200
def test_user_claim_in_refresh_token_specified_at_creation(app):
    app.config['JWT_CLAIMS_IN_REFRESH_TOKEN'] = True

    with app.test_request_context():
        refresh_token = create_refresh_token('username', user_claims={'foo': 'bar'})

    test_client = app.test_client()
    response = test_client.get('/protected2', headers=make_headers(refresh_token))
    assert response.get_json() == {'foo': 'bar'}
    assert response.status_code == 200
示例#29
0
 def test_last_action_can_get_too_old(self, app, client, user_factory):
     """An error is thrown if using an old auth token."""
     user = user_factory.get()
     headers = make_headers("GET", user)
     with freeze_time(datetime.utcnow() + app.config['AUTH_TOKEN_TIMEOUT'] +
                      timedelta(days=1)):
         resp = client.get("/whoami", headers=headers)
         assert resp.status_code == codes.UNAUTHORIZED
         assert resp.json[
             'message'] == "Auth token too old, please log in again."
async def test_no_blacklist_callback_method_provided(app):
    app.config["JWT_BLACKLIST_TOKEN_CHECKS"] = ["access"]

    async with app.test_request_context("/protected"):
        access_token = create_access_token("username")

    test_client = app.test_client()
    response = await test_client.get("/protected",
                                     headers=make_headers(access_token))
    assert response.status_code == 500