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