feat: add import
This commit is contained in:
@@ -5,7 +5,7 @@ from src.application.domain.entities.admin_user import AdminUserEntity
|
||||
|
||||
class IAdminUserRepository(ABC):
|
||||
@abstractmethod
|
||||
async def get_by_email(self, email: str) -> AdminUserEntity:
|
||||
async def get_by_login(self, login: str) -> AdminUserEntity:
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
|
||||
@@ -23,16 +23,18 @@ class AdminLoginCommand:
|
||||
self._logger = logger
|
||||
|
||||
@transactional
|
||||
async def __call__(self, *, email: str, password: str) -> AdminLoginDto:
|
||||
email = (email or '').strip().lower()
|
||||
admin = await self._unit_of_work.admin_user_repository.get_by_email(email)
|
||||
async def __call__(self, *, login: str, password: str) -> AdminLoginDto:
|
||||
login = (login or '').strip()
|
||||
if not login:
|
||||
raise ApplicationException(status_code=400, message='Login is required')
|
||||
admin = await self._unit_of_work.admin_user_repository.get_by_login(login)
|
||||
|
||||
if not admin.is_active:
|
||||
raise ApplicationException(status_code=403, message='Admin account is inactive')
|
||||
|
||||
ok = await self._hash_service.verify(plain_value=password, hashed_value=admin.password_hash)
|
||||
if not ok:
|
||||
self._logger.warning(f'Admin login failed for {email}')
|
||||
self._logger.warning(f'Admin login failed for {login}')
|
||||
raise ApplicationException(status_code=401, message='Invalid credentials')
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
@@ -47,7 +49,7 @@ class AdminLoginCommand:
|
||||
|
||||
return AdminLoginDto(
|
||||
id=admin.id,
|
||||
email=admin.email,
|
||||
login=admin.login,
|
||||
first_name=admin.first_name,
|
||||
last_name=admin.last_name,
|
||||
role=admin.role,
|
||||
|
||||
@@ -7,7 +7,7 @@ from datetime import datetime
|
||||
@dataclass
|
||||
class AdminLoginDto:
|
||||
id: str
|
||||
email: str
|
||||
login: str
|
||||
first_name: str | None
|
||||
last_name: str | None
|
||||
role: str
|
||||
|
||||
@@ -7,7 +7,7 @@ from datetime import datetime
|
||||
@dataclass
|
||||
class AdminUserEntity:
|
||||
id: str
|
||||
email: str
|
||||
login: str
|
||||
password_hash: str
|
||||
first_name: str | None
|
||||
last_name: str | None
|
||||
|
||||
@@ -12,7 +12,7 @@ from src.infrastructure.database.models.mixins import AuditTimestampsMixin, Ulid
|
||||
class AdminUserModel(Base, UlidPrimaryKeyMixin, AuditTimestampsMixin):
|
||||
__tablename__ = 'admin_users'
|
||||
|
||||
email: Mapped[str] = mapped_column(String(255), nullable=False, unique=True, index=True)
|
||||
login: Mapped[str] = mapped_column(String(255), nullable=False, unique=True, index=True)
|
||||
password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
first_name: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
||||
last_name: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
||||
|
||||
@@ -22,7 +22,7 @@ class AdminUserRepository(IAdminUserRepository):
|
||||
def _to_entity(self, m: AdminUserModel) -> AdminUserEntity:
|
||||
return AdminUserEntity(
|
||||
id=m.id,
|
||||
email=m.email,
|
||||
login=m.login,
|
||||
password_hash=m.password_hash,
|
||||
first_name=m.first_name,
|
||||
last_name=m.last_name,
|
||||
@@ -33,9 +33,9 @@ class AdminUserRepository(IAdminUserRepository):
|
||||
updated_at=m.updated_at,
|
||||
)
|
||||
|
||||
async def get_by_email(self, email: str) -> AdminUserEntity:
|
||||
async def get_by_login(self, login: str) -> AdminUserEntity:
|
||||
try:
|
||||
stmt = select(AdminUserModel).where(func.lower(AdminUserModel.email) == email.lower())
|
||||
stmt = select(AdminUserModel).where(func.lower(AdminUserModel.login) == login.lower())
|
||||
result = await self._session.execute(stmt)
|
||||
user = result.scalar_one_or_none()
|
||||
if user is None:
|
||||
|
||||
@@ -15,11 +15,11 @@ async def admin_login(
|
||||
body: AdminLoginRequest,
|
||||
command: AdminLoginCommand = Depends(get_admin_login_command),
|
||||
):
|
||||
dto = await command(email=str(body.email), password=body.password)
|
||||
dto = await command(login=body.login, password=body.password)
|
||||
return AdminLoginResponse(
|
||||
access_token=dto.access_token,
|
||||
id=dto.id,
|
||||
email=dto.email,
|
||||
login=dto.login,
|
||||
first_name=dto.first_name,
|
||||
last_name=dto.last_name,
|
||||
role=dto.role,
|
||||
@@ -40,7 +40,7 @@ async def admin_me(
|
||||
admin = await command(auth.admin_user_id)
|
||||
return AdminMeResponse(
|
||||
id=admin.id,
|
||||
email=admin.email,
|
||||
login=admin.login,
|
||||
first_name=admin.first_name,
|
||||
last_name=admin.last_name,
|
||||
role=admin.role,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from pydantic import BaseModel, EmailStr, Field
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class AdminLoginRequest(BaseModel):
|
||||
email: EmailStr
|
||||
login: str = Field(min_length=3, max_length=255)
|
||||
password: str = Field(min_length=8)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ class AdminLoginResponse(BaseModel):
|
||||
access_token: str
|
||||
token_type: str = 'Bearer'
|
||||
id: str
|
||||
email: str
|
||||
login: str
|
||||
first_name: str | None
|
||||
last_name: str | None
|
||||
role: str
|
||||
@@ -18,7 +18,7 @@ class AdminLoginResponse(BaseModel):
|
||||
|
||||
class AdminMeResponse(BaseModel):
|
||||
id: str
|
||||
email: str
|
||||
login: str
|
||||
first_name: str | None
|
||||
last_name: str | None
|
||||
role: str
|
||||
|
||||
Reference in New Issue
Block a user