import bcrypt from typing import Tuple, Union from mysql.connector import Error as mysqlError 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.api_responses import user_responses as response import app.messages.api_errors as errors from app.messages.mail_responses.user_email import ( USER_EMAIL_SUCCESSFULLY_UPDATED_ACCOUNT, ) def update_user( user_id: str, new_username: str = None, new_displayname: str = None, new_email: str = None, new_password: str = None, ) -> Tuple[Union[dict, str], int]: user: User = user_db.fetch_by_id(user_id) updated_attributes = [] if user is None: return response.UNKNOWN_ERROR if new_username: if not helper.verify_username(new_username): return response.INVALID_USERNAME_FORMAT user.username = new_username updated_attributes.append("username") if new_displayname: if not helper.verify_displayname(new_displayname): return response.INVALID_DISPLAYNAME_FORMAT user.displayname = new_displayname updated_attributes.append("displayname") if new_email: if not helper.verify_email(new_email): return response.INVALID_EMAIL_FORMAT user.email = new_email updated_attributes.append("email") if new_password: if not helper.verify_password(new_password): return response.INVALID_PASSWORD_FORMAT hashed_password = bcrypt.hashpw(new_password.encode("utf-8"), bcrypt.gensalt()) user.password = hashed_password updated_attributes.append("password") try: user_db.update_user(user) except mysqlError as e: if "username" in e.msg: return response.USERNAME_ALREADY_IN_USE if "email" in e.msg: return response.EMAIL_ALREADY_IN_USE return errors.UNKNOWN_DATABASE_ERROR(e) send_mail(USER_EMAIL_SUCCESSFULLY_UPDATED_ACCOUNT, user.email) return response.USER_ACCOUNT_UPDATED_SUCCESSFULLY(updated_attributes)