Add user update ability

This commit is contained in:
Esa Kataja
2025-05-16 12:18:10 +03:00
parent 0733965540
commit f6c6d96c02
2 changed files with 48 additions and 13 deletions
+8 -5
View File
@@ -26,7 +26,7 @@ class User(UserBase):
updated_at: datetime = Field( updated_at: datetime = Field(
description="Last update timestamp", examples=["2025-01-01T00:00:00.000Z"] description="Last update timestamp", examples=["2025-01-01T00:00:00.000Z"]
) )
@property @property
def has_logged_in(self) -> bool: def has_logged_in(self) -> bool:
"""Returns True if the user has ever logged in, False if last_login is the epoch date.""" """Returns True if the user has ever logged in, False if last_login is the epoch date."""
@@ -46,9 +46,12 @@ class UserLogin(UserBase):
password: str = Field(description="Password of the user", examples=["sn1rbul4"]) password: str = Field(description="Password of the user", examples=["sn1rbul4"])
class UserChangePassword(BaseModel): class UpdateUser(BaseModel):
id: int = Field(description="ID of the user", examples=[1]) id: int = Field(description="ID of the user", examples=[1])
old_password: str = Field( avatar_id: int | None = Field(None, description="ID of the avatar", examples=[1])
description="Old password of the user", examples=["sn1rbul4"] email: str | None = Field(
None, description="Email of the user", examples=["[email protected]"]
)
password: str | None = Field(
None, description="Password of the user", examples=["p1p4l1"]
) )
password: str = Field(description="Password of the user", examples=["p1p4l1"])
+40 -8
View File
@@ -1,8 +1,11 @@
from fastapi import APIRouter, HTTPException, Request from fastapi import APIRouter, HTTPException, Request
from models.user import User, UserChangePassword from models.user import User, UpdateUser
from models.msg import Message
from lib.db import get_connection from lib.db import get_connection
from lib.logger import logger from lib.logger import logger
from lib.helpers import hash_password
from datetime import datetime
router = APIRouter(prefix="/users", tags=["users"]) router = APIRouter(prefix="/users", tags=["users"])
@@ -37,11 +40,40 @@ async def get_user(user_id: int, request: Request):
return User(**user_data) return User(**user_data)
@router.patch("/{user_id}") @router.patch("/", response_model=Message)
async def change_password(user_id: int, user: UserChangePassword, request: Request): async def update_user(user: UpdateUser, request: Request):
logger.info( logger.info(f"Update attempt for user_id: {user.id} from {request.client.host}")
f"Password change attempt for user_id: {user_id} from {request.client.host}" user_id = user.id
avatar_id = user.avatar_id if user.avatar_id else None
email = user.email if user.email else None
password = hash_password(user.password) if user.password else None
updated_at = datetime.now()
with get_connection() as conn:
# Build query dynamically based on non-None values
update_fields = []
params = []
if avatar_id is not None:
update_fields.append("avatar_id = ?")
params.append(avatar_id)
if email is not None:
update_fields.append("email = ?")
params.append(email)
if password is not None:
update_fields.append("password = ?")
params.append(password)
# Only proceed if there are fields to update
if update_fields:
query = f'UPDATE "User" SET {", ".join(update_fields)}, updated_at = ? WHERE id = ?'
params.append(updated_at)
params.append(user_id)
conn.execute(query, params)
logger.debug(
f"User updated successfully: {user_id}, avatar_id: {avatar_id}, email: {email}, password: {password}"
) )
# Implementation will go here when completed return Message(type="success", message="User updated successfully")
logger.warning(f"Password change not implemented for user_id: {user_id}")
raise HTTPException(status_code=401, detail="Not implemented")