Improved api #70

This commit is contained in:
Sven Heidemann 2022-10-15 12:54:10 +02:00
parent 5cd91d8341
commit 119f4e9d04
16 changed files with 108 additions and 88 deletions

View File

@ -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

View File

@ -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": [

View File

@ -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",

View File

@ -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

View File

@ -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)

View File

@ -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
}, },

View File

@ -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):

View File

@ -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()

View File

@ -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)

View File

@ -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,
} }

View File

@ -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')

View File

@ -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
) )

View File

@ -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`)
) )
""") """)
) )

View File

@ -3,5 +3,5 @@ from enum import Enum
class AuthRoleEnum(Enum): class AuthRoleEnum(Enum):
Normal = 0 normal = 0
Admin = 1 admin = 1

View File

@ -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};
""") """)

View File

@ -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