Skip to content

Commit dc7c7bb

Browse files
committed
update user passwrrod
1 parent fa5077b commit dc7c7bb

File tree

3 files changed

+50
-11
lines changed

3 files changed

+50
-11
lines changed

packages/postgres-database/src/simcore_postgres_database/utils_users.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,23 @@ async def update_user_phone(
297297
users.update().where(users.c.id == user_id).values(phone=phone)
298298
)
299299

300+
async def update_user_password_hash(
301+
self,
302+
connection: AsyncConnection | None = None,
303+
*,
304+
user_id: int,
305+
password_hash: str,
306+
) -> None:
307+
assert (
308+
password_hash.strip()
309+
), f"Password hash cannot be empty: {password_hash}" # nosec
310+
async with transaction_context(self._engine, connection) as conn:
311+
await conn.execute(
312+
users_secrets.update()
313+
.where(users_secrets.c.user_id == user_id)
314+
.values(password_hash=password_hash)
315+
)
316+
300317
async def is_email_used(
301318
self, connection: AsyncConnection | None = None, *, email: str
302319
) -> bool:

services/web/server/src/simcore_service_webserver/login/_auth_service.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,29 @@ async def check_authorized_user_in_product_or_raise(
138138
raise web.HTTPUnauthorized(
139139
text=MSG_UNKNOWN_EMAIL, content_type=MIMETYPE_APPLICATION_JSON
140140
)
141+
142+
143+
async def update_user_password(
144+
app: web.Application,
145+
*,
146+
user_id: int,
147+
current_password: str,
148+
new_password: str,
149+
) -> None:
150+
"""Updates user password after verifying current password"""
151+
repo = UsersRepo(get_asyncpg_engine(app))
152+
153+
# Get current password hash
154+
current_password_hash = await repo.get_password_hash(user_id=user_id)
155+
156+
# Verify current password
157+
if not security_service.check_password(current_password, current_password_hash):
158+
raise web.HTTPUnauthorized(
159+
text=MSG_WRONG_PASSWORD, content_type=MIMETYPE_APPLICATION_JSON
160+
)
161+
162+
# Encrypt new password and update
163+
new_password_hash = security_service.encrypt_password(new_password)
164+
await repo.update_user_password_hash(
165+
user_id=user_id, password_hash=new_password_hash
166+
)

services/web/server/src/simcore_service_webserver/login/_controller/rest/change.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from ....db.plugin import get_asyncpg_engine
1212
from ....products import products_web
1313
from ....products.models import Product
14-
from ....security import security_service
1514
from ....users import users_service
1615
from ....utils import HOUR
1716
from ....utils_rate_limiting import global_rate_limit_route
@@ -268,10 +267,9 @@ async def initiate_change_email(request: web.Request):
268267
@login_required
269268
async def change_password(request: web.Request):
270269

271-
db: AsyncpgStorage = get_plugin_storage(request.app)
272270
passwords = await parse_request_body_as(ChangePasswordBody, request)
273-
274-
user = await _auth_service.get_user_or_none(request.app, user_id=user["id"])
271+
user_id = request[RQT_USERID_KEY]
272+
user = await _auth_service.get_user_or_none(request.app, user_id=user_id)
275273

276274
await _auth_service.check_authorized_user_credentials_or_raise(
277275
request.app,
@@ -280,13 +278,11 @@ async def change_password(request: web.Request):
280278
product=products_web.get_current_product(request),
281279
)
282280

283-
await db.update_user(
284-
dict(user),
285-
{
286-
"password_hash": security_service.encrypt_password(
287-
passwords.new.get_secret_value()
288-
)
289-
},
281+
await _auth_service.update_user_password(
282+
request.app,
283+
user_id=user_id,
284+
current_password=passwords.current.get_secret_value(),
285+
new_password=passwords.new.get_secret_value(),
290286
)
291287

292288
return flash_response(MSG_PASSWORD_CHANGED)

0 commit comments

Comments
 (0)