From 5f04c0c2f1086171a3b9e6232808d54870f94a5b Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Mon, 21 Aug 2017 17:45:11 -0700 Subject: [PATCH] nomad: adding policy subset check --- nomad/structs/structs.go | 18 ++++++++++++++++++ nomad/structs/structs_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index eb3e51d65..a88fd1e33 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -5512,6 +5512,24 @@ func (a *ACLToken) Validate() error { return mErr.ErrorOrNil() } +// PolicySubset checks if a given set of policies is a subset of the token +func (a *ACLToken) PolicySubset(policies []string) bool { + // Hot-path the management tokens, superset of all policies. + if a.Type == ACLManagementToken { + return true + } + associatedPolicies := make(map[string]struct{}, len(a.Policies)) + for _, policy := range a.Policies { + associatedPolicies[policy] = struct{}{} + } + for _, policy := range policies { + if _, ok := associatedPolicies[policy]; !ok { + return false + } + } + return true +} + // ACLTokenListRequest is used to request a list of tokens type ACLTokenListRequest struct { GlobalOnly bool diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index 9d3355722..83247b6dd 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -2307,3 +2307,28 @@ func TestACLTokenValidate(t *testing.T) { err = tk.Validate() assert.Nil(t, err) } + +func TestACLTokenPolicySubset(t *testing.T) { + tk := &ACLToken{ + Type: ACLClientToken, + Policies: []string{"foo", "bar", "baz"}, + } + + assert.Equal(t, true, tk.PolicySubset([]string{"foo", "bar", "baz"})) + assert.Equal(t, true, tk.PolicySubset([]string{"foo", "bar"})) + assert.Equal(t, true, tk.PolicySubset([]string{"foo"})) + assert.Equal(t, true, tk.PolicySubset([]string{})) + assert.Equal(t, false, tk.PolicySubset([]string{"foo", "bar", "new"})) + assert.Equal(t, false, tk.PolicySubset([]string{"new"})) + + tk = &ACLToken{ + Type: ACLManagementToken, + } + + assert.Equal(t, true, tk.PolicySubset([]string{"foo", "bar", "baz"})) + assert.Equal(t, true, tk.PolicySubset([]string{"foo", "bar"})) + assert.Equal(t, true, tk.PolicySubset([]string{"foo"})) + assert.Equal(t, true, tk.PolicySubset([]string{})) + assert.Equal(t, true, tk.PolicySubset([]string{"foo", "bar", "new"})) + assert.Equal(t, true, tk.PolicySubset([]string{"new"})) +}