@ -4,6 +4,8 @@ from cpl_query.extension import List
|
||||
|
||||
from bot_api.filter.auth_user_select_criteria import AuthUserSelectCriteria
|
||||
from bot_api.model.auth_user_dto import AuthUserDTO
|
||||
from bot_api.model.auth_user_filtered_result_dto import AuthUserFilteredResultDTO
|
||||
from bot_api.model.email_string_dto import EMailStringDTO
|
||||
from bot_api.model.reset_password_dto import ResetPasswordDTO
|
||||
from bot_api.model.token_dto import TokenDTO
|
||||
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
||||
@ -19,7 +21,7 @@ class AuthServiceABC(ABC):
|
||||
async def get_all_auth_users_async(self) -> List[AuthUser]: pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> List[AuthUser]: pass
|
||||
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO: pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_auth_user_by_email_async(self, email: str) -> AuthUser: pass
|
||||
@ -28,37 +30,37 @@ class AuthServiceABC(ABC):
|
||||
async def find_auth_user_by_email_async(self, email: str) -> AuthUser: pass
|
||||
|
||||
@abstractmethod
|
||||
async def add_auth_user_async(self, user_dto: AuthUserDTO) -> AuthUser: pass
|
||||
async def add_auth_user_async(self, user_dto: AuthUserDTO) -> int: pass
|
||||
|
||||
@abstractmethod
|
||||
async def confirm_email_async(self, id: str) -> AuthUser: pass
|
||||
async def confirm_email_async(self, id: str) -> bool: pass
|
||||
|
||||
@abstractmethod
|
||||
async def login_async(self, user_dto: AuthUserDTO) -> AuthUser: pass
|
||||
async def login_async(self, user_dto: AuthUserDTO) -> TokenDTO: pass
|
||||
|
||||
@abstractmethod
|
||||
async def forgot_password_async(self, email: str) -> AuthUser: pass
|
||||
async def forgot_password_async(self, email: str): pass
|
||||
|
||||
@abstractmethod
|
||||
async def confirm_forgot_password_async(self, id: str) -> AuthUser: pass
|
||||
async def confirm_forgot_password_async(self, id: str) -> EMailStringDTO: pass
|
||||
|
||||
@abstractmethod
|
||||
async def reset_password_async(self, rp_dto: ResetPasswordDTO) -> AuthUser: pass
|
||||
async def reset_password_async(self, rp_dto: ResetPasswordDTO): pass
|
||||
|
||||
@abstractmethod
|
||||
async def update_user_async(self, update_user_dto: UpdateAuthUserDTO) -> AuthUser: pass
|
||||
async def update_user_async(self, update_user_dto: UpdateAuthUserDTO): pass
|
||||
|
||||
@abstractmethod
|
||||
async def update_user_as_admin_async(self, update_user_dto: UpdateAuthUserDTO) -> AuthUser: pass
|
||||
async def update_user_as_admin_async(self, update_user_dto: UpdateAuthUserDTO): pass
|
||||
|
||||
@abstractmethod
|
||||
async def refresh_async(self, token_dto: TokenDTO) -> AuthUser: pass
|
||||
async def refresh_async(self, token_dto: TokenDTO) -> TokenDTO: pass
|
||||
|
||||
@abstractmethod
|
||||
async def revoke_async(self, token_dto: TokenDTO) -> AuthUser: pass
|
||||
async def revoke_async(self, token_dto: TokenDTO): pass
|
||||
|
||||
@abstractmethod
|
||||
async def delete_auth_user_by_email_async(self, email: str) -> AuthUser: pass
|
||||
async def delete_auth_user_by_email_async(self, email: str): pass
|
||||
|
||||
@abstractmethod
|
||||
async def delete_auth_user_async(self, user_dto: AuthUserDTO) -> AuthUser: pass
|
||||
async def delete_auth_user_async(self, user_dto: AuthUserDTO): pass
|
||||
|
@ -54,7 +54,6 @@ class Api(Flask):
|
||||
self._logger.debug(__name__, f'Received GET @{request.url}')
|
||||
headers = str(request.headers).replace("\n", "\n\t")
|
||||
self._logger.trace(__name__, f'Headers: \n\t{headers}')
|
||||
self._logger.trace(__name__, f'Body: {request.get_json(force=True, silent=True)}')
|
||||
|
||||
def start(self):
|
||||
self._logger.info(__name__, f'Starting API {self._apt_settings.host}:{self._apt_settings.port}')
|
||||
|
@ -7,10 +7,12 @@ from cpl_core.mailing import EMailClientABC, EMailClient
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
from flask import Flask
|
||||
|
||||
from bot_api.abc.auth_service_abc import AuthServiceABC
|
||||
from bot_api.api import Api
|
||||
from bot_api.api_thread import ApiThread
|
||||
from bot_api.controller.api_controller import ApiController
|
||||
from bot_api.controller.auth_controller import AuthController
|
||||
from bot_api.service.auth_service import AuthService
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
|
||||
@ -34,5 +36,6 @@ class ApiModule(ModuleABC):
|
||||
services.add_singleton(ApiThread)
|
||||
services.add_singleton(Flask, Api)
|
||||
|
||||
services.add_transient(AuthServiceABC, AuthService)
|
||||
services.add_transient(AuthController)
|
||||
services.add_transient(ApiController)
|
||||
|
@ -1,19 +1,22 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_core.mailing import EMailClientABC, EMailClientSettings
|
||||
from cpl_query.extension import List
|
||||
from cpl_translation import TranslatePipe
|
||||
from flask import request
|
||||
from flask_cors import cross_origin
|
||||
from flask import request, jsonify, Response
|
||||
|
||||
from bot_api.abc.auth_service_abc import AuthServiceABC
|
||||
from bot_api.api import Api
|
||||
from bot_api.filter.auth_user_select_criteria import AuthUserSelectCriteria
|
||||
from bot_api.json_processor import JSONProcessor
|
||||
from bot_api.logging.api_logger import ApiLogger
|
||||
from bot_api.model.auth_user_dto import AuthUserDTO
|
||||
from bot_api.model.token_dto import TokenDTO
|
||||
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
||||
from bot_api.route.route import Route
|
||||
from bot_data.model.auth_user import AuthUser
|
||||
|
||||
|
||||
class AuthController:
|
||||
BasePath = '/api/auth'
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -23,7 +26,8 @@ class AuthController:
|
||||
t: TranslatePipe,
|
||||
api: Api,
|
||||
mail_settings: EMailClientSettings,
|
||||
mailer: EMailClientABC
|
||||
mailer: EMailClientABC,
|
||||
auth_service: AuthServiceABC
|
||||
):
|
||||
self._config = config
|
||||
self._env = env
|
||||
@ -32,16 +36,79 @@ class AuthController:
|
||||
self._api = api
|
||||
self._mail_settings = mail_settings
|
||||
self._mailer = mailer
|
||||
self._auth_service = auth_service
|
||||
|
||||
@Route.route('/api/auth/get-all-users')
|
||||
async def get_all_users(self) -> List[AuthUser]:
|
||||
pass
|
||||
@Route.get(f'{BasePath}/users')
|
||||
async def get_all_users(self) -> Response:
|
||||
return jsonify(await self._auth_service.get_all_auth_users_async())
|
||||
|
||||
@Route.route('/api/auth/get-filtered-users', methods=['POST'])
|
||||
async def get_filtered_users(self) -> List[AuthUser]:
|
||||
pass
|
||||
@Route.post(f'{BasePath}/users/get/filtered')
|
||||
async def get_filtered_users(self) -> Response:
|
||||
dto: AuthUserSelectCriteria = JSONProcessor.process(AuthUserSelectCriteria, request.get_json(force=True, silent=True))
|
||||
result = await self._auth_service.get_filtered_auth_users_async(dto)
|
||||
return jsonify(result.to_dict())
|
||||
|
||||
@Route.route('/api/auth/login', methods=['POST'])
|
||||
async def login(self) -> dict:
|
||||
self._logger.warn(__name__, f'Received {request.json}')
|
||||
return TokenDTO().to_dict()
|
||||
@Route.get(f'{BasePath}/users/get/<email>')
|
||||
async def get_user_from_email(self, email: str) -> Response:
|
||||
return jsonify(await self._auth_service.get_auth_user_by_email_async(email))
|
||||
|
||||
@Route.get(f'{BasePath}/users/find/<email>')
|
||||
async def find_user_from_email(self, email: str) -> Response:
|
||||
return jsonify(await self._auth_service.find_auth_user_by_email_async(email))
|
||||
|
||||
@Route.post(f'{BasePath}/register')
|
||||
async def register(self):
|
||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.add_auth_user_async(dto)
|
||||
return '', 200
|
||||
|
||||
@Route.post(f'{BasePath}/login')
|
||||
async def login(self) -> Response:
|
||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
||||
result = await self._auth_service.login_async(dto)
|
||||
return jsonify(result.to_dict())
|
||||
|
||||
@Route.post(f'{BasePath}/forgot-password/<email>')
|
||||
async def forgot_password(self, email: str):
|
||||
await self._auth_service.forgot_password_async(email)
|
||||
return '', 200
|
||||
|
||||
@Route.post(f'{BasePath}/confirm-forgot-password/<id>')
|
||||
async def confirm_forgot_password(self, id: str):
|
||||
await self._auth_service.confirm_forgot_password_async(id)
|
||||
return '', 200
|
||||
|
||||
@Route.post(f'{BasePath}/update-user')
|
||||
async def update_user(self):
|
||||
dto: UpdateAuthUserDTO = JSONProcessor.process(UpdateAuthUserDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.update_user_async(dto)
|
||||
return '', 200
|
||||
|
||||
@Route.post(f'{BasePath}/update-user-as-admin')
|
||||
async def update_user_as_admin(self):
|
||||
dto: UpdateAuthUserDTO = JSONProcessor.process(UpdateAuthUserDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.update_user_async(dto)
|
||||
return '', 200
|
||||
|
||||
@Route.post(f'{BasePath}/refresh')
|
||||
async def refresh(self) -> Response:
|
||||
dto: TokenDTO = JSONProcessor.process(TokenDTO, request.get_json(force=True, silent=True))
|
||||
result = await self._auth_service.refresh_async(dto)
|
||||
return jsonify(result.to_dict())
|
||||
|
||||
@Route.post(f'{BasePath}/revoke')
|
||||
async def revoke(self):
|
||||
dto: TokenDTO = JSONProcessor.process(TokenDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.revoke_async(dto)
|
||||
return '', 200
|
||||
|
||||
@Route.post(f'{BasePath}/delete-user')
|
||||
async def delete_user(self):
|
||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.delete_auth_user_async(dto)
|
||||
return '', 200
|
||||
|
||||
@Route.post(f'{BasePath}/delete-user-by-mail/<email>')
|
||||
async def delete_user_by_mail(self, email: str):
|
||||
await self._auth_service.delete_auth_user_by_email_async(email)
|
||||
return '', 200
|
||||
|
32
src/bot_api/json_processor.py
Normal file
32
src/bot_api/json_processor.py
Normal file
@ -0,0 +1,32 @@
|
||||
from inspect import signature, Parameter
|
||||
|
||||
from cpl_core.utils import String
|
||||
|
||||
|
||||
class JSONProcessor:
|
||||
|
||||
@staticmethod
|
||||
def process(_t: type, values: dict) -> object:
|
||||
args = []
|
||||
|
||||
sig = signature(_t.__init__)
|
||||
for param in sig.parameters.items():
|
||||
parameter = param[1]
|
||||
if parameter.name == 'self' or parameter.annotation == Parameter.empty:
|
||||
continue
|
||||
|
||||
name = String.convert_to_camel_case(parameter.name)
|
||||
name_first_lower = String.first_to_lower(name)
|
||||
if name in values or name_first_lower in values:
|
||||
if name in values:
|
||||
args.append(values[name])
|
||||
else:
|
||||
args.append(values[name_first_lower])
|
||||
|
||||
elif parameter.default != Parameter.empty:
|
||||
args.append(parameter.default)
|
||||
|
||||
else:
|
||||
args.append(None)
|
||||
|
||||
return _t(*args)
|
@ -14,7 +14,7 @@ class AuthUserDTO(DtoABC):
|
||||
id: int,
|
||||
first_name: str,
|
||||
last_name: str,
|
||||
email: str,
|
||||
e_mail: str,
|
||||
password: str,
|
||||
confirmation_id: Optional[str],
|
||||
auth_role: AuthRoleEnum,
|
||||
@ -24,20 +24,38 @@ class AuthUserDTO(DtoABC):
|
||||
self._id = id
|
||||
self._first_name = first_name
|
||||
self._last_name = last_name
|
||||
self._email = email
|
||||
self._email = e_mail
|
||||
self._password = password
|
||||
self._is_confirmed = confirmation_id is None
|
||||
self._auth_role = auth_role
|
||||
|
||||
"""
|
||||
long Id { get; set; }
|
||||
string FirstName { get; set; }
|
||||
string LastName { get; set; }
|
||||
string EMail { get; set; }
|
||||
string Password { get; set; }
|
||||
bool IsConfirmed { get; set; }
|
||||
AuthRoles AuthRole { get; set; }
|
||||
"""
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def first_name(self) -> str:
|
||||
return self._first_name
|
||||
|
||||
@property
|
||||
def last_name(self) -> str:
|
||||
return self._last_name
|
||||
|
||||
@property
|
||||
def email(self) -> str:
|
||||
return self._email
|
||||
|
||||
@property
|
||||
def password(self) -> str:
|
||||
return self._password
|
||||
|
||||
@property
|
||||
def is_confirmed(self) -> bool:
|
||||
return self._is_confirmed
|
||||
|
||||
@property
|
||||
def auth_role(self) -> AuthRoleEnum:
|
||||
return self._auth_role
|
||||
|
||||
def from_dict(self, values: dict):
|
||||
self._id = values['Id']
|
||||
|
21
src/bot_api/model/auth_user_filtered_result_dto.py
Normal file
21
src/bot_api/model/auth_user_filtered_result_dto.py
Normal file
@ -0,0 +1,21 @@
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_api.abc.dto_abc import DtoABC
|
||||
from bot_data.filtered_result import FilteredResult
|
||||
|
||||
|
||||
class AuthUserFilteredResultDTO(DtoABC, FilteredResult):
|
||||
|
||||
def __init__(self, result: List = None, total_count: int = 0):
|
||||
DtoABC.__init__(self)
|
||||
FilteredResult.__init__(self, result, total_count)
|
||||
|
||||
def from_dict(self, values: dict):
|
||||
self._result = values['Users']
|
||||
self._total_count = values['TotalCount']
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
'Users': self.result,
|
||||
'TotalCount': self.total_count
|
||||
}
|
18
src/bot_api/model/email_string_dto.py
Normal file
18
src/bot_api/model/email_string_dto.py
Normal file
@ -0,0 +1,18 @@
|
||||
import traceback
|
||||
|
||||
from cpl_core.console import Console
|
||||
|
||||
from bot_api.abc.dto_abc import DtoABC
|
||||
|
||||
|
||||
class EMailStringDTO(DtoABC):
|
||||
|
||||
def __init__(self):
|
||||
DtoABC.__init__(self)
|
||||
|
||||
def from_dict(self, values: dict):
|
||||
pass
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
}
|
@ -9,3 +9,23 @@ class Route:
|
||||
return fn
|
||||
|
||||
return inner
|
||||
|
||||
@classmethod
|
||||
def get(cls, path=None, **kwargs):
|
||||
return cls.route(path, methods=['GET'], **kwargs)
|
||||
|
||||
@classmethod
|
||||
def post(cls, path=None, **kwargs):
|
||||
return cls.route(path, methods=['POST'], **kwargs)
|
||||
|
||||
@classmethod
|
||||
def head(cls, path=None, **kwargs):
|
||||
return cls.route(path, methods=['HEAD'], **kwargs)
|
||||
|
||||
@classmethod
|
||||
def put(cls, path=None, **kwargs):
|
||||
return cls.route(path, methods=['PUT'], **kwargs)
|
||||
|
||||
@classmethod
|
||||
def delete(cls, path=None, **kwargs):
|
||||
return cls.route(path, methods=['DELETE'], **kwargs)
|
||||
|
@ -2,7 +2,9 @@ from cpl_query.extension import List
|
||||
|
||||
from bot_api.abc.auth_service_abc import AuthServiceABC
|
||||
from bot_api.filter.auth_user_select_criteria import AuthUserSelectCriteria
|
||||
from bot_api.logging.api_logger import ApiLogger
|
||||
from bot_api.model.auth_user_dto import AuthUserDTO
|
||||
from bot_api.model.auth_user_filtered_result_dto import AuthUserFilteredResultDTO
|
||||
from bot_api.model.reset_password_dto import ResetPasswordDTO
|
||||
from bot_api.model.token_dto import TokenDTO
|
||||
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
||||
@ -11,13 +13,18 @@ from bot_data.model.auth_user import AuthUser
|
||||
|
||||
class AuthService(AuthServiceABC):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
def __init__(
|
||||
self,
|
||||
logger: ApiLogger,
|
||||
):
|
||||
AuthServiceABC.__init__(self)
|
||||
|
||||
self._logger = logger
|
||||
|
||||
async def get_all_auth_users_async(self) -> List[AuthUser]:
|
||||
pass
|
||||
|
||||
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> List[AuthUser]:
|
||||
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO:
|
||||
pass
|
||||
|
||||
async def get_auth_user_by_email_async(self, email: str) -> AuthUser:
|
||||
@ -32,7 +39,7 @@ class AuthService(AuthServiceABC):
|
||||
async def confirm_email_async(self, id: str) -> AuthUser:
|
||||
pass
|
||||
|
||||
async def login_async(self, user_dto: AuthUserDTO) -> AuthUser:
|
||||
async def login_async(self, user_dto: AuthUserDTO) -> TokenDTO:
|
||||
pass
|
||||
|
||||
async def forgot_password_async(self, email: str) -> AuthUser:
|
||||
|
Loading…
Reference in New Issue
Block a user