PayrollManagementSystem/backend/app/services/authorization_policy.py

97 lines
5.5 KiB
Python
Raw Normal View History

"""每个受保护接口必须映射权限;未登记接口默认拒绝。"""
RESOURCE_MODULES = {
"base.personnel": "base:personnel", "base.products": "base:products",
"base.customers": "base:customers", "business.businesses": "business:businesses",
"business.shipments": "business:shipments", "business.receipts": "business:receipts",
"business.ratings": "business:ratings", "system.users": "system:users",
"system.roles": "system:roles", "system.business_roles": "system:business_roles",
"system.logs": "system:logs", "system.settings": "system:settings",
"system.monitor": "system:monitor",
}
REPORT_MODULES = {
"personal-detail": "reports:personal", "department-summary": "reports:department",
"business-stats": "reports:business", "payment-stats": "reports:payments",
}
PUBLIC_ENDPOINTS = {("auth", "get_captcha"), ("auth", "login"),
("system.settings", "get_settings_public"), ("system.settings", "get_logo_public")}
LOGIN_ENDPOINTS = {("auth", "me"), ("auth", "logout")}
def permission_for(module, name, method, *, params=None, body=None):
"""返回目录操作码;None 表示没有登记,空串仅用于显式登录态接口。"""
params, body = params or {}, body or {}
if (module, name) in PUBLIC_ENDPOINTS | LOGIN_ENDPOINTS:
return ""
if module == "dashboard":
return "dashboard:view"
if module == "system.authorization":
resource = "system:users" if name in ("user_authorization", "preview", "save_user") else "system:roles"
return resource + (":view" if method == "GET" or name == "preview" else ":update")
if module == "metadata":
return "" # 此端点按请求的参照资源执行独立的关联功能校验。
if module == "base.business_roles":
return "" # 下拉只返回选项;由端点校验人员查看/维护能力。
if module in RESOURCE_MODULES:
resource = RESOURCE_MODULES[module]
if module == "base.products" and name in ("extraction_preview", "extraction_apply", "restore_source"):
return resource + (":create" if name == "extraction_apply" else ":update" if name == "restore_source" else ":view")
if method == "GET":
return resource + ":view"
special = {"set_status": "status", "change_status": "status", "reset_password": "password",
"confirm_receipt": "confirm",
"replace_regions": "regions", "replace_plans": "plans", "rate_customer": "rating",
"change_ownership": "ownership", "batch_ownership": "ownership", "upload_logo": "update"}
action = special.get(name) or {"POST": "create", "PUT": "update", "DELETE": "delete"}.get(method)
return resource + ":" + action if action else None
if module == "system.params":
action = "view" if method == "GET" else {"submit_change": "update", "withdraw_batch": "withdraw", "preview": "preview"}.get(name)
if name == "export_changes":
action = "export"
return "system:params:" + action if action else None
if module == "system.coefficients":
return "system:params:" + ({"save": "update", "export": "export", "import_preview": "preview"}.get(name, "view"))
if module == "system.calc_templates":
return "system:params:" + ("view" if method == "GET" else "update")
if module == "system.monitor":
return "system:monitor:" + ("export" if name == "diagnostic" else "view")
if module == "system.tplus":
return "tplus:" + ("view" if method == "GET" else "retry" if name == "retry" else "collect")
if module == "system.tplus_workbench":
if name == "business_sync_preview":
return "tplus:preview"
if name.startswith("business_sync_"):
return "tplus:view" if method == "GET" else "tplus:import"
if name == "work_report":
return "tplus:export"
if method == "GET":
return "tplus:view"
if name in ("save_fact", "save_correction_pair"):
return "tplus:facts"
if name == "create_work":
return "tplus:import" if body.get("kind") in ("MASTER_APPLY", "BUSINESS_APPLY") else "tplus:preview"
if module in ("payroll", "calc"):
if name == "probation_adjustment":
return "adjustments:create"
if name in ("probation_export", "salary_export"):
return "reports:personal:export"
if method == "GET":
return "payroll:view"
return "adjustments:create" if name == "adjustment" else "payroll:prepare" if name == "save_input" else "payroll:calculate"
if module == "settlements":
if name in ("create_adjustment", "list_adjustments"):
return "adjustments:" + ("view" if method == "GET" else "create")
return "settlements:" + ("view" if method == "GET" else "generate" if name == "generate" else "submit")
if module == "system.approvals":
return "approvals:view" # 节点动作由服务层根据当前节点检查 finance/leader。
if module == "reports":
code = params.get("code") if name == "export_report" else {
"personal_detail": "personal-detail", "department_summary": "department-summary",
"business_stats": "business-stats", "payment_stats": "payment-stats",
"payment_detail": "payment-stats", "payment_day_buckets": "payment-stats",
}.get(name)
resource = REPORT_MODULES.get(code)
return resource + (":export" if name == "export_report" else ":view") if resource else None
return None