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 datetime import datetime
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from lib import settings
|
||||||
|
|
||||||
class User(SQLModel, table=True):
|
|
||||||
id: Optional[int] = Field(default=None, primary_key=True)
|
class UserCredentials(BaseModel):
|
||||||
name: str
|
username: str = Field(description="Username of the user", examples=["admin"])
|
||||||
email: str = Field(unique=True)
|
password: str = Field(description="Password of the user", examples=["password"])
|
||||||
password: str
|
|
||||||
avatar_url: str
|
|
||||||
is_active: bool = Field(default=True)
|
class UserBase(BaseModel):
|
||||||
is_admin: bool = Field(default=False)
|
id: Optional[str] = Field(
|
||||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
default=None,
|
||||||
updated_at: datetime = Field(default_factory=datetime.utcnow)
|
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(
|
router = APIRouter(
|
||||||
prefix="/user",
|
prefix="/user",
|
||||||
@@ -9,11 +13,41 @@ router = APIRouter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/")
|
@router.get("/", response_model=list[UserOut])
|
||||||
async def get_users():
|
async def get_users() -> list[UserOut]:
|
||||||
return {"users": ["user1", "user2", "user3"]}
|
"""Get all users"""
|
||||||
|
return get_all_users()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/login")
|
@router.post(
|
||||||
async def login():
|
"/login",
|
||||||
return {"token": "token"}
|
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