forked from sh-edraft.de/sh_discord_bot
Improved api #70
This commit is contained in:
parent
5cd91d8341
commit
119f4e9d04
@ -46,7 +46,7 @@ class Application(DiscordBotApplicationABC):
|
|||||||
if self._feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
if self._feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
||||||
self._api.start()
|
self._api.start()
|
||||||
|
|
||||||
if self._feature_flags.get_flag(FeatureFlagsEnum.api_only):
|
if self._feature_flags.get_flag(FeatureFlagsEnum.api_only) and self._environment.environment_name == 'development':
|
||||||
self._api.join()
|
self._api.join()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"Dependencies": [
|
"Dependencies": [
|
||||||
"cpl-core==2022.10.0.post6",
|
"cpl-core==2022.10.0.post6",
|
||||||
"cpl-translation==2022.10.0.post1",
|
"cpl-translation==2022.10.0.post1",
|
||||||
"cpl-query==2022.10.0",
|
"cpl-query==2022.10.0.post1",
|
||||||
"cpl-discord==2022.10.0.post5"
|
"cpl-discord==2022.10.0.post5"
|
||||||
],
|
],
|
||||||
"DevDependencies": [
|
"DevDependencies": [
|
||||||
|
@ -163,7 +163,7 @@
|
|||||||
"auth": {
|
"auth": {
|
||||||
"confirmation": {
|
"confirmation": {
|
||||||
"subject": "E-Mail für {} {} bestätigen",
|
"subject": "E-Mail für {} {} bestätigen",
|
||||||
"message": "Öffne den Link um die E-Mail zu bestätigen:\n{}auth/forgot-password/{}"
|
"message": "Öffne den Link um die E-Mail zu bestätigen:\n{}auth/register/{}"
|
||||||
},
|
},
|
||||||
"forgot_password": {
|
"forgot_password": {
|
||||||
"subject": "Passwort für {} {} zurücksetzen",
|
"subject": "Passwort für {} {} zurücksetzen",
|
||||||
|
@ -9,7 +9,6 @@ from bot_api.model.email_string_dto import EMailStringDTO
|
|||||||
from bot_api.model.reset_password_dto import ResetPasswordDTO
|
from bot_api.model.reset_password_dto import ResetPasswordDTO
|
||||||
from bot_api.model.token_dto import TokenDTO
|
from bot_api.model.token_dto import TokenDTO
|
||||||
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
||||||
from bot_data.model.auth_user import AuthUser
|
|
||||||
|
|
||||||
|
|
||||||
class AuthServiceABC(ABC):
|
class AuthServiceABC(ABC):
|
||||||
@ -18,16 +17,16 @@ class AuthServiceABC(ABC):
|
|||||||
def __init__(self): pass
|
def __init__(self): pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_all_auth_users_async(self) -> List[AuthUser]: pass
|
async def get_all_auth_users_async(self) -> List[AuthUserDTO]: pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO: pass
|
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO: pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_auth_user_by_email_async(self, email: str) -> AuthUser: pass
|
async def get_auth_user_by_email_async(self, email: str) -> AuthUserDTO: pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def find_auth_user_by_email_async(self, email: str) -> AuthUser: pass
|
async def find_auth_user_by_email_async(self, email: str) -> AuthUserDTO: pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def add_auth_user_async(self, user_dto: AuthUserDTO) -> int: pass
|
async def add_auth_user_async(self, user_dto: AuthUserDTO) -> int: pass
|
||||||
|
@ -10,7 +10,7 @@ from flask import Flask
|
|||||||
from bot_api.abc.auth_service_abc import AuthServiceABC
|
from bot_api.abc.auth_service_abc import AuthServiceABC
|
||||||
from bot_api.api import Api
|
from bot_api.api import Api
|
||||||
from bot_api.api_thread import ApiThread
|
from bot_api.api_thread import ApiThread
|
||||||
from bot_api.controller.api_controller import ApiController
|
from bot_api.controller.gui_controller import GuiController
|
||||||
from bot_api.controller.auth_controller import AuthController
|
from bot_api.controller.auth_controller import AuthController
|
||||||
from bot_api.service.auth_service import AuthService
|
from bot_api.service.auth_service import AuthService
|
||||||
from bot_core.abc.module_abc import ModuleABC
|
from bot_core.abc.module_abc import ModuleABC
|
||||||
@ -38,4 +38,4 @@ class ApiModule(ModuleABC):
|
|||||||
|
|
||||||
services.add_transient(AuthServiceABC, AuthService)
|
services.add_transient(AuthServiceABC, AuthService)
|
||||||
services.add_transient(AuthController)
|
services.add_transient(AuthController)
|
||||||
services.add_transient(ApiController)
|
services.add_transient(GuiController)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"Authentication": {
|
"Authentication": {
|
||||||
"SecretKey": "F3b5LDz+#Jvzg=W!@gsa%xsF",
|
"SecretKey": "F3b5LDz+#Jvzg=W!@gsa%xsF",
|
||||||
"Issuer": "http://localhost:5000",
|
"Issuer": "http://localhost:5000",
|
||||||
"Audience": "http://localhost:5000",
|
"Audience": "http://localhost:4200",
|
||||||
"TokenExpireTime": 1,
|
"TokenExpireTime": 1,
|
||||||
"RefreshTokenExpireTime": 7
|
"RefreshTokenExpireTime": 7
|
||||||
},
|
},
|
||||||
|
@ -40,21 +40,25 @@ class AuthController:
|
|||||||
|
|
||||||
@Route.get(f'{BasePath}/users')
|
@Route.get(f'{BasePath}/users')
|
||||||
async def get_all_users(self) -> Response:
|
async def get_all_users(self) -> Response:
|
||||||
return jsonify(await self._auth_service.get_all_auth_users_async())
|
result = await self._auth_service.get_all_auth_users_async()
|
||||||
|
return jsonify(result.select(lambda x: x.to_dict()))
|
||||||
|
|
||||||
@Route.post(f'{BasePath}/users/get/filtered')
|
@Route.post(f'{BasePath}/users/get/filtered')
|
||||||
async def get_filtered_users(self) -> Response:
|
async def get_filtered_users(self) -> Response:
|
||||||
dto: AuthUserSelectCriteria = JSONProcessor.process(AuthUserSelectCriteria, request.get_json(force=True, silent=True))
|
dto: AuthUserSelectCriteria = JSONProcessor.process(AuthUserSelectCriteria, request.get_json(force=True, silent=True))
|
||||||
result = await self._auth_service.get_filtered_auth_users_async(dto)
|
result = await self._auth_service.get_filtered_auth_users_async(dto)
|
||||||
|
result.result = result.result.select(lambda x: x.to_dict())
|
||||||
return jsonify(result.to_dict())
|
return jsonify(result.to_dict())
|
||||||
|
|
||||||
@Route.get(f'{BasePath}/users/get/<email>')
|
@Route.get(f'{BasePath}/users/get/<email>')
|
||||||
async def get_user_from_email(self, email: str) -> Response:
|
async def get_user_from_email(self, email: str) -> Response:
|
||||||
return jsonify(await self._auth_service.get_auth_user_by_email_async(email))
|
result = await self._auth_service.get_auth_user_by_email_async(email)
|
||||||
|
return jsonify(result.to_dict())
|
||||||
|
|
||||||
@Route.get(f'{BasePath}/users/find/<email>')
|
@Route.get(f'{BasePath}/users/find/<email>')
|
||||||
async def find_user_from_email(self, email: str) -> Response:
|
async def find_user_from_email(self, email: str) -> Response:
|
||||||
return jsonify(await self._auth_service.find_auth_user_by_email_async(email))
|
result = await self._auth_service.find_auth_user_by_email_async(email)
|
||||||
|
return jsonify(result.to_dict())
|
||||||
|
|
||||||
@Route.post(f'{BasePath}/register')
|
@Route.post(f'{BasePath}/register')
|
||||||
async def register(self):
|
async def register(self):
|
||||||
|
@ -12,7 +12,8 @@ from bot_api.model.version_dto import VersionDTO
|
|||||||
from bot_api.route.route import Route
|
from bot_api.route.route import Route
|
||||||
|
|
||||||
|
|
||||||
class ApiController:
|
class GuiController:
|
||||||
|
BasePath = f'/api/gui'
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -32,13 +33,13 @@ class ApiController:
|
|||||||
self._mail_settings = mail_settings
|
self._mail_settings = mail_settings
|
||||||
self._mailer = mailer
|
self._mailer = mailer
|
||||||
|
|
||||||
@Route.route('/api/api-version')
|
@Route.get(f'{BasePath}/api-version')
|
||||||
async def api_version(self):
|
async def api_version(self):
|
||||||
import bot_api
|
import bot_api
|
||||||
version = bot_api.version_info
|
version = bot_api.version_info
|
||||||
return VersionDTO(version.major, version.minor, version.micro).to_dict()
|
return VersionDTO(version.major, version.minor, version.micro).to_dict()
|
||||||
|
|
||||||
@Route.route('/api/settings')
|
@Route.get(f'{BasePath}/settings')
|
||||||
async def settings(self):
|
async def settings(self):
|
||||||
# TODO: Authentication
|
# TODO: Authentication
|
||||||
import bot_api
|
import bot_api
|
||||||
@ -59,7 +60,7 @@ class ApiController:
|
|||||||
self._mail_settings.user_name,
|
self._mail_settings.user_name,
|
||||||
).to_dict()
|
).to_dict()
|
||||||
|
|
||||||
@Route.route('/api/send-test-mail/<email>')
|
@Route.get(f'{BasePath}/send-test-mail/<email>')
|
||||||
async def send_test_mail(self, email: str):
|
async def send_test_mail(self, email: str):
|
||||||
# TODO: Authentication
|
# TODO: Authentication
|
||||||
mail = EMail()
|
mail = EMail()
|
@ -13,7 +13,7 @@ class AuthUserSelectCriteria(SelectCriteriaABC):
|
|||||||
first_name: str,
|
first_name: str,
|
||||||
last_name: str,
|
last_name: str,
|
||||||
email: str,
|
email: str,
|
||||||
auth_role=0
|
auth_role: int
|
||||||
):
|
):
|
||||||
SelectCriteriaABC.__init__(self, page_index, page_size, sort_direction, sort_column)
|
SelectCriteriaABC.__init__(self, page_index, page_size, sort_direction, sort_column)
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import traceback
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from cpl_core.console import Console
|
|
||||||
|
|
||||||
from bot_api.abc.dto_abc import DtoABC
|
from bot_api.abc.dto_abc import DtoABC
|
||||||
from bot_data.model.auth_role_enum import AuthRoleEnum
|
from bot_data.model.auth_role_enum import AuthRoleEnum
|
||||||
|
|
||||||
@ -14,7 +11,7 @@ class AuthUserDTO(DtoABC):
|
|||||||
id: int,
|
id: int,
|
||||||
first_name: str,
|
first_name: str,
|
||||||
last_name: str,
|
last_name: str,
|
||||||
e_mail: str,
|
email: str,
|
||||||
password: str,
|
password: str,
|
||||||
confirmation_id: Optional[str],
|
confirmation_id: Optional[str],
|
||||||
auth_role: AuthRoleEnum,
|
auth_role: AuthRoleEnum,
|
||||||
@ -24,7 +21,7 @@ class AuthUserDTO(DtoABC):
|
|||||||
self._id = id
|
self._id = id
|
||||||
self._first_name = first_name
|
self._first_name = first_name
|
||||||
self._last_name = last_name
|
self._last_name = last_name
|
||||||
self._email = e_mail
|
self._email = email
|
||||||
self._password = password
|
self._password = password
|
||||||
self._is_confirmed = confirmation_id is None
|
self._is_confirmed = confirmation_id is None
|
||||||
self._auth_role = auth_role
|
self._auth_role = auth_role
|
||||||
@ -75,11 +72,11 @@ class AuthUserDTO(DtoABC):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def auth_role(self) -> AuthRoleEnum:
|
def auth_role(self) -> AuthRoleEnum:
|
||||||
return self.auth_role
|
return self._auth_role
|
||||||
|
|
||||||
@auth_role.setter
|
@auth_role.setter
|
||||||
def auth_role(self, value: AuthRoleEnum):
|
def auth_role(self, value: AuthRoleEnum):
|
||||||
self.auth_role = value
|
self._auth_role = value
|
||||||
|
|
||||||
def from_dict(self, values: dict):
|
def from_dict(self, values: dict):
|
||||||
self._id = values['id']
|
self._id = values['id']
|
||||||
@ -98,5 +95,5 @@ class AuthUserDTO(DtoABC):
|
|||||||
'email': self._email,
|
'email': self._email,
|
||||||
'password': self._password,
|
'password': self._password,
|
||||||
'isConfirmed': self._is_confirmed,
|
'isConfirmed': self._is_confirmed,
|
||||||
'authRole': self._auth_role,
|
'authRole': self._auth_role.value,
|
||||||
}
|
}
|
||||||
|
@ -65,24 +65,35 @@ class AuthService(AuthServiceABC):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_email_valid(email: str) -> bool:
|
def _is_email_valid(email: str) -> bool:
|
||||||
regex = '^[a-z0-9]+[\\._]?[a-z0-9]+[@]\\w+[.]\\w{2,3}$'
|
if re.match(re.compile(r'^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$'), email) is not None:
|
||||||
return bool(re.search(regex, email))
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def _generate_token(self, user: AuthUser) -> str:
|
def _generate_token(self, user: AuthUser) -> str:
|
||||||
token = jwt.encode(
|
token = jwt.encode(
|
||||||
payload={
|
payload={
|
||||||
'user_id': user.id,
|
'user_id': user.id,
|
||||||
'email': user.email,
|
'email': user.email,
|
||||||
'role': user.auth_role,
|
'role': user.auth_role.value,
|
||||||
'exp': datetime.now(tz=timezone.utc) + timedelta(days=self._auth_settings.token_expire_time),
|
'exp': datetime.now(tz=timezone.utc) + timedelta(days=self._auth_settings.token_expire_time),
|
||||||
'iss': self._auth_settings.issuer,
|
'iss': self._auth_settings.issuer,
|
||||||
'aud': self._auth_settings.audience
|
'aud': self._auth_settings.audience
|
||||||
},
|
},
|
||||||
key=self._auth_settings.secret_key,
|
key=self._auth_settings.secret_key
|
||||||
)
|
)
|
||||||
|
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
def _decode_token(self, token: str) -> dict:
|
||||||
|
return jwt.decode(
|
||||||
|
token,
|
||||||
|
key=self._auth_settings.secret_key,
|
||||||
|
issuer=self._auth_settings.issuer,
|
||||||
|
audience=self._auth_settings.audience,
|
||||||
|
algorithms=['HS256']
|
||||||
|
)
|
||||||
|
|
||||||
def _create_and_save_refresh_token(self, user: AuthUser) -> str:
|
def _create_and_save_refresh_token(self, user: AuthUser) -> str:
|
||||||
token = str(uuid.uuid4())
|
token = str(uuid.uuid4())
|
||||||
user.refresh_token = token
|
user.refresh_token = token
|
||||||
@ -113,7 +124,7 @@ class AuthService(AuthServiceABC):
|
|||||||
mail.body = self._t.transform('api.auth.forgot_password.message').format(url, user.forgot_password_id)
|
mail.body = self._t.transform('api.auth.forgot_password.message').format(url, user.forgot_password_id)
|
||||||
self._mailer.send_mail(mail)
|
self._mailer.send_mail(mail)
|
||||||
|
|
||||||
async def get_all_auth_users_async(self) -> List[AuthUser]:
|
async def get_all_auth_users_async(self) -> List[AuthUserDTO]:
|
||||||
result = self._auth_users.get_all_auth_users() \
|
result = self._auth_users.get_all_auth_users() \
|
||||||
.select(lambda x: AUT.to_dto(x))
|
.select(lambda x: AUT.to_dto(x))
|
||||||
return List(AuthUserDTO, result)
|
return List(AuthUserDTO, result)
|
||||||
@ -127,10 +138,9 @@ class AuthService(AuthServiceABC):
|
|||||||
users.total_count
|
users.total_count
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_auth_user_by_email_async(self, email: str) -> AuthUser:
|
async def get_auth_user_by_email_async(self, email: str) -> AuthUserDTO:
|
||||||
try:
|
try:
|
||||||
user = self._auth_users.get_auth_user_by_email(email)
|
return AUT.to_dto(self._auth_users.get_auth_user_by_email(email))
|
||||||
return user
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._logger.error(__name__, f'AuthUser not found', e)
|
self._logger.error(__name__, f'AuthUser not found', e)
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, f'User not found {email}')
|
raise ServiceException(ServiceErrorCode.InvalidData, f'User not found {email}')
|
||||||
@ -139,7 +149,7 @@ class AuthService(AuthServiceABC):
|
|||||||
user = self._auth_users.find_auth_user_by_email(email)
|
user = self._auth_users.find_auth_user_by_email(email)
|
||||||
return AUT.to_dto(user) if user is not None else None
|
return AUT.to_dto(user) if user is not None else None
|
||||||
|
|
||||||
async def add_auth_user_async(self, user_dto: AuthUserDTO):
|
async def add_auth_user_async(self, user_dto: AuthUser):
|
||||||
db_user = self._auth_users.find_auth_user_by_email(user_dto.email)
|
db_user = self._auth_users.find_auth_user_by_email(user_dto.email)
|
||||||
if db_user is not None:
|
if db_user is not None:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidUser, 'User already exists')
|
raise ServiceException(ServiceErrorCode.InvalidUser, 'User already exists')
|
||||||
@ -151,7 +161,7 @@ class AuthService(AuthServiceABC):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
user.confirmation_id = uuid.uuid4()
|
user.confirmation_id = uuid.uuid4()
|
||||||
self._auth_users.update_auth_user(user)
|
self._auth_users.add_auth_user(user)
|
||||||
self._send_confirmation_id_to_user(user)
|
self._send_confirmation_id_to_user(user)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
self._logger.info(__name__, f'Added auth user with E-Mail: {user_dto.email}')
|
self._logger.info(__name__, f'Added auth user with E-Mail: {user_dto.email}')
|
||||||
@ -273,7 +283,7 @@ class AuthService(AuthServiceABC):
|
|||||||
self._logger.error(__name__, f'Cannot delete user', e)
|
self._logger.error(__name__, f'Cannot delete user', e)
|
||||||
raise ServiceException(ServiceErrorCode.UnableToDelete, f'Cannot delete user by mail {email}')
|
raise ServiceException(ServiceErrorCode.UnableToDelete, f'Cannot delete user by mail {email}')
|
||||||
|
|
||||||
async def delete_auth_user_async(self, user_dto: AuthUserDTO):
|
async def delete_auth_user_async(self, user_dto: AuthUser):
|
||||||
try:
|
try:
|
||||||
self._auth_users.delete_auth_user(AUT.to_db(user_dto))
|
self._auth_users.delete_auth_user(AUT.to_db(user_dto))
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
@ -281,7 +291,7 @@ class AuthService(AuthServiceABC):
|
|||||||
self._logger.error(__name__, f'Cannot delete user', e)
|
self._logger.error(__name__, f'Cannot delete user', e)
|
||||||
raise ServiceException(ServiceErrorCode.UnableToDelete, f'Cannot delete user by mail {user_dto.email}')
|
raise ServiceException(ServiceErrorCode.UnableToDelete, f'Cannot delete user by mail {user_dto.email}')
|
||||||
|
|
||||||
async def login_async(self, user_dto: AuthUserDTO) -> TokenDTO:
|
async def login_async(self, user_dto: AuthUser) -> TokenDTO:
|
||||||
if user_dto is None:
|
if user_dto is None:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, 'User not set')
|
raise ServiceException(ServiceErrorCode.InvalidData, 'User not set')
|
||||||
|
|
||||||
@ -305,12 +315,12 @@ class AuthService(AuthServiceABC):
|
|||||||
if token_dto is None:
|
if token_dto is None:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, f'Token not set')
|
raise ServiceException(ServiceErrorCode.InvalidData, f'Token not set')
|
||||||
|
|
||||||
token = jwt.decode(token_dto.token, key=self._auth_settings.secret_key)
|
token = self._decode_token(token_dto.token)
|
||||||
if token is None or 'email' not in token:
|
if token is None or 'email' not in token:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, 'Token invalid')
|
raise ServiceException(ServiceErrorCode.InvalidData, 'Token invalid')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = self._auth_users.get_auth_user_by_email(token)
|
user = self._auth_users.get_auth_user_by_email(token['email'])
|
||||||
if user is None or user.refresh_token != token_dto.refresh_token or user.refresh_token_expire_time <= datetime.now():
|
if user is None or user.refresh_token != token_dto.refresh_token or user.refresh_token_expire_time <= datetime.now():
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, 'Token expired')
|
raise ServiceException(ServiceErrorCode.InvalidData, 'Token expired')
|
||||||
|
|
||||||
@ -323,9 +333,9 @@ class AuthService(AuthServiceABC):
|
|||||||
if token_dto is None or token_dto.token is None or token_dto.refresh_token is None:
|
if token_dto is None or token_dto.token is None or token_dto.refresh_token is None:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, 'Token not set')
|
raise ServiceException(ServiceErrorCode.InvalidData, 'Token not set')
|
||||||
|
|
||||||
token = jwt.decode(token_dto.token, key=self._auth_settings.secret_key)
|
token = self._decode_token(token_dto.token)
|
||||||
try:
|
try:
|
||||||
user = self._auth_users.get_auth_user_by_email(token)
|
user = self._auth_users.get_auth_user_by_email(token['email'])
|
||||||
if user is None or user.refresh_token != token_dto.refresh_token or user.refresh_token_expire_time <= datetime.now():
|
if user is None or user.refresh_token != token_dto.refresh_token or user.refresh_token_expire_time <= datetime.now():
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, 'Token expired')
|
raise ServiceException(ServiceErrorCode.InvalidData, 'Token expired')
|
||||||
|
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
from bot_api.abc.auth_user_transformer_abc import AuthUserTransformerABC
|
from bot_api.abc.auth_user_transformer_abc import AuthUserTransformerABC
|
||||||
from bot_api.model.auth_user_dto import AuthUserDTO
|
from bot_api.model.auth_user_dto import AuthUserDTO
|
||||||
|
from bot_data.model.auth_role_enum import AuthRoleEnum
|
||||||
from bot_data.model.auth_user import AuthUser
|
from bot_data.model.auth_user import AuthUser
|
||||||
|
|
||||||
|
|
||||||
class AuthUserTransformer(AuthUserTransformerABC):
|
class AuthUserTransformer(AuthUserTransformerABC):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def to_db(dto: AuthUserDTO) -> AuthUser:
|
def to_db(dto: AuthUser) -> AuthUser:
|
||||||
return AuthUser(
|
return AuthUser(
|
||||||
dto.first_name,
|
dto.first_name,
|
||||||
dto.last_name,
|
dto.last_name,
|
||||||
@ -15,9 +18,9 @@ class AuthUserTransformer(AuthUserTransformerABC):
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
datetime.now(tz=timezone.utc),
|
||||||
dto.auth_role,
|
AuthRoleEnum.normal if dto.auth_role is None else dto.auth_role,
|
||||||
id=dto.id
|
id=0 if dto.id is None else dto.id
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -28,6 +31,6 @@ class AuthUserTransformer(AuthUserTransformerABC):
|
|||||||
db.last_name,
|
db.last_name,
|
||||||
db.email,
|
db.email,
|
||||||
db.password,
|
db.password,
|
||||||
db.confirmation_id is None,
|
db.confirmation_id,
|
||||||
db.auth_role
|
db.auth_role
|
||||||
)
|
)
|
||||||
|
@ -18,18 +18,19 @@ class ApiMigration(MigrationABC):
|
|||||||
self._cursor.execute(
|
self._cursor.execute(
|
||||||
str(f"""
|
str(f"""
|
||||||
CREATE TABLE IF NOT EXISTS `AuthUsers` (
|
CREATE TABLE IF NOT EXISTS `AuthUsers` (
|
||||||
`Id` bigint NOT NULL,
|
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||||
`FirstName` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
|
`FirstName` VARCHAR(255),
|
||||||
`LastName` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
|
`LastName` VARCHAR(255),
|
||||||
`EMail` varchar(255) DEFAULT NULL,
|
`EMail` VARCHAR(255),
|
||||||
`Password` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
|
`Password` VARCHAR(255),
|
||||||
`RefreshToken` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
|
`RefreshToken` VARCHAR(255),
|
||||||
`ConfirmationId` varchar(255) DEFAULT NULL,
|
`ConfirmationId` VARCHAR(255) DEFAULT NULL,
|
||||||
`ForgotPasswordId` varchar(255) DEFAULT NULL,
|
`ForgotPasswordId` VARCHAR(255) DEFAULT NULL,
|
||||||
`RefreshTokenExpiryTime` datetime(6) NOT NULL,
|
`RefreshTokenExpiryTime` DATETIME(6) NOT NULL,
|
||||||
`AuthRole` int NOT NULL DEFAULT '0',
|
`AuthRole` INT NOT NULL DEFAULT '0',
|
||||||
`CreatedOn` datetime(6) NOT NULL,
|
`CreatedOn` DATETIME(6) NOT NULL,
|
||||||
`LastModifiedOn` datetime(6) NOT NULL
|
`LastModifiedOn` DATETIME(6) NOT NULL,
|
||||||
|
PRIMARY KEY(`Id`)
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
)
|
)
|
||||||
|
@ -3,5 +3,5 @@ from enum import Enum
|
|||||||
|
|
||||||
class AuthRoleEnum(Enum):
|
class AuthRoleEnum(Enum):
|
||||||
|
|
||||||
Normal = 0
|
normal = 0
|
||||||
Admin = 1
|
admin = 1
|
||||||
|
@ -17,7 +17,7 @@ class AuthUser(TableABC):
|
|||||||
refresh_token: Optional[str],
|
refresh_token: Optional[str],
|
||||||
confirmation_id: Optional[str],
|
confirmation_id: Optional[str],
|
||||||
forgot_password_id: Optional[str],
|
forgot_password_id: Optional[str],
|
||||||
refresh_token_expire_time: Optional[datetime],
|
refresh_token_expire_time: datetime,
|
||||||
auth_role: AuthRoleEnum,
|
auth_role: AuthRoleEnum,
|
||||||
created_at: datetime = None,
|
created_at: datetime = None,
|
||||||
modified_at: datetime = None,
|
modified_at: datetime = None,
|
||||||
@ -100,11 +100,11 @@ class AuthUser(TableABC):
|
|||||||
self._forgot_password_id = value
|
self._forgot_password_id = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def refresh_token_expire_time(self) -> Optional[datetime]:
|
def refresh_token_expire_time(self) -> datetime:
|
||||||
return self._refresh_token_expire_time
|
return self._refresh_token_expire_time
|
||||||
|
|
||||||
@refresh_token_expire_time.setter
|
@refresh_token_expire_time.setter
|
||||||
def refresh_token_expire_time(self, value: Optional[datetime]):
|
def refresh_token_expire_time(self, value: datetime):
|
||||||
self._refresh_token_expire_time = value
|
self._refresh_token_expire_time = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -143,7 +143,7 @@ class AuthUser(TableABC):
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_select_by_forgot_password_i_string(id: str) -> str:
|
def get_select_by_forgot_password_id_string(id: str) -> str:
|
||||||
return str(f"""
|
return str(f"""
|
||||||
SELECT * FROM `AuthUsers`
|
SELECT * FROM `AuthUsers`
|
||||||
WHERE `ForgotPasswordId` = '{id}';
|
WHERE `ForgotPasswordId` = '{id}';
|
||||||
@ -172,8 +172,8 @@ class AuthUser(TableABC):
|
|||||||
'{self._email}',
|
'{self._email}',
|
||||||
'{self._password}',
|
'{self._password}',
|
||||||
'{self._refresh_token}',
|
'{self._refresh_token}',
|
||||||
'{self._confirmation_id}',
|
'{"NULL" if self._confirmation_id is None else self._confirmation_id}',
|
||||||
'{self._forgot_password_id}',
|
'{"NULL" if self._forgot_password_id is None else self._forgot_password_id}',
|
||||||
'{self._refresh_token_expire_time}',
|
'{self._refresh_token_expire_time}',
|
||||||
{self._auth_role_id.value},
|
{self._auth_role_id.value},
|
||||||
'{self._created_at}',
|
'{self._created_at}',
|
||||||
@ -190,11 +190,11 @@ class AuthUser(TableABC):
|
|||||||
`EMail` = '{self._email}',
|
`EMail` = '{self._email}',
|
||||||
`Password` = '{self._password}',
|
`Password` = '{self._password}',
|
||||||
`RefreshToken` = '{self._refresh_token}',
|
`RefreshToken` = '{self._refresh_token}',
|
||||||
`ConfirmationId` = '{self._confirmation_id}',
|
`ConfirmationId` = '{"NULL" if self._confirmation_id is None else self._confirmation_id}',
|
||||||
`ForgotPasswordId` = '{self._forgot_password_id}',
|
`ForgotPasswordId` = '{"NULL" if self._forgot_password_id is None else self._forgot_password_id}',
|
||||||
`RefreshTokenExpiryTime` = '{self._refresh_token_expire_time}',
|
`RefreshTokenExpiryTime` = '{self._refresh_token_expire_time}',
|
||||||
`AutoRole` = {self._auth_role_id.value},
|
`AuthRole` = {self._auth_role_id.value},
|
||||||
`LastModifiedAt` = '{self._modified_at}'
|
`LastModifiedOn` = '{self._modified_at}'
|
||||||
WHERE `AuthUsers`.`Id` = {self._auth_user_id};
|
WHERE `AuthUsers`.`Id` = {self._auth_user_id};
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
@ -20,18 +20,24 @@ class AuthUserRepositoryService(AuthUserRepositoryABC):
|
|||||||
AuthUserRepositoryABC.__init__(self)
|
AuthUserRepositoryABC.__init__(self)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _user_from_result(result: tuple) -> AuthUser:
|
def _get_value_from_result(value: any) -> Optional[any]:
|
||||||
|
if isinstance(value, str) and 'NULL' in value:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def _user_from_result(self, result: tuple) -> AuthUser:
|
||||||
return AuthUser(
|
return AuthUser(
|
||||||
result[1],
|
self._get_value_from_result(result[1]),
|
||||||
result[2],
|
self._get_value_from_result(result[2]),
|
||||||
result[3],
|
self._get_value_from_result(result[3]),
|
||||||
result[4],
|
self._get_value_from_result(result[4]),
|
||||||
result[5],
|
self._get_value_from_result(result[5]),
|
||||||
result[6],
|
self._get_value_from_result(result[6]),
|
||||||
result[7],
|
self._get_value_from_result(result[7]),
|
||||||
result[8],
|
self._get_value_from_result(result[8]),
|
||||||
AuthRoleEnum(result[9]),
|
AuthRoleEnum(self._get_value_from_result(result[9])),
|
||||||
id=result[0]
|
id=self._get_value_from_result(result[0])
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_all_auth_users(self) -> List[AuthUser]:
|
def get_all_auth_users(self) -> List[AuthUser]:
|
||||||
@ -47,7 +53,6 @@ class AuthUserRepositoryService(AuthUserRepositoryABC):
|
|||||||
def get_filtered_auth_users(self, criteria: AuthUserSelectCriteria) -> FilteredResult:
|
def get_filtered_auth_users(self, criteria: AuthUserSelectCriteria) -> FilteredResult:
|
||||||
users = self.get_all_auth_users()
|
users = self.get_all_auth_users()
|
||||||
self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_all_string()}')
|
self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_all_string()}')
|
||||||
|
|
||||||
query = users
|
query = users
|
||||||
|
|
||||||
if criteria.first_name is not None and criteria.first_name != '':
|
if criteria.first_name is not None and criteria.first_name != '':
|
||||||
@ -70,9 +75,9 @@ class AuthUserRepositoryService(AuthUserRepositoryABC):
|
|||||||
else:
|
else:
|
||||||
query = query.order_by(lambda x: getattr(x, criteria.sort_column))
|
query = query.order_by(lambda x: getattr(x, criteria.sort_column))
|
||||||
|
|
||||||
skip = criteria.page_size * criteria.page_index
|
|
||||||
result = FilteredResult()
|
result = FilteredResult()
|
||||||
result.total_count = query.count()
|
result.total_count = query.count()
|
||||||
|
skip = criteria.page_size * criteria.page_index
|
||||||
result.result = query.skip(skip).take(criteria.page_size)
|
result.result = query.skip(skip).take(criteria.page_size)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -93,8 +98,8 @@ class AuthUserRepositoryService(AuthUserRepositoryABC):
|
|||||||
return self._user_from_result(result)
|
return self._user_from_result(result)
|
||||||
|
|
||||||
def find_auth_user_by_confirmation_id(self, id: str) -> Optional[AuthUser]:
|
def find_auth_user_by_confirmation_id(self, id: str) -> Optional[AuthUser]:
|
||||||
self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_by_email_string(id)}')
|
self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_by_confirmation_id_string(id)}')
|
||||||
result = self._context.select(AuthUser.get_select_by_email_string(id))
|
result = self._context.select(AuthUser.get_select_by_confirmation_id_string(id))
|
||||||
if result is None or len(result) == 0:
|
if result is None or len(result) == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -103,8 +108,8 @@ class AuthUserRepositoryService(AuthUserRepositoryABC):
|
|||||||
return self._user_from_result(result)
|
return self._user_from_result(result)
|
||||||
|
|
||||||
def find_auth_user_by_forgot_password_id(self, id: str) -> Optional[AuthUser]:
|
def find_auth_user_by_forgot_password_id(self, id: str) -> Optional[AuthUser]:
|
||||||
self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_by_email_string(id)}')
|
self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_by_forgot_password_id_string(id)}')
|
||||||
result = self._context.select(AuthUser.get_select_by_email_string(id))
|
result = self._context.select(AuthUser.get_select_by_forgot_password_id_string(id))
|
||||||
if result is None or len(result) == 0:
|
if result is None or len(result) == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user