perf: Token

This commit is contained in:
fit2cloud-chenyw
2025-07-17 09:19:41 +08:00
parent 98a6bbb92a
commit e9a893a330
6 changed files with 28 additions and 15 deletions
+5 -1
View File
@@ -1,6 +1,7 @@
from typing import Annotated
from fastapi import APIRouter, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from apps.system.schemas.system_schema import BaseUserDTO
from common.core.deps import SessionDep
from ..crud.user import authenticate
from common.core.security import create_access_token
@@ -14,9 +15,12 @@ def local_login(
session: SessionDep,
form_data: Annotated[OAuth2PasswordRequestForm, Depends()]
) -> Token:
user = authenticate(session=session, account=form_data.username, password=form_data.password)
user: BaseUserDTO = authenticate(session=session, account=form_data.username, password=form_data.password)
if not user:
raise HTTPException(status_code=400, detail="Incorrect account or password")
if not user.oid or user.oid == 0:
raise HTTPException(status_code=400, detail="No associated workspace, Please contact the administrator")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
user_dict = user.to_dict()
return Token(access_token=create_access_token(
+11 -8
View File
@@ -1,5 +1,5 @@
from typing import Optional
from fastapi import APIRouter, Query
from fastapi import APIRouter, HTTPException, Query
from sqlmodel import func, or_, select, delete as sqlmodel_delete
from apps.system.crud.user import get_db_user, single_delete, user_ws_options
from apps.system.models.system_model import UserWsModel
@@ -99,7 +99,7 @@ async def ws_options(session: SessionDep, current_user: CurrentUser, trans: Tran
async def ws_change(session: SessionDep, current_user: CurrentUser, oid: int):
ws_list: list[UserWs] = await user_ws_options(session, current_user.id)
if not any(x.id == oid for x in ws_list):
raise RuntimeError(f"oid [{oid}] is invalid!")
raise HTTPException(f"oid [{oid}] is invalid!")
user_model: UserModel = get_db_user(session = session, user_id = current_user.id)
user_model.oid = oid
session.add(user_model)
@@ -120,7 +120,7 @@ async def create(session: SessionDep, creator: UserCreator):
user_model = UserModel.model_validate(data)
#user_model.create_time = get_timestamp()
user_model.language = "zh-CN"
session.add(user_model)
user_model.oid = 0
if creator.oid_list:
# need to validate oid_list
db_model_list = [
@@ -132,20 +132,22 @@ async def create(session: SessionDep, creator: UserCreator):
for oid in creator.oid_list
]
session.add_all(db_model_list)
user_model.oid = creator.oid_list[0]
session.add(user_model)
session.commit()
@router.put("")
@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="editor.id")
async def update(session: SessionDep, editor: UserEditor):
user_model: UserModel = get_db_user(session = session, user_id = editor.id)
origin_oid: int = user_model.oid
del_stmt = sqlmodel_delete(UserWsModel).where(UserWsModel.uid == editor.id)
session.exec(del_stmt)
data = editor.model_dump(exclude_unset=True)
user_model.sqlmodel_update(data)
session.add(user_model)
user_model.oid = 0
if editor.oid_list:
# need to validate oid_list
db_model_list = [
@@ -157,7 +159,8 @@ async def update(session: SessionDep, editor: UserEditor):
for oid in editor.oid_list
]
session.add_all(db_model_list)
user_model.oid = origin_oid if origin_oid in editor.oid_list else editor.oid_list[0]
session.add(user_model)
session.commit()
@router.delete("/{id}")
@@ -184,7 +187,7 @@ async def langChange(session: SessionDep, current_user: CurrentUser, language: U
@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id")
async def pwdReset(session: SessionDep, current_user: CurrentUser, id: int):
if not current_user.isAdmin:
raise RuntimeError('only for admin')
raise HTTPException('only for admin')
db_user: UserModel = get_db_user(session=session, user_id=id)
db_user.password = default_md5_pwd()
session.add(db_user)
@@ -195,7 +198,7 @@ async def pwdReset(session: SessionDep, current_user: CurrentUser, id: int):
async def pwdUpdate(session: SessionDep, current_user: CurrentUser, editor: PwdEditor):
db_user: UserModel = get_db_user(session=session, user_id=current_user.id)
if not verify_md5pwd(editor.pwd, db_user.password):
raise RuntimeError("pwd error")
raise HTTPException("pwd error")
db_user.password = md5pwd(editor.new_pwd)
session.add(db_user)
session.commit()
+9 -3
View File
@@ -1,6 +1,6 @@
from typing import Optional
from fastapi import Request
from fastapi import HTTPException, Request
from fastapi.responses import JSONResponse
import jwt
from sqlmodel import Session
@@ -35,7 +35,7 @@ class TokenMiddleware(BaseHTTPMiddleware):
request.state.current_user = validator[1]
request.state.assistant = validator[2]
return await call_next(request)
return JSONResponse({"error": f"Unauthorized:[{validator[1]}]"}, status_code=401)
return JSONResponse({"msg": f"Unauthorized:[{validator[1]}]"}, status_code=401)
#validate pass
tokenkey = settings.TOKEN_KEY
token = request.headers.get(tokenkey)
@@ -43,7 +43,7 @@ class TokenMiddleware(BaseHTTPMiddleware):
if validate_pass:
request.state.current_user = data
return await call_next(request)
return JSONResponse({"error": f"Unauthorized:[{data}]"}, status_code=401)
return JSONResponse({"msg": f"Unauthorized:[{data}]"}, status_code=401)
def is_options(self, request: Request):
return request.method == "OPTIONS"
@@ -62,6 +62,12 @@ class TokenMiddleware(BaseHTTPMiddleware):
with Session(engine) as session:
session_user = await get_user_info(session = session, user_id = token_data.id)
session_user = UserInfoDTO.model_validate(session_user)
session_user = UserInfoDTO.model_validate(session_user)
if token_data.oid != session_user.oid:
raise HTTPException(
status_code=401,
detail="Default space has been changed, please login again!"
)
return True, session_user
except Exception as e:
return False, e
+1 -1
View File
@@ -10,7 +10,7 @@ from common.utils.time import get_timestamp
class BaseUserPO(SQLModel):
account: str = Field(max_length=255, unique=True)
oid: int = Field(nullable=False, sa_type=BigInteger())
oid: int = Field(nullable=False, sa_type=BigInteger(), default=0)
name: str = Field(max_length=255, unique=True)
password: str = Field(default_factory=default_md5_pwd, max_length=255)
email: str = Field(max_length=255)
+1 -1
View File
@@ -121,7 +121,7 @@ const router = createRouter({
{
path: '/system',
component: LayoutDsl,
redirect: '/system/model',
redirect: '/system/user',
children: [
{
path: 'user',
+1 -1
View File
@@ -352,7 +352,7 @@ const state = reactive<any>({
id: '',
name: '',
account: '',
oid: 1,
oid: 0,
email: '',
status: '',
phoneNumber: '',