1package policies
2
3import "sort"
4
5// ComparePolicies checks whether the given policy sets are equivalent, as in,
6// they contain the same values. The benefit of this method is that it leaves
7// the "default" policy out of its comparisons as it may be added later by core
8// after a set of policies has been saved by a backend.
9func EquivalentPolicies(a, b []string) bool {
10	if a == nil && b == nil {
11		return true
12	}
13
14	if a == nil || b == nil {
15		return false
16	}
17
18	// First we'll build maps to ensure unique values and filter default
19	mapA := map[string]bool{}
20	mapB := map[string]bool{}
21	for _, keyA := range a {
22		if keyA == "default" {
23			continue
24		}
25		mapA[keyA] = true
26	}
27	for _, keyB := range b {
28		if keyB == "default" {
29			continue
30		}
31		mapB[keyB] = true
32	}
33
34	// Now we'll build our checking slices
35	var sortedA, sortedB []string
36	for keyA, _ := range mapA {
37		sortedA = append(sortedA, keyA)
38	}
39	for keyB, _ := range mapB {
40		sortedB = append(sortedB, keyB)
41	}
42	sort.Strings(sortedA)
43	sort.Strings(sortedB)
44
45	// Finally, compare
46	if len(sortedA) != len(sortedB) {
47		return false
48	}
49
50	for i := range sortedA {
51		if sortedA[i] != sortedB[i] {
52			return false
53		}
54	}
55
56	return true
57}
58