import bcrypt from typing import Tuple, Union from mysql.connector import Error as mysqlError import app.messages.api_responses.user_responses as response import app.messages.api_errors as errors from app.db import user_db from app.mail.mail import send_mail from app.models.user_model import User from app.services.user import user_helper as helper from app.messages.mail_responses.user_email import USER_EMAIL_SUCCESSFULLY_REGISTERED def register( username: str, displayname: str, email: str, password: str ) -> Tuple[Union[dict, str], int]: """ Registers a new user with the provided username, email, and password. :param username: User's username. :type username: str :param email: User's email address. :type email: str :param password: User's password. :type password: str :return: Tuple containing a dictionary and an HTTP status code. :rtype: Tuple[Union[dict, str], int] """ try: if not helper.verify_username(username): return response.INVALID_USERNAME_FORMAT if not helper.verify_displayname(displayname): return response.INVALID_DISPLAYNAME_FORMAT if not helper.verify_email(email): return response.INVALID_EMAIL_FORMAT if not helper.verify_password(password): return response.INVALID_PASSWORD_FORMAT hashed_password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()) new_user: User = User( username=username, displayname=displayname, email=email, password=hashed_password, ) user_db.insert_user(new_user) except mysqlError as e: if "email" in e.msg: return response.EMAIL_ALREADY_IN_USE if "username" in e.msg: return response.USERNAME_ALREADY_IN_USE return errors.UNKNOWN_DATABASE_ERROR(e) send_mail(USER_EMAIL_SUCCESSFULLY_REGISTERED, new_user.email) return response.USER_CREATED_SUCCESSFULLY