diff --git a/utils/super/permission.go b/utils/super/permission.go new file mode 100644 index 0000000..360012a --- /dev/null +++ b/utils/super/permission.go @@ -0,0 +1,78 @@ +package super + +import ( + "github.com/kercylan98/minotaur/utils/generic" + "sync" +) + +// NewPermission 创建权限 +func NewPermission[Code generic.Integer, EntityID comparable]() *Permission[Code, EntityID] { + return &Permission[Code, EntityID]{ + permissions: make(map[EntityID]Code), + } +} + +type Permission[Code generic.Integer, EntityID comparable] struct { + permissions map[EntityID]Code + l sync.RWMutex +} + +// HasPermission 是否有权限 +func (slf *Permission[Code, EntityID]) HasPermission(entityId EntityID, permission Code) bool { + slf.l.RLock() + c, exist := slf.permissions[entityId] + slf.l.RUnlock() + if !exist { + return false + } + + return c&permission != 0 +} + +// AddPermission 添加权限 +func (slf *Permission[Code, EntityID]) AddPermission(entityId EntityID, permission ...Code) { + + slf.l.Lock() + defer slf.l.Unlock() + + userPermission, exist := slf.permissions[entityId] + if !exist { + userPermission = 0 + slf.permissions[entityId] = userPermission + } + + for _, p := range permission { + userPermission |= p + } + + slf.permissions[entityId] = userPermission +} + +// RemovePermission 移除权限 +func (slf *Permission[Code, EntityID]) RemovePermission(entityId EntityID, permission ...Code) { + slf.l.Lock() + defer slf.l.Unlock() + + userPermission, exist := slf.permissions[entityId] + if !exist { + return + } + + for _, p := range permission { + userPermission &= ^p + } + + slf.permissions[entityId] = userPermission +} + +// SetPermission 设置权限 +func (slf *Permission[Code, EntityID]) SetPermission(entityId EntityID, permission ...Code) { + slf.l.Lock() + defer slf.l.Unlock() + + var userPermission Code + for _, p := range permission { + userPermission |= p + } + slf.permissions[entityId] = userPermission +} diff --git a/utils/super/permission_test.go b/utils/super/permission_test.go new file mode 100644 index 0000000..0cd1e45 --- /dev/null +++ b/utils/super/permission_test.go @@ -0,0 +1,28 @@ +package super_test + +import ( + "github.com/kercylan98/minotaur/utils/super" + "testing" +) + +func TestNewPermission(t *testing.T) { + const ( + Read = 1 << iota + Write + Execute + ) + + p := super.NewPermission[int, int]() + p.AddPermission(1, Read, Write) + t.Log(p.HasPermission(1, Read)) + t.Log(p.HasPermission(1, Write)) + p.SetPermission(2, Read|Write) + t.Log(p.HasPermission(2, Read)) + t.Log(p.HasPermission(2, Execute)) + p.SetPermission(2, Execute) + t.Log(p.HasPermission(2, Execute)) + t.Log(p.HasPermission(2, Read)) + t.Log(p.HasPermission(2, Write)) + p.RemovePermission(2, Execute) + t.Log(p.HasPermission(2, Execute)) +}