This repository has been archived by the owner on Jun 10, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgrant_map.go
128 lines (107 loc) · 2.46 KB
/
grant_map.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
package consulacl
import (
"fmt"
"sort"
"strings"
"sync"
)
// GrantMap defines the type holding grant maps
type GrantMap struct {
mu sync.RWMutex
grants map[string]Grant
}
// Set applies the given grant for the given target
//
// This method overrides potentially existing grants
func (gm *GrantMap) Set(target string, grant Grant) {
// If we receive a "none" grant we revoke it
if grant == GrantNone {
gm.Remove(target)
return
}
gm.mu.Lock()
defer gm.mu.Unlock()
if gm.grants == nil {
gm.grants = make(map[string]Grant, 16)
}
gm.grants[target] = grant
}
// Remove removes the grant for the given target
func (gm *GrantMap) Remove(target string) {
gm.mu.Lock()
defer gm.mu.Unlock()
if gm.grants == nil {
return
}
if _, exists := gm.grants[target]; exists {
delete(gm.grants, target)
}
}
// Get retrieves the grant for a given target
func (gm *GrantMap) Get(target string) Grant {
gm.mu.RLock()
defer gm.mu.RUnlock()
return gm.grants[target]
}
// Is checks if the grant for the given target is the same as provided
func (gm *GrantMap) Is(target string, grant Grant) bool {
g := gm.Get(target)
return g == grant
}
// Equals checks if the given GrantMap equals another GrantMap
func (gm *GrantMap) Equals(other *GrantMap) bool {
if other == nil {
return false
}
// Acquire read-lock on both grant maps
gm.mu.RLock()
defer gm.mu.RUnlock()
other.mu.RLock()
defer other.mu.RUnlock()
// Short-cut: length mismatch
if len(gm.grants) != len(other.grants) {
return false
}
// Compare each grant
for target, grant := range gm.grants {
if other.grants[target] != grant {
return false
}
}
return true
}
// Clone creates a copy of the GrantMap
func (gm *GrantMap) Clone() *GrantMap {
gm.mu.RLock()
defer gm.mu.RUnlock()
clone := &GrantMap{
grants: make(map[string]Grant, len(gm.grants)),
}
for target, grant := range gm.grants {
clone.grants[target] = grant
}
return clone
}
func (gm *GrantMap) generateRules(typePrefix string) string {
var rules []string
gm.mu.RLock()
defer gm.mu.RUnlock()
// Sort the targets first
targets := make([]string, 0, len(gm.grants))
for target := range gm.grants {
targets = append(targets, target)
}
sort.Strings(targets)
for _, target := range targets {
grant := gm.grants[target]
// Skip "none" grants
if grant == GrantNone {
continue
}
rules = append(rules, fmt.Sprintf(
`%s "%s" {
policy = "%s"
}`, typePrefix, target, grant.String()))
}
return strings.Join(rules, "\n")
}