diff --git a/api/main.py b/api/main.py index 61034022..dffc6f37 100644 --- a/api/main.py +++ b/api/main.py @@ -352,6 +352,28 @@ async def whoami(current_user: User = Depends(get_user)): return current_user +@app.post('/password') +async def reset_password( + username: str, current_password: Password, new_password: Password): + """Set a new password for an authenticated user""" + authenticated = await auth.authenticate_user( + username, current_password.password.get_secret_value()) + if not authenticated: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Incorrect username or password", + ) + + user = await db.find_one_by_attributes( + User, {'profile.username': username}) + user.profile.hashed_password = auth.get_password_hash( + new_password.password.get_secret_value()) + obj = await db.update(user) + await pubsub.publish_cloudevent('user', {'op': 'updated', + 'id': str(obj.id)}) + return obj + + @app.post('/hash') def get_password_hash(password: Password): """Get a password hash from the provided string password""" diff --git a/tests/e2e_tests/test_password_handler.py b/tests/e2e_tests/test_password_handler.py new file mode 100644 index 00000000..c239b7d7 --- /dev/null +++ b/tests/e2e_tests/test_password_handler.py @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Copyright (C) 2023 Collabora Limited +# Author: Paweł Wieczorek + +"""End-to-end test functions for KernelCI API password reset handler""" + +import json +import pytest + + +@pytest.mark.dependency( + depends=["e2e_tests/test_user_creation.py::test_create_regular_user"], + scope="session", +) +@pytest.mark.order("last") +@pytest.mark.asyncio +async def test_password_endpoint(test_async_client): + """ + Test Case : Test KernelCI API /password endpoint to set a new password + when requested with current user's password + Expected Result : + HTTP Response Code 200 OK + """ + response = await test_async_client.post( + "password?username=test_user", + data=json.dumps( + { + "current_password": {"password": "test"}, + "new_password": {"password": "foo"}, + } + ), + ) + assert response.status_code == 200