Prepare ERP source for Gitea deployment
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.db.deps import get_common_db
|
||||
from app.core.security.session_auth import require_login
|
||||
from app.modules.core.audit.service import write_audit_log
|
||||
from app.modules.core.iam.models import User
|
||||
from app.modules.core.iam.scope import build_scope, scope_to_http, assert_can_manage_role_object
|
||||
from app.modules.core.rbac.models import Permission, Role, RolePermission
|
||||
|
||||
router = APIRouter(prefix="/rbac", tags=["rbac"])
|
||||
|
||||
|
||||
class RoleCreateRequest(BaseModel):
|
||||
name: str
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class PermissionCreateRequest(BaseModel):
|
||||
code: str
|
||||
name: str
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class RolePermissionUpdateRequest(BaseModel):
|
||||
permission_ids: list[int] = []
|
||||
|
||||
|
||||
def _require_system_admin_scope(db: Session, current_user: User):
|
||||
scope = build_scope(db, current_user)
|
||||
if not scope.is_system_admin:
|
||||
raise HTTPException(status_code=403, detail="Only System Admin can access RBAC.")
|
||||
return scope
|
||||
|
||||
|
||||
@router.get("/roles")
|
||||
def list_roles(
|
||||
current_user: User = Depends(require_login),
|
||||
db: Session = Depends(get_common_db),
|
||||
):
|
||||
_require_system_admin_scope(db, current_user)
|
||||
roles = db.execute(select(Role).order_by(Role.name)).scalars().all()
|
||||
return [{"id": r.id, "name": r.name, "is_active": r.is_active} for r in roles]
|
||||
|
||||
|
||||
@router.post("/roles")
|
||||
def create_role(
|
||||
payload: RoleCreateRequest,
|
||||
current_user: User = Depends(require_login),
|
||||
db: Session = Depends(get_common_db),
|
||||
):
|
||||
_require_system_admin_scope(db, current_user)
|
||||
|
||||
name = payload.name.strip()
|
||||
if not name:
|
||||
raise HTTPException(status_code=400, detail="Role name is required")
|
||||
|
||||
exists = db.execute(select(Role).where(Role.name == name)).scalar_one_or_none()
|
||||
if exists:
|
||||
raise HTTPException(status_code=400, detail="Role already exists")
|
||||
|
||||
role = Role(name=name, is_active=payload.is_active)
|
||||
db.add(role)
|
||||
db.commit()
|
||||
db.refresh(role)
|
||||
|
||||
write_audit_log(
|
||||
db,
|
||||
action="role.create.api",
|
||||
entity_type="role",
|
||||
actor=current_user,
|
||||
entity_id=role.id,
|
||||
entity_name=role.name,
|
||||
target_tenant_id=current_user.tenant_id,
|
||||
target_branch_id=current_user.branch_id,
|
||||
details={"name": role.name, "is_active": role.is_active},
|
||||
)
|
||||
return {"status": "ok", "id": role.id}
|
||||
|
||||
|
||||
@router.get("/permissions")
|
||||
def list_permissions(
|
||||
current_user: User = Depends(require_login),
|
||||
db: Session = Depends(get_common_db),
|
||||
):
|
||||
_require_system_admin_scope(db, current_user)
|
||||
permissions = db.execute(select(Permission).order_by(Permission.code)).scalars().all()
|
||||
return [{"id": p.id, "code": p.code, "name": p.name, "is_active": p.is_active} for p in permissions]
|
||||
|
||||
|
||||
@router.post("/permissions")
|
||||
def create_permission(
|
||||
payload: PermissionCreateRequest,
|
||||
current_user: User = Depends(require_login),
|
||||
db: Session = Depends(get_common_db),
|
||||
):
|
||||
_require_system_admin_scope(db, current_user)
|
||||
|
||||
code = payload.code.strip()
|
||||
if not code:
|
||||
raise HTTPException(status_code=400, detail="Permission code is required")
|
||||
|
||||
exists = db.execute(select(Permission).where(Permission.code == code)).scalar_one_or_none()
|
||||
if exists:
|
||||
raise HTTPException(status_code=400, detail="Permission already exists")
|
||||
|
||||
permission = Permission(code=code, name=payload.name.strip(), is_active=payload.is_active)
|
||||
db.add(permission)
|
||||
db.commit()
|
||||
db.refresh(permission)
|
||||
|
||||
write_audit_log(
|
||||
db,
|
||||
action="permission.create.api",
|
||||
entity_type="permission",
|
||||
actor=current_user,
|
||||
entity_id=permission.id,
|
||||
entity_name=permission.code,
|
||||
target_tenant_id=current_user.tenant_id,
|
||||
target_branch_id=current_user.branch_id,
|
||||
details={"code": permission.code, "name": permission.name, "is_active": permission.is_active},
|
||||
)
|
||||
return {"status": "ok", "id": permission.id}
|
||||
|
||||
|
||||
@router.get("/roles/{role_id}")
|
||||
def role_detail(
|
||||
role_id: int,
|
||||
current_user: User = Depends(require_login),
|
||||
db: Session = Depends(get_common_db),
|
||||
):
|
||||
scope = _require_system_admin_scope(db, current_user)
|
||||
|
||||
role = db.execute(select(Role).where(Role.id == role_id)).scalar_one_or_none()
|
||||
if not role:
|
||||
raise HTTPException(status_code=404, detail="Role not found")
|
||||
|
||||
try:
|
||||
assert_can_manage_role_object(scope, role)
|
||||
except Exception as exc:
|
||||
raise scope_to_http(exc)
|
||||
|
||||
permission_ids = db.execute(
|
||||
select(RolePermission.permission_id).where(RolePermission.role_id == role.id)
|
||||
).scalars().all()
|
||||
|
||||
return {
|
||||
"id": role.id,
|
||||
"name": role.name,
|
||||
"is_active": role.is_active,
|
||||
"permission_ids": list(permission_ids),
|
||||
}
|
||||
|
||||
|
||||
@router.put("/roles/{role_id}/permissions")
|
||||
def update_role_permissions(
|
||||
role_id: int,
|
||||
payload: RolePermissionUpdateRequest,
|
||||
current_user: User = Depends(require_login),
|
||||
db: Session = Depends(get_common_db),
|
||||
):
|
||||
_require_system_admin_scope(db, current_user)
|
||||
|
||||
role = db.execute(select(Role).where(Role.id == role_id)).scalar_one_or_none()
|
||||
if not role:
|
||||
raise HTTPException(status_code=404, detail="Role not found")
|
||||
|
||||
old_permission_ids = db.execute(
|
||||
select(RolePermission.permission_id).where(RolePermission.role_id == role.id)
|
||||
).scalars().all()
|
||||
|
||||
db.execute(RolePermission.__table__.delete().where(RolePermission.role_id == role.id))
|
||||
for permission_id in payload.permission_ids:
|
||||
db.add(RolePermission(role_id=role.id, permission_id=permission_id))
|
||||
db.commit()
|
||||
|
||||
write_audit_log(
|
||||
db,
|
||||
action="role.permissions.update.api",
|
||||
entity_type="role",
|
||||
actor=current_user,
|
||||
entity_id=role.id,
|
||||
entity_name=role.name,
|
||||
target_tenant_id=current_user.tenant_id,
|
||||
target_branch_id=current_user.branch_id,
|
||||
details={
|
||||
"old_permission_ids": list(old_permission_ids),
|
||||
"new_permission_ids": list(payload.permission_ids),
|
||||
},
|
||||
)
|
||||
return {"status": "ok"}
|
||||
Reference in New Issue
Block a user