2023-07-10 20:07:19 -07:00
|
|
|
from typing import Optional, Union
|
|
|
|
|
2023-07-09 13:15:39 -07:00
|
|
|
from passlib.context import CryptContext
|
|
|
|
from supabase_py import create_client, Client
|
2023-07-09 16:42:44 -07:00
|
|
|
from fastapi import HTTPException, status
|
|
|
|
|
2023-07-09 13:15:39 -07:00
|
|
|
from api.core.users import UserInDB
|
|
|
|
from settings import SUPABASE_URL, SUPABASE_KEY
|
|
|
|
|
|
|
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
2023-08-26 12:28:02 -07:00
|
|
|
if SUPABASE_URL:
|
|
|
|
supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
|
2023-07-09 13:15:39 -07:00
|
|
|
|
2023-07-09 16:42:44 -07:00
|
|
|
|
|
|
|
def create_user(user_create: UserInDB):
|
2023-07-10 20:07:19 -07:00
|
|
|
"""
|
|
|
|
Creates a new user record in the 'users' table in Supabase.
|
|
|
|
|
|
|
|
:param user_create: The data of the user to be created.
|
|
|
|
:raises HTTPException: If an error occurs while creating the user.
|
|
|
|
:return: The result of the insert operation.
|
|
|
|
"""
|
2023-07-09 16:42:44 -07:00
|
|
|
result = supabase.table("users").insert(user_create.dict()).execute()
|
|
|
|
print(f"Insert result: {result}")
|
|
|
|
|
|
|
|
if "error" in result and result["error"]:
|
|
|
|
raise HTTPException(
|
|
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
|
|
detail=f"User could not be created due to {result['error']['message']}",
|
|
|
|
)
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
2023-07-10 20:07:19 -07:00
|
|
|
def get_user(username: str) -> Optional[UserInDB]:
|
|
|
|
"""
|
|
|
|
Retrieves a user from the 'users' table by their username.
|
|
|
|
|
|
|
|
:param username: The username of the user to retrieve.
|
|
|
|
:return: The user data if found, otherwise None.
|
|
|
|
"""
|
2023-07-09 16:42:44 -07:00
|
|
|
result = supabase.table("users").select().eq("username", username).execute()
|
2023-07-09 13:15:39 -07:00
|
|
|
|
2023-07-09 16:42:44 -07:00
|
|
|
if "error" in result and result["error"]:
|
2023-07-09 13:15:39 -07:00
|
|
|
print(f"Error: {result['error']['message']}")
|
|
|
|
return None
|
|
|
|
else:
|
2023-07-09 16:42:44 -07:00
|
|
|
if result["data"]:
|
|
|
|
user_data = result["data"][0]
|
2023-07-09 13:15:39 -07:00
|
|
|
return UserInDB(**user_data)
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
2023-07-09 16:42:44 -07:00
|
|
|
|
2023-07-10 20:07:19 -07:00
|
|
|
def verify_password(password: str, hashed_password: str) -> bool:
|
|
|
|
"""
|
|
|
|
Verifies a password against a hashed password using the bcrypt hashing algorithm.
|
|
|
|
|
|
|
|
:param password: The plaintext password to verify.
|
|
|
|
:param hashed_password: The hashed password to compare against.
|
|
|
|
:return: True if the password matches the hashed password, otherwise False.
|
|
|
|
"""
|
2023-07-09 13:15:39 -07:00
|
|
|
return pwd_context.verify(password, hashed_password)
|
|
|
|
|
|
|
|
|
2023-07-10 20:07:19 -07:00
|
|
|
def get_password_hash(password: str) -> str:
|
|
|
|
"""
|
|
|
|
Hashes a password using the bcrypt hashing algorithm.
|
|
|
|
|
|
|
|
:param password: The plaintext password to hash.
|
|
|
|
:return: The hashed password
|
|
|
|
"""
|
2023-07-09 13:15:39 -07:00
|
|
|
return pwd_context.hash(password)
|
|
|
|
|
|
|
|
|
2023-07-10 20:07:19 -07:00
|
|
|
def authenticate_user(username: str, password: str) -> Union[UserInDB, bool]:
|
|
|
|
"""
|
|
|
|
Authenticates a user based on their username and password.
|
|
|
|
|
|
|
|
:param username: The username of the user to authenticate.
|
|
|
|
:param password: The plaintext password to authenticate.
|
|
|
|
:return: The authenticated user if the username and password are correct, otherwise False.
|
|
|
|
"""
|
2023-07-09 13:15:39 -07:00
|
|
|
user = get_user(username)
|
|
|
|
if not user:
|
|
|
|
return False
|
|
|
|
if not verify_password(password, user.hashed_password):
|
|
|
|
return False
|
|
|
|
return user
|