def test_should_allow_valid_token_with_post_body(notify_api, notify_db, notify_db_session, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: service = Service.query.get(sample_api_key.service_id) data = { 'name': 'new name', 'users': [service.users[0].id], 'limit': 1000, 'restricted': False, 'active': False } token = create_jwt_token( request_method="PUT", request_path=url_for('service.update_service', service_id=sample_api_key.service_id), secret=get_unsigned_secret(sample_api_key.id), client_id=sample_api_key.service_id, request_body=json.dumps(data)) headers = [('Content-Type', 'application/json'), ('Authorization', 'Bearer {}'.format(token))] response = client.put(url_for('service.update_service', service_id=service.id), data=json.dumps(data), headers=headers) assert response.status_code == 200
def test_authentication_returns_token_expired_when_service_uses_expired_key_and_has_multiple_keys( notify_api, notify_db, notify_db_session, sample_api_key ): with notify_api.test_request_context(): with notify_api.test_client() as client: expired_key = {"service_id": sample_api_key.service_id, "name": "expired_key"} expired_api_key = ApiKey(**expired_key) save_model_api_key(expired_api_key) another_key = {"service_id": sample_api_key.service_id, "name": "another_key"} api_key = ApiKey(**another_key) save_model_api_key(api_key) token = create_jwt_token( request_method="GET", request_path=url_for("service.get_service"), secret=get_unsigned_secret(expired_api_key.id), client_id=sample_api_key.service_id, ) # expire the key expire_the_key = { "id": expired_api_key.id, "service_id": sample_api_key.service_id, "name": "expired_key", "expiry_date": datetime.now() + timedelta(hours=-2), } save_model_api_key(expired_api_key, expire_the_key) response = client.get(url_for("service.get_service"), headers={"Authorization": "Bearer {}".format(token)}) assert response.status_code == 403 data = json.loads(response.get_data()) assert data["error"] == "Invalid token: signature"
def test_authentication_passes_when_service_has_multiple_keys_some_expired( notify_api, notify_db, notify_db_session, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: exprired_key = { 'service_id': sample_api_key.service_id, 'name': 'expired_key', 'expiry_date': datetime.now() } expired_api_key = ApiKey(**exprired_key) save_model_api_key(expired_api_key) another_key = { 'service_id': sample_api_key.service_id, 'name': 'another_key' } api_key = ApiKey(**another_key) save_model_api_key(api_key) token = create_jwt_token( request_method="GET", request_path=url_for('service.get_service'), secret=get_unsigned_secret(api_key.id), client_id=sample_api_key.service_id) response = client.get( url_for('service.get_service'), headers={'Authorization': 'Bearer {}'.format(token)}) assert response.status_code == 200
def test_authentication_returns_token_expired_when_service_uses_expired_key_and_has_multiple_keys( notify_api, notify_db, notify_db_session, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: expired_key = { 'service_id': sample_api_key.service_id, 'name': 'expired_key' } expired_api_key = ApiKey(**expired_key) save_model_api_key(expired_api_key) another_key = { 'service_id': sample_api_key.service_id, 'name': 'another_key' } api_key = ApiKey(**another_key) save_model_api_key(api_key) token = create_jwt_token( request_method="GET", request_path=url_for('service.get_service'), secret=get_unsigned_secret(expired_api_key.id), client_id=sample_api_key.service_id) # expire the key expire_the_key = { 'id': expired_api_key.id, 'service_id': sample_api_key.service_id, 'name': 'expired_key', 'expiry_date': datetime.now() + timedelta(hours=-2) } save_model_api_key(expired_api_key, expire_the_key) response = client.get( url_for('service.get_service'), headers={'Authorization': 'Bearer {}'.format(token)}) assert response.status_code == 403 data = json.loads(response.get_data()) assert data['error'] == 'Invalid token: signature'
def test_get_unsigned_secret_returns_key(notify_api, notify_db, notify_db_session, sample_api_key): unsigned_api_key = get_unsigned_secret(sample_api_key.id) assert sample_api_key.secret != unsigned_api_key assert unsigned_api_key == _get_secret(sample_api_key.secret)
def test_authentication_returns_token_expired_when_service_uses_expired_key_and_has_multiple_keys( client, sample_api_key): expired_key = { 'service': sample_api_key.service, 'name': 'expired_key', 'created_by': sample_api_key.created_by, 'key_type': KEY_TYPE_NORMAL } expired_api_key = ApiKey(**expired_key) save_model_api_key(expired_api_key) another_key = { 'service': sample_api_key.service, 'name': 'another_key', 'created_by': sample_api_key.created_by, 'key_type': KEY_TYPE_NORMAL } api_key = ApiKey(**another_key) save_model_api_key(api_key) token = create_jwt_token(secret=get_unsigned_secret(expired_api_key.id), client_id=str(sample_api_key.service_id)) expire_api_key(service_id=sample_api_key.service_id, api_key_id=expired_api_key.id) request.headers = {'Authorization': 'Bearer {}'.format(token)} with pytest.raises(AuthError) as exc: validate_service_api_key_auth() assert exc.value.short_message == 'Invalid token: API key revoked' assert exc.value.service_id == expired_api_key.service_id assert exc.value.api_key_id == expired_api_key.id
def test_authentication_returns_token_expired_when_service_uses_expired_key_and_has_multiple_keys( client, sample_api_key): expired_key = { "service": sample_api_key.service, "name": "expired_key", "created_by": sample_api_key.created_by, "key_type": KEY_TYPE_NORMAL, } expired_api_key = ApiKey(**expired_key) save_model_api_key(expired_api_key) another_key = { "service": sample_api_key.service, "name": "another_key", "created_by": sample_api_key.created_by, "key_type": KEY_TYPE_NORMAL, } api_key = ApiKey(**another_key) save_model_api_key(api_key) token = create_jwt_token( secret=get_unsigned_secret(expired_api_key.id), client_id=str(sample_api_key.service_id), ) expire_api_key(service_id=sample_api_key.service_id, api_key_id=expired_api_key.id) request.headers = {"Authorization": "Bearer {}".format(token)} with pytest.raises(AuthError) as exc: requires_auth() assert exc.value.short_message == "Invalid token: API key revoked" assert exc.value.service_id == expired_api_key.service_id assert exc.value.api_key_id == expired_api_key.id
def test_authentication_passes_when_service_has_multiple_keys_some_expired( client, sample_api_key): expired_key_data = {'service': sample_api_key.service, 'name': 'expired_key', 'expiry_date': datetime.utcnow(), 'created_by': sample_api_key.created_by, 'key_type': KEY_TYPE_NORMAL } expired_key = ApiKey(**expired_key_data) save_model_api_key(expired_key) another_key = {'service': sample_api_key.service, 'name': 'another_key', 'created_by': sample_api_key.created_by, 'key_type': KEY_TYPE_NORMAL } api_key = ApiKey(**another_key) save_model_api_key(api_key) token = create_jwt_token( secret=get_unsigned_secret(api_key.id), client_id=str(sample_api_key.service_id)) response = client.get( '/notifications', headers={'Authorization': 'Bearer {}'.format(token)}) assert response.status_code == 200
def create_api_key(service_id=None): fetched_service = dao_fetch_service_by_id(service_id=service_id) valid_api_key = api_key_schema.load(request.get_json()).data valid_api_key.service = fetched_service save_model_api_key(valid_api_key) unsigned_api_key = get_unsigned_secret(valid_api_key.id) return jsonify(data=unsigned_api_key), 201
def test_should_allow_auth_with_api_key_scheme(client, sample_api_key, scheme): api_key_secret = get_unsigned_secret(sample_api_key.id) response = client.get( "/notifications", headers={"Authorization": f"{scheme} {api_key_secret}"}) assert response.status_code == 200
def test_should_allow_auth_with_api_key_scheme_36_chars_or_longer( client, sample_api_key): api_key_secret = "fhsdkjhfdsfhsd" + get_unsigned_secret(sample_api_key.id) response = client.get( "/notifications", headers={"Authorization": f"ApiKey-v1 {api_key_secret}"}) assert response.status_code == 200
def test_should_not_allow_expired_api_key(client, sample_api_key): api_key_secret = get_unsigned_secret(sample_api_key.id) expire_api_key(service_id=sample_api_key.service_id, api_key_id=sample_api_key.id) response = client.get( "/notifications", headers={"Authorization": f"ApiKey-v1 {api_key_secret}"}) assert response.status_code == 403 error_message = json.loads(response.get_data()) assert error_message["message"] == { "token": ["Invalid token: API key revoked"] }
def renew_api_key(service_id=None): try: service = get_model_services(service_id=service_id) except DataError: return jsonify(result="error", message="Invalid service id"), 400 except NoResultFound: return jsonify(result="error", message="Service not found"), 404 try: # create a new one # TODO: what validation should be done here? secret_name = request.get_json()['name'] key = ApiKey(service=service, name=secret_name) save_model_api_key(key) except DAOException as e: return jsonify(result='error', message=str(e)), 400 unsigned_api_key = get_unsigned_secret(key.id) return jsonify(data=unsigned_api_key), 201
def test_authentication_passes_when_service_has_multiple_keys_some_expired( notify_api, notify_db, notify_db_session, sample_api_key ): with notify_api.test_request_context(): with notify_api.test_client() as client: exprired_key = { "service_id": sample_api_key.service_id, "name": "expired_key", "expiry_date": datetime.now(), } expired_api_key = ApiKey(**exprired_key) save_model_api_key(expired_api_key) another_key = {"service_id": sample_api_key.service_id, "name": "another_key"} api_key = ApiKey(**another_key) save_model_api_key(api_key) token = create_jwt_token( request_method="GET", request_path=url_for("service.get_service"), secret=get_unsigned_secret(api_key.id), client_id=sample_api_key.service_id, ) response = client.get(url_for("service.get_service"), headers={"Authorization": "Bearer {}".format(token)}) assert response.status_code == 200
def test_should_allow_valid_token_with_post_body(notify_api, notify_db, notify_db_session, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: service = Service.query.get(sample_api_key.service_id) data = { "name": "new name", "users": [service.users[0].id], "limit": 1000, "restricted": False, "active": False, } token = create_jwt_token( request_method="PUT", request_path=url_for("service.update_service", service_id=sample_api_key.service_id), secret=get_unsigned_secret(sample_api_key.id), client_id=sample_api_key.service_id, request_body=json.dumps(data), ) headers = [("Content-Type", "application/json"), ("Authorization", "Bearer {}".format(token))] response = client.put( url_for("service.update_service", service_id=service.id), data=json.dumps(data), headers=headers ) assert response.status_code == 200
def test_authentication_passes_when_service_has_multiple_keys_some_expired( client, sample_api_key): expired_key_data = { "service": sample_api_key.service, "name": "expired_key", "expiry_date": datetime.utcnow(), "created_by": sample_api_key.created_by, "key_type": KEY_TYPE_NORMAL, } expired_key = ApiKey(**expired_key_data) save_model_api_key(expired_key) another_key = { "service": sample_api_key.service, "name": "another_key", "created_by": sample_api_key.created_by, "key_type": KEY_TYPE_NORMAL, } api_key = ApiKey(**another_key) save_model_api_key(api_key) token = create_jwt_token(secret=get_unsigned_secret(api_key.id), client_id=str(sample_api_key.service_id)) response = client.get("/notifications", headers={"Authorization": "Bearer {}".format(token)}) assert response.status_code == 200
def test_get_api_key_by_secret(sample_api_key): unsigned_secret = get_unsigned_secret(sample_api_key.id) assert get_api_key_by_secret(unsigned_secret).id == sample_api_key.id with pytest.raises(NoResultFound): get_api_key_by_secret("nope")
def test_get_unsigned_secret_returns_key(sample_api_key): unsigned_api_key = get_unsigned_secret(sample_api_key.id) assert sample_api_key.secret != unsigned_api_key assert unsigned_api_key == get_secret(sample_api_key.secret)
def test_get_unsigned_secret_returns_key(sample_api_key): unsigned_api_key = get_unsigned_secret(sample_api_key.id) assert sample_api_key._secret != unsigned_api_key assert unsigned_api_key == sample_api_key.secret