Files

225 lines
7.8 KiB
Go

package httpx
import (
"sync"
"github.com/gin-gonic/gin"
)
// Permission 权限标识(对应 API 操作)。
type Permission string
// 预定义权限常量(覆盖全部 API 操作)。
const (
// 内容管理
PermContentRegister Permission = "content:register"
PermContentReview Permission = "content:review"
PermContentIssue Permission = "content:issue"
PermContentVerify Permission = "content:verify"
PermContentTranscode Permission = "content:transcode"
PermContentIngest Permission = "content:ingest"
PermContentPublish Permission = "content:publish"
PermContentInject Permission = "content:inject"
PermContentVersionChange Permission = "content:version_change"
PermContentTakedown Permission = "content:takedown"
PermContentRestore Permission = "content:restore"
PermContentMerge Permission = "content:merge"
PermContentSplit Permission = "content:split"
PermContentAddEpisodes Permission = "content:add_episodes"
// 查询
PermQueryByMA Permission = "query:by_ma"
PermQueryByHash Permission = "query:by_hash"
PermQueryByProvincial Permission = "query:by_provincial"
PermQueryByLibraryID Permission = "query:by_library_id"
PermQueryMappings Permission = "query:mappings"
PermQueryEpisodes Permission = "query:episodes"
PermQueryReviews Permission = "query:reviews"
PermQueryContents Permission = "query:contents"
PermQueryProvenance Permission = "query:provenance"
PermQueryAccountability Permission = "query:accountability"
PermQueryEvidence Permission = "query:evidence"
// 数据与分账
PermPlaybackReport Permission = "data:playback_report"
PermPlaybackSummary Permission = "data:playback_summary"
PermSettlement Permission = "data:settlement"
// 确权与侵权
PermInfringeMatch Permission = "rights:infringe_match"
PermAuthorize Permission = "rights:authorize"
PermAuthCheck Permission = "rights:auth_check"
// 跨省与终端
PermCrossProvince Permission = "cross:province_admit"
PermTerminalVerify Permission = "terminal:verify"
// 备案与监管
PermBindFiling Permission = "regulatory:bind_filing"
PermQueryFiling Permission = "regulatory:query_filing"
PermNationalStats Permission = "regulatory:national_stats"
PermDailyReport Permission = "regulatory:daily_report"
PermListSegments Permission = "admin:list_segments"
PermRegisterSegment Permission = "admin:register_segment"
// 大小屏融合
PermResolve Permission = "screen:resolve"
PermScanVerify Permission = "screen:scan_verify"
PermRecordPurchase Permission = "rights:record_purchase"
PermVerifyRights Permission = "rights:verify_rights"
// 系统管理
PermManageUsers Permission = "admin:manage_users"
PermManageOrgs Permission = "admin:manage_orgs"
)
// RBACManager 基于角色的动态权限管理器。
// 支持运行时配置角色-权限映射,替代硬编码角色检查。
type RBACManager struct {
mu sync.RWMutex
roles map[string]map[Permission]bool // role -> permission set
}
// NewRBACManager 创建权限管理器并预置默认角色权限。
func NewRBACManager() *RBACManager {
r := &RBACManager{roles: make(map[string]map[Permission]bool)}
r.loadDefaults()
return r
}
// loadDefaults 加载默认四角色权限矩阵。
func (r *RBACManager) loadDefaults() {
// 监管主体:全部权限
r.SetRolePermissions("regulator", allPermissions())
// 审核主体:审核、入库、转码、查询、验真
r.SetRolePermissions("reviewer", []Permission{
PermContentReview, PermContentTranscode, PermContentIngest,
PermContentVerify, PermContentVersionChange,
PermQueryByMA, PermQueryByHash, PermQueryByProvincial, PermQueryByLibraryID,
PermQueryMappings, PermQueryEpisodes, PermQueryReviews, PermQueryContents,
PermQueryProvenance, PermQueryAccountability, PermQueryEvidence,
PermBindFiling, PermQueryFiling,
PermResolve, PermScanVerify,
})
// 内容提供商:送审、查询、确权
r.SetRolePermissions("cp", []Permission{
PermContentRegister,
PermQueryByMA, PermQueryByHash, PermQueryByProvincial, PermQueryByLibraryID,
PermQueryMappings, PermQueryEpisodes, PermQueryReviews, PermQueryContents,
PermQueryProvenance, PermQueryEvidence,
PermInfringeMatch, PermAuthorize, PermAuthCheck,
PermResolve, PermScanVerify, PermRecordPurchase, PermVerifyRights,
})
// 运营商:注入、发布、查询、播放回传
r.SetRolePermissions("operator", []Permission{
PermContentPublish, PermContentInject,
PermContentVerify, PermTerminalVerify,
PermQueryByMA, PermQueryByHash, PermQueryMappings, PermQueryEpisodes,
PermQueryContents, PermQueryProvenance,
PermPlaybackReport, PermPlaybackSummary, PermSettlement,
PermResolve, PermScanVerify, PermVerifyRights,
})
}
// SetRolePermissions 设置某角色的权限集合(覆盖原有)。
func (r *RBACManager) SetRolePermissions(role string, perms []Permission) {
r.mu.Lock()
defer r.mu.Unlock()
set := make(map[Permission]bool, len(perms))
for _, p := range perms {
set[p] = true
}
r.roles[role] = set
}
// GrantPermission 为角色追加单个权限。
func (r *RBACManager) GrantPermission(role string, perm Permission) {
r.mu.Lock()
defer r.mu.Unlock()
if r.roles[role] == nil {
r.roles[role] = make(map[Permission]bool)
}
r.roles[role][perm] = true
}
// RevokePermission 移除角色的某个权限。
func (r *RBACManager) RevokePermission(role string, perm Permission) {
r.mu.Lock()
defer r.mu.Unlock()
if r.roles[role] != nil {
delete(r.roles[role], perm)
}
}
// HasPermission 检查角色是否拥有指定权限。
func (r *RBACManager) HasPermission(role string, perm Permission) bool {
r.mu.RLock()
defer r.mu.RUnlock()
perms, ok := r.roles[role]
if !ok {
return false
}
return perms[perm]
}
// ListPermissions 列出角色的全部权限。
func (r *RBACManager) ListPermissions(role string) []Permission {
r.mu.RLock()
defer r.mu.RUnlock()
perms, ok := r.roles[role]
if !ok {
return nil
}
out := make([]Permission, 0, len(perms))
for p := range perms {
out = append(out, p)
}
return out
}
// ListRoles 列出全部已配置角色。
func (r *RBACManager) ListRoles() []string {
r.mu.RLock()
defer r.mu.RUnlock()
out := make([]string, 0, len(r.roles))
for role := range r.roles {
out = append(out, role)
}
return out
}
// RequirePermission 返回 Gin 中间件,校验当前角色是否拥有指定权限。
// 用法:rg.POST("/content/issue", rbac.RequirePermission(httpx.PermContentIssue), h.issue)
func (r *RBACManager) RequirePermission(perm Permission) gin.HandlerFunc {
return func(c *gin.Context) {
role := RoleFromContext(c)
if role == "" {
Error(c, 401, "UNAUTHORIZED", "未认证")
c.Abort()
return
}
if !r.HasPermission(role, perm) {
Error(c, 403, "FORBIDDEN", "角色 "+role+" 无权限: "+string(perm))
c.Abort()
return
}
c.Next()
}
}
// allPermissions 返回全部权限列表(用于监管角色)。
func allPermissions() []Permission {
return []Permission{
PermContentRegister, PermContentReview, PermContentIssue, PermContentVerify,
PermContentTranscode, PermContentIngest, PermContentPublish, PermContentInject,
PermContentVersionChange, PermContentTakedown, PermContentRestore,
PermContentMerge, PermContentSplit, PermContentAddEpisodes,
PermQueryByMA, PermQueryByHash, PermQueryByProvincial, PermQueryByLibraryID,
PermQueryMappings, PermQueryEpisodes, PermQueryReviews, PermQueryContents,
PermQueryProvenance, PermQueryAccountability, PermQueryEvidence,
PermPlaybackReport, PermPlaybackSummary, PermSettlement,
PermInfringeMatch, PermAuthorize, PermAuthCheck,
PermCrossProvince, PermTerminalVerify,
PermBindFiling, PermQueryFiling, PermNationalStats, PermDailyReport,
PermListSegments, PermRegisterSegment,
PermResolve, PermScanVerify, PermRecordPurchase, PermVerifyRights,
PermManageUsers, PermManageOrgs,
}
}