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.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
@@ -16,9 +16,21 @@ class SetPasswordCommand:
self._logger = logger
@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:
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(
user_id=user_id,
password_hash=password_hash,

View File

@@ -23,7 +23,7 @@ async def search_parties(
q: str = Query(min_length=1, max_length=255),
limit: int = Query(default=50, ge=1, le=200),
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),
):
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
]
@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)
async def set_password(
user_id: str,

View File

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