/
policy_filter.go
112 lines (94 loc) · 2.86 KB
/
policy_filter.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
package handlers
import (
"fmt"
"policy-server/api"
"policy-server/store"
"policy-server/uaa_client"
)
//go:generate counterfeiter -o fakes/uua_client.go --fake-name UAAClient . uaaClient
type uaaClient interface {
GetToken() (string, error)
CheckToken(string) (uaa_client.CheckTokenResponse, error)
}
//go:generate counterfeiter -o fakes/cc_client.go --fake-name CCClient . ccClient
type ccClient interface {
GetAppSpaces(token string, appGUIDs []string) (map[string]string, error)
GetSpace(token, spaceGUID string) (*api.Space, error)
GetSpaceGUIDs(token string, appGUIDs []string) ([]string, error)
GetUserSpace(token, userGUID string, spaces api.Space) (*api.Space, error)
GetUserSpaces(token, userGUID string) (map[string]struct{}, error)
}
type PolicyFilter struct {
CCClient ccClient
UAAClient uaaClient
ChunkSize int
}
func NewPolicyFilter(uaaClient uaaClient, ccClient ccClient, chunkSize int) *PolicyFilter {
return &PolicyFilter{
CCClient: ccClient,
UAAClient: uaaClient,
ChunkSize: chunkSize,
}
}
func (f *PolicyFilter) FilterPolicies(policies []store.Policy, userToken uaa_client.CheckTokenResponse) ([]store.Policy, error) {
for _, scope := range userToken.Scope {
if scope == "network.admin" {
return policies, nil
}
}
token, err := f.UAAClient.GetToken()
if err != nil {
return nil, fmt.Errorf("getting token: %s", err)
}
appGuids := uniqueAppGUIDs(policies)
appGuidChunks := getChunks(appGuids, f.ChunkSize)
appSpacesList := []map[string]string{}
for _, chunk := range appGuidChunks {
spaces, err := f.CCClient.GetAppSpaces(token, chunk)
if err != nil {
return nil, fmt.Errorf("getting app spaces: %s", err)
}
appSpacesList = append(appSpacesList, spaces)
}
appSpaces := flatten(appSpacesList)
userSpaces, err := f.CCClient.GetUserSpaces(token, userToken.UserID)
if err != nil {
return nil, fmt.Errorf("getting user spaces: %s", err)
}
filtered := filter(policies, appSpaces, userSpaces)
return filtered, nil
}
func flatten(list []map[string]string) map[string]string {
ret := make(map[string]string)
for _, m := range list {
for k, v := range m {
ret[k] = v
}
}
return ret
}
func getChunks(appGuids []string, chunkSize int) [][]string {
if chunkSize < 1 {
chunkSize = 100
}
appGuidChunks := [][]string{}
for i := 0; i < len(appGuids); i += chunkSize {
last := i + chunkSize
if last > len(appGuids) {
last = len(appGuids)
}
appGuidChunks = append(appGuidChunks, appGuids[i:last])
}
return appGuidChunks
}
func filter(policies []store.Policy, appSpaces map[string]string, userSpaces map[string]struct{}) []store.Policy {
filtered := []store.Policy{}
for _, policy := range policies {
_, sourceFound := userSpaces[appSpaces[policy.Source.ID]]
_, destFound := userSpaces[appSpaces[policy.Destination.ID]]
if sourceFound && destFound {
filtered = append(filtered, policy)
}
}
return filtered
}