feat: add set password by email and by id

This commit is contained in:
2026-06-15 11:24:33 +03:00
parent db30feb0e2
commit a97605c478
4 changed files with 28 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
from src.application.abstractions import IUnitOfWork from src.application.abstractions import IUnitOfWork
from src.application.contracts import IHashService, ILogger from src.application.contracts import IHashService, ILogger
from src.application.domain.exceptions import ApplicationException from src.application.domain.exceptions import ApplicationException, BadRequestException
from src.infrastructure.database.decorators import transactional from src.infrastructure.database.decorators import transactional
@@ -16,9 +16,21 @@ class SetPasswordCommand:
self._logger = logger self._logger = logger
@transactional @transactional
async def __call__(self, user_id: str, password: str) -> bool: async def __call__(
self,
password: str,
email: str | None = None,
user_id: str | None = None,
) -> bool:
try: try:
password_hash = await self._hash_service.hash(password) password_hash = await self._hash_service.hash(password)
if email == None and user_id == None:
raise BadRequestException('An email is required')
if email != None:
user = await self._unit_of_work.user_repository.get_user_by_email(email)
user_id = user.id
await self._unit_of_work.user_repository.set_password( await self._unit_of_work.user_repository.set_password(
user_id=user_id, user_id=user_id,
password_hash=password_hash, password_hash=password_hash,

View File

@@ -23,7 +23,7 @@ async def search_parties(
q: str = Query(min_length=1, max_length=255), q: str = Query(min_length=1, max_length=255),
limit: int = Query(default=50, ge=1, le=200), limit: int = Query(default=50, ge=1, le=200),
offset: int = Query(default=0, ge=0), offset: int = Query(default=0, ge=0),
# auth: AdminAuthContext = Depends(require_admin_access), auth: AdminAuthContext = Depends(require_admin_access),
command: SearchPartiesCommand = Depends(get_search_parties_command), command: SearchPartiesCommand = Depends(get_search_parties_command),
): ):
items, total = await command(query=q, limit=limit, offset=offset) items, total = await command(query=q, limit=limit, offset=offset)

View File

@@ -104,6 +104,18 @@ async def get_user_secret_keys(
for k in keys for k in keys
] ]
@users_router.patch(path='/change_password', response_class=ORJSONResponse, status_code=status.HTTP_200_OK)
async def change_password(
request: Request,
body: SetPasswordRequest,
auth: AdminAuthContext = Depends(require_admin_role('compliance', 'superadmin')),
command: SetPasswordCommand = Depends(get_set_password_command),
):
await command(email=body.email, password=body.password)
return ORJSONResponse(content={'message': 'Password updated successfully'})
@users_router.patch(path='/{user_id}/set_password', response_class=ORJSONResponse, status_code=status.HTTP_200_OK) @users_router.patch(path='/{user_id}/set_password', response_class=ORJSONResponse, status_code=status.HTTP_200_OK)
async def set_password( async def set_password(
user_id: str, user_id: str,

View File

@@ -4,6 +4,7 @@ from src.application.domain.password_policy import validate_password_strength
class SetPasswordRequest(BaseModel): class SetPasswordRequest(BaseModel):
email: str | None = None
password: str password: str
@field_validator('password') @field_validator('password')