mirror of
https://github.com/eigent-ai/eigent.git
synced 2026-04-30 12:40:10 +00:00
update server logs
This commit is contained in:
parent
6eed287dcb
commit
40779bf1e5
43 changed files with 2354 additions and 1808 deletions
|
|
@ -1,106 +1,114 @@
|
|||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi_babel import _
|
||||
from sqlmodel import Session
|
||||
from app.component import code
|
||||
from app.component.auth import Auth
|
||||
from app.component.database import session
|
||||
from app.component.encrypt import password_verify
|
||||
from app.component.stack_auth import StackAuth
|
||||
from app.exception.exception import UserException
|
||||
from app.model.user.user import LoginByPasswordIn, LoginResponse, Status, User, RegisterIn
|
||||
from app.component.environment import env
|
||||
import traceroot
|
||||
|
||||
logger = traceroot.get_logger("server_login_controller")
|
||||
|
||||
|
||||
router = APIRouter(tags=["Login/Registration"])
|
||||
|
||||
|
||||
@router.post("/login", name="login by email or password")
|
||||
@traceroot.trace()
|
||||
async def by_password(data: LoginByPasswordIn, session: Session = Depends(session)) -> LoginResponse:
|
||||
"""
|
||||
User login with email and password
|
||||
"""
|
||||
logger.info(f"Login attempt for email: {data.email}")
|
||||
user = User.by(User.email == data.email, s=session).one_or_none()
|
||||
if not user or not password_verify(data.password, user.password):
|
||||
raise UserException(code.password, _("Account or password error"))
|
||||
return LoginResponse(token=Auth.create_access_token(user.id), email=user.email)
|
||||
|
||||
|
||||
@router.post("/login-by_stack", name="login by stack")
|
||||
@traceroot.trace()
|
||||
async def by_stack_auth(
|
||||
token: str,
|
||||
type: str = "signup",
|
||||
invite_code: str | None = None,
|
||||
session: Session = Depends(session),
|
||||
):
|
||||
logger.info(f"Stack auth attempt, type: {type}")
|
||||
try:
|
||||
stack_id = await StackAuth.user_id(token)
|
||||
info = await StackAuth.user_info(token)
|
||||
logger.debug(f"Stack auth successful for stack_id: {stack_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"Stack auth failed: {e}", exc_info=True)
|
||||
raise HTTPException(500, detail=_(f"{e}"))
|
||||
user = User.by(User.stack_id == stack_id, s=session).one_or_none()
|
||||
|
||||
if not user:
|
||||
# Only signup can create user
|
||||
if type != "signup":
|
||||
logger.warning(f"User not found for stack_id: {stack_id}, type: {type}")
|
||||
raise UserException(code.error, _("User not found"))
|
||||
logger.info(f"Creating new user via stack auth: {info.get('primary_email')}")
|
||||
with session as s:
|
||||
try:
|
||||
user = User(
|
||||
username=info["username"] if "username" in info else None,
|
||||
nickname=info["display_name"],
|
||||
email=info["primary_email"],
|
||||
avatar=info["profile_image_url"],
|
||||
stack_id=stack_id,
|
||||
)
|
||||
s.add(user)
|
||||
s.commit()
|
||||
session.refresh(user)
|
||||
logger.info(f"New user registered via stack auth: {user.id}")
|
||||
return LoginResponse(token=Auth.create_access_token(user.id), email=user.email)
|
||||
except Exception as e:
|
||||
s.rollback()
|
||||
logger.error(f"Failed to register via stack auth: {e}", exc_info=True)
|
||||
raise UserException(code.error, _("Failed to register"))
|
||||
else:
|
||||
if user.status == Status.Block:
|
||||
logger.warning(f"Blocked user attempted login: {user.id}")
|
||||
raise UserException(code.error, _("Your account has been blocked."))
|
||||
logger.info(f"Existing user logged in via stack auth: {user.id}")
|
||||
return LoginResponse(token=Auth.create_access_token(user.id), email=user.email)
|
||||
|
||||
|
||||
@router.post("/register", name="register by email/password")
|
||||
@traceroot.trace()
|
||||
async def register(data: RegisterIn, session: Session = Depends(session)):
|
||||
logger.info(f"Registration attempt for email: {data.email}")
|
||||
# Check if email is already registered
|
||||
if User.by(User.email == data.email, s=session).one_or_none():
|
||||
logger.warning(f"Registration failed - email already exists: {data.email}")
|
||||
raise UserException(code.error, _("Email already registered"))
|
||||
|
||||
with session as s:
|
||||
try:
|
||||
user = User(
|
||||
email=data.email,
|
||||
password=data.password,
|
||||
)
|
||||
s.add(user)
|
||||
s.commit()
|
||||
s.refresh(user)
|
||||
logger.info(f"New user registered: {user.id}, email: {user.email}")
|
||||
except Exception as e:
|
||||
s.rollback()
|
||||
logger.error(f"Failed to register user: {e}", exc_info=True)
|
||||
raise UserException(code.error, _("Failed to register"))
|
||||
return {"status": "success"}
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi_babel import _
|
||||
from sqlmodel import Session
|
||||
from app.component import code
|
||||
from app.component.auth import Auth
|
||||
from app.component.database import session
|
||||
from app.component.encrypt import password_verify
|
||||
from app.component.stack_auth import StackAuth
|
||||
from app.exception.exception import UserException
|
||||
from app.model.user.user import LoginByPasswordIn, LoginResponse, Status, User, RegisterIn
|
||||
from app.component.environment import env
|
||||
from utils import traceroot_wrapper as traceroot
|
||||
|
||||
logger = traceroot.get_logger("server_login_controller")
|
||||
|
||||
|
||||
router = APIRouter(tags=["Login/Registration"])
|
||||
|
||||
|
||||
@router.post("/login", name="login by email or password")
|
||||
@traceroot.trace()
|
||||
async def by_password(data: LoginByPasswordIn, session: Session = Depends(session)) -> LoginResponse:
|
||||
"""
|
||||
User login with email and password
|
||||
"""
|
||||
email = data.email
|
||||
user = User.by(User.email == email, s=session).one_or_none()
|
||||
|
||||
if not user:
|
||||
logger.warning("Login failed: user not found", extra={"email": email})
|
||||
raise UserException(code.password, _("Account or password error"))
|
||||
|
||||
if not password_verify(data.password, user.password):
|
||||
logger.warning("Login failed: invalid password", extra={"user_id": user.id, "email": email})
|
||||
raise UserException(code.password, _("Account or password error"))
|
||||
|
||||
logger.info("User login successful", extra={"user_id": user.id, "email": email})
|
||||
return LoginResponse(token=Auth.create_access_token(user.id), email=user.email)
|
||||
|
||||
|
||||
@router.post("/login-by_stack", name="login by stack")
|
||||
@traceroot.trace()
|
||||
async def by_stack_auth(
|
||||
token: str,
|
||||
type: str = "signup",
|
||||
invite_code: str | None = None,
|
||||
session: Session = Depends(session),
|
||||
):
|
||||
try:
|
||||
stack_id = await StackAuth.user_id(token)
|
||||
info = await StackAuth.user_info(token)
|
||||
except Exception as e:
|
||||
logger.error("Stack auth failed", extra={"type": type, "error": str(e)}, exc_info=True)
|
||||
raise HTTPException(500, detail=_(f"{e}"))
|
||||
|
||||
user = User.by(User.stack_id == stack_id, s=session).one_or_none()
|
||||
|
||||
if not user:
|
||||
if type != "signup":
|
||||
logger.warning("Stack auth signup blocked: user not found", extra={"stack_id": stack_id, "type": type})
|
||||
raise UserException(code.error, _("User not found"))
|
||||
|
||||
with session as s:
|
||||
try:
|
||||
user = User(
|
||||
username=info["username"] if "username" in info else None,
|
||||
nickname=info["display_name"],
|
||||
email=info["primary_email"],
|
||||
avatar=info["profile_image_url"],
|
||||
stack_id=stack_id,
|
||||
)
|
||||
s.add(user)
|
||||
s.commit()
|
||||
s.refresh(user)
|
||||
logger.info("New user registered via stack", extra={"user_id": user.id, "email": user.email, "stack_id": stack_id})
|
||||
return LoginResponse(token=Auth.create_access_token(user.id), email=user.email)
|
||||
except Exception as e:
|
||||
s.rollback()
|
||||
logger.error("Stack auth registration failed", extra={"stack_id": stack_id, "error": str(e)}, exc_info=True)
|
||||
raise UserException(code.error, _("Failed to register"))
|
||||
else:
|
||||
if user.status == Status.Block:
|
||||
logger.warning("Blocked user login attempt", extra={"user_id": user.id, "stack_id": stack_id})
|
||||
raise UserException(code.error, _("Your account has been blocked."))
|
||||
|
||||
logger.info("User login via stack successful", extra={"user_id": user.id, "email": user.email, "stack_id": stack_id})
|
||||
return LoginResponse(token=Auth.create_access_token(user.id), email=user.email)
|
||||
|
||||
|
||||
@router.post("/register", name="register by email/password")
|
||||
@traceroot.trace()
|
||||
async def register(data: RegisterIn, session: Session = Depends(session)):
|
||||
email = data.email
|
||||
|
||||
if User.by(User.email == email, s=session).one_or_none():
|
||||
logger.warning("Registration failed: email already exists", extra={"email": email})
|
||||
raise UserException(code.error, _("Email already registered"))
|
||||
|
||||
with session as s:
|
||||
try:
|
||||
user = User(
|
||||
email=email,
|
||||
password=data.password,
|
||||
)
|
||||
s.add(user)
|
||||
s.commit()
|
||||
s.refresh(user)
|
||||
logger.info("User registered successfully", extra={"user_id": user.id, "email": email})
|
||||
except Exception as e:
|
||||
s.rollback()
|
||||
logger.error("User registration failed", extra={"email": email, "error": str(e)}, exc_info=True)
|
||||
raise UserException(code.error, _("Failed to register"))
|
||||
|
||||
return {"status": "success"}
|
||||
|
|
@ -1,115 +1,151 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy import func
|
||||
from sqlmodel import Session, select
|
||||
from app.component.auth import Auth, auth_must
|
||||
from app.component.database import session
|
||||
from app.model.user.privacy import UserPrivacy, UserPrivacySettings
|
||||
from app.model.user.user import User, UserIn, UserOut, UserProfile
|
||||
from app.model.user.user_stat import UserStat, UserStatActionIn, UserStatOut
|
||||
from app.model.chat.chat_history import ChatHistory
|
||||
from app.model.mcp.mcp_user import McpUser
|
||||
from app.model.config.config import Config
|
||||
from app.model.chat.chat_snpshot import ChatSnapshot
|
||||
from app.model.user.user_credits_record import UserCreditsRecord
|
||||
|
||||
|
||||
router = APIRouter(tags=["User"])
|
||||
|
||||
|
||||
@router.get("/user", name="user info", response_model=UserOut)
|
||||
def get(auth: Auth = Depends(auth_must), session: Session = Depends(session)):
|
||||
# 获取用户信息时触发积分刷新
|
||||
user: User = auth.user
|
||||
user.refresh_credits_on_active(session)
|
||||
return user
|
||||
|
||||
|
||||
@router.put("/user", name="update user info", response_model=UserOut)
|
||||
def put(data: UserIn, session: Session = Depends(session), auth: Auth = Depends(auth_must)):
|
||||
model = auth.user
|
||||
model.username = data.username
|
||||
model.save(session)
|
||||
return model
|
||||
|
||||
|
||||
@router.put("/user/profile", name="update user profile", response_model=UserProfile)
|
||||
def put_profile(data: UserProfile, session: Session = Depends(session), auth: Auth = Depends(auth_must)):
|
||||
model = auth.user
|
||||
model.nickname = data.nickname
|
||||
model.fullname = data.fullname
|
||||
model.work_desc = data.work_desc
|
||||
model.save(session)
|
||||
return model
|
||||
|
||||
|
||||
@router.get("/user/privacy", name="get user privacy")
|
||||
def get_privacy(session: Session = Depends(session), auth: Auth = Depends(auth_must)):
|
||||
user_id = auth.user.id
|
||||
stmt = select(UserPrivacy).where(UserPrivacy.user_id == user_id)
|
||||
model = session.exec(stmt).one_or_none()
|
||||
|
||||
if not model:
|
||||
return UserPrivacySettings.default_settings()
|
||||
return model.pricacy_setting
|
||||
|
||||
|
||||
@router.put("/user/privacy", name="update user privacy")
|
||||
def put_privacy(data: UserPrivacySettings, session: Session = Depends(session), auth: Auth = Depends(auth_must)):
|
||||
user_id = auth.user.id
|
||||
stmt = select(UserPrivacy).where(UserPrivacy.user_id == user_id)
|
||||
model = session.exec(stmt).one_or_none()
|
||||
default_settings = UserPrivacySettings.default_settings()
|
||||
|
||||
if model:
|
||||
model.pricacy_setting = {**model.pricacy_setting, **data.model_dump()}
|
||||
model.save(session)
|
||||
else:
|
||||
model = UserPrivacy(user_id=user_id, pricacy_setting={**default_settings, **data.model_dump()})
|
||||
model.save(session)
|
||||
|
||||
return model.pricacy_setting
|
||||
|
||||
|
||||
@router.get("/user/current_credits", name="get user current credits")
|
||||
def get_user_credits(auth: Auth = Depends(auth_must), session: Session = Depends(session)):
|
||||
user = auth.user
|
||||
user.refresh_credits_on_active(session)
|
||||
credits = user.credits
|
||||
daily_credits: UserCreditsRecord | None = UserCreditsRecord.get_daily_balance(user.id)
|
||||
current_daily_credits = 0
|
||||
if daily_credits:
|
||||
current_daily_credits = daily_credits.amount - daily_credits.balance
|
||||
credits += current_daily_credits if current_daily_credits > 0 else 0
|
||||
return {"credits": credits, "daily_credits": current_daily_credits}
|
||||
|
||||
|
||||
@router.get("/user/stat", name="get user stat", response_model=UserStatOut)
|
||||
def get_user_stat(auth: Auth = Depends(auth_must), session: Session = Depends(session)):
|
||||
"""Get current user's operation statistics."""
|
||||
stat = session.exec(select(UserStat).where(UserStat.user_id == auth.user.id)).first()
|
||||
data = UserStatOut()
|
||||
if stat:
|
||||
data = UserStatOut(**stat.model_dump())
|
||||
else:
|
||||
data = UserStatOut(user_id=auth.user.id)
|
||||
data.task_queries = ChatHistory.count(ChatHistory.user_id == auth.user.id, s=session)
|
||||
mcp = McpUser.count(McpUser.user_id == auth.user.id, s=session)
|
||||
tool: list = session.exec(
|
||||
select(func.count("*")).where(Config.user_id == auth.user.id).group_by(Config.config_group)
|
||||
).all()
|
||||
tool = tool.__len__()
|
||||
data.mcp_install_count = mcp + tool
|
||||
data.storage_used = ChatSnapshot.caclDir(ChatSnapshot.get_user_dir(auth.user.id))
|
||||
return data
|
||||
|
||||
|
||||
@router.post("/user/stat", name="record user stat")
|
||||
def record_user_stat(
|
||||
data: UserStatActionIn,
|
||||
auth: Auth = Depends(auth_must),
|
||||
session: Session = Depends(session),
|
||||
):
|
||||
"""Record or update current user's operation statistics."""
|
||||
data.user_id = auth.user.id
|
||||
stat = UserStat.record_action(session, data)
|
||||
return stat
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy import func
|
||||
from sqlmodel import Session, select
|
||||
from app.component.auth import Auth, auth_must
|
||||
from app.component.database import session
|
||||
from app.model.user.privacy import UserPrivacy, UserPrivacySettings
|
||||
from app.model.user.user import User, UserIn, UserOut, UserProfile
|
||||
from app.model.user.user_stat import UserStat, UserStatActionIn, UserStatOut
|
||||
from app.model.chat.chat_history import ChatHistory
|
||||
from app.model.mcp.mcp_user import McpUser
|
||||
from app.model.config.config import Config
|
||||
from app.model.chat.chat_snpshot import ChatSnapshot
|
||||
from app.model.user.user_credits_record import UserCreditsRecord
|
||||
from utils import traceroot_wrapper as traceroot
|
||||
|
||||
logger = traceroot.get_logger("server_user_controller")
|
||||
|
||||
router = APIRouter(tags=["User"])
|
||||
|
||||
|
||||
@router.get("/user", name="user info", response_model=UserOut)
|
||||
@traceroot.trace()
|
||||
def get(auth: Auth = Depends(auth_must), session: Session = Depends(session)):
|
||||
"""Get current user information and refresh credits."""
|
||||
user: User = auth.user
|
||||
user.refresh_credits_on_active(session)
|
||||
logger.debug("User info retrieved", extra={"user_id": user.id})
|
||||
return user
|
||||
|
||||
|
||||
@router.put("/user", name="update user info", response_model=UserOut)
|
||||
@traceroot.trace()
|
||||
def put(data: UserIn, session: Session = Depends(session), auth: Auth = Depends(auth_must)):
|
||||
"""Update user basic information."""
|
||||
model = auth.user
|
||||
model.username = data.username
|
||||
model.save(session)
|
||||
logger.info("User info updated", extra={"user_id": model.id, "username": data.username})
|
||||
return model
|
||||
|
||||
|
||||
@router.put("/user/profile", name="update user profile", response_model=UserProfile)
|
||||
@traceroot.trace()
|
||||
def put_profile(data: UserProfile, session: Session = Depends(session), auth: Auth = Depends(auth_must)):
|
||||
"""Update user profile details."""
|
||||
model = auth.user
|
||||
model.nickname = data.nickname
|
||||
model.fullname = data.fullname
|
||||
model.work_desc = data.work_desc
|
||||
model.save(session)
|
||||
logger.info("User profile updated", extra={"user_id": model.id, "nickname": data.nickname})
|
||||
return model
|
||||
|
||||
|
||||
@router.get("/user/privacy", name="get user privacy")
|
||||
@traceroot.trace()
|
||||
def get_privacy(session: Session = Depends(session), auth: Auth = Depends(auth_must)):
|
||||
"""Get user privacy settings."""
|
||||
user_id = auth.user.id
|
||||
stmt = select(UserPrivacy).where(UserPrivacy.user_id == user_id)
|
||||
model = session.exec(stmt).one_or_none()
|
||||
|
||||
if not model:
|
||||
logger.debug("Privacy settings not found, returning defaults", extra={"user_id": user_id})
|
||||
return UserPrivacySettings.default_settings()
|
||||
|
||||
logger.debug("Privacy settings retrieved", extra={"user_id": user_id})
|
||||
return model.pricacy_setting
|
||||
|
||||
|
||||
@router.put("/user/privacy", name="update user privacy")
|
||||
@traceroot.trace()
|
||||
def put_privacy(data: UserPrivacySettings, session: Session = Depends(session), auth: Auth = Depends(auth_must)):
|
||||
"""Update user privacy settings."""
|
||||
user_id = auth.user.id
|
||||
stmt = select(UserPrivacy).where(UserPrivacy.user_id == user_id)
|
||||
model = session.exec(stmt).one_or_none()
|
||||
default_settings = UserPrivacySettings.default_settings()
|
||||
|
||||
if model:
|
||||
model.pricacy_setting = {**model.pricacy_setting, **data.model_dump()}
|
||||
model.save(session)
|
||||
logger.info("Privacy settings updated", extra={"user_id": user_id})
|
||||
else:
|
||||
model = UserPrivacy(user_id=user_id, pricacy_setting={**default_settings, **data.model_dump()})
|
||||
model.save(session)
|
||||
logger.info("Privacy settings created", extra={"user_id": user_id})
|
||||
|
||||
return model.pricacy_setting
|
||||
|
||||
|
||||
@router.get("/user/current_credits", name="get user current credits")
|
||||
@traceroot.trace()
|
||||
def get_user_credits(auth: Auth = Depends(auth_must), session: Session = Depends(session)):
|
||||
"""Get user's current credit balance."""
|
||||
user = auth.user
|
||||
user.refresh_credits_on_active(session)
|
||||
credits = user.credits
|
||||
daily_credits: UserCreditsRecord | None = UserCreditsRecord.get_daily_balance(user.id)
|
||||
current_daily_credits = 0
|
||||
if daily_credits:
|
||||
current_daily_credits = daily_credits.amount - daily_credits.balance
|
||||
credits += current_daily_credits if current_daily_credits > 0 else 0
|
||||
|
||||
logger.debug("Credits retrieved", extra={"user_id": user.id, "total_credits": credits, "daily_credits": current_daily_credits})
|
||||
return {"credits": credits, "daily_credits": current_daily_credits}
|
||||
|
||||
|
||||
@router.get("/user/stat", name="get user stat", response_model=UserStatOut)
|
||||
@traceroot.trace()
|
||||
def get_user_stat(auth: Auth = Depends(auth_must), session: Session = Depends(session)):
|
||||
"""Get current user's operation statistics."""
|
||||
user_id = auth.user.id
|
||||
stat = session.exec(select(UserStat).where(UserStat.user_id == user_id)).first()
|
||||
data = UserStatOut()
|
||||
|
||||
if stat:
|
||||
data = UserStatOut(**stat.model_dump())
|
||||
else:
|
||||
data = UserStatOut(user_id=user_id)
|
||||
|
||||
data.task_queries = ChatHistory.count(ChatHistory.user_id == user_id, s=session)
|
||||
mcp = McpUser.count(McpUser.user_id == user_id, s=session)
|
||||
tool: list = session.exec(
|
||||
select(func.count("*")).where(Config.user_id == user_id).group_by(Config.config_group)
|
||||
).all()
|
||||
tool = tool.__len__()
|
||||
data.mcp_install_count = mcp + tool
|
||||
data.storage_used = ChatSnapshot.caclDir(ChatSnapshot.get_user_dir(user_id))
|
||||
|
||||
logger.debug("User stats retrieved", extra={
|
||||
"user_id": user_id,
|
||||
"task_queries": data.task_queries,
|
||||
"mcp_install_count": data.mcp_install_count,
|
||||
"storage_used": data.storage_used
|
||||
})
|
||||
return data
|
||||
|
||||
|
||||
@router.post("/user/stat", name="record user stat")
|
||||
@traceroot.trace()
|
||||
def record_user_stat(
|
||||
data: UserStatActionIn,
|
||||
auth: Auth = Depends(auth_must),
|
||||
session: Session = Depends(session),
|
||||
):
|
||||
"""Record or update current user's operation statistics."""
|
||||
data.user_id = auth.user.id
|
||||
stat = UserStat.record_action(session, data)
|
||||
logger.info("User stat recorded", extra={"user_id": data.user_id, "action": data.action if hasattr(data, 'action') else "unknown"})
|
||||
return stat
|
||||
|
|
@ -1,24 +1,36 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
from sqlmodel import Session
|
||||
|
||||
from app.component import code
|
||||
from app.component.auth import Auth, auth_must
|
||||
from app.component.database import session
|
||||
from app.component.encrypt import password_hash, password_verify
|
||||
from app.exception.exception import UserException
|
||||
from app.model.user.user import UpdatePassword, UserOut
|
||||
from fastapi_babel import _
|
||||
|
||||
router = APIRouter(tags=["User"])
|
||||
|
||||
|
||||
@router.put("/user/update-password", name="update password", response_model=UserOut)
|
||||
def update_password(data: UpdatePassword, auth: Auth = Depends(auth_must), session: Session = Depends(session)):
|
||||
model = auth.user
|
||||
if not password_verify(data.password, model.password):
|
||||
raise UserException(code.error, _("Password is incorrect"))
|
||||
if data.new_password != data.re_new_password:
|
||||
raise UserException(code.error, _("The two passwords do not match"))
|
||||
model.password = password_hash(data.new_password)
|
||||
model.save(session)
|
||||
return model
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlmodel import Session
|
||||
|
||||
from app.component import code
|
||||
from app.component.auth import Auth, auth_must
|
||||
from app.component.database import session
|
||||
from app.component.encrypt import password_hash, password_verify
|
||||
from app.exception.exception import UserException
|
||||
from app.model.user.user import UpdatePassword, UserOut
|
||||
from fastapi_babel import _
|
||||
from utils import traceroot_wrapper as traceroot
|
||||
|
||||
logger = traceroot.get_logger("server_password_controller")
|
||||
|
||||
router = APIRouter(tags=["User"])
|
||||
|
||||
|
||||
@router.put("/user/update-password", name="update password", response_model=UserOut)
|
||||
@traceroot.trace()
|
||||
def update_password(data: UpdatePassword, auth: Auth = Depends(auth_must), session: Session = Depends(session)):
|
||||
"""Update user password after verifying current password."""
|
||||
user_id = auth.user.id
|
||||
model = auth.user
|
||||
|
||||
if not password_verify(data.password, model.password):
|
||||
logger.warning("Password update failed: incorrect current password", extra={"user_id": user_id})
|
||||
raise UserException(code.error, _("Password is incorrect"))
|
||||
|
||||
if data.new_password != data.re_new_password:
|
||||
logger.warning("Password update failed: new passwords do not match", extra={"user_id": user_id})
|
||||
raise UserException(code.error, _("The two passwords do not match"))
|
||||
|
||||
model.password = password_hash(data.new_password)
|
||||
model.save(session)
|
||||
logger.info("Password updated successfully", extra={"user_id": user_id})
|
||||
return model
|
||||
Loading…
Add table
Add a link
Reference in a new issue