// Package permission — 能力點(capability)與角色預設對照。 // // 現行策略(M1~M2): // - JWT 帶 roles[];中介層/業務用 permission.Has(roles, code) 判定 // - 尚未做 DB 動態 permission 表;擴充時只改本檔 RoleGrants 即可 // // 命名:{domain}:{resource}:{action} 或 {domain}:{action} package permission // ─── 公開/系統(不需登入)──────────────────────────────── const ( // PublicPing 健康檢查(無 JWT) PublicPing = "public:ping" // PublicAuthLogin 登入/註冊/忘密/refresh 等公開 auth PublicAuthLogin = "public:auth:login" // PublicThreadsOAuthCallback OAuth 回調(state 驗證) PublicThreadsOAuthCallback = "public:threads:oauth_callback" ) // ─── 已登入會員(member)────────────────────────────────── const ( AuthMe = "auth:me" AuthProfileUpdate = "auth:profile:update" AuthPasswordChange = "auth:password:change" AuthEmailVerify = "auth:email:verify" AuthLogout = "auth:logout" AuthIdentities = "auth:identities" AuthBind = "auth:bind" AuthUnbind = "auth:unbind" MediaUpload = "media:upload" SettingsAIRead = "settings:ai:read" SettingsAIWrite = "settings:ai:write" SettingsPlacementRead = "settings:placement:read" SettingsPlacementWrite = "settings:placement:write" SettingsModelsList = "settings:models:list" ThreadsOAuthStart = "threads:oauth:start" ThreadsList = "threads:list" ThreadsRefresh = "threads:refresh" ThreadsDisconnect = "threads:disconnect" JobsList = "jobs:list" JobsGet = "jobs:get" // JobsDemoCreate 僅 admin(任務頁「產生測試任務」) JobsDemoCreate = "jobs:demo:create" NotifList = "notifications:list" NotifUnread = "notifications:unread" NotifMarkRead = "notifications:mark_read" ) // ─── 管理員(admin)─────────────────────────────────────── const ( // AdminAccess 進入管理能力的總閘(AdminAuth middleware 檢查此碼) AdminAccess = "admin:access" AdminMembersList = "admin:members:list" AdminMembersGet = "admin:members:get" AdminMembersCreate = "admin:members:create" AdminMembersSuspend = "admin:members:suspend" AdminMembersRoles = "admin:members:roles" AdminMembersEmailVerified = "admin:members:email_verified" AdminMembersResetPassword = "admin:members:reset_password" AdminMembersIdentities = "admin:members:identities" AdminMembersStatus = "admin:members:status" ) // Role names(與 member.domain 一致) const ( RoleMember = "member" RoleAdmin = "admin" ) // memberBase — 一般會員可做的事 var memberBase = []string{ AuthMe, AuthProfileUpdate, AuthPasswordChange, AuthEmailVerify, AuthLogout, AuthIdentities, AuthBind, AuthUnbind, MediaUpload, SettingsAIRead, SettingsAIWrite, SettingsPlacementRead, SettingsPlacementWrite, SettingsModelsList, ThreadsOAuthStart, ThreadsList, ThreadsRefresh, ThreadsDisconnect, JobsList, JobsGet, NotifList, NotifUnread, NotifMarkRead, } // adminExtra — 管理員額外能力 var adminExtra = []string{ AdminAccess, AdminMembersList, AdminMembersGet, AdminMembersCreate, AdminMembersSuspend, AdminMembersRoles, AdminMembersEmailVerified, AdminMembersResetPassword, AdminMembersIdentities, AdminMembersStatus, JobsDemoCreate, } // RoleGrants 角色 → 能力列表(可擴充自訂角色) var RoleGrants = map[string][]string{ RoleMember: memberBase, RoleAdmin: append(append([]string{}, memberBase...), adminExtra...), } // Expand 合併多角色能力(去重) func Expand(roles []string) map[string]struct{} { out := make(map[string]struct{}) for _, r := range roles { for _, p := range RoleGrants[r] { out[p] = struct{}{} } } // admin 一定含 AdminAccess if hasRole(roles, RoleAdmin) { out[AdminAccess] = struct{}{} } return out } func hasRole(roles []string, want string) bool { for _, r := range roles { if r == want { return true } } return false } // Has 是否具備指定 permission func Has(roles []string, code string) bool { if code == "" { return false } _, ok := Expand(roles)[code] return ok } // HasAny 具備任一即可 func HasAny(roles []string, codes ...string) bool { set := Expand(roles) for _, c := range codes { if _, ok := set[c]; ok { return true } } return false } // HasAll 必須全部具備 func HasAll(roles []string, codes ...string) bool { set := Expand(roles) for _, c := range codes { if _, ok := set[c]; !ok { return false } } return true } // IsAdmin 是否具管理總閘(相容舊呼叫) func IsAdmin(roles []string) bool { return Has(roles, AdminAccess) }