529 lines
17 KiB
Plaintext
529 lines
17 KiB
Plaintext
syntax = "v1"
|
||
|
||
type (
|
||
// ===== Permission catalog =====
|
||
|
||
PermissionCatalogQuery {
|
||
Status string `form:"status,optional,options=open|close" validate:"omitempty,oneof=open close"` // 狀態篩選;可選值: open / close
|
||
Type string `form:"type,optional,options=backend_user|frontend_user" validate:"omitempty,oneof=backend_user frontend_user"` // 權限類型篩選;可選值: backend_user / frontend_user
|
||
Tree bool `form:"tree,optional"` // 是否回傳樹狀結構(false 則扁平 list)
|
||
}
|
||
|
||
PermissionNode {
|
||
ID string `json:"id"`
|
||
Parent string `json:"parent,omitempty"`
|
||
Name string `json:"name"`
|
||
HTTPMethods string `json:"http_methods,omitempty"`
|
||
HTTPPath string `json:"http_path,omitempty"`
|
||
Status string `json:"status"`
|
||
Type string `json:"type"`
|
||
Children []PermissionNode `json:"children,omitempty"`
|
||
}
|
||
|
||
PermissionCatalogData {
|
||
Tree []PermissionNode `json:"tree,omitempty"`
|
||
List []PermissionNode `json:"list,omitempty"`
|
||
}
|
||
|
||
// ===== Me permissions =====
|
||
|
||
MePermissionsQuery {
|
||
IncludeTree bool `form:"include_tree,optional"` // 是否同時回傳 permission tree(true 會多包一份樹狀結構)
|
||
}
|
||
|
||
MePermissionsData {
|
||
UID string `json:"uid"`
|
||
TenantID string `json:"tenant_id"`
|
||
Roles []string `json:"roles"`
|
||
Permissions map[string]string `json:"permissions"`
|
||
Tree []PermissionNode `json:"tree,omitempty"`
|
||
}
|
||
|
||
// ===== Roles =====
|
||
|
||
RoleData {
|
||
ID string `json:"id"`
|
||
TenantID string `json:"tenant_id"`
|
||
Key string `json:"key"`
|
||
DisplayName string `json:"display_name"`
|
||
CreatorUID string `json:"creator_uid,omitempty"`
|
||
Status string `json:"status"`
|
||
IsSystem bool `json:"is_system"`
|
||
CreateAt int64 `json:"create_at"`
|
||
UpdateAt int64 `json:"update_at"`
|
||
}
|
||
|
||
RoleListData {
|
||
Roles []RoleData `json:"roles"`
|
||
}
|
||
|
||
CreateRoleReq {
|
||
Key string `json:"key" validate:"required,min=2,max=64"` // 角色 key(2-64 字元,不可以 system. / platform_ 開頭)
|
||
DisplayName string `json:"display_name,optional"` // 角色顯示名稱(給人看的)
|
||
Status string `json:"status,optional,options=open|close" validate:"omitempty,oneof=open close"` // 角色狀態;可選值: open / close(預設 open)
|
||
}
|
||
|
||
UpdateRoleReq {
|
||
DisplayName string `json:"display_name,optional"` // 角色顯示名稱
|
||
Status string `json:"status,optional,options=open|close" validate:"omitempty,oneof=open close"` // 角色狀態;可選值: open / close
|
||
}
|
||
|
||
UpdateRoleByIDReq {
|
||
ID string `path:"id"` // Role ID(path)
|
||
DisplayName string `json:"display_name,optional"` // 角色顯示名稱
|
||
Status string `json:"status,optional,options=open|close" validate:"omitempty,oneof=open close"` // 角色狀態;可選值: open / close
|
||
}
|
||
|
||
DeleteRoleByIDReq {
|
||
ID string `path:"id"` // Role ID(path)
|
||
}
|
||
|
||
GetRolePermissionsByIDReq {
|
||
ID string `path:"id"` // Role ID(path)
|
||
}
|
||
|
||
ReplaceRolePermissionsByIDReq {
|
||
ID string `path:"id"` // Role ID(path)
|
||
PermissionIDs []string `json:"permission_ids"` // 要勾選的 Permission ID 陣列(全量取代,會自動補齊父權限)
|
||
}
|
||
|
||
ListUserRolesReq {
|
||
UID string `path:"uid"` // 使用者 UID(path)
|
||
}
|
||
|
||
AssignUserRoleByUIDReq {
|
||
UID string `path:"uid"` // 使用者 UID(path)
|
||
RoleID string `json:"role_id" validate:"required"` // 要指派的 Role ID
|
||
Source string `json:"source,optional,options=manual|zitadel|ldap|scim" validate:"omitempty,oneof=manual zitadel ldap scim"` // 指派來源;可選值: manual / zitadel / ldap / scim(預設 manual)
|
||
}
|
||
|
||
RevokeUserRoleByIDReq {
|
||
UID string `path:"uid"` // 使用者 UID(path)
|
||
RoleID string `path:"role_id"` // Role ID(path)
|
||
}
|
||
|
||
// ===== Role permissions =====
|
||
|
||
RolePermissionsListData {
|
||
Permissions []PermissionNode `json:"permissions"`
|
||
}
|
||
|
||
ReplaceRolePermissionsReq {
|
||
PermissionIDs []string `json:"permission_ids"` // 要勾選的 Permission ID 陣列(全量取代,會自動補齊父權限)
|
||
}
|
||
|
||
// ===== User roles =====
|
||
|
||
UIDPath {
|
||
UID string `path:"uid"` // 使用者 UID(path)
|
||
}
|
||
|
||
UserRoleData {
|
||
ID string `json:"id"`
|
||
TenantID string `json:"tenant_id"`
|
||
UID string `json:"uid"`
|
||
RoleID string `json:"role_id"`
|
||
RoleKey string `json:"role_key"`
|
||
RoleDisplayName string `json:"role_display_name"`
|
||
Source string `json:"source"`
|
||
CreateAt int64 `json:"create_at"`
|
||
UpdateAt int64 `json:"update_at"`
|
||
}
|
||
|
||
UserRoleListData {
|
||
UserRoles []UserRoleData `json:"user_roles"`
|
||
}
|
||
|
||
AssignUserRoleReq {
|
||
RoleID string `json:"role_id" validate:"required"` // 要指派的 Role ID
|
||
Source string `json:"source,optional,options=manual|zitadel|ldap|scim" validate:"omitempty,oneof=manual zitadel ldap scim"` // 指派來源;可選值: manual / zitadel / ldap / scim(預設 manual)
|
||
}
|
||
|
||
UserRoleIDPath {
|
||
UID string `path:"uid"` // 使用者 UID(path)
|
||
RoleID string `path:"role_id"` // Role ID(path)
|
||
}
|
||
|
||
// ===== Role mappings =====
|
||
|
||
RoleMappingData {
|
||
ID string `json:"id"`
|
||
TenantID string `json:"tenant_id"`
|
||
ExternalSource string `json:"external_source"`
|
||
ExternalKey string `json:"external_key"`
|
||
InternalRoleID string `json:"internal_role_id"`
|
||
InternalRoleKey string `json:"internal_role_key"`
|
||
CreateAt int64 `json:"create_at"`
|
||
UpdateAt int64 `json:"update_at"`
|
||
}
|
||
|
||
RoleMappingListData {
|
||
Mappings []RoleMappingData `json:"mappings"`
|
||
Total int64 `json:"total"`
|
||
Offset int64 `json:"offset"`
|
||
Limit int64 `json:"limit"`
|
||
}
|
||
|
||
RoleMappingListQuery {
|
||
Source string `form:"source,optional,options=zitadel|ldap|scim" validate:"omitempty,oneof=zitadel ldap scim"` // 外部來源篩選;可選值: zitadel / ldap / scim
|
||
Offset int64 `form:"offset,optional"` // 分頁起點(從 0 起算)
|
||
Limit int64 `form:"limit,optional"` // 每頁筆數(最大值由 server 限制)
|
||
}
|
||
|
||
UpsertRoleMappingReq {
|
||
ExternalSource string `json:"external_source,options=zitadel|ldap|scim" validate:"required,oneof=zitadel ldap scim"` // 外部來源;可選值: zitadel / ldap / scim
|
||
ExternalKey string `json:"external_key" validate:"required"` // 外部群組 / claim 的 key(例如 zitadel role 名稱)
|
||
InternalRoleKey string `json:"internal_role_key" validate:"required"` // 對映的內部角色 key(必須存在於 roles 集合)
|
||
}
|
||
|
||
DeleteRoleMappingReq {
|
||
ExternalSource string `json:"external_source,options=zitadel|ldap|scim" validate:"required,oneof=zitadel ldap scim"` // 外部來源;可選值: zitadel / ldap / scim
|
||
ExternalKey string `json:"external_key" validate:"required"` // 外部群組 / claim 的 key
|
||
}
|
||
|
||
// ===== Policy reload =====
|
||
|
||
PolicyReloadReq {
|
||
TenantID string `json:"tenant_id,optional"` // 指定要 reload 的租戶 ID;留空則 reload 所有租戶
|
||
}
|
||
|
||
PolicyReloadData {
|
||
Tenant string `json:"tenant"`
|
||
TS int64 `json:"ts"`
|
||
}
|
||
|
||
// ===== OK envelopes for swagger =====
|
||
|
||
PermissionCatalogOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data PermissionCatalogData `json:"data"`
|
||
}
|
||
|
||
MePermissionsOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data MePermissionsData `json:"data"`
|
||
}
|
||
|
||
RoleListOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data RoleListData `json:"data"`
|
||
}
|
||
|
||
RoleOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data RoleData `json:"data"`
|
||
}
|
||
|
||
RolePermissionsListOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data RolePermissionsListData `json:"data"`
|
||
}
|
||
|
||
UserRoleListOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data UserRoleListData `json:"data"`
|
||
}
|
||
|
||
UserRoleOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data UserRoleData `json:"data"`
|
||
}
|
||
|
||
RoleMappingListOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data RoleMappingListData `json:"data"`
|
||
}
|
||
|
||
RoleMappingOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data RoleMappingData `json:"data"`
|
||
}
|
||
|
||
PolicyReloadOKStatus {
|
||
Code int64 `json:"code"`
|
||
Message string `json:"message"`
|
||
Data PolicyReloadData `json:"data"`
|
||
}
|
||
)
|
||
|
||
@server(
|
||
group: permission
|
||
prefix: /api/v1/permissions
|
||
tags: "Permission - 權限"
|
||
summary: "Catalog / 角色 / 使用者角色 / 外部映射 / Policy"
|
||
)
|
||
service gateway {
|
||
@doc "取得全局 Permission Catalog(樹狀或扁平;可篩 status/type)"
|
||
/*
|
||
@respdoc-200 (PermissionCatalogOKStatus) // 成功(code=102000)
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
31601000: (APIErrorStatus) 系統內部錯誤
|
||
) // 內部錯誤
|
||
@respdoc-501 (
|
||
31605000: (APIErrorStatus) Permission 模組未配置
|
||
) // 未實作
|
||
*/
|
||
@handler getPermissionCatalog
|
||
get /catalog (PermissionCatalogQuery) returns (PermissionCatalogData)
|
||
|
||
@doc "取得當前使用者的 role / permission map(前端渲染選單)"
|
||
/*
|
||
@respdoc-200 (MePermissionsOKStatus) // 成功(code=102000)
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
|
||
) // 未授權
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
31601000: (APIErrorStatus) 系統內部錯誤
|
||
) // 內部錯誤
|
||
@respdoc-501 (
|
||
31605000: (APIErrorStatus) Permission 模組未配置
|
||
) // 未實作
|
||
*/
|
||
@handler getMePermissions
|
||
get /me (MePermissionsQuery) returns (MePermissionsData)
|
||
|
||
@doc "列出租戶內所有角色(含 system role)"
|
||
/*
|
||
@respdoc-200 (RoleListOKStatus) // 成功
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler listRoles
|
||
get /roles returns (RoleListData)
|
||
|
||
@doc "建立租戶自訂角色(key 不可改、不可使用 system./platform_ 開頭)"
|
||
/*
|
||
@respdoc-200 (RoleOKStatus) // 成功
|
||
@respdoc-400 (
|
||
10101000: (APIErrorStatus) 參數格式錯誤
|
||
31101000: (APIErrorStatus) role key 格式或保留字錯誤
|
||
) // 參數錯誤
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-409 (
|
||
31303000: (APIErrorStatus) 同名 role 已存在
|
||
) // 衝突
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler createRole
|
||
post /roles (CreateRoleReq) returns (RoleData)
|
||
|
||
@doc "更新角色(display_name / status;is_system 角色不可改 status)"
|
||
/*
|
||
@respdoc-200 (RoleOKStatus) // 成功
|
||
@respdoc-400 (
|
||
10101000: (APIErrorStatus) 參數格式錯誤
|
||
) // 參數錯誤
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-404 (
|
||
31301000: (APIErrorStatus) role 不存在
|
||
) // 不存在
|
||
@respdoc-409 (
|
||
31309000: (APIErrorStatus) 系統角色無法更新此欄位
|
||
) // 衝突
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler updateRole
|
||
patch /roles/:id (UpdateRoleByIDReq) returns (RoleData)
|
||
|
||
@doc "刪除角色(is_system 不可刪;存在 user 指派時拒絕)"
|
||
/*
|
||
@respdoc-200 (EmptyOKStatus) // 成功
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-404 (
|
||
31301000: (APIErrorStatus) role 不存在
|
||
) // 不存在
|
||
@respdoc-409 (
|
||
31309000: (APIErrorStatus) 系統角色無法刪除
|
||
31312000: (APIErrorStatus) 角色仍有使用者指派
|
||
) // 衝突
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler deleteRole
|
||
delete /roles/:id (DeleteRoleByIDReq)
|
||
|
||
@doc "讀取角色目前勾選的 permission 集合"
|
||
/*
|
||
@respdoc-200 (RolePermissionsListOKStatus) // 成功
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-404 (
|
||
31301000: (APIErrorStatus) role 不存在
|
||
) // 不存在
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler getRolePermissions
|
||
get /roles/:id/permissions (GetRolePermissionsByIDReq) returns (RolePermissionsListData)
|
||
|
||
@doc "全量取代角色的 permission 勾選(自動補齊父權限;觸發 LoadPolicy + Pub/Sub reload)"
|
||
/*
|
||
@respdoc-200 (EmptyOKStatus) // 成功
|
||
@respdoc-400 (
|
||
10101000: (APIErrorStatus) 參數格式錯誤
|
||
) // 參數錯誤
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-404 (
|
||
31301000: (APIErrorStatus) role 或 permission 不存在
|
||
) // 不存在
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
31601000: (APIErrorStatus) 系統內部錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler replaceRolePermissions
|
||
put /roles/:id/permissions (ReplaceRolePermissionsByIDReq)
|
||
|
||
@doc "查詢使用者目前指派的角色(含 RoleKey / DisplayName)"
|
||
/*
|
||
@respdoc-200 (UserRoleListOKStatus) // 成功
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler listUserRoles
|
||
get /users/:uid/roles (ListUserRolesReq) returns (UserRoleListData)
|
||
|
||
@doc "指派角色給使用者(預設 source=manual;source 來源由 SyncFromX 自動標)"
|
||
/*
|
||
@respdoc-200 (UserRoleOKStatus) // 成功
|
||
@respdoc-400 (
|
||
10101000: (APIErrorStatus) 參數格式錯誤
|
||
) // 參數錯誤
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-404 (
|
||
31301000: (APIErrorStatus) role 不存在
|
||
) // 不存在
|
||
@respdoc-409 (
|
||
31303000: (APIErrorStatus) 角色已指派
|
||
) // 衝突
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler assignUserRole
|
||
post /users/:uid/roles (AssignUserRoleByUIDReq) returns (UserRoleData)
|
||
|
||
@doc "撤銷使用者的單一角色"
|
||
/*
|
||
@respdoc-200 (EmptyOKStatus) // 成功
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-404 (
|
||
31301000: (APIErrorStatus) 指派不存在
|
||
) // 不存在
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler revokeUserRole
|
||
delete /users/:uid/roles/:role_id (RevokeUserRoleByIDReq)
|
||
|
||
@doc "列出外部來源 → 內部 role 的映射(zitadel / ldap / scim)"
|
||
/*
|
||
@respdoc-200 (RoleMappingListOKStatus) // 成功
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler listRoleMappings
|
||
get /role-mappings (RoleMappingListQuery) returns (RoleMappingListData)
|
||
|
||
@doc "Upsert 外部 IdP 群組到內部 role 的映射"
|
||
/*
|
||
@respdoc-200 (RoleMappingOKStatus) // 成功
|
||
@respdoc-400 (
|
||
10101000: (APIErrorStatus) 參數格式錯誤
|
||
) // 參數錯誤
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-404 (
|
||
31301000: (APIErrorStatus) 對應 internal role 不存在
|
||
) // 不存在
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler upsertRoleMapping
|
||
put /role-mappings (UpsertRoleMappingReq) returns (RoleMappingData)
|
||
|
||
@doc "刪除外部 → 內部 role 映射"
|
||
/*
|
||
@respdoc-200 (EmptyOKStatus) // 成功
|
||
@respdoc-400 (
|
||
10101000: (APIErrorStatus) 參數格式錯誤
|
||
) // 參數錯誤
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-404 (
|
||
31301000: (APIErrorStatus) 映射不存在
|
||
) // 不存在
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
) // 內部錯誤
|
||
*/
|
||
@handler deleteRoleMapping
|
||
delete /role-mappings (DeleteRoleMappingReq)
|
||
|
||
@doc "強制重載 Casbin policy(單租戶或所有租戶;同步 + Pub/Sub broadcast)"
|
||
/*
|
||
@respdoc-200 (PolicyReloadOKStatus) // 成功
|
||
@respdoc-401 (
|
||
31501000: (APIErrorStatus) 未授權
|
||
) // 未授權
|
||
@respdoc-500 (
|
||
31201000: (APIErrorStatus) 資料庫錯誤
|
||
31601000: (APIErrorStatus) 系統內部錯誤
|
||
) // 內部錯誤
|
||
@respdoc-501 (
|
||
31605000: (APIErrorStatus) Casbin enforcer 未配置
|
||
) // 未實作
|
||
*/
|
||
@handler reloadPolicy
|
||
post /policy/reload (PolicyReloadReq) returns (PolicyReloadData)
|
||
}
|