permissions.go
1package abac
2
3// Permission is a bitflag representing read/write/delete/admin privileges to a resource
4type Permission uint8
5
6const (
7 r Permission = 1 << iota // 0b0001
8 w // 0b0010
9 d // 0b0100
10 a // 0b1000
11
12 // Normal hierarchy of permissions
13 Read = r
14 Write = r | w
15 Delete = r | w | d
16 Admin = r | w | d | a
17
18 // Special permissions
19 Private = Permission(0)
20 None = Permission(0) // alias for private
21 Ban = Permission(0b11110000)
22 God = Permission(0b11111111)
23)
24
25// Has checks to see if authorization includes the requested permission
26func Has(p Permission, do Permission) bool {
27 return do&p >= do
28}
29
30// Add another permission to the current permission. It is a no-op if the current permission
31// is already sufficient.
32func Add(current Permission, add Permission) Permission {
33 switch add {
34 // special permissions take precedence
35 case None, Ban, God:
36 return add
37 // otherwise return the higher of the current or new permission
38 default:
39 if Has(current, add) {
40 return current
41 }
42 return add
43 }
44}
45
46// Remove the given permission and calculate a new permission that reflects an
47// allowable lower permission state. Convenience function so that the current position does not need to be
48// introspected to determine the next allowable lower permission.
49func Remove(current Permission, remove Permission) Permission {
50 var n Permission
51 switch remove {
52 case Read:
53 n = None
54 case Write:
55 // remove all higher permissions
56 n = current &^ (a | d | w)
57 case Delete:
58 n = current &^ (d | a)
59 case Admin:
60 n = current &^ a
61 // all special permissions have no sensible default. included here only
62 // for exhaustiveness
63 default:
64 n = Private
65 }
66 return n
67}