feat: register done
This commit is contained in:
parent
bc5094ed7d
commit
c06b7ab899
|
@ -1,5 +1,6 @@
|
|||
from .default import default_blueprint
|
||||
|
||||
from .auth import auth_blueprint
|
||||
from .user import user_blueprint
|
||||
|
||||
# from .user import user_blueprint
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import sys
|
||||
from flask import Blueprint
|
||||
from controllers import AuthController
|
||||
from di_container import Container
|
||||
|
@ -8,12 +7,6 @@ from dependency_injector.wiring import inject, Provide
|
|||
auth_blueprint = Blueprint("auth", __name__)
|
||||
|
||||
|
||||
@auth_blueprint.route("/register", methods=["POST"])
|
||||
@inject
|
||||
def register(auth_controller: AuthController = Provide[Container.auth_controller]):
|
||||
return auth_controller.register()
|
||||
|
||||
|
||||
@auth_blueprint.route("/login", methods=["POST"])
|
||||
@inject
|
||||
def login(auth_controller: AuthController = Provide[Container.auth_controller]):
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
from flask import Blueprint
|
||||
from controllers import UserController
|
||||
from di_container import container
|
||||
from di_container import Container
|
||||
from dependency_injector.wiring import inject, Provide
|
||||
|
||||
user_blueprint = Blueprint("user", __name__)
|
||||
|
||||
user_controller = UserController(container.user_service)
|
||||
|
||||
|
||||
@user_blueprint.route("/users", methods=["GET"])
|
||||
def get_users():
|
||||
@inject
|
||||
def get_users(user_controller: UserController = Provide[Container.user_controller]):
|
||||
return user_controller.get_users()
|
||||
|
||||
|
||||
@user_blueprint.route("/register", methods=["POST"])
|
||||
@inject
|
||||
def register(user_controller: UserController = Provide[Container.user_controller]):
|
||||
return user_controller.register()
|
||||
|
|
|
@ -4,7 +4,7 @@ from schemas.basic_response_schema import ResponseSchema
|
|||
from schemas.google_login_schema import GoogleLoginSchema
|
||||
from schemas import LoginSchema
|
||||
from services import UserService, AuthService
|
||||
from core import AuthException
|
||||
from exception import AuthException
|
||||
|
||||
|
||||
class AuthController:
|
||||
|
@ -17,10 +17,10 @@ class AuthController:
|
|||
data = request.get_json()
|
||||
dataSchema = LoginSchema(**data)
|
||||
response = self.auth_service.login(dataSchema)
|
||||
|
||||
if response.success:
|
||||
return jsonify({}), 200
|
||||
return jsonify({}), 400
|
||||
return (
|
||||
jsonify(ResponseSchema(message="Register success", data=response)),
|
||||
200,
|
||||
)
|
||||
except ValidationError as e:
|
||||
current_app.logger.error(f"Validation error: {e}")
|
||||
response = ResponseSchema(message="Invalid input", data=None, meta=None)
|
||||
|
@ -79,11 +79,5 @@ class AuthController:
|
|||
)
|
||||
return jsonify(response.model_dump()), 500
|
||||
|
||||
def register(self):
|
||||
return jsonify({"message": "register"}), 200
|
||||
|
||||
def logout(self):
|
||||
return jsonify({"message": "logout"}), 200
|
||||
|
||||
def test(self):
|
||||
return "test"
|
||||
|
|
|
@ -1,12 +1,41 @@
|
|||
# /controllers/user_controller.py
|
||||
from flask import jsonify
|
||||
from flask import jsonify, request, current_app
|
||||
from services import UserService
|
||||
from schemas import RegisterSchema
|
||||
from pydantic import ValidationError
|
||||
from schemas import ResponseSchema
|
||||
from exception import AlreadyExistException
|
||||
|
||||
|
||||
class UserController:
|
||||
def __init__(self, userService: UserService):
|
||||
self.user_service = userService
|
||||
|
||||
def get_users(self):
|
||||
users = self.user_service.get_all_users()
|
||||
return jsonify(users)
|
||||
def register(self):
|
||||
try:
|
||||
request_data = request.get_json()
|
||||
register_data = RegisterSchema(**request_data)
|
||||
self.user_service.register_user(register_data)
|
||||
return jsonify(ResponseSchema(message="Register Success").model_dump()), 200
|
||||
|
||||
except ValidationError as e:
|
||||
current_app.logger.error(f"Validation error: {e}")
|
||||
response = ResponseSchema(message="Invalid input", data=None, meta=None)
|
||||
return jsonify(response.model_dump()), 400
|
||||
|
||||
except AlreadyExistException as e:
|
||||
return (
|
||||
jsonify(
|
||||
ResponseSchema(message=str(e), data=None, meta=None).model_dump()
|
||||
),
|
||||
409,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
current_app.logger.error(
|
||||
f"Error during Google login: {str(e)}", exc_info=True
|
||||
)
|
||||
response = ResponseSchema(
|
||||
message="Internal server error", data=None, meta=None
|
||||
)
|
||||
return jsonify(response.model_dump()), 500
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
from .exception import AuthException
|
|
@ -1 +0,0 @@
|
|||
from .auth_exception import AuthException
|
|
@ -1,9 +0,0 @@
|
|||
class AuthException(Exception):
|
||||
"""Custom exception for authentication-related errors"""
|
||||
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
self.message = message
|
||||
|
||||
def __str__(self):
|
||||
return f"AuthException: {self.message}"
|
|
@ -1,4 +1,5 @@
|
|||
from dependency_injector import containers, providers
|
||||
from controllers import UserController
|
||||
from repositories.user_repository import UserRepository
|
||||
from services import UserService, AuthService
|
||||
from controllers import AuthController
|
||||
|
@ -19,3 +20,4 @@ class Container(containers.DeclarativeContainer):
|
|||
|
||||
# controllers
|
||||
auth_controller = providers.Factory(AuthController, user_service, auth_service)
|
||||
user_controller = providers.Factory(UserController, user_service)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
from .auth_exception import AuthException
|
||||
from .already_exist_exception import AlreadyExistException
|
|
@ -0,0 +1,6 @@
|
|||
class AlreadyExistException(Exception):
|
||||
def __init__(self, entity: str, message: str = None):
|
||||
if message is None:
|
||||
message = f"{entity} already exists"
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
|
@ -0,0 +1,8 @@
|
|||
from .base_exception import BaseExceptionTemplate
|
||||
|
||||
|
||||
class AuthException(BaseExceptionTemplate):
|
||||
"""Exception for authentication-related errors"""
|
||||
|
||||
def __init__(self, message: str = "Authentication failed"):
|
||||
super().__init__(message, status_code=401)
|
|
@ -0,0 +1,10 @@
|
|||
class BaseExceptionTemplate(Exception):
|
||||
"""Base exception template for custom exceptions"""
|
||||
|
||||
def __init__(self, message: str, status_code: int = 400):
|
||||
self.message = message
|
||||
self.status_code = status_code
|
||||
super().__init__(self.message)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.__class__.__name__}: {self.message}"
|
|
@ -2,7 +2,7 @@ from blueprints import default_blueprint
|
|||
from di_container import Container
|
||||
from configs import Config, LoggerConfig
|
||||
from flask import Flask
|
||||
from blueprints import auth_blueprint
|
||||
from blueprints import auth_blueprint, user_blueprint
|
||||
from database import init_db
|
||||
|
||||
|
||||
|
@ -19,10 +19,12 @@ def createApp() -> Flask:
|
|||
container.mongo.override(mongo)
|
||||
|
||||
container.wire(modules=["blueprints.auth"])
|
||||
container.wire(modules=["blueprints.user"])
|
||||
|
||||
# Register Blueprints
|
||||
app.register_blueprint(default_blueprint)
|
||||
app.register_blueprint(auth_blueprint, url_prefix="/api")
|
||||
app.register_blueprint(user_blueprint, url_prefix="/api")
|
||||
|
||||
# Initialize Logging
|
||||
LoggerConfig.init_logger(app)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from datetime import datetime
|
||||
from typing import Dict, Optional
|
||||
from models import UserEntity
|
||||
from schemas import RegisterSchema
|
||||
|
||||
|
||||
class UserMapper:
|
||||
|
@ -22,3 +23,19 @@ class UserMapper:
|
|||
updated_at=datetime.now(),
|
||||
verification_token=None,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def from_register(data: RegisterSchema) -> UserEntity:
|
||||
return UserEntity(
|
||||
email=data.email,
|
||||
password=data.password,
|
||||
name=data.name,
|
||||
birth_date=datetime.strptime(data.birth_date, "%d-%m-%Y").date(),
|
||||
phone=data.phone,
|
||||
role="user",
|
||||
is_active=False,
|
||||
address=None,
|
||||
created_at=datetime.now(),
|
||||
updated_at=datetime.now(),
|
||||
verification_token=None,
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from typing import Optional
|
||||
from pydantic import BaseModel, EmailStr
|
||||
from datetime import date, datetime
|
||||
from datetime import datetime
|
||||
from .base import PyObjectId
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@ class UserEntity(BaseModel):
|
|||
email: EmailStr
|
||||
password: Optional[str] = None
|
||||
name: str
|
||||
birth_date: Optional[date] = None
|
||||
birth_date: Optional[datetime] = None
|
||||
pic_url: Optional[str] = None
|
||||
phone: Optional[str] = None
|
||||
locale: str = "en-US"
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
from .login_schema import LoginSchema
|
||||
from .basic_response_schema import ResponseSchema, MetaSchema
|
||||
from .requests import RegisterSchema
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
from .register_schema import RegisterSchema
|
|
@ -0,0 +1,10 @@
|
|||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class RegisterSchema(BaseModel):
|
||||
email: str
|
||||
password: str
|
||||
name: str
|
||||
birth_date: str
|
||||
phone: Optional[str] = None
|
|
@ -4,7 +4,7 @@ from mapper import UserMapper
|
|||
from google.oauth2 import id_token
|
||||
from google.auth.transport import requests
|
||||
from configs import Config
|
||||
from core import AuthException
|
||||
from exception import AuthException
|
||||
from flask import current_app
|
||||
|
||||
|
||||
|
@ -13,14 +13,12 @@ class AuthService:
|
|||
self.user_repository = userRepository
|
||||
|
||||
def verify_google_id_token(self, id_token_str):
|
||||
|
||||
# Verifikasi token Google
|
||||
payload = id_token.verify_oauth2_token(
|
||||
id_token_str, requests.Request(), Config.GOOGLE_CLIENT_ID
|
||||
)
|
||||
|
||||
if not payload:
|
||||
return AuthException("Invalid Google ID Token")
|
||||
raise AuthException("Invalid Google ID Token")
|
||||
|
||||
google_id = payload.get("sub")
|
||||
email = payload.get("email")
|
||||
|
@ -29,7 +27,7 @@ class AuthService:
|
|||
if existing_user:
|
||||
if existing_user.email == email:
|
||||
return existing_user
|
||||
return AuthException("Email not match")
|
||||
raise AuthException("Email not match")
|
||||
|
||||
new_user = UserMapper.from_google_payload(google_id, email, payload)
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
from flask import current_app
|
||||
from repositories import UserRepository
|
||||
from schemas import RegisterSchema
|
||||
from mapper import UserMapper
|
||||
from exception import AlreadyExistException
|
||||
|
||||
|
||||
class UserService:
|
||||
|
@ -7,3 +11,11 @@ class UserService:
|
|||
|
||||
def get_all_users(self):
|
||||
return self.user_repository.get_all_users()
|
||||
|
||||
def register_user(self, user_data: RegisterSchema):
|
||||
existData = self.user_repository.get_user_by_email(user_data.email)
|
||||
if existData:
|
||||
raise AlreadyExistException(entity="Email")
|
||||
|
||||
data = UserMapper.from_register(user_data)
|
||||
return self.user_repository.insert_user(data)
|
||||
|
|
Loading…
Reference in New Issue