46 lines
1.4 KiB
Python
46 lines
1.4 KiB
Python
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)
|