import datetime from typing import Tuple, Union import bcrypt from mysql.connector import Error as mysqlError from flask_jwt_extended import create_access_token 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.messages.mail_responses.user_email import USER_EMAIL_SUCCESSFULLY_LOGGED_IN def login(username: str, password: str) -> Tuple[Union[dict, str], int]: """ Authenticates a user with the provided username and password. :param username: User's username. :type username: str :param password: User's password. :type password: str :return: Tuple containing a dictionary with a token and an HTTP status code. :rtype: Tuple[Union[dict, str], int] """ try: user: User = user_db.fetch_by_username(username) if user is None: return response.USERNAME_NOT_FOUND if not bcrypt.checkpw(password.encode("utf-8"), user.password.encode("utf-8")): return response.INCORRECT_PASSWORD expire = datetime.timedelta(hours=1) token = create_access_token(identity=user.user_id, expires_delta=expire) send_mail(USER_EMAIL_SUCCESSFULLY_LOGGED_IN, user.email) return {"token": token}, 200 except mysqlError as e: return errors.UNKNOWN_DATABASE_ERROR(e)