78 lines
3.3 KiB
Python
78 lines
3.3 KiB
Python
from fastapi import HTTPException
|
|
from users.models import Users
|
|
from users.serializers import serialize_user
|
|
from users.plugins import clean_user_payload,verify_password,decode_token
|
|
from dotenv import load_dotenv
|
|
load_dotenv()
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
import jwt
|
|
|
|
class User:
|
|
def __init__(self,session:AsyncSession):
|
|
self.session=session
|
|
|
|
async def create_user(self,payload):
|
|
existing=await Users.get_user_by_email(self.session,payload.get("email"))
|
|
if existing:
|
|
raise HTTPException(status_code=409,detail="Email already registered")
|
|
# this is for password hasshing
|
|
fields=clean_user_payload(payload)
|
|
if not fields.get("password"):
|
|
raise HTTPException(status_code=400,detail="Password is required")
|
|
user=await Users.insert_user(self.session,fields)
|
|
return serialize_user(user)
|
|
|
|
async def get_users(self,top,skip,search=None):
|
|
users=await Users.get_users(self.session,top,skip,search)
|
|
return [serialize_user(u) for u in users]
|
|
|
|
async def get_user_by_id(self,record_id):
|
|
user=await Users.get_user_by_id(self.session,record_id)
|
|
if not user:
|
|
raise HTTPException(status_code=404,detail="User not found")
|
|
return serialize_user(user)
|
|
|
|
async def update_user(self,record_id,payload):
|
|
user=await Users.get_user_by_id(self.session,record_id)
|
|
if not user:
|
|
raise HTTPException(status_code=404,detail="User not found")
|
|
fields=clean_user_payload(payload,partial=True)
|
|
email=fields.get("email")
|
|
if email and email!=user.email:
|
|
clash=await Users.get_user_by_email(self.session,email)
|
|
if clash:
|
|
raise HTTPException(status_code=409,detail="Email already registered")
|
|
updated=await Users.update_user(self.session,record_id,fields)
|
|
return serialize_user(updated)
|
|
|
|
async def delete_user(self,record_id):
|
|
user=await Users.soft_delete_user(self.session,record_id)
|
|
if not user:
|
|
raise HTTPException(status_code=404,detail="User not found")
|
|
return serialize_user(user)
|
|
|
|
async def count_users(self,search=None):
|
|
return await Users.count_users(self.session,search)
|
|
|
|
async def authenticate_user(self,email,password):
|
|
user=await Users.get_user_by_email(self.session,email)
|
|
if not user or not verify_password(password,user.password):
|
|
raise HTTPException(
|
|
status_code=401,
|
|
detail="Incorrect email or password",
|
|
headers={"WWW-Authenticate":"Bearer"},
|
|
)
|
|
if user.is_deleted or not user.is_active:
|
|
raise HTTPException(status_code=401,detail="User is inactive")
|
|
return await Users.get_user_by_id(self.session,user.id)
|
|
|
|
async def refresh_access_token(self,refresh_token):
|
|
try:
|
|
payload=decode_token(refresh_token,expected_type="refresh")
|
|
except jwt.PyJWTError:
|
|
raise HTTPException(status_code=401,detail="Invalid or expired refresh token")
|
|
user=await Users.get_user_by_id(self.session,payload.get("sub"))
|
|
if not user or user.is_deleted or not user.is_active:
|
|
raise HTTPException(status_code=401,detail="User is inactive or does not exist")
|
|
return user
|