forked from mikespook/gorbac
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrole.go
136 lines (116 loc) · 2.99 KB
/
role.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package gorbac
const (
ParentKey = "parents"
PermissionKey = "permissions"
NameKey = "name"
RankKey = "rank"
DescriptionKey = "description"
)
// Sometimes, a custom role structure is needed by projects.
// You should define your own role factory function for this purpuse.
type RoleFactoryFunc func(*Rbac, string) Role
// An exportable data structure
type RoleMap map[string]interface{}
// An interface can't export directly. But you can convert it into a map.
func RoleToMap(role Role) RoleMap {
roleMap := make(RoleMap)
roleMap[PermissionKey] = role.Permissions()
roleMap[ParentKey] = role.Parents()
roleMap[NameKey] = role.Name()
roleMap[RankKey] = role.Rank()
roleMap[DescriptionKey] = role.Description()
return roleMap
}
// Implement this interface for your own role structure.
type Role interface {
Rank() int
Name() string
Description() string
AddRank(int)
AddDescription(string)
AddPermission(string)
HasPermission(string) bool
RevokePermission(string)
Permissions() []string
AddParent(string)
RemoveParent(string)
Parents() []string
Reset()
}
func newBaseRole(rbac *Rbac, name string) Role {
role := &baseRole{
rbac: rbac,
name: name,
permissions: make(map[string]bool, bufferSize),
parents: make(map[string]bool, bufferSize),
}
return role
}
type baseRole struct {
rbac *Rbac
rank int
name string
description string
permissions map[string]bool
parents map[string]bool
}
func (role *baseRole) AddRank(rank int) {
role.rank = rank
}
func (role *baseRole) AddDescription(description string) {
role.description = description
}
func (role *baseRole) AddPermission(permission string) {
role.permissions[permission] = true
}
func (role *baseRole) HasPermission(permission string) bool {
if permit, ok := role.permissions[permission]; ok {
return permit
}
for pname, _ := range role.parents {
if parent := role.rbac.Get(pname); parent != nil {
if parent.HasPermission(permission) {
return true
}
} else {
delete(role.parents, pname)
}
}
return false
}
func (role *baseRole) RevokePermission(permission string) {
delete(role.permissions, permission)
}
func (role *baseRole) AddParent(name string) {
role.parents[name] = true
}
func (role *baseRole) RemoveParent(name string) {
delete(role.parents, name)
}
func (role *baseRole) Reset() {
role.permissions = make(map[string]bool, bufferSize)
role.parents = make(map[string]bool, bufferSize)
}
func (role *baseRole) Permissions() []string {
result := make([]string, 0, len(role.permissions))
for name, _ := range role.permissions {
result = append(result, name)
}
return result
}
func (role *baseRole) Parents() []string {
result := make([]string, 0, len(role.parents))
for name, _ := range role.parents {
result = append(result, name)
}
return result
}
func (role *baseRole) Rank() int {
return role.rank
}
func (role *baseRole) Name() string {
return role.name
}
func (role *baseRole) Description() string {
return role.description
}