From 93086b82ba788a6fa02fed2f04ee8503a08496f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Wieczorek?= Date: Wed, 19 Jul 2023 13:32:31 +0200 Subject: [PATCH 1/2] api.main: change user password to the provided new one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds initial implementation of endpoint POST `/password` to allow users to update their own password. The user can update password to any requested string, additional checks will follow. Signed-off-by: Paweł Wieczorek --- api/main.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) 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""" From 639d810d2d192b45e76efbdce1e1f32165bdd89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Wieczorek?= Date: Mon, 7 Aug 2023 15:22:05 +0200 Subject: [PATCH 2/2] e2e_tests: add test for POST '/password' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a test for changing regular user's password from API. The test depends on regular user creation test i.e. 'test_create_regular_user. Signed-off-by: Paweł Wieczorek --- tests/e2e_tests/test_password_handler.py | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/e2e_tests/test_password_handler.py 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