-
Notifications
You must be signed in to change notification settings - Fork 2
/
server_check.go
150 lines (134 loc) · 4.06 KB
/
server_check.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package caskin
import "fmt"
func (s *server) CheckObject(user User, domain Domain, one Object, action Action) error {
if ok := Check(s.Enforcer, user, domain, one, action); ok {
return nil
}
return fmt.Errorf("no %v permission", action)
}
func (s *server) CheckObjectData(user User, domain Domain, one ObjectData, action Action) error {
if ok := Check(s.Enforcer, user, domain, one, action); ok {
return nil
}
return fmt.Errorf("no %v permission", action)
}
func (s *server) DBCreateCheck(item any) error {
if err := s.DB.Take(item); err == nil {
return ErrAlreadyExists
}
return nil
}
func (s *server) DBRecoverCheck(item any) error {
if err := s.DB.Take(item); err == nil {
return ErrAlreadyExists
}
if err := s.DB.TakeUnscoped(item); err != nil {
return ErrNotExists
}
return nil
}
func (s *server) IDInterfaceDeleteCheck(item idInterface) error {
return s.IDInterfaceValidAndExistsCheck(item)
}
func (s *server) IDInterfaceUpdateCheck(item, old idInterface) error {
if err := isValid(item); err != nil {
return err
}
old.SetID(item.GetID())
if err := s.DB.Take(old); err != nil {
return ErrNotExists
}
return nil
}
func (s *server) IDInterfaceValidAndExistsCheck(item idInterface) error {
if err := isValid(item); err != nil {
return err
}
if err := s.DB.Take(item); err != nil {
return ErrNotExists
}
return nil
}
func (s *server) IDInterfaceGetCheck(item idInterface) error {
return s.IDInterfaceValidAndExistsCheck(item)
}
func (s *server) IDInterfaceModifyCheck(item idInterface) error {
return s.IDInterfaceValidAndExistsCheck(item)
}
func (s *server) ObjectManageCheck(user User, domain Domain, item Object) error {
if err := s.IDInterfaceModifyCheck(item); err != nil {
return err
}
return s.CheckObject(user, domain, item, Manage)
}
func (s *server) ObjectParentCheck(user User, domain Domain, object Object) error {
if object.GetParentID() == 0 {
return ErrCantOperateRootObject
}
parent := newByE(object)
parent.SetID(object.GetParentID())
if err := s.ObjectManageCheck(user, domain, parent); err != nil {
return err
}
if parent.GetObjectType() != object.GetObjectType() {
return ErrInValidObjectType
}
return nil
}
func (s *server) ObjectParentToDescendantCheck(domain Domain, object Object, old Object) error {
if object.GetParentID() == 0 || object.GetParentID() == old.GetParentID() {
return nil
}
to := newByE(object)
to.SetID(object.GetParentID())
if ok, _ := s.Enforcer.EnforceObject(object, to, domain); ok {
return ErrParentToDescendant
}
return nil
}
func (s *server) ObjectUpdateCheck(user User, domain Domain, object Object) error {
old := newByE(object)
if err := s.IDInterfaceUpdateCheck(object, old); err != nil {
return err
}
if object.GetID() == object.GetParentID() {
return ErrParentCanNotBeItself
}
if object.GetObjectType() != "" && object.GetObjectType() != old.GetObjectType() {
return ErrCantChangeObjectType
}
if err := s.ObjectManageCheck(user, domain, old); err != nil {
return err
}
return s.ObjectParentToDescendantCheck(domain, object, old)
}
func (s *server) ObjectHierarchyCheck(domain Domain, object Object) error {
parent := newByE(object)
parent.SetID(object.GetParentID())
hierarchyLevel1 := objectHierarchyBFS(domain, parent, s.Enforcer.GetParentsForObjectInDomain)
hierarchyLevel2 := objectHierarchyBFS(domain, object, s.Enforcer.GetChildrenForObjectInDomain)
if hierarchyLevel := hierarchyLevel1 + hierarchyLevel2; hierarchyLevel > 10 {
return fmt.Errorf("max directory depth %v is too large than 10", hierarchyLevel)
}
return nil
}
func objectHierarchyBFS(domain Domain, object Object, fn func(Object, Domain) []Object) int {
hierarchyLevel := 0
m := map[uint64]int{object.GetID(): 1}
queue := []uint64{object.GetID()}
for i := 0; i < len(queue); i++ {
node := newByE(object)
node.SetID(queue[i])
for _, v := range fn(node, domain) {
if _, ok := m[v.GetID()]; ok {
continue
}
m[v.GetID()] = m[node.GetID()] + 1
queue = append(queue, v.GetID())
}
if hierarchyLevel < m[node.GetID()] {
hierarchyLevel = m[node.GetID()]
}
}
return hierarchyLevel
}