chore: initialize GSREA website project
This commit is contained in:
commit
d3c5461de5
1842 files changed
+246140
No files matched your search
@@ -0,0 +1,232 @@
|
||||
from fastapi import APIRouter, Depends, Query, Request
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.deps import require_staff
|
||||
from app.db import get_db
|
||||
from app.services import rbac as rbac_service
|
||||
|
||||
public_router = APIRouter()
|
||||
router = APIRouter(dependencies=[Depends(require_staff)])
|
||||
|
||||
|
||||
class LoginIn(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
captchaId: str = ""
|
||||
captchaCode: str = ""
|
||||
|
||||
|
||||
class OwnPasswordIn(BaseModel):
|
||||
oldPassword: str
|
||||
newPassword: str
|
||||
|
||||
|
||||
class UserCreateIn(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
displayName: str
|
||||
mobile: str | None = None
|
||||
roleIds: list[int] = []
|
||||
|
||||
|
||||
class UserUpdateIn(BaseModel):
|
||||
displayName: str
|
||||
mobile: str | None = None
|
||||
status: str
|
||||
roleIds: list[int] = []
|
||||
|
||||
|
||||
class ResetPasswordIn(BaseModel):
|
||||
password: str | None = None
|
||||
newPassword: str | None = None
|
||||
|
||||
|
||||
class RoleCreateIn(BaseModel):
|
||||
code: str
|
||||
name: str
|
||||
description: str | None = None
|
||||
|
||||
|
||||
class RoleUpdateIn(BaseModel):
|
||||
name: str
|
||||
description: str | None = None
|
||||
status: str
|
||||
|
||||
|
||||
class RoleResourcesIn(BaseModel):
|
||||
resourceIds: list[int] = []
|
||||
|
||||
|
||||
class ResourceIn(BaseModel):
|
||||
parentId: int | None = None
|
||||
type: str
|
||||
name: str
|
||||
title: str
|
||||
path: str | None = ""
|
||||
component: str | None = ""
|
||||
icon: str | None = ""
|
||||
permission: str | None = ""
|
||||
sort: int = 0
|
||||
visible: bool = True
|
||||
status: str = "active"
|
||||
|
||||
|
||||
def _actor_id(principal: dict = Depends(require_staff)) -> int:
|
||||
try:
|
||||
return int(principal["sub"])
|
||||
except (TypeError, ValueError):
|
||||
from fastapi import HTTPException
|
||||
|
||||
raise HTTPException(status_code=401, detail="登录已失效")
|
||||
|
||||
|
||||
def _resource_payload(body: ResourceIn) -> dict:
|
||||
return {
|
||||
"parent_id": body.parentId,
|
||||
"type": body.type,
|
||||
"name": body.name,
|
||||
"title": body.title,
|
||||
"path": body.path,
|
||||
"component": body.component,
|
||||
"icon": body.icon,
|
||||
"permission": body.permission,
|
||||
"sort": body.sort,
|
||||
"visible": body.visible,
|
||||
"status": body.status,
|
||||
}
|
||||
|
||||
|
||||
@public_router.post("/auth/login")
|
||||
def login(body: LoginIn, request: Request, db: Session = Depends(get_db)) -> dict:
|
||||
request.state.audit_username = (body.username or "").strip()[:64]
|
||||
return rbac_service.authenticate(db, body.username, body.password, body.captchaId, body.captchaCode)
|
||||
|
||||
|
||||
@router.post("/auth/password")
|
||||
def change_password(
|
||||
body: OwnPasswordIn,
|
||||
actor_id: int = Depends(_actor_id),
|
||||
db: Session = Depends(get_db),
|
||||
) -> dict:
|
||||
return rbac_service.change_own_password(db, actor_id, body.oldPassword, body.newPassword)
|
||||
|
||||
|
||||
@router.get("/users")
|
||||
def list_users(
|
||||
current: int = Query(1, ge=1),
|
||||
size: int = Query(10, ge=1, le=200),
|
||||
username: str | None = None,
|
||||
displayName: str | None = None,
|
||||
status: str | None = None,
|
||||
db: Session = Depends(get_db),
|
||||
) -> dict:
|
||||
return rbac_service.query_users(
|
||||
db,
|
||||
current=current,
|
||||
size=size,
|
||||
username=username,
|
||||
display_name=displayName,
|
||||
status_value=status,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/users")
|
||||
def create_user(body: UserCreateIn, db: Session = Depends(get_db)) -> dict:
|
||||
return rbac_service.create_user(
|
||||
db,
|
||||
username=body.username,
|
||||
password=body.password,
|
||||
display_name=body.displayName,
|
||||
mobile=body.mobile,
|
||||
role_ids=body.roleIds,
|
||||
)
|
||||
|
||||
|
||||
@router.put("/users/{user_id}")
|
||||
def update_user(
|
||||
user_id: int,
|
||||
body: UserUpdateIn,
|
||||
actor_id: int = Depends(_actor_id),
|
||||
db: Session = Depends(get_db),
|
||||
) -> dict:
|
||||
return rbac_service.update_user(
|
||||
db,
|
||||
user_id,
|
||||
actor_id,
|
||||
display_name=body.displayName,
|
||||
status_value=body.status,
|
||||
role_ids=body.roleIds,
|
||||
mobile=body.mobile,
|
||||
mobile_provided="mobile" in body.model_fields_set,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/users/{user_id}/password")
|
||||
def reset_password(user_id: int, body: ResetPasswordIn, db: Session = Depends(get_db)) -> dict:
|
||||
plain = body.password if body.password is not None else body.newPassword
|
||||
if plain is None:
|
||||
from fastapi import HTTPException
|
||||
|
||||
raise HTTPException(status_code=400, detail="请填写密码")
|
||||
return rbac_service.reset_user_password(db, user_id, plain)
|
||||
|
||||
|
||||
@router.get("/roles")
|
||||
def list_roles(
|
||||
current: int = Query(1, ge=1),
|
||||
size: int = Query(10, ge=1, le=200),
|
||||
name: str | None = None,
|
||||
code: str | None = None,
|
||||
status: str | None = None,
|
||||
db: Session = Depends(get_db),
|
||||
) -> dict:
|
||||
return rbac_service.query_roles(
|
||||
db,
|
||||
current=current,
|
||||
size=size,
|
||||
name=name,
|
||||
code=code,
|
||||
status_value=status,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/roles")
|
||||
def create_role(body: RoleCreateIn, db: Session = Depends(get_db)) -> dict:
|
||||
return rbac_service.create_role(db, code=body.code, name=body.name, description=body.description)
|
||||
|
||||
|
||||
@router.put("/roles/{role_id}")
|
||||
def update_role(role_id: int, body: RoleUpdateIn, db: Session = Depends(get_db)) -> dict:
|
||||
return rbac_service.update_role(
|
||||
db,
|
||||
role_id,
|
||||
name=body.name,
|
||||
description=body.description,
|
||||
status_value=body.status,
|
||||
)
|
||||
|
||||
|
||||
@router.put("/roles/{role_id}/resources")
|
||||
def replace_role_resources(role_id: int, body: RoleResourcesIn, db: Session = Depends(get_db)) -> dict:
|
||||
return rbac_service.replace_role_resources(db, role_id, body.resourceIds)
|
||||
|
||||
|
||||
@router.get("/resources")
|
||||
def list_resources(db: Session = Depends(get_db)) -> list[dict]:
|
||||
return rbac_service.list_resources(db)
|
||||
|
||||
|
||||
@router.post("/resources")
|
||||
def create_resource(body: ResourceIn, db: Session = Depends(get_db)) -> dict:
|
||||
return rbac_service.create_resource(db, _resource_payload(body))
|
||||
|
||||
|
||||
@router.put("/resources/{resource_id}")
|
||||
def update_resource(resource_id: int, body: ResourceIn, db: Session = Depends(get_db)) -> dict:
|
||||
return rbac_service.update_resource(db, resource_id, _resource_payload(body))
|
||||
|
||||
|
||||
@router.delete("/resources/{resource_id}")
|
||||
def delete_resource(resource_id: int, db: Session = Depends(get_db)) -> dict:
|
||||
return rbac_service.delete_resource(db, resource_id)
|
||||
Reference in new issue
Block a user