78 lines
2.5 KiB
Python
78 lines
2.5 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.db.session import get_db
|
|
from app.models.org import User
|
|
from app.schemas.database import (
|
|
AuthChangePasswordRequest,
|
|
AuthLoginKeyResponse,
|
|
AuthLoginRequest,
|
|
AuthResetPasswordRequest,
|
|
AuthSession,
|
|
LoginUser,
|
|
)
|
|
from app.services.auth import (
|
|
build_login_user,
|
|
get_current_auth_context,
|
|
hash_password,
|
|
login_with_password,
|
|
require_system_admin,
|
|
verify_password,
|
|
)
|
|
from app.services.login_crypto import decrypt_login_password, get_login_public_key
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/login-key", response_model=AuthLoginKeyResponse)
|
|
def login_key() -> AuthLoginKeyResponse:
|
|
return AuthLoginKeyResponse(**get_login_public_key().__dict__)
|
|
|
|
|
|
@router.post("/login", response_model=AuthSession)
|
|
def login(payload: AuthLoginRequest, db: Session = Depends(get_db)) -> AuthSession:
|
|
password = decrypt_login_password(payload.password_ciphertext, payload.login_key_id)
|
|
return login_with_password(db, payload.username, password)
|
|
|
|
|
|
@router.get("/me", response_model=LoginUser)
|
|
def profile(context=Depends(get_current_auth_context)) -> LoginUser:
|
|
return build_login_user(context)
|
|
|
|
|
|
@router.post("/password/change")
|
|
def change_password(
|
|
payload: AuthChangePasswordRequest,
|
|
context=Depends(get_current_auth_context),
|
|
db: Session = Depends(get_db),
|
|
) -> dict[str, str]:
|
|
user = db.get(User, context.user.id)
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="当前用户不存在")
|
|
if not verify_password(payload.old_password, user.password_hash):
|
|
raise HTTPException(status_code=400, detail="原密码不正确")
|
|
if verify_password(payload.new_password, user.password_hash):
|
|
raise HTTPException(status_code=400, detail="新密码不能与原密码相同")
|
|
|
|
user.password_hash = hash_password(payload.new_password)
|
|
db.add(user)
|
|
db.commit()
|
|
return {"message": "密码已修改"}
|
|
|
|
|
|
@router.post("/password/reset")
|
|
def reset_password(
|
|
payload: AuthResetPasswordRequest,
|
|
context=Depends(require_system_admin),
|
|
db: Session = Depends(get_db),
|
|
) -> dict[str, str]:
|
|
user = db.scalar(select(User).where(User.username == payload.username))
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="账号不存在")
|
|
|
|
user.password_hash = hash_password(payload.new_password)
|
|
db.add(user)
|
|
db.commit()
|
|
return {"message": f"账号 {payload.username} 密码已重置"}
|