Add User login route
This commit is contained in:
+48
-11
@@ -1,15 +1,52 @@
|
||||
from sqlmodel import Field, SQLModel
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from lib import settings
|
||||
|
||||
class User(SQLModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
name: str
|
||||
email: str = Field(unique=True)
|
||||
password: str
|
||||
avatar_url: str
|
||||
is_active: bool = Field(default=True)
|
||||
is_admin: bool = Field(default=False)
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
updated_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
class UserCredentials(BaseModel):
|
||||
username: str = Field(description="Username of the user", examples=["admin"])
|
||||
password: str = Field(description="Password of the user", examples=["password"])
|
||||
|
||||
|
||||
class UserBase(BaseModel):
|
||||
id: Optional[str] = Field(
|
||||
default=None,
|
||||
description="UUID representation of the user",
|
||||
examples=["123e4567-e89b-12d3-a456-426655440000"],
|
||||
)
|
||||
username: str = Field(description="Username of the user", examples=["Palli-Pate"])
|
||||
email: Optional[str] = Field(
|
||||
default=None, description="Email of the user", examples=["[email protected]"]
|
||||
)
|
||||
avatar_url: str = Field(
|
||||
default=settings.default_avatar_url, description="Avatar URL of the user"
|
||||
)
|
||||
is_active: bool = Field(
|
||||
default=True, description="Whether the user is active or not"
|
||||
)
|
||||
is_admin: bool = Field(
|
||||
default=False, description="Whether the user is an admin or not"
|
||||
)
|
||||
last_login: Optional[datetime] = Field(
|
||||
default=None,
|
||||
description="Last login date of the user",
|
||||
examples=[datetime.utcnow()],
|
||||
)
|
||||
created_at: datetime = Field(
|
||||
default_factory=datetime.utcnow, description="Creation date of the user"
|
||||
)
|
||||
modified_at: datetime = Field(
|
||||
default_factory=datetime.utcnow, description="Modification date of the user"
|
||||
)
|
||||
|
||||
|
||||
class UserIn(UserBase):
|
||||
password: Optional[str] = Field(
|
||||
default=None, description="Password of the user", examples=["password"]
|
||||
)
|
||||
|
||||
|
||||
class UserOut(UserBase):
|
||||
pass
|
||||
|
||||
+42
-8
@@ -1,6 +1,10 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import APIRouter, Response
|
||||
import bcrypt
|
||||
|
||||
from models.user import UserIn, UserOut, UserCredentials
|
||||
from models.general import Message
|
||||
from lib.database import get_all_users, get_user_by_username
|
||||
|
||||
from models import User
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/user",
|
||||
@@ -9,11 +13,41 @@ router = APIRouter(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def get_users():
|
||||
return {"users": ["user1", "user2", "user3"]}
|
||||
@router.get("/", response_model=list[UserOut])
|
||||
async def get_users() -> list[UserOut]:
|
||||
"""Get all users"""
|
||||
return get_all_users()
|
||||
|
||||
|
||||
@router.post("/login")
|
||||
async def login():
|
||||
return {"token": "token"}
|
||||
@router.post(
|
||||
"/login",
|
||||
responses={
|
||||
200: {"model": UserOut, "description": "Login successful"},
|
||||
400: {"model": Message},
|
||||
404: {"model": Message},
|
||||
},
|
||||
)
|
||||
async def login(user: UserCredentials):
|
||||
"""Login a user"""
|
||||
user_from_db: UserIn = get_user_by_username(user.username)
|
||||
if user_from_db is None:
|
||||
return Response(
|
||||
status_code=404,
|
||||
media_type="application/json",
|
||||
content=Message(
|
||||
message="User not found", message_type="error"
|
||||
).model_dump_json(),
|
||||
)
|
||||
|
||||
password = user.password.encode("utf-8")
|
||||
|
||||
if bcrypt.checkpw(password, user_from_db.password.encode("utf-8")):
|
||||
return UserOut(**user_from_db.model_dump())
|
||||
|
||||
return Response(
|
||||
status_code=400,
|
||||
media_type="application/json",
|
||||
content=Message(
|
||||
message="Invalid password", message_type="error"
|
||||
).model_dump_json(),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user