Exemple #1
0
 def post(self):
     args = login_parser.parse_args()
     user = User.query.filter(User.email==args.username).first()
     if user and args.password == user.password:
         auth_token = auth.encode_auth_token(user.id)
         return {'auth_token': auth_token.decode('utf-8')}
     else:
         return {'message': "Unauthorized"}, 401
Exemple #2
0
def test_decode_auth_token():
    '''Tests that a token can be decoded'''
    token = encode_auth_token('access', 123, datetime.timedelta(days=1),
                              'shazaam')
    res = decode_auth_token(token, 'shazaam')
    keys = ['sub', 'exp', 'iat', 'type']
    assert set(keys) == set(res)
    assert res['sub'] == 123
Exemple #3
0
def login():
    '''Log a user in'''
    json_data = request.get_json()
    if not json_data:
        return jsonify({'error': 'Request body must be json.'}), 400

    if not all(k in json_data for k in ('email', 'password')):
        return jsonify({'error': 'Login request must have email and password'}), 400

    db_conn = get_db(current_app, g)

    result = get_user_by_email(db_conn, json_data['email'])

    # check that user exists
    if result is None:
        return jsonify({'error': 'Invalid email address or password'}), 400

    # verify password
    salt = bytes(result['salt'])
    db_pass = bytes(result['password'])
    req_pass = bcrypt.hashpw(json_data['password'].encode('utf-8'), salt)
    if req_pass != db_pass:
        return jsonify({'error': 'Invalid email address or password'}), 400

    # generate jwt
    access_token = encode_auth_token(
        'access',
        result['id'],
        datetime.timedelta(minutes=20),
        current_app.config['SECRET_KEY']
    )

    refresh_token = encode_auth_token(
        'refresh',
        result['id'],
        datetime.timedelta(days=5),
        current_app.config['SECRET_KEY']
    )

    return jsonify({
        'message': 'Success',
        'email': result['email'],
        'userId': result['id'],
        'accessToken': access_token.decode(),
        'refreshToken': refresh_token.decode()
    }), 200
Exemple #4
0
def authenticate():
    ''' Verifies a refresh token and generates an access token '''
    token_data = get_data_from_token(request.headers, current_app.config['SECRET_KEY'])
    if 'error' in token_data:
        return jsonify({'error': token_data['error']}), token_data['status_code']

    if token_data['type'] != 'refresh':
        return jsonify({'error': 'Invalid token type'}), 401

    db_conn = get_db(current_app, g)
    user = get_user_by_id(db_conn, token_data['sub'])


    # create new access token
    access_token = encode_auth_token(
        'access',
        token_data['sub'],
        datetime.timedelta(minutes=20),
        current_app.config['SECRET_KEY']
    )

    response_data = {
        'message': 'Success',
        'userId': token_data['sub'],
        'email': user['email'],
        'accessToken': access_token.decode()
    }

    print(token_data['exp'])
    print(datetime.datetime.utcnow())

    # create a new refresh token if the current one is about to expire
    expiry_time = datetime.datetime.fromtimestamp(token_data['exp'])
    time_til_expiry = expiry_time - datetime.datetime.utcnow()
    if time_til_expiry <= datetime.timedelta(minutes=30):
        refresh_token = encode_auth_token(
            'refresh',
            token_data['sub'],
            datetime.timedelta(days=5),
            current_app.config['SECRET_KEY']
        )
        response_data['refreshToken'] = refresh_token.decode()

    return jsonify(response_data)
Exemple #5
0
def test_save_existing_project_fail(temp_app, temp_db):
    '''Tests various failure cases when saving an existing project'''

    # Tests trying to save a nonexistent project
    login_res = login_mackland(temp_app)
    auth_token = login_res['accessToken']
    project = generate_temp_project()
    project['id'] = 0
    res = put_save(project, auth_token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 404
    assert res_data['error'] == 'Project does not exist'

    # Tests trying to save a project created by a different user
    project['id'] = 1
    res = put_save(project, auth_token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 403
    assert res_data['error'] == 'Forbidden: project belongs to another user'

    # Tests trying to save a project with no auth header
    res = temp_app.put('/save',
                       data=json.dumps(project),
                       content_type='application/json')
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to save a project with no auth token
    res = put_save(project, '', temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to save a project with an expired auth token
    token = generate_expired_token('access',
                                   temp_app.application.config['SECRET_KEY'])
    res = put_save(project, token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to save a project with an invalid auth token
    token = generate_invalid_token('access')
    res = put_save(project, token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to use a refresh token to access projects
    token = encode_auth_token('refresh', 1, datetime.timedelta(days=3),
                              temp_app.application.config['SECRET_KEY'])
    res = put_save(project, token.decode(), temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token type'
Exemple #6
0
def test_get_new_refresh_token(temp_app, temp_db):
    '''Tests sending a refresh token that's about to expire, and getting a new one'''
    auth_token = encode_auth_token('refresh', 1,
                                   datetime.timedelta(minutes=30),
                                   temp_app.application.config['SECRET_KEY'])
    res = get_authenticate(auth_token.decode(), temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 200
    keys = ['message', 'userId', 'email', 'accessToken', 'refreshToken']
    assert set(keys) == set(res_data)
    assert res_data['email'] == '*****@*****.**'
Exemple #7
0
def test_save_new_project_fail(temp_app, temp_db):
    '''Tests various failure cases when trying to save a new project'''

    # Tests trying to save a project with a duplicate name under the same user
    login_res = login_hello(temp_app)
    auth_token = login_res['accessToken']

    data = generate_temp_project()
    data['name'] = 'New Project 1'

    res = post_save(data, auth_token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 400
    assert res_data['error'] == 'A project with that name already exists'

    # Tests trying to save project with no auth header
    data = generate_temp_project()
    res = temp_app.post('/save',
                        data=json.dumps(data),
                        content_type='application/json')
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to save project with no auth token
    res = post_save(data, '', temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to save project with an expired token
    token = generate_expired_token('access',
                                   temp_app.application.config['SECRET_KEY'])
    res = post_save(data, token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to save project with a token signed with the wrong key
    token = generate_invalid_token('access')
    res = post_save(data, token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to use a refresh token to access projects
    token = encode_auth_token('refresh', 1, datetime.timedelta(days=3),
                              temp_app.application.config['SECRET_KEY'])
    res = post_save(data, token.decode(), temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token type'
Exemple #8
0
def test_delete_project_fail(temp_app, temp_db):
    '''Tests various failure cases when trying to delete a project'''

    # Tests trying to delete a nonexistent project'''
    login_res = login_mackland(temp_app)
    auth_token = login_res['accessToken']
    res = delete_project(0, auth_token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 400
    assert res_data['error'] == 'Project does not exist'

    # Tests trying to delete a project created by a different user
    res = delete_project(1, auth_token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 403
    assert res_data['error'] == 'Forbidden: project belongs to another user'

    # Tests trying to delete project with no auth header
    res = temp_app.delete('/project/1')
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to delete project with no auth token
    res = temp_app.delete('/project/1', headers=dict(Authorization='Bearer '))
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to delete project with an expired token
    token = generate_expired_token('access',
                                   temp_app.application.config['SECRET_KEY'])
    res = delete_project(1, token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to delete project with a token signed with the wrong key
    token = generate_invalid_token('access')
    res = delete_project(1, token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to use a refresh token to access projects
    token = encode_auth_token('refresh', 1, datetime.timedelta(days=3),
                              temp_app.application.config['SECRET_KEY'])
    res = delete_project(1, token.decode(), temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token type'
Exemple #9
0
def test_get_projects_fail(temp_app, temp_db):
    '''Tests getting projects with various failure cases'''

    # Tests trying to get projects with no auth header
    res = temp_app.get('/projects')
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to get projects with no auth header
    res = temp_app.get('/projects', headers=dict(Authorization='Bearer '))
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to get projects with an expired token
    token = generate_expired_token('access',
                                   temp_app.application.config['SECRET_KEY'])
    res = get_projects(token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to get projects with a token signed with the wrong key
    token = generate_invalid_token('access')
    res = get_projects(token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to use a refresh token to access projects
    token = encode_auth_token('refresh', 1, datetime.timedelta(days=3),
                              temp_app.application.config['SECRET_KEY'])
    res = get_projects(token.decode(), temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token type'
Exemple #10
0
def test_authenticate_fail(temp_app, temp_db):
    '''Tests various failure cases when verifying a jwt'''

    # Tests verifying with no auth header
    res = temp_app.get('auth/authenticate')
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests verifying with no auth token
    res = get_authenticate('', temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'No authentication provided'

    # Tests trying to verify with an expired token
    auth_token = generate_expired_token(
        'refresh', temp_app.application.config['SECRET_KEY'])
    res = get_authenticate(auth_token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to verify with a token signed with the wrong key
    auth_token = generate_invalid_token('refresh')
    res = get_authenticate(auth_token, temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token'

    # Tests trying to use an access token to refresh
    token = encode_auth_token('access', 1, datetime.timedelta(days=3),
                              temp_app.application.config['SECRET_KEY'])
    res = get_authenticate(token.decode(), temp_app)
    res_data = json.loads(res.data)
    assert res.status_code == 401
    assert res_data['error'] == 'Invalid token type'
Exemple #11
0
def test_encode_auth_token():
    '''Tests that a token can be encoded'''
    token = encode_auth_token('access', 134, datetime.timedelta(days=1),
                              'shazaam')
    assert isinstance(token, bytes)
Exemple #12
0
def test_decode_token_wrong_key():
    '''Tests that a token can't be decoded with the wrong key'''
    token = encode_auth_token('access', 123, datetime.timedelta(days=1),
                              'shazaam')
    res = decode_auth_token(token, 'kazaam')
    assert res is None