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}