github.com/Aestek/consul@v1.2.4-0.20190309222502-b2c31e33971a/agent/consul/acl_test.go (about)

     1  package consul
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"reflect"
     8  	"strings"
     9  	"sync/atomic"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/hashicorp/consul/acl"
    14  	"github.com/hashicorp/consul/agent/structs"
    15  	"github.com/hashicorp/consul/testutil/retry"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  var testACLPolicy = `
    21  key "" {
    22  	policy = "deny"
    23  }
    24  key "foo/" {
    25  	policy = "write"
    26  }
    27  `
    28  
    29  var testACLPolicyNew = `
    30  key_prefix "" {
    31  	policy = "deny"
    32  }
    33  key_prefix "foo/" {
    34  	policy = "write"
    35  }
    36  `
    37  
    38  type asyncResolutionResult struct {
    39  	authz acl.Authorizer
    40  	err   error
    41  }
    42  
    43  func resolveTokenAsync(r *ACLResolver, token string, ch chan *asyncResolutionResult) {
    44  	authz, err := r.ResolveToken(token)
    45  	ch <- &asyncResolutionResult{authz: authz, err: err}
    46  }
    47  
    48  func testIdentityForToken(token string) (bool, structs.ACLIdentity, error) {
    49  	switch token {
    50  	case "missing-policy":
    51  		return true, &structs.ACLToken{
    52  			AccessorID: "435a75af-1763-4980-89f4-f0951dda53b4",
    53  			SecretID:   "b1b6be70-ed2e-4c80-8495-bdb3db110b1e",
    54  			Policies: []structs.ACLTokenPolicyLink{
    55  				structs.ACLTokenPolicyLink{
    56  					ID: "not-found",
    57  				},
    58  				structs.ACLTokenPolicyLink{
    59  					ID: "acl-ro",
    60  				},
    61  			},
    62  		}, nil
    63  	case "legacy-management":
    64  		return true, &structs.ACLToken{
    65  			AccessorID: "d109a033-99d1-47e2-a711-d6593373a973",
    66  			SecretID:   "415cd1e1-1493-4fb4-827d-d762ed9cfe7c",
    67  			Type:       structs.ACLTokenTypeManagement,
    68  		}, nil
    69  	case "legacy-client":
    70  		return true, &structs.ACLToken{
    71  			AccessorID: "b7375838-b104-4a25-b457-329d939bf257",
    72  			SecretID:   "03f49328-c23c-4b26-92a2-3b898332400d",
    73  			Type:       structs.ACLTokenTypeClient,
    74  			Rules:      `service "" { policy = "read" }`,
    75  		}, nil
    76  	case "found":
    77  		return true, &structs.ACLToken{
    78  			AccessorID: "5f57c1f6-6a89-4186-9445-531b316e01df",
    79  			SecretID:   "a1a54629-5050-4d17-8a4e-560d2423f835",
    80  			Policies: []structs.ACLTokenPolicyLink{
    81  				structs.ACLTokenPolicyLink{
    82  					ID: "node-wr",
    83  				},
    84  				structs.ACLTokenPolicyLink{
    85  					ID: "dc2-key-wr",
    86  				},
    87  			},
    88  		}, nil
    89  	case "acl-ro":
    90  		return true, &structs.ACLToken{
    91  			AccessorID: "435a75af-1763-4980-89f4-f0951dda53b4",
    92  			SecretID:   "b1b6be70-ed2e-4c80-8495-bdb3db110b1e",
    93  			Policies: []structs.ACLTokenPolicyLink{
    94  				structs.ACLTokenPolicyLink{
    95  					ID: "acl-ro",
    96  				},
    97  			},
    98  		}, nil
    99  	case "acl-wr":
   100  		return true, &structs.ACLToken{
   101  			AccessorID: "435a75af-1763-4980-89f4-f0951dda53b4",
   102  			SecretID:   "b1b6be70-ed2e-4c80-8495-bdb3db110b1e",
   103  			Policies: []structs.ACLTokenPolicyLink{
   104  				structs.ACLTokenPolicyLink{
   105  					ID: "acl-wr",
   106  				},
   107  			},
   108  		}, nil
   109  	case "racey-unmodified":
   110  		return true, &structs.ACLToken{
   111  			AccessorID: "5f57c1f6-6a89-4186-9445-531b316e01df",
   112  			SecretID:   "a1a54629-5050-4d17-8a4e-560d2423f835",
   113  			Policies: []structs.ACLTokenPolicyLink{
   114  				structs.ACLTokenPolicyLink{
   115  					ID: "node-wr",
   116  				},
   117  				structs.ACLTokenPolicyLink{
   118  					ID: "acl-wr",
   119  				},
   120  			},
   121  		}, nil
   122  	case "racey-modified":
   123  		return true, &structs.ACLToken{
   124  			AccessorID: "5f57c1f6-6a89-4186-9445-531b316e01df",
   125  			SecretID:   "a1a54629-5050-4d17-8a4e-560d2423f835",
   126  			Policies: []structs.ACLTokenPolicyLink{
   127  				structs.ACLTokenPolicyLink{
   128  					ID: "node-wr",
   129  				},
   130  			},
   131  		}, nil
   132  	case "concurrent-resolve-1":
   133  		return true, &structs.ACLToken{
   134  			AccessorID: "5f57c1f6-6a89-4186-9445-531b316e01df",
   135  			SecretID:   "a1a54629-5050-4d17-8a4e-560d2423f835",
   136  			Policies: []structs.ACLTokenPolicyLink{
   137  				structs.ACLTokenPolicyLink{
   138  					ID: "node-wr",
   139  				},
   140  				structs.ACLTokenPolicyLink{
   141  					ID: "acl-wr",
   142  				},
   143  			},
   144  		}, nil
   145  	case "concurrent-resolve-2":
   146  		return true, &structs.ACLToken{
   147  			AccessorID: "296bbe10-01aa-437e-ac3b-3ecdc00ea65c",
   148  			SecretID:   "cc58f0f3-2273-42a7-8b4a-2bef9d2863d7",
   149  			Policies: []structs.ACLTokenPolicyLink{
   150  				structs.ACLTokenPolicyLink{
   151  					ID: "node-wr",
   152  				},
   153  				structs.ACLTokenPolicyLink{
   154  					ID: "acl-wr",
   155  				},
   156  			},
   157  		}, nil
   158  	case anonymousToken:
   159  		return true, &structs.ACLToken{
   160  			AccessorID: "00000000-0000-0000-0000-000000000002",
   161  			SecretID:   anonymousToken,
   162  			Policies: []structs.ACLTokenPolicyLink{
   163  				structs.ACLTokenPolicyLink{
   164  					ID: "node-wr",
   165  				},
   166  			},
   167  		}, nil
   168  	default:
   169  		return true, nil, acl.ErrNotFound
   170  	}
   171  }
   172  
   173  func testPolicyForID(policyID string) (bool, *structs.ACLPolicy, error) {
   174  	switch policyID {
   175  	case "acl-ro":
   176  		return true, &structs.ACLPolicy{
   177  			ID:          "acl-ro",
   178  			Name:        "acl-ro",
   179  			Description: "acl-ro",
   180  			Rules:       `acl = "read"`,
   181  			Syntax:      acl.SyntaxCurrent,
   182  			RaftIndex:   structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
   183  		}, nil
   184  	case "acl-wr":
   185  		return true, &structs.ACLPolicy{
   186  			ID:          "acl-wr",
   187  			Name:        "acl-wr",
   188  			Description: "acl-wr",
   189  			Rules:       `acl = "write"`,
   190  			Syntax:      acl.SyntaxCurrent,
   191  			RaftIndex:   structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
   192  		}, nil
   193  	case "node-wr":
   194  		return true, &structs.ACLPolicy{
   195  			ID:          "node-wr",
   196  			Name:        "node-wr",
   197  			Description: "node-wr",
   198  			Rules:       `node_prefix "" { policy = "write"}`,
   199  			Syntax:      acl.SyntaxCurrent,
   200  			Datacenters: []string{"dc1"},
   201  			RaftIndex:   structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
   202  		}, nil
   203  	case "dc2-key-wr":
   204  		return true, &structs.ACLPolicy{
   205  			ID:          "dc2-key-wr",
   206  			Name:        "dc2-key-wr",
   207  			Description: "dc2-key-wr",
   208  			Rules:       `key_prefix "" { policy = "write"}`,
   209  			Syntax:      acl.SyntaxCurrent,
   210  			Datacenters: []string{"dc2"},
   211  			RaftIndex:   structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
   212  		}, nil
   213  	default:
   214  		return true, nil, acl.ErrNotFound
   215  	}
   216  }
   217  
   218  // ACLResolverTestDelegate is used to test
   219  // the ACLResolver without running Agents
   220  type ACLResolverTestDelegate struct {
   221  	enabled         bool
   222  	datacenter      string
   223  	legacy          bool
   224  	localTokens     bool
   225  	localPolicies   bool
   226  	getPolicyFn     func(*structs.ACLPolicyResolveLegacyRequest, *structs.ACLPolicyResolveLegacyResponse) error
   227  	tokenReadFn     func(*structs.ACLTokenGetRequest, *structs.ACLTokenResponse) error
   228  	policyResolveFn func(*structs.ACLPolicyBatchGetRequest, *structs.ACLPolicyBatchResponse) error
   229  }
   230  
   231  func (d *ACLResolverTestDelegate) ACLsEnabled() bool {
   232  	return d.enabled
   233  }
   234  
   235  func (d *ACLResolverTestDelegate) ACLDatacenter(legacy bool) string {
   236  	return d.datacenter
   237  }
   238  
   239  func (d *ACLResolverTestDelegate) UseLegacyACLs() bool {
   240  	return d.legacy
   241  }
   242  
   243  func (d *ACLResolverTestDelegate) ResolveIdentityFromToken(token string) (bool, structs.ACLIdentity, error) {
   244  	if !d.localTokens {
   245  		return false, nil, nil
   246  	}
   247  
   248  	return testIdentityForToken(token)
   249  }
   250  
   251  func (d *ACLResolverTestDelegate) ResolvePolicyFromID(policyID string) (bool, *structs.ACLPolicy, error) {
   252  	if !d.localPolicies {
   253  		return false, nil, nil
   254  	}
   255  
   256  	return testPolicyForID(policyID)
   257  }
   258  
   259  func (d *ACLResolverTestDelegate) RPC(method string, args interface{}, reply interface{}) error {
   260  	switch method {
   261  	case "ACL.GetPolicy":
   262  		if d.getPolicyFn != nil {
   263  			return d.getPolicyFn(args.(*structs.ACLPolicyResolveLegacyRequest), reply.(*structs.ACLPolicyResolveLegacyResponse))
   264  		}
   265  		panic("Bad Test Implmentation: should provide a getPolicyFn to the ACLResolverTestDelegate")
   266  	case "ACL.TokenRead":
   267  		if d.tokenReadFn != nil {
   268  			return d.tokenReadFn(args.(*structs.ACLTokenGetRequest), reply.(*structs.ACLTokenResponse))
   269  		}
   270  		panic("Bad Test Implmentation: should provide a tokenReadFn to the ACLResolverTestDelegate")
   271  	case "ACL.PolicyResolve":
   272  		if d.policyResolveFn != nil {
   273  			return d.policyResolveFn(args.(*structs.ACLPolicyBatchGetRequest), reply.(*structs.ACLPolicyBatchResponse))
   274  		}
   275  		panic("Bad Test Implmentation: should provide a policyResolveFn to the ACLResolverTestDelegate")
   276  	}
   277  	panic("Bad Test Implementation: Was the ACLResolver updated to use new RPC methods")
   278  }
   279  
   280  func newTestACLResolver(t *testing.T, delegate ACLResolverDelegate, cb func(*ACLResolverConfig)) *ACLResolver {
   281  	config := DefaultConfig()
   282  	config.ACLDefaultPolicy = "deny"
   283  	config.ACLDownPolicy = "extend-cache"
   284  	rconf := &ACLResolverConfig{
   285  		Config: config,
   286  		Logger: log.New(os.Stdout, t.Name()+" - ", log.LstdFlags|log.Lmicroseconds),
   287  		CacheConfig: &structs.ACLCachesConfig{
   288  			Identities:     4,
   289  			Policies:       4,
   290  			ParsedPolicies: 4,
   291  			Authorizers:    4,
   292  		},
   293  		AutoDisable: true,
   294  		Delegate:    delegate,
   295  	}
   296  
   297  	if cb != nil {
   298  		cb(rconf)
   299  	}
   300  
   301  	resolver, err := NewACLResolver(rconf)
   302  	require.NoError(t, err)
   303  	return resolver
   304  }
   305  
   306  func TestACLResolver_Disabled(t *testing.T) {
   307  	t.Parallel()
   308  
   309  	delegate := &ACLResolverTestDelegate{
   310  		enabled:    false,
   311  		datacenter: "dc1",
   312  		legacy:     false,
   313  	}
   314  
   315  	r := newTestACLResolver(t, delegate, nil)
   316  
   317  	authz, err := r.ResolveToken("does not exist")
   318  	require.Nil(t, authz)
   319  	require.Nil(t, err)
   320  }
   321  
   322  func TestACLResolver_ResolveRootACL(t *testing.T) {
   323  	t.Parallel()
   324  	delegate := &ACLResolverTestDelegate{
   325  		enabled:    true,
   326  		datacenter: "dc1",
   327  		legacy:     false,
   328  	}
   329  	r := newTestACLResolver(t, delegate, nil)
   330  
   331  	t.Run("Allow", func(t *testing.T) {
   332  		authz, err := r.ResolveToken("allow")
   333  		require.Nil(t, authz)
   334  		require.Error(t, err)
   335  		require.True(t, acl.IsErrRootDenied(err))
   336  	})
   337  
   338  	t.Run("Deny", func(t *testing.T) {
   339  		authz, err := r.ResolveToken("deny")
   340  		require.Nil(t, authz)
   341  		require.Error(t, err)
   342  		require.True(t, acl.IsErrRootDenied(err))
   343  	})
   344  
   345  	t.Run("Manage", func(t *testing.T) {
   346  		authz, err := r.ResolveToken("manage")
   347  		require.Nil(t, authz)
   348  		require.Error(t, err)
   349  		require.True(t, acl.IsErrRootDenied(err))
   350  	})
   351  }
   352  
   353  func TestACLResolver_DownPolicy(t *testing.T) {
   354  	t.Parallel()
   355  
   356  	t.Run("Deny", func(t *testing.T) {
   357  		t.Parallel()
   358  		delegate := &ACLResolverTestDelegate{
   359  			enabled:       true,
   360  			datacenter:    "dc1",
   361  			legacy:        false,
   362  			localTokens:   false,
   363  			localPolicies: true,
   364  			tokenReadFn: func(*structs.ACLTokenGetRequest, *structs.ACLTokenResponse) error {
   365  				return fmt.Errorf("Induced RPC Error")
   366  			},
   367  		}
   368  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   369  			config.Config.ACLDownPolicy = "deny"
   370  		})
   371  
   372  		authz, err := r.ResolveToken("foo")
   373  		require.NoError(t, err)
   374  		require.NotNil(t, authz)
   375  		require.Equal(t, authz, acl.DenyAll())
   376  	})
   377  
   378  	t.Run("Allow", func(t *testing.T) {
   379  		t.Parallel()
   380  		delegate := &ACLResolverTestDelegate{
   381  			enabled:       true,
   382  			datacenter:    "dc1",
   383  			legacy:        false,
   384  			localTokens:   false,
   385  			localPolicies: true,
   386  			tokenReadFn: func(*structs.ACLTokenGetRequest, *structs.ACLTokenResponse) error {
   387  				return fmt.Errorf("Induced RPC Error")
   388  			},
   389  		}
   390  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   391  			config.Config.ACLDownPolicy = "allow"
   392  		})
   393  
   394  		authz, err := r.ResolveToken("foo")
   395  		require.NoError(t, err)
   396  		require.NotNil(t, authz)
   397  		require.Equal(t, authz, acl.AllowAll())
   398  	})
   399  
   400  	t.Run("Expired-Policy", func(t *testing.T) {
   401  		t.Parallel()
   402  		policyCached := false
   403  		delegate := &ACLResolverTestDelegate{
   404  			enabled:       true,
   405  			datacenter:    "dc1",
   406  			legacy:        false,
   407  			localTokens:   true,
   408  			localPolicies: false,
   409  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
   410  				if !policyCached {
   411  					for _, policyID := range args.PolicyIDs {
   412  						_, policy, _ := testPolicyForID(policyID)
   413  						if policy != nil {
   414  							reply.Policies = append(reply.Policies, policy)
   415  						}
   416  					}
   417  
   418  					policyCached = true
   419  					return nil
   420  				}
   421  
   422  				return fmt.Errorf("Induced RPC Error")
   423  			},
   424  		}
   425  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   426  			config.Config.ACLDownPolicy = "deny"
   427  			config.Config.ACLPolicyTTL = 0
   428  		})
   429  
   430  		authz, err := r.ResolveToken("found")
   431  		require.NoError(t, err)
   432  		require.NotNil(t, authz)
   433  		require.True(t, authz.NodeWrite("foo", nil))
   434  
   435  		// policy cache expired - so we will fail to resolve that policy and use the default policy only
   436  		authz2, err := r.ResolveToken("found")
   437  		require.NoError(t, err)
   438  		require.NotNil(t, authz2)
   439  		require.False(t, authz == authz2)
   440  		require.False(t, authz2.NodeWrite("foo", nil))
   441  	})
   442  
   443  	t.Run("Extend-Cache", func(t *testing.T) {
   444  		t.Parallel()
   445  		cached := false
   446  		delegate := &ACLResolverTestDelegate{
   447  			enabled:       true,
   448  			datacenter:    "dc1",
   449  			legacy:        false,
   450  			localTokens:   false,
   451  			localPolicies: true,
   452  			tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
   453  				if !cached {
   454  					_, token, _ := testIdentityForToken("found")
   455  					reply.Token = token.(*structs.ACLToken)
   456  					cached = true
   457  					return nil
   458  				}
   459  				return fmt.Errorf("Induced RPC Error")
   460  			},
   461  		}
   462  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   463  			config.Config.ACLDownPolicy = "extend-cache"
   464  			config.Config.ACLTokenTTL = 0
   465  		})
   466  
   467  		authz, err := r.ResolveToken("foo")
   468  		require.NoError(t, err)
   469  		require.NotNil(t, authz)
   470  		require.True(t, authz.NodeWrite("foo", nil))
   471  
   472  		authz2, err := r.ResolveToken("foo")
   473  		require.NoError(t, err)
   474  		require.NotNil(t, authz2)
   475  		// testing pointer equality - these will be the same object because it is cached.
   476  		require.True(t, authz == authz2)
   477  		require.True(t, authz.NodeWrite("foo", nil))
   478  	})
   479  
   480  	t.Run("Extend-Cache-Expired-Policy", func(t *testing.T) {
   481  		t.Parallel()
   482  		policyCached := false
   483  		delegate := &ACLResolverTestDelegate{
   484  			enabled:       true,
   485  			datacenter:    "dc1",
   486  			legacy:        false,
   487  			localTokens:   true,
   488  			localPolicies: false,
   489  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
   490  				if !policyCached {
   491  					for _, policyID := range args.PolicyIDs {
   492  						_, policy, _ := testPolicyForID(policyID)
   493  						if policy != nil {
   494  							reply.Policies = append(reply.Policies, policy)
   495  						}
   496  					}
   497  
   498  					policyCached = true
   499  					return nil
   500  				}
   501  
   502  				return fmt.Errorf("Induced RPC Error")
   503  			},
   504  		}
   505  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   506  			config.Config.ACLDownPolicy = "extend-cache"
   507  			config.Config.ACLPolicyTTL = 0
   508  		})
   509  
   510  		authz, err := r.ResolveToken("found")
   511  		require.NoError(t, err)
   512  		require.NotNil(t, authz)
   513  		require.True(t, authz.NodeWrite("foo", nil))
   514  
   515  		// Will just use the policy cache
   516  		authz2, err := r.ResolveToken("found")
   517  		require.NoError(t, err)
   518  		require.NotNil(t, authz2)
   519  		require.True(t, authz == authz2)
   520  		require.True(t, authz.NodeWrite("foo", nil))
   521  	})
   522  
   523  	t.Run("Async-Cache-Expired-Policy", func(t *testing.T) {
   524  		t.Parallel()
   525  		policyCached := false
   526  		delegate := &ACLResolverTestDelegate{
   527  			enabled:       true,
   528  			datacenter:    "dc1",
   529  			legacy:        false,
   530  			localTokens:   true,
   531  			localPolicies: false,
   532  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
   533  				if !policyCached {
   534  					for _, policyID := range args.PolicyIDs {
   535  						_, policy, _ := testPolicyForID(policyID)
   536  						if policy != nil {
   537  							reply.Policies = append(reply.Policies, policy)
   538  						}
   539  					}
   540  
   541  					policyCached = true
   542  					return nil
   543  				}
   544  
   545  				// We don't need to return acl.ErrNotFound here but we could. The ACLResolver will search for any
   546  				// policies not in the response and emit an ACL not found for any not-found within the result set.
   547  				return nil
   548  			},
   549  		}
   550  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   551  			config.Config.ACLDownPolicy = "async-cache"
   552  			config.Config.ACLPolicyTTL = 0
   553  		})
   554  
   555  		authz, err := r.ResolveToken("found")
   556  		require.NoError(t, err)
   557  		require.NotNil(t, authz)
   558  		require.True(t, authz.NodeWrite("foo", nil))
   559  
   560  		// The identity should have been cached so this should still be valid
   561  		authz2, err := r.ResolveToken("found")
   562  		require.NoError(t, err)
   563  		require.NotNil(t, authz2)
   564  		// testing pointer equality - these will be the same object because it is cached.
   565  		require.True(t, authz == authz2)
   566  		require.True(t, authz.NodeWrite("foo", nil))
   567  
   568  		// the go routine spawned will eventually return with a authz that doesn't have the policy
   569  		retry.Run(t, func(t *retry.R) {
   570  			authz3, err := r.ResolveToken("found")
   571  			assert.NoError(t, err)
   572  			assert.NotNil(t, authz3)
   573  			assert.False(t, authz3.NodeWrite("foo", nil))
   574  		})
   575  	})
   576  
   577  	t.Run("Extend-Cache-Client", func(t *testing.T) {
   578  		t.Parallel()
   579  		tokenCached := false
   580  		policyCached := false
   581  		delegate := &ACLResolverTestDelegate{
   582  			enabled:       true,
   583  			datacenter:    "dc1",
   584  			legacy:        false,
   585  			localTokens:   false,
   586  			localPolicies: false,
   587  			tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
   588  				if !tokenCached {
   589  					_, token, _ := testIdentityForToken("found")
   590  					reply.Token = token.(*structs.ACLToken)
   591  					tokenCached = true
   592  					return nil
   593  				}
   594  				return fmt.Errorf("Induced RPC Error")
   595  			},
   596  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
   597  				if !policyCached {
   598  					for _, policyID := range args.PolicyIDs {
   599  						_, policy, _ := testPolicyForID(policyID)
   600  						if policy != nil {
   601  							reply.Policies = append(reply.Policies, policy)
   602  						}
   603  					}
   604  
   605  					policyCached = true
   606  					return nil
   607  				}
   608  
   609  				return fmt.Errorf("Induced RPC Error")
   610  			},
   611  		}
   612  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   613  			config.Config.ACLDownPolicy = "extend-cache"
   614  			config.Config.ACLTokenTTL = 0
   615  			config.Config.ACLPolicyTTL = 0
   616  		})
   617  
   618  		authz, err := r.ResolveToken("found")
   619  		require.NoError(t, err)
   620  		require.NotNil(t, authz)
   621  		require.True(t, authz.NodeWrite("foo", nil))
   622  
   623  		authz2, err := r.ResolveToken("found")
   624  		require.NoError(t, err)
   625  		require.NotNil(t, authz2)
   626  		// testing pointer equality - these will be the same object because it is cached.
   627  		require.True(t, authz == authz2)
   628  		require.True(t, authz.NodeWrite("foo", nil))
   629  	})
   630  
   631  	t.Run("Async-Cache", func(t *testing.T) {
   632  		t.Parallel()
   633  		cached := false
   634  		delegate := &ACLResolverTestDelegate{
   635  			enabled:       true,
   636  			datacenter:    "dc1",
   637  			legacy:        false,
   638  			localTokens:   false,
   639  			localPolicies: true,
   640  			tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
   641  				if !cached {
   642  					_, token, _ := testIdentityForToken("found")
   643  					reply.Token = token.(*structs.ACLToken)
   644  					cached = true
   645  					return nil
   646  				}
   647  				return acl.ErrNotFound
   648  			},
   649  		}
   650  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   651  			config.Config.ACLDownPolicy = "async-cache"
   652  			config.Config.ACLTokenTTL = 0
   653  		})
   654  
   655  		authz, err := r.ResolveToken("foo")
   656  		require.NoError(t, err)
   657  		require.NotNil(t, authz)
   658  		require.True(t, authz.NodeWrite("foo", nil))
   659  
   660  		// The identity should have been cached so this should still be valid
   661  		authz2, err := r.ResolveToken("foo")
   662  		require.NoError(t, err)
   663  		require.NotNil(t, authz2)
   664  		// testing pointer equality - these will be the same object because it is cached.
   665  		require.True(t, authz == authz2)
   666  		require.True(t, authz.NodeWrite("foo", nil))
   667  
   668  		// the go routine spawned will eventually return and this will be a not found error
   669  		retry.Run(t, func(t *retry.R) {
   670  			authz3, err := r.ResolveToken("foo")
   671  			assert.Error(t, err)
   672  			assert.True(t, acl.IsErrNotFound(err))
   673  			assert.Nil(t, authz3)
   674  		})
   675  	})
   676  }
   677  
   678  func TestACLResolver_DatacenterScoping(t *testing.T) {
   679  	t.Parallel()
   680  	t.Run("dc1", func(t *testing.T) {
   681  		delegate := &ACLResolverTestDelegate{
   682  			enabled:       true,
   683  			datacenter:    "dc1",
   684  			legacy:        false,
   685  			localTokens:   true,
   686  			localPolicies: true,
   687  			// No need to provide any of the RPC callbacks
   688  		}
   689  		r := newTestACLResolver(t, delegate, nil)
   690  
   691  		authz, err := r.ResolveToken("found")
   692  		require.NotNil(t, authz)
   693  		require.NoError(t, err)
   694  		require.False(t, authz.ACLRead())
   695  		require.True(t, authz.NodeWrite("foo", nil))
   696  		require.False(t, authz.KeyWrite("foo", nil))
   697  	})
   698  
   699  	t.Run("dc2", func(t *testing.T) {
   700  		delegate := &ACLResolverTestDelegate{
   701  			enabled:       true,
   702  			datacenter:    "dc2",
   703  			legacy:        false,
   704  			localTokens:   true,
   705  			localPolicies: true,
   706  			// No need to provide any of the RPC callbacks
   707  		}
   708  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   709  			config.Config.Datacenter = "dc2"
   710  		})
   711  
   712  		authz, err := r.ResolveToken("found")
   713  		require.NotNil(t, authz)
   714  		require.NoError(t, err)
   715  		require.False(t, authz.ACLRead())
   716  		require.False(t, authz.NodeWrite("foo", nil))
   717  		require.True(t, authz.KeyWrite("foo", nil))
   718  	})
   719  }
   720  
   721  func TestACLResolver_Client(t *testing.T) {
   722  	t.Parallel()
   723  
   724  	t.Run("Racey-Token-Mod-Policy-Resolve", func(t *testing.T) {
   725  		t.Parallel()
   726  		var tokenReads int32
   727  		var policyResolves int32
   728  		modified := false
   729  		deleted := false
   730  		delegate := &ACLResolverTestDelegate{
   731  			enabled:       true,
   732  			datacenter:    "dc1",
   733  			legacy:        false,
   734  			localTokens:   false,
   735  			localPolicies: false,
   736  			tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
   737  				atomic.AddInt32(&tokenReads, 1)
   738  				if deleted {
   739  					return acl.ErrNotFound
   740  				} else if modified {
   741  					_, token, _ := testIdentityForToken("racey-modified")
   742  					reply.Token = token.(*structs.ACLToken)
   743  				} else {
   744  					_, token, _ := testIdentityForToken("racey-unmodified")
   745  					reply.Token = token.(*structs.ACLToken)
   746  				}
   747  				return nil
   748  			},
   749  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
   750  				atomic.AddInt32(&policyResolves, 1)
   751  				if deleted {
   752  					return acl.ErrNotFound
   753  				} else if !modified {
   754  					modified = true
   755  					return acl.ErrPermissionDenied
   756  				} else {
   757  					deleted = true
   758  					for _, policyID := range args.PolicyIDs {
   759  						_, policy, _ := testPolicyForID(policyID)
   760  						if policy != nil {
   761  							reply.Policies = append(reply.Policies, policy)
   762  						}
   763  					}
   764  
   765  					modified = true
   766  					return nil
   767  				}
   768  			},
   769  		}
   770  
   771  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   772  			config.Config.ACLTokenTTL = 600 * time.Second
   773  			config.Config.ACLPolicyTTL = 30 * time.Millisecond
   774  			config.Config.ACLDownPolicy = "extend-cache"
   775  		})
   776  
   777  		// resolves the token
   778  		// gets a permission denied resolving the policies - token updated
   779  		// invalidates the token
   780  		// refetches the token
   781  		// fetches the policies from the modified token
   782  		// creates the authorizers
   783  		//
   784  		// Must use the token secret here in order for the cached identity
   785  		// to be removed properly. Many other tests just resolve some other
   786  		// random name and it wont matter but this one cannot.
   787  		authz, err := r.ResolveToken("a1a54629-5050-4d17-8a4e-560d2423f835")
   788  		require.NoError(t, err)
   789  		require.NotNil(t, authz)
   790  		require.True(t, authz.NodeWrite("foo", nil))
   791  		require.False(t, authz.ACLRead())
   792  		require.True(t, modified)
   793  		require.True(t, deleted)
   794  		require.Equal(t, int32(2), tokenReads)
   795  		require.Equal(t, int32(2), policyResolves)
   796  
   797  		// sleep long enough for the policy cache to expire
   798  		time.Sleep(50 * time.Millisecond)
   799  
   800  		// this round the identity will be resolved from the cache
   801  		// then the policy will be resolved but resolution will return ACL not found
   802  		// resolution will stop with the not found error (even though we still have the
   803  		// policies within the cache)
   804  		authz, err = r.ResolveToken("a1a54629-5050-4d17-8a4e-560d2423f835")
   805  		require.EqualError(t, err, acl.ErrNotFound.Error())
   806  		require.Nil(t, authz)
   807  
   808  		require.True(t, modified)
   809  		require.True(t, deleted)
   810  		require.Equal(t, tokenReads, int32(2))
   811  		require.Equal(t, policyResolves, int32(3))
   812  	})
   813  
   814  	t.Run("Concurrent-Token-Resolve", func(t *testing.T) {
   815  		t.Parallel()
   816  
   817  		var tokenReads int32
   818  		var policyResolves int32
   819  		readyCh := make(chan struct{})
   820  
   821  		delegate := &ACLResolverTestDelegate{
   822  			enabled:       true,
   823  			datacenter:    "dc1",
   824  			legacy:        false,
   825  			localTokens:   false,
   826  			localPolicies: false,
   827  			tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
   828  				atomic.AddInt32(&tokenReads, 1)
   829  
   830  				switch args.TokenID {
   831  				case "a1a54629-5050-4d17-8a4e-560d2423f835":
   832  					_, token, _ := testIdentityForToken("concurrent-resolve-1")
   833  					reply.Token = token.(*structs.ACLToken)
   834  				default:
   835  					return acl.ErrNotFound
   836  				}
   837  
   838  				select {
   839  				case <-readyCh:
   840  				}
   841  				time.Sleep(100 * time.Millisecond)
   842  				return nil
   843  			},
   844  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
   845  				atomic.AddInt32(&policyResolves, 1)
   846  				for _, policyID := range args.PolicyIDs {
   847  					_, policy, _ := testPolicyForID(policyID)
   848  					if policy != nil {
   849  						reply.Policies = append(reply.Policies, policy)
   850  					}
   851  				}
   852  				return nil
   853  			},
   854  		}
   855  
   856  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   857  			// effectively disable caching - so the only way we end up with 1 token read is if they were
   858  			// being resolved concurrently
   859  			config.Config.ACLTokenTTL = 0 * time.Second
   860  			config.Config.ACLPolicyTTL = 30 * time.Millisecond
   861  			config.Config.ACLDownPolicy = "extend-cache"
   862  		})
   863  
   864  		ch1 := make(chan *asyncResolutionResult)
   865  		ch2 := make(chan *asyncResolutionResult)
   866  		go resolveTokenAsync(r, "a1a54629-5050-4d17-8a4e-560d2423f835", ch1)
   867  		go resolveTokenAsync(r, "a1a54629-5050-4d17-8a4e-560d2423f835", ch2)
   868  		close(readyCh)
   869  
   870  		res1 := <-ch1
   871  		res2 := <-ch2
   872  		require.NoError(t, res1.err)
   873  		require.NoError(t, res2.err)
   874  		require.Equal(t, res1.authz, res2.authz)
   875  		require.Equal(t, int32(1), tokenReads)
   876  		require.Equal(t, int32(1), policyResolves)
   877  	})
   878  
   879  	t.Run("Concurrent-Policy-Resolve", func(t *testing.T) {
   880  		t.Parallel()
   881  
   882  		var tokenReads int32
   883  		var policyResolves int32
   884  		delegate := &ACLResolverTestDelegate{
   885  			enabled:       true,
   886  			datacenter:    "dc1",
   887  			legacy:        false,
   888  			localTokens:   false,
   889  			localPolicies: false,
   890  			tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
   891  				atomic.AddInt32(&tokenReads, 1)
   892  
   893  				switch args.TokenID {
   894  				case "a1a54629-5050-4d17-8a4e-560d2423f835":
   895  					_, token, _ := testIdentityForToken("concurrent-resolve-1")
   896  					reply.Token = token.(*structs.ACLToken)
   897  				case "cc58f0f3-2273-42a7-8b4a-2bef9d2863d7":
   898  					_, token, _ := testIdentityForToken("concurrent-resolve-2")
   899  					reply.Token = token.(*structs.ACLToken)
   900  				default:
   901  					return acl.ErrNotFound
   902  				}
   903  
   904  				return nil
   905  			},
   906  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
   907  				atomic.AddInt32(&policyResolves, 1)
   908  				// waits until both tokens have been read for up to 1 second
   909  				for i := 0; i < 100; i++ {
   910  					time.Sleep(10 * time.Millisecond)
   911  					reads := atomic.LoadInt32(&tokenReads)
   912  					if reads >= 2 {
   913  						time.Sleep(100 * time.Millisecond)
   914  						break
   915  					}
   916  				}
   917  
   918  				for _, policyID := range args.PolicyIDs {
   919  					_, policy, _ := testPolicyForID(policyID)
   920  					if policy != nil {
   921  						reply.Policies = append(reply.Policies, policy)
   922  					}
   923  				}
   924  				return nil
   925  			},
   926  		}
   927  
   928  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
   929  			config.Config.ACLTokenTTL = 600 * time.Second
   930  			// effectively disables the cache - therefore the only way we end up
   931  			// with 1 policy resolution is if they get single flighted
   932  			config.Config.ACLPolicyTTL = 0 * time.Millisecond
   933  			config.Config.ACLDownPolicy = "extend-cache"
   934  		})
   935  
   936  		ch1 := make(chan *asyncResolutionResult)
   937  		ch2 := make(chan *asyncResolutionResult)
   938  
   939  		go resolveTokenAsync(r, "a1a54629-5050-4d17-8a4e-560d2423f835", ch1)
   940  		go resolveTokenAsync(r, "cc58f0f3-2273-42a7-8b4a-2bef9d2863d7", ch2)
   941  
   942  		res1 := <-ch1
   943  		res2 := <-ch2
   944  
   945  		require.NoError(t, res1.err)
   946  		require.NoError(t, res2.err)
   947  		require.Equal(t, res1.authz, res2.authz)
   948  		require.Equal(t, int32(2), tokenReads)
   949  		require.Equal(t, int32(1), policyResolves)
   950  	})
   951  
   952  	t.Run("Concurrent-Policy-Resolve-Permission-Denied", func(t *testing.T) {
   953  		t.Parallel()
   954  
   955  		var waitReady int32 = 1
   956  		var tokenReads int32
   957  		var policyResolves int32
   958  		delegate := &ACLResolverTestDelegate{
   959  			enabled:       true,
   960  			datacenter:    "dc1",
   961  			legacy:        false,
   962  			localTokens:   false,
   963  			localPolicies: false,
   964  			tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
   965  				atomic.AddInt32(&tokenReads, 1)
   966  
   967  				switch args.TokenID {
   968  				case "a1a54629-5050-4d17-8a4e-560d2423f835":
   969  					_, token, _ := testIdentityForToken("concurrent-resolve-1")
   970  					reply.Token = token.(*structs.ACLToken)
   971  				case "cc58f0f3-2273-42a7-8b4a-2bef9d2863d7":
   972  					_, token, _ := testIdentityForToken("concurrent-resolve-2")
   973  					reply.Token = token.(*structs.ACLToken)
   974  				default:
   975  					return acl.ErrNotFound
   976  				}
   977  
   978  				return nil
   979  			},
   980  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
   981  				atomic.AddInt32(&policyResolves, 1)
   982  
   983  				if atomic.CompareAndSwapInt32(&waitReady, 1, 0) {
   984  					// waits until both tokens have been read for up to 1 second
   985  					for i := 0; i < 100; i++ {
   986  						time.Sleep(10 * time.Millisecond)
   987  						reads := atomic.LoadInt32(&tokenReads)
   988  						if reads >= 2 {
   989  							time.Sleep(100 * time.Millisecond)
   990  							break
   991  						}
   992  					}
   993  
   994  					return acl.ErrPermissionDenied
   995  				}
   996  
   997  				for _, policyID := range args.PolicyIDs {
   998  					_, policy, _ := testPolicyForID(policyID)
   999  					if policy != nil {
  1000  						reply.Policies = append(reply.Policies, policy)
  1001  					}
  1002  				}
  1003  				return nil
  1004  			},
  1005  		}
  1006  
  1007  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
  1008  			config.Config.ACLTokenTTL = 600 * time.Second
  1009  			config.Config.ACLPolicyTTL = 600 * time.Second
  1010  			config.Config.ACLDownPolicy = "extend-cache"
  1011  		})
  1012  
  1013  		ch1 := make(chan *asyncResolutionResult)
  1014  		ch2 := make(chan *asyncResolutionResult)
  1015  
  1016  		go resolveTokenAsync(r, "a1a54629-5050-4d17-8a4e-560d2423f835", ch1)
  1017  		go resolveTokenAsync(r, "cc58f0f3-2273-42a7-8b4a-2bef9d2863d7", ch2)
  1018  
  1019  		res1 := <-ch1
  1020  		res2 := <-ch2
  1021  
  1022  		require.NoError(t, res1.err)
  1023  		require.NoError(t, res2.err)
  1024  		require.Equal(t, res1.authz, res2.authz)
  1025  		// 2 reads for 1 token (cache gets invalidated and only 1 for the other)
  1026  		require.Equal(t, int32(3), tokenReads)
  1027  		require.Equal(t, int32(2), policyResolves)
  1028  		require.True(t, res1.authz.ACLRead())
  1029  		require.True(t, res1.authz.NodeWrite("foo", nil))
  1030  	})
  1031  
  1032  	t.Run("Concurrent-Policy-Resolve-Not-Found", func(t *testing.T) {
  1033  		t.Parallel()
  1034  
  1035  		var waitReady int32 = 1
  1036  		var tokenReads int32
  1037  		var policyResolves int32
  1038  		var tokenNotAllowed string
  1039  		delegate := &ACLResolverTestDelegate{
  1040  			enabled:       true,
  1041  			datacenter:    "dc1",
  1042  			legacy:        false,
  1043  			localTokens:   false,
  1044  			localPolicies: false,
  1045  			tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
  1046  				atomic.AddInt32(&tokenReads, 1)
  1047  
  1048  				switch args.TokenID {
  1049  				case "a1a54629-5050-4d17-8a4e-560d2423f835":
  1050  					_, token, _ := testIdentityForToken("concurrent-resolve-1")
  1051  					reply.Token = token.(*structs.ACLToken)
  1052  				case "cc58f0f3-2273-42a7-8b4a-2bef9d2863d7":
  1053  					_, token, _ := testIdentityForToken("concurrent-resolve-2")
  1054  					reply.Token = token.(*structs.ACLToken)
  1055  				default:
  1056  					return acl.ErrNotFound
  1057  				}
  1058  
  1059  				return nil
  1060  			},
  1061  			policyResolveFn: func(args *structs.ACLPolicyBatchGetRequest, reply *structs.ACLPolicyBatchResponse) error {
  1062  				atomic.AddInt32(&policyResolves, 1)
  1063  
  1064  				if atomic.CompareAndSwapInt32(&waitReady, 1, 0) {
  1065  					// waits until both tokens have been read for up to 1 second
  1066  					for i := 0; i < 100; i++ {
  1067  						time.Sleep(10 * time.Millisecond)
  1068  						reads := atomic.LoadInt32(&tokenReads)
  1069  						if reads >= 2 {
  1070  							time.Sleep(100 * time.Millisecond)
  1071  							break
  1072  						}
  1073  					}
  1074  
  1075  					tokenNotAllowed = args.Token
  1076  					return acl.ErrNotFound
  1077  				}
  1078  
  1079  				for _, policyID := range args.PolicyIDs {
  1080  					_, policy, _ := testPolicyForID(policyID)
  1081  					if policy != nil {
  1082  						reply.Policies = append(reply.Policies, policy)
  1083  					}
  1084  				}
  1085  				return nil
  1086  			},
  1087  		}
  1088  
  1089  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
  1090  			config.Config.ACLTokenTTL = 600 * time.Second
  1091  			config.Config.ACLPolicyTTL = 600 * time.Second
  1092  			config.Config.ACLDownPolicy = "extend-cache"
  1093  		})
  1094  
  1095  		ch1 := make(chan *asyncResolutionResult)
  1096  		ch2 := make(chan *asyncResolutionResult)
  1097  
  1098  		go resolveTokenAsync(r, "a1a54629-5050-4d17-8a4e-560d2423f835", ch1)
  1099  		go resolveTokenAsync(r, "cc58f0f3-2273-42a7-8b4a-2bef9d2863d7", ch2)
  1100  
  1101  		res1 := <-ch1
  1102  		res2 := <-ch2
  1103  
  1104  		var errResult *asyncResolutionResult
  1105  		var goodResult *asyncResolutionResult
  1106  
  1107  		// can't be sure which token resolution is going to be the one that does the first policy resolution
  1108  		// so we record it and then determine here how the results should be validated
  1109  		if tokenNotAllowed == "a1a54629-5050-4d17-8a4e-560d2423f835" {
  1110  			errResult = res1
  1111  			goodResult = res2
  1112  		} else {
  1113  			errResult = res2
  1114  			goodResult = res1
  1115  		}
  1116  
  1117  		require.Error(t, errResult.err)
  1118  		require.Nil(t, errResult.authz)
  1119  		require.EqualError(t, errResult.err, acl.ErrNotFound.Error())
  1120  		require.NoError(t, goodResult.err)
  1121  		require.Equal(t, int32(2), tokenReads)
  1122  		require.Equal(t, int32(2), policyResolves)
  1123  		require.NotNil(t, goodResult.authz)
  1124  		require.True(t, goodResult.authz.ACLRead())
  1125  		require.True(t, goodResult.authz.NodeWrite("foo", nil))
  1126  	})
  1127  }
  1128  
  1129  func TestACLResolver_LocalTokensAndPolicies(t *testing.T) {
  1130  	t.Parallel()
  1131  	delegate := &ACLResolverTestDelegate{
  1132  		enabled:       true,
  1133  		datacenter:    "dc1",
  1134  		legacy:        false,
  1135  		localTokens:   true,
  1136  		localPolicies: true,
  1137  		// No need to provide any of the RPC callbacks
  1138  	}
  1139  	r := newTestACLResolver(t, delegate, nil)
  1140  
  1141  	t.Run("Missing Identity", func(t *testing.T) {
  1142  		authz, err := r.ResolveToken("doesn't exist")
  1143  		require.Nil(t, authz)
  1144  		require.Error(t, err)
  1145  		require.True(t, acl.IsErrNotFound(err))
  1146  	})
  1147  
  1148  	t.Run("Missing Policy", func(t *testing.T) {
  1149  		authz, err := r.ResolveToken("missing-policy")
  1150  		require.NoError(t, err)
  1151  		require.NotNil(t, authz)
  1152  		require.True(t, authz.ACLRead())
  1153  		require.False(t, authz.NodeWrite("foo", nil))
  1154  	})
  1155  
  1156  	t.Run("Normal", func(t *testing.T) {
  1157  		authz, err := r.ResolveToken("found")
  1158  		require.NotNil(t, authz)
  1159  		require.NoError(t, err)
  1160  		require.False(t, authz.ACLRead())
  1161  		require.True(t, authz.NodeWrite("foo", nil))
  1162  	})
  1163  
  1164  	t.Run("Anonymous", func(t *testing.T) {
  1165  		authz, err := r.ResolveToken("")
  1166  		require.NotNil(t, authz)
  1167  		require.NoError(t, err)
  1168  		require.False(t, authz.ACLRead())
  1169  		require.True(t, authz.NodeWrite("foo", nil))
  1170  	})
  1171  
  1172  	t.Run("legacy-management", func(t *testing.T) {
  1173  		authz, err := r.ResolveToken("legacy-management")
  1174  		require.NotNil(t, authz)
  1175  		require.NoError(t, err)
  1176  		require.True(t, authz.ACLWrite())
  1177  		require.True(t, authz.KeyRead("foo"))
  1178  	})
  1179  
  1180  	t.Run("legacy-client", func(t *testing.T) {
  1181  		authz, err := r.ResolveToken("legacy-client")
  1182  		require.NoError(t, err)
  1183  		require.NotNil(t, authz)
  1184  		require.False(t, authz.OperatorRead())
  1185  		require.True(t, authz.ServiceRead("foo"))
  1186  	})
  1187  }
  1188  
  1189  func TestACLResolver_LocalPolicies(t *testing.T) {
  1190  	t.Parallel()
  1191  	delegate := &ACLResolverTestDelegate{
  1192  		enabled:       true,
  1193  		datacenter:    "dc1",
  1194  		legacy:        false,
  1195  		localTokens:   false,
  1196  		localPolicies: true,
  1197  		tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
  1198  			_, token, err := testIdentityForToken(args.TokenID)
  1199  
  1200  			if token != nil {
  1201  				reply.Token = token.(*structs.ACLToken)
  1202  			}
  1203  			return err
  1204  		},
  1205  	}
  1206  	r := newTestACLResolver(t, delegate, nil)
  1207  
  1208  	t.Run("Missing Identity", func(t *testing.T) {
  1209  		authz, err := r.ResolveToken("doesn't exist")
  1210  		require.Nil(t, authz)
  1211  		require.Error(t, err)
  1212  		require.True(t, acl.IsErrNotFound(err))
  1213  	})
  1214  
  1215  	t.Run("Missing Policy", func(t *testing.T) {
  1216  		authz, err := r.ResolveToken("missing-policy")
  1217  		require.NoError(t, err)
  1218  		require.NotNil(t, authz)
  1219  		require.True(t, authz.ACLRead())
  1220  		require.False(t, authz.NodeWrite("foo", nil))
  1221  	})
  1222  
  1223  	t.Run("Normal", func(t *testing.T) {
  1224  		authz, err := r.ResolveToken("found")
  1225  		require.NotNil(t, authz)
  1226  		require.NoError(t, err)
  1227  		require.False(t, authz.ACLRead())
  1228  		require.True(t, authz.NodeWrite("foo", nil))
  1229  	})
  1230  
  1231  	t.Run("Anonymous", func(t *testing.T) {
  1232  		authz, err := r.ResolveToken("")
  1233  		require.NotNil(t, authz)
  1234  		require.NoError(t, err)
  1235  		require.False(t, authz.ACLRead())
  1236  		require.True(t, authz.NodeWrite("foo", nil))
  1237  	})
  1238  
  1239  	t.Run("legacy-management", func(t *testing.T) {
  1240  		authz, err := r.ResolveToken("legacy-management")
  1241  		require.NotNil(t, authz)
  1242  		require.NoError(t, err)
  1243  		require.True(t, authz.ACLWrite())
  1244  		require.True(t, authz.KeyRead("foo"))
  1245  	})
  1246  
  1247  	t.Run("legacy-client", func(t *testing.T) {
  1248  		authz, err := r.ResolveToken("legacy-client")
  1249  		require.NoError(t, err)
  1250  		require.NotNil(t, authz)
  1251  		require.False(t, authz.OperatorRead())
  1252  		require.True(t, authz.ServiceRead("foo"))
  1253  	})
  1254  }
  1255  
  1256  func TestACLResolver_Legacy(t *testing.T) {
  1257  	t.Parallel()
  1258  
  1259  	t.Run("Cached", func(t *testing.T) {
  1260  		t.Parallel()
  1261  		cached := false
  1262  		delegate := &ACLResolverTestDelegate{
  1263  			enabled:       true,
  1264  			datacenter:    "dc1",
  1265  			legacy:        true,
  1266  			localTokens:   false,
  1267  			localPolicies: false,
  1268  			getPolicyFn: func(args *structs.ACLPolicyResolveLegacyRequest, reply *structs.ACLPolicyResolveLegacyResponse) error {
  1269  				if !cached {
  1270  					reply.Parent = "deny"
  1271  					reply.TTL = 30
  1272  					reply.ETag = "nothing"
  1273  					reply.Policy = &acl.Policy{
  1274  						ID: "not-needed",
  1275  						Nodes: []*acl.NodePolicy{
  1276  							&acl.NodePolicy{
  1277  								Name:   "foo",
  1278  								Policy: acl.PolicyWrite,
  1279  							},
  1280  						},
  1281  					}
  1282  					cached = true
  1283  					return nil
  1284  				}
  1285  				return fmt.Errorf("Induced RPC Error")
  1286  			},
  1287  		}
  1288  		r := newTestACLResolver(t, delegate, nil)
  1289  
  1290  		authz, err := r.ResolveToken("foo")
  1291  		require.NoError(t, err)
  1292  		require.NotNil(t, authz)
  1293  		// there is a bit of translation that happens
  1294  		require.True(t, authz.NodeWrite("foo", nil))
  1295  		require.True(t, authz.NodeWrite("foo/bar", nil))
  1296  		require.False(t, authz.NodeWrite("fo", nil))
  1297  
  1298  		// this should be from the cache
  1299  		authz, err = r.ResolveToken("foo")
  1300  		require.NoError(t, err)
  1301  		require.NotNil(t, authz)
  1302  		// there is a bit of translation that happens
  1303  		require.True(t, authz.NodeWrite("foo", nil))
  1304  		require.True(t, authz.NodeWrite("foo/bar", nil))
  1305  		require.False(t, authz.NodeWrite("fo", nil))
  1306  	})
  1307  
  1308  	t.Run("Cache-Expiry-Extend", func(t *testing.T) {
  1309  		t.Parallel()
  1310  		cached := false
  1311  		delegate := &ACLResolverTestDelegate{
  1312  			enabled:       true,
  1313  			datacenter:    "dc1",
  1314  			legacy:        true,
  1315  			localTokens:   false,
  1316  			localPolicies: false,
  1317  			getPolicyFn: func(args *structs.ACLPolicyResolveLegacyRequest, reply *structs.ACLPolicyResolveLegacyResponse) error {
  1318  				if !cached {
  1319  					reply.Parent = "deny"
  1320  					reply.TTL = 0
  1321  					reply.ETag = "nothing"
  1322  					reply.Policy = &acl.Policy{
  1323  						ID: "not-needed",
  1324  						Nodes: []*acl.NodePolicy{
  1325  							&acl.NodePolicy{
  1326  								Name:   "foo",
  1327  								Policy: acl.PolicyWrite,
  1328  							},
  1329  						},
  1330  					}
  1331  					cached = true
  1332  					return nil
  1333  				}
  1334  				return fmt.Errorf("Induced RPC Error")
  1335  			},
  1336  		}
  1337  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
  1338  			config.Config.ACLTokenTTL = 0
  1339  		})
  1340  
  1341  		authz, err := r.ResolveToken("foo")
  1342  		require.NoError(t, err)
  1343  		require.NotNil(t, authz)
  1344  		// there is a bit of translation that happens
  1345  		require.True(t, authz.NodeWrite("foo", nil))
  1346  		require.True(t, authz.NodeWrite("foo/bar", nil))
  1347  		require.False(t, authz.NodeWrite("fo", nil))
  1348  
  1349  		// this should be from the cache
  1350  		authz, err = r.ResolveToken("foo")
  1351  		require.NoError(t, err)
  1352  		require.NotNil(t, authz)
  1353  		// there is a bit of translation that happens
  1354  		require.True(t, authz.NodeWrite("foo", nil))
  1355  		require.True(t, authz.NodeWrite("foo/bar", nil))
  1356  		require.False(t, authz.NodeWrite("fo", nil))
  1357  	})
  1358  
  1359  	t.Run("Cache-Expiry-Allow", func(t *testing.T) {
  1360  		t.Parallel()
  1361  		cached := false
  1362  		delegate := &ACLResolverTestDelegate{
  1363  			enabled:       true,
  1364  			datacenter:    "dc1",
  1365  			legacy:        true,
  1366  			localTokens:   false,
  1367  			localPolicies: false,
  1368  			getPolicyFn: func(args *structs.ACLPolicyResolveLegacyRequest, reply *structs.ACLPolicyResolveLegacyResponse) error {
  1369  				if !cached {
  1370  					reply.Parent = "deny"
  1371  					reply.TTL = 0
  1372  					reply.ETag = "nothing"
  1373  					reply.Policy = &acl.Policy{
  1374  						ID: "not-needed",
  1375  						Nodes: []*acl.NodePolicy{
  1376  							&acl.NodePolicy{
  1377  								Name:   "foo",
  1378  								Policy: acl.PolicyWrite,
  1379  							},
  1380  						},
  1381  					}
  1382  					cached = true
  1383  					return nil
  1384  				}
  1385  				return fmt.Errorf("Induced RPC Error")
  1386  			},
  1387  		}
  1388  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
  1389  			config.Config.ACLDownPolicy = "allow"
  1390  			config.Config.ACLTokenTTL = 0
  1391  		})
  1392  
  1393  		authz, err := r.ResolveToken("foo")
  1394  		require.NoError(t, err)
  1395  		require.NotNil(t, authz)
  1396  		// there is a bit of translation that happens
  1397  		require.True(t, authz.NodeWrite("foo", nil))
  1398  		require.True(t, authz.NodeWrite("foo/bar", nil))
  1399  		require.False(t, authz.NodeWrite("fo", nil))
  1400  
  1401  		// this should be from the cache
  1402  		authz, err = r.ResolveToken("foo")
  1403  		require.NoError(t, err)
  1404  		require.NotNil(t, authz)
  1405  		// there is a bit of translation that happens
  1406  		require.True(t, authz.NodeWrite("foo", nil))
  1407  		require.True(t, authz.NodeWrite("foo/bar", nil))
  1408  		require.True(t, authz.NodeWrite("fo", nil))
  1409  	})
  1410  
  1411  	t.Run("Cache-Expiry-Deny", func(t *testing.T) {
  1412  		t.Parallel()
  1413  		cached := false
  1414  		delegate := &ACLResolverTestDelegate{
  1415  			enabled:       true,
  1416  			datacenter:    "dc1",
  1417  			legacy:        true,
  1418  			localTokens:   false,
  1419  			localPolicies: false,
  1420  			getPolicyFn: func(args *structs.ACLPolicyResolveLegacyRequest, reply *structs.ACLPolicyResolveLegacyResponse) error {
  1421  				if !cached {
  1422  					reply.Parent = "deny"
  1423  					reply.TTL = 0
  1424  					reply.ETag = "nothing"
  1425  					reply.Policy = &acl.Policy{
  1426  						ID: "not-needed",
  1427  						Nodes: []*acl.NodePolicy{
  1428  							&acl.NodePolicy{
  1429  								Name:   "foo",
  1430  								Policy: acl.PolicyWrite,
  1431  							},
  1432  						},
  1433  					}
  1434  					cached = true
  1435  					return nil
  1436  				}
  1437  				return fmt.Errorf("Induced RPC Error")
  1438  			},
  1439  		}
  1440  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
  1441  			config.Config.ACLDownPolicy = "deny"
  1442  			config.Config.ACLTokenTTL = 0
  1443  		})
  1444  
  1445  		authz, err := r.ResolveToken("foo")
  1446  		require.NoError(t, err)
  1447  		require.NotNil(t, authz)
  1448  		// there is a bit of translation that happens
  1449  		require.True(t, authz.NodeWrite("foo", nil))
  1450  		require.True(t, authz.NodeWrite("foo/bar", nil))
  1451  		require.False(t, authz.NodeWrite("fo", nil))
  1452  
  1453  		// this should be from the cache
  1454  		authz, err = r.ResolveToken("foo")
  1455  		require.NoError(t, err)
  1456  		require.NotNil(t, authz)
  1457  		// there is a bit of translation that happens
  1458  		require.False(t, authz.NodeWrite("foo", nil))
  1459  		require.False(t, authz.NodeWrite("foo/bar", nil))
  1460  		require.False(t, authz.NodeWrite("fo", nil))
  1461  	})
  1462  
  1463  	t.Run("Cache-Expiry-Async-Cache", func(t *testing.T) {
  1464  		t.Parallel()
  1465  		cached := false
  1466  		delegate := &ACLResolverTestDelegate{
  1467  			enabled:       true,
  1468  			datacenter:    "dc1",
  1469  			legacy:        true,
  1470  			localTokens:   false,
  1471  			localPolicies: false,
  1472  			getPolicyFn: func(args *structs.ACLPolicyResolveLegacyRequest, reply *structs.ACLPolicyResolveLegacyResponse) error {
  1473  				if !cached {
  1474  					reply.Parent = "deny"
  1475  					reply.TTL = 0
  1476  					reply.ETag = "nothing"
  1477  					reply.Policy = &acl.Policy{
  1478  						ID: "not-needed",
  1479  						Nodes: []*acl.NodePolicy{
  1480  							&acl.NodePolicy{
  1481  								Name:   "foo",
  1482  								Policy: acl.PolicyWrite,
  1483  							},
  1484  						},
  1485  					}
  1486  					cached = true
  1487  					return nil
  1488  				}
  1489  				return acl.ErrNotFound
  1490  			},
  1491  		}
  1492  		r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
  1493  			config.Config.ACLDownPolicy = "async-cache"
  1494  			config.Config.ACLTokenTTL = 0
  1495  		})
  1496  
  1497  		authz, err := r.ResolveToken("foo")
  1498  		require.NoError(t, err)
  1499  		require.NotNil(t, authz)
  1500  		// there is a bit of translation that happens
  1501  		require.True(t, authz.NodeWrite("foo", nil))
  1502  		require.True(t, authz.NodeWrite("foo/bar", nil))
  1503  		require.False(t, authz.NodeWrite("fo", nil))
  1504  
  1505  		// delivered from the cache
  1506  		authz2, err := r.ResolveToken("foo")
  1507  		require.NoError(t, err)
  1508  		require.NotNil(t, authz)
  1509  		require.True(t, authz == authz2)
  1510  
  1511  		// the go routine spawned will eventually return and this will be a not found error
  1512  		retry.Run(t, func(t *retry.R) {
  1513  			authz3, err := r.ResolveToken("foo")
  1514  			assert.Error(t, err)
  1515  			assert.True(t, acl.IsErrNotFound(err))
  1516  			assert.Nil(t, authz3)
  1517  		})
  1518  	})
  1519  }
  1520  
  1521  /*
  1522  
  1523  func TestACL_Replication(t *testing.T) {
  1524  	t.Parallel()
  1525  	aclExtendPolicies := []string{"extend-cache", "async-cache"} //"async-cache"
  1526  
  1527  	for _, aclDownPolicy := range aclExtendPolicies {
  1528  		dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1529  			c.ACLDatacenter = "dc1"
  1530  			c.ACLMasterToken = "root"
  1531  		})
  1532  		defer os.RemoveAll(dir1)
  1533  		defer s1.Shutdown()
  1534  		client := rpcClient(t, s1)
  1535  		defer client.Close()
  1536  
  1537  		dir2, s2 := testServerWithConfig(t, func(c *Config) {
  1538  			c.Datacenter = "dc2"
  1539  			c.ACLDatacenter = "dc1"
  1540  			c.ACLDefaultPolicy = "deny"
  1541  			c.ACLDownPolicy = aclDownPolicy
  1542  			c.ACLTokenReplication = true
  1543  			c.ACLReplicationRate = 100
  1544  			c.ACLReplicationBurst = 100
  1545  			c.ACLReplicationApplyLimit = 1000000
  1546  		})
  1547  		s2.tokens.UpdateReplicationToken("root")
  1548  		defer os.RemoveAll(dir2)
  1549  		defer s2.Shutdown()
  1550  
  1551  		dir3, s3 := testServerWithConfig(t, func(c *Config) {
  1552  			c.Datacenter = "dc3"
  1553  			c.ACLDatacenter = "dc1"
  1554  			c.ACLDownPolicy = "deny"
  1555  			c.ACLTokenReplication = true
  1556  			c.ACLReplicationRate = 100
  1557  			c.ACLReplicationBurst = 100
  1558  			c.ACLReplicationApplyLimit = 1000000
  1559  		})
  1560  		s3.tokens.UpdateReplicationToken("root")
  1561  		defer os.RemoveAll(dir3)
  1562  		defer s3.Shutdown()
  1563  
  1564  		// Try to join.
  1565  		joinWAN(t, s2, s1)
  1566  		joinWAN(t, s3, s1)
  1567  		testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1568  		testrpc.WaitForLeader(t, s1.RPC, "dc2")
  1569  		testrpc.WaitForLeader(t, s1.RPC, "dc3")
  1570  
  1571  		// Create a new token.
  1572  		arg := structs.ACLRequest{
  1573  			Datacenter: "dc1",
  1574  			Op:         structs.ACLSet,
  1575  			ACL: structs.ACL{
  1576  				Name:  "User token",
  1577  				Type:  structs.ACLTokenTypeClient,
  1578  				Rules: testACLPolicy,
  1579  			},
  1580  			WriteRequest: structs.WriteRequest{Token: "root"},
  1581  		}
  1582  		var id string
  1583  		if err := s1.RPC("ACL.Apply", &arg, &id); err != nil {
  1584  			t.Fatalf("err: %v", err)
  1585  		}
  1586  		// Wait for replication to occur.
  1587  		retry.Run(t, func(r *retry.R) {
  1588  			_, acl, err := s2.fsm.State().ACLTokenGetBySecret(nil, id)
  1589  			if err != nil {
  1590  				r.Fatal(err)
  1591  			}
  1592  			if acl == nil {
  1593  				r.Fatal(nil)
  1594  			}
  1595  			_, acl, err = s3.fsm.State().ACLTokenGetBySecret(nil, id)
  1596  			if err != nil {
  1597  				r.Fatal(err)
  1598  			}
  1599  			if acl == nil {
  1600  				r.Fatal(nil)
  1601  			}
  1602  		})
  1603  
  1604  		// Kill the ACL datacenter.
  1605  		s1.Shutdown()
  1606  
  1607  		// Token should resolve on s2, which has replication + extend-cache.
  1608  		acl, err := s2.ResolveToken(id)
  1609  		if err != nil {
  1610  			t.Fatalf("err: %v", err)
  1611  		}
  1612  		if acl == nil {
  1613  			t.Fatalf("missing acl")
  1614  		}
  1615  
  1616  		// Check the policy
  1617  		if acl.KeyRead("bar") {
  1618  			t.Fatalf("unexpected read")
  1619  		}
  1620  		if !acl.KeyRead("foo/test") {
  1621  			t.Fatalf("unexpected failed read")
  1622  		}
  1623  
  1624  		// Although s3 has replication, and we verified that the ACL is there,
  1625  		// it can not be used because of the down policy.
  1626  		acl, err = s3.ResolveToken(id)
  1627  		if err != nil {
  1628  			t.Fatalf("err: %v", err)
  1629  		}
  1630  		if acl == nil {
  1631  			t.Fatalf("missing acl")
  1632  		}
  1633  
  1634  		// Check the policy.
  1635  		if acl.KeyRead("bar") {
  1636  			t.Fatalf("unexpected read")
  1637  		}
  1638  		if acl.KeyRead("foo/test") {
  1639  			t.Fatalf("unexpected read")
  1640  		}
  1641  	}
  1642  }
  1643  
  1644  func TestACL_MultiDC_Found(t *testing.T) {
  1645  	t.Parallel()
  1646  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1647  		c.ACLDatacenter = "dc1"
  1648  		c.ACLMasterToken = "root"
  1649  	})
  1650  	defer os.RemoveAll(dir1)
  1651  	defer s1.Shutdown()
  1652  	client := rpcClient(t, s1)
  1653  	defer client.Close()
  1654  
  1655  	dir2, s2 := testServerWithConfig(t, func(c *Config) {
  1656  		c.Datacenter = "dc2"
  1657  		c.ACLDatacenter = "dc1" // Enable ACLs!
  1658  	})
  1659  	defer os.RemoveAll(dir2)
  1660  	defer s2.Shutdown()
  1661  
  1662  	// Try to join
  1663  	joinWAN(t, s2, s1)
  1664  
  1665  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1666  	testrpc.WaitForLeader(t, s1.RPC, "dc2")
  1667  
  1668  	// Create a new token
  1669  	arg := structs.ACLRequest{
  1670  		Datacenter: "dc1",
  1671  		Op:         structs.ACLSet,
  1672  		ACL: structs.ACL{
  1673  			Name:  "User token",
  1674  			Type:  structs.ACLTokenTypeClient,
  1675  			Rules: testACLPolicy,
  1676  		},
  1677  		WriteRequest: structs.WriteRequest{Token: "root"},
  1678  	}
  1679  	var id string
  1680  	if err := s1.RPC("ACL.Apply", &arg, &id); err != nil {
  1681  		t.Fatalf("err: %v", err)
  1682  	}
  1683  
  1684  	// Token should resolve
  1685  	acl, err := s2.ResolveToken(id)
  1686  	if err != nil {
  1687  		t.Fatalf("err: %v", err)
  1688  	}
  1689  	if acl == nil {
  1690  		t.Fatalf("missing acl")
  1691  	}
  1692  
  1693  	// Check the policy
  1694  	if acl.KeyRead("bar") {
  1695  		t.Fatalf("unexpected read")
  1696  	}
  1697  	if !acl.KeyRead("foo/test") {
  1698  		t.Fatalf("unexpected failed read")
  1699  	}
  1700  }
  1701  */
  1702  
  1703  func TestACL_filterHealthChecks(t *testing.T) {
  1704  	t.Parallel()
  1705  	// Create some health checks.
  1706  	fill := func() structs.HealthChecks {
  1707  		return structs.HealthChecks{
  1708  			&structs.HealthCheck{
  1709  				Node:        "node1",
  1710  				CheckID:     "check1",
  1711  				ServiceName: "foo",
  1712  			},
  1713  		}
  1714  	}
  1715  
  1716  	// Try permissive filtering.
  1717  	{
  1718  		hc := fill()
  1719  		filt := newACLFilter(acl.AllowAll(), nil, false)
  1720  		filt.filterHealthChecks(&hc)
  1721  		if len(hc) != 1 {
  1722  			t.Fatalf("bad: %#v", hc)
  1723  		}
  1724  	}
  1725  
  1726  	// Try restrictive filtering.
  1727  	{
  1728  		hc := fill()
  1729  		filt := newACLFilter(acl.DenyAll(), nil, false)
  1730  		filt.filterHealthChecks(&hc)
  1731  		if len(hc) != 0 {
  1732  			t.Fatalf("bad: %#v", hc)
  1733  		}
  1734  	}
  1735  
  1736  	// Allowed to see the service but not the node.
  1737  	policy, err := acl.NewPolicyFromSource("", 0, `
  1738  service "foo" {
  1739    policy = "read"
  1740  }
  1741  `, acl.SyntaxLegacy, nil)
  1742  	if err != nil {
  1743  		t.Fatalf("err %v", err)
  1744  	}
  1745  	perms, err := acl.NewPolicyAuthorizer(acl.DenyAll(), []*acl.Policy{policy}, nil)
  1746  	if err != nil {
  1747  		t.Fatalf("err: %v", err)
  1748  	}
  1749  
  1750  	// This will work because version 8 ACLs aren't being enforced.
  1751  	{
  1752  		hc := fill()
  1753  		filt := newACLFilter(perms, nil, false)
  1754  		filt.filterHealthChecks(&hc)
  1755  		if len(hc) != 1 {
  1756  			t.Fatalf("bad: %#v", hc)
  1757  		}
  1758  	}
  1759  
  1760  	// But with version 8 the node will block it.
  1761  	{
  1762  		hc := fill()
  1763  		filt := newACLFilter(perms, nil, true)
  1764  		filt.filterHealthChecks(&hc)
  1765  		if len(hc) != 0 {
  1766  			t.Fatalf("bad: %#v", hc)
  1767  		}
  1768  	}
  1769  
  1770  	// Chain on access to the node.
  1771  	policy, err = acl.NewPolicyFromSource("", 0, `
  1772  node "node1" {
  1773    policy = "read"
  1774  }
  1775  `, acl.SyntaxLegacy, nil)
  1776  	if err != nil {
  1777  		t.Fatalf("err %v", err)
  1778  	}
  1779  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  1780  	if err != nil {
  1781  		t.Fatalf("err: %v", err)
  1782  	}
  1783  
  1784  	// Now it should go through.
  1785  	{
  1786  		hc := fill()
  1787  		filt := newACLFilter(perms, nil, true)
  1788  		filt.filterHealthChecks(&hc)
  1789  		if len(hc) != 1 {
  1790  			t.Fatalf("bad: %#v", hc)
  1791  		}
  1792  	}
  1793  }
  1794  
  1795  func TestACL_filterIntentions(t *testing.T) {
  1796  	t.Parallel()
  1797  	assert := assert.New(t)
  1798  
  1799  	fill := func() structs.Intentions {
  1800  		return structs.Intentions{
  1801  			&structs.Intention{
  1802  				ID:              "f004177f-2c28-83b7-4229-eacc25fe55d1",
  1803  				DestinationName: "bar",
  1804  			},
  1805  			&structs.Intention{
  1806  				ID:              "f004177f-2c28-83b7-4229-eacc25fe55d2",
  1807  				DestinationName: "foo",
  1808  			},
  1809  		}
  1810  	}
  1811  
  1812  	// Try permissive filtering.
  1813  	{
  1814  		ixns := fill()
  1815  		filt := newACLFilter(acl.AllowAll(), nil, false)
  1816  		filt.filterIntentions(&ixns)
  1817  		assert.Len(ixns, 2)
  1818  	}
  1819  
  1820  	// Try restrictive filtering.
  1821  	{
  1822  		ixns := fill()
  1823  		filt := newACLFilter(acl.DenyAll(), nil, false)
  1824  		filt.filterIntentions(&ixns)
  1825  		assert.Len(ixns, 0)
  1826  	}
  1827  
  1828  	// Policy to see one
  1829  	policy, err := acl.NewPolicyFromSource("", 0, `
  1830  service "foo" {
  1831    policy = "read"
  1832  }
  1833  `, acl.SyntaxLegacy, nil)
  1834  	assert.Nil(err)
  1835  	perms, err := acl.NewPolicyAuthorizer(acl.DenyAll(), []*acl.Policy{policy}, nil)
  1836  	assert.Nil(err)
  1837  
  1838  	// Filter
  1839  	{
  1840  		ixns := fill()
  1841  		filt := newACLFilter(perms, nil, false)
  1842  		filt.filterIntentions(&ixns)
  1843  		assert.Len(ixns, 1)
  1844  	}
  1845  }
  1846  
  1847  func TestACL_filterServices(t *testing.T) {
  1848  	t.Parallel()
  1849  	// Create some services
  1850  	services := structs.Services{
  1851  		"service1": []string{},
  1852  		"service2": []string{},
  1853  		"consul":   []string{},
  1854  	}
  1855  
  1856  	// Try permissive filtering.
  1857  	filt := newACLFilter(acl.AllowAll(), nil, false)
  1858  	filt.filterServices(services)
  1859  	if len(services) != 3 {
  1860  		t.Fatalf("bad: %#v", services)
  1861  	}
  1862  
  1863  	// Try restrictive filtering.
  1864  	filt = newACLFilter(acl.DenyAll(), nil, false)
  1865  	filt.filterServices(services)
  1866  	if len(services) != 1 {
  1867  		t.Fatalf("bad: %#v", services)
  1868  	}
  1869  	if _, ok := services["consul"]; !ok {
  1870  		t.Fatalf("bad: %#v", services)
  1871  	}
  1872  
  1873  	// Try restrictive filtering with version 8 enforcement.
  1874  	filt = newACLFilter(acl.DenyAll(), nil, true)
  1875  	filt.filterServices(services)
  1876  	if len(services) != 0 {
  1877  		t.Fatalf("bad: %#v", services)
  1878  	}
  1879  }
  1880  
  1881  func TestACL_filterServiceNodes(t *testing.T) {
  1882  	t.Parallel()
  1883  	// Create some service nodes.
  1884  	fill := func() structs.ServiceNodes {
  1885  		return structs.ServiceNodes{
  1886  			&structs.ServiceNode{
  1887  				Node:        "node1",
  1888  				ServiceName: "foo",
  1889  			},
  1890  		}
  1891  	}
  1892  
  1893  	// Try permissive filtering.
  1894  	{
  1895  		nodes := fill()
  1896  		filt := newACLFilter(acl.AllowAll(), nil, false)
  1897  		filt.filterServiceNodes(&nodes)
  1898  		if len(nodes) != 1 {
  1899  			t.Fatalf("bad: %#v", nodes)
  1900  		}
  1901  	}
  1902  
  1903  	// Try restrictive filtering.
  1904  	{
  1905  		nodes := fill()
  1906  		filt := newACLFilter(acl.DenyAll(), nil, false)
  1907  		filt.filterServiceNodes(&nodes)
  1908  		if len(nodes) != 0 {
  1909  			t.Fatalf("bad: %#v", nodes)
  1910  		}
  1911  	}
  1912  
  1913  	// Allowed to see the service but not the node.
  1914  	policy, err := acl.NewPolicyFromSource("", 0, `
  1915  service "foo" {
  1916    policy = "read"
  1917  }
  1918  `, acl.SyntaxLegacy, nil)
  1919  	if err != nil {
  1920  		t.Fatalf("err %v", err)
  1921  	}
  1922  	perms, err := acl.NewPolicyAuthorizer(acl.DenyAll(), []*acl.Policy{policy}, nil)
  1923  	if err != nil {
  1924  		t.Fatalf("err: %v", err)
  1925  	}
  1926  
  1927  	// This will work because version 8 ACLs aren't being enforced.
  1928  	{
  1929  		nodes := fill()
  1930  		filt := newACLFilter(perms, nil, false)
  1931  		filt.filterServiceNodes(&nodes)
  1932  		if len(nodes) != 1 {
  1933  			t.Fatalf("bad: %#v", nodes)
  1934  		}
  1935  	}
  1936  
  1937  	// But with version 8 the node will block it.
  1938  	{
  1939  		nodes := fill()
  1940  		filt := newACLFilter(perms, nil, true)
  1941  		filt.filterServiceNodes(&nodes)
  1942  		if len(nodes) != 0 {
  1943  			t.Fatalf("bad: %#v", nodes)
  1944  		}
  1945  	}
  1946  
  1947  	// Chain on access to the node.
  1948  	policy, err = acl.NewPolicyFromSource("", 0, `
  1949  node "node1" {
  1950    policy = "read"
  1951  }
  1952  `, acl.SyntaxLegacy, nil)
  1953  	if err != nil {
  1954  		t.Fatalf("err %v", err)
  1955  	}
  1956  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  1957  	if err != nil {
  1958  		t.Fatalf("err: %v", err)
  1959  	}
  1960  
  1961  	// Now it should go through.
  1962  	{
  1963  		nodes := fill()
  1964  		filt := newACLFilter(perms, nil, true)
  1965  		filt.filterServiceNodes(&nodes)
  1966  		if len(nodes) != 1 {
  1967  			t.Fatalf("bad: %#v", nodes)
  1968  		}
  1969  	}
  1970  }
  1971  
  1972  func TestACL_filterNodeServices(t *testing.T) {
  1973  	t.Parallel()
  1974  	// Create some node services.
  1975  	fill := func() *structs.NodeServices {
  1976  		return &structs.NodeServices{
  1977  			Node: &structs.Node{
  1978  				Node: "node1",
  1979  			},
  1980  			Services: map[string]*structs.NodeService{
  1981  				"foo": &structs.NodeService{
  1982  					ID:      "foo",
  1983  					Service: "foo",
  1984  				},
  1985  			},
  1986  		}
  1987  	}
  1988  
  1989  	// Try nil, which is a possible input.
  1990  	{
  1991  		var services *structs.NodeServices
  1992  		filt := newACLFilter(acl.AllowAll(), nil, false)
  1993  		filt.filterNodeServices(&services)
  1994  		if services != nil {
  1995  			t.Fatalf("bad: %#v", services)
  1996  		}
  1997  	}
  1998  
  1999  	// Try permissive filtering.
  2000  	{
  2001  		services := fill()
  2002  		filt := newACLFilter(acl.AllowAll(), nil, false)
  2003  		filt.filterNodeServices(&services)
  2004  		if len(services.Services) != 1 {
  2005  			t.Fatalf("bad: %#v", services.Services)
  2006  		}
  2007  	}
  2008  
  2009  	// Try restrictive filtering.
  2010  	{
  2011  		services := fill()
  2012  		filt := newACLFilter(acl.DenyAll(), nil, false)
  2013  		filt.filterNodeServices(&services)
  2014  		if len((*services).Services) != 0 {
  2015  			t.Fatalf("bad: %#v", (*services).Services)
  2016  		}
  2017  	}
  2018  
  2019  	// Allowed to see the service but not the node.
  2020  	policy, err := acl.NewPolicyFromSource("", 0, `
  2021  service "foo" {
  2022    policy = "read"
  2023  }
  2024  `, acl.SyntaxLegacy, nil)
  2025  	if err != nil {
  2026  		t.Fatalf("err %v", err)
  2027  	}
  2028  	perms, err := acl.NewPolicyAuthorizer(acl.DenyAll(), []*acl.Policy{policy}, nil)
  2029  	if err != nil {
  2030  		t.Fatalf("err: %v", err)
  2031  	}
  2032  
  2033  	// This will work because version 8 ACLs aren't being enforced.
  2034  	{
  2035  		services := fill()
  2036  		filt := newACLFilter(perms, nil, false)
  2037  		filt.filterNodeServices(&services)
  2038  		if len((*services).Services) != 1 {
  2039  			t.Fatalf("bad: %#v", (*services).Services)
  2040  		}
  2041  	}
  2042  
  2043  	// But with version 8 the node will block it.
  2044  	{
  2045  		services := fill()
  2046  		filt := newACLFilter(perms, nil, true)
  2047  		filt.filterNodeServices(&services)
  2048  		if services != nil {
  2049  			t.Fatalf("bad: %#v", services)
  2050  		}
  2051  	}
  2052  
  2053  	// Chain on access to the node.
  2054  	policy, err = acl.NewPolicyFromSource("", 0, `
  2055  node "node1" {
  2056    policy = "read"
  2057  }
  2058  `, acl.SyntaxLegacy, nil)
  2059  	if err != nil {
  2060  		t.Fatalf("err %v", err)
  2061  	}
  2062  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  2063  	if err != nil {
  2064  		t.Fatalf("err: %v", err)
  2065  	}
  2066  
  2067  	// Now it should go through.
  2068  	{
  2069  		services := fill()
  2070  		filt := newACLFilter(perms, nil, true)
  2071  		filt.filterNodeServices(&services)
  2072  		if len((*services).Services) != 1 {
  2073  			t.Fatalf("bad: %#v", (*services).Services)
  2074  		}
  2075  	}
  2076  }
  2077  
  2078  func TestACL_filterCheckServiceNodes(t *testing.T) {
  2079  	t.Parallel()
  2080  	// Create some nodes.
  2081  	fill := func() structs.CheckServiceNodes {
  2082  		return structs.CheckServiceNodes{
  2083  			structs.CheckServiceNode{
  2084  				Node: &structs.Node{
  2085  					Node: "node1",
  2086  				},
  2087  				Service: &structs.NodeService{
  2088  					ID:      "foo",
  2089  					Service: "foo",
  2090  				},
  2091  				Checks: structs.HealthChecks{
  2092  					&structs.HealthCheck{
  2093  						Node:        "node1",
  2094  						CheckID:     "check1",
  2095  						ServiceName: "foo",
  2096  					},
  2097  				},
  2098  			},
  2099  		}
  2100  	}
  2101  
  2102  	// Try permissive filtering.
  2103  	{
  2104  		nodes := fill()
  2105  		filt := newACLFilter(acl.AllowAll(), nil, false)
  2106  		filt.filterCheckServiceNodes(&nodes)
  2107  		if len(nodes) != 1 {
  2108  			t.Fatalf("bad: %#v", nodes)
  2109  		}
  2110  		if len(nodes[0].Checks) != 1 {
  2111  			t.Fatalf("bad: %#v", nodes[0].Checks)
  2112  		}
  2113  	}
  2114  
  2115  	// Try restrictive filtering.
  2116  	{
  2117  		nodes := fill()
  2118  		filt := newACLFilter(acl.DenyAll(), nil, false)
  2119  		filt.filterCheckServiceNodes(&nodes)
  2120  		if len(nodes) != 0 {
  2121  			t.Fatalf("bad: %#v", nodes)
  2122  		}
  2123  	}
  2124  
  2125  	// Allowed to see the service but not the node.
  2126  	policy, err := acl.NewPolicyFromSource("", 0, `
  2127  service "foo" {
  2128    policy = "read"
  2129  }
  2130  `, acl.SyntaxLegacy, nil)
  2131  	if err != nil {
  2132  		t.Fatalf("err %v", err)
  2133  	}
  2134  	perms, err := acl.NewPolicyAuthorizer(acl.DenyAll(), []*acl.Policy{policy}, nil)
  2135  	if err != nil {
  2136  		t.Fatalf("err: %v", err)
  2137  	}
  2138  
  2139  	// This will work because version 8 ACLs aren't being enforced.
  2140  	{
  2141  		nodes := fill()
  2142  		filt := newACLFilter(perms, nil, false)
  2143  		filt.filterCheckServiceNodes(&nodes)
  2144  		if len(nodes) != 1 {
  2145  			t.Fatalf("bad: %#v", nodes)
  2146  		}
  2147  		if len(nodes[0].Checks) != 1 {
  2148  			t.Fatalf("bad: %#v", nodes[0].Checks)
  2149  		}
  2150  	}
  2151  
  2152  	// But with version 8 the node will block it.
  2153  	{
  2154  		nodes := fill()
  2155  		filt := newACLFilter(perms, nil, true)
  2156  		filt.filterCheckServiceNodes(&nodes)
  2157  		if len(nodes) != 0 {
  2158  			t.Fatalf("bad: %#v", nodes)
  2159  		}
  2160  	}
  2161  
  2162  	// Chain on access to the node.
  2163  	policy, err = acl.NewPolicyFromSource("", 0, `
  2164  node "node1" {
  2165    policy = "read"
  2166  }
  2167  `, acl.SyntaxLegacy, nil)
  2168  	if err != nil {
  2169  		t.Fatalf("err %v", err)
  2170  	}
  2171  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  2172  	if err != nil {
  2173  		t.Fatalf("err: %v", err)
  2174  	}
  2175  
  2176  	// Now it should go through.
  2177  	{
  2178  		nodes := fill()
  2179  		filt := newACLFilter(perms, nil, true)
  2180  		filt.filterCheckServiceNodes(&nodes)
  2181  		if len(nodes) != 1 {
  2182  			t.Fatalf("bad: %#v", nodes)
  2183  		}
  2184  		if len(nodes[0].Checks) != 1 {
  2185  			t.Fatalf("bad: %#v", nodes[0].Checks)
  2186  		}
  2187  	}
  2188  }
  2189  
  2190  func TestACL_filterCoordinates(t *testing.T) {
  2191  	t.Parallel()
  2192  	// Create some coordinates.
  2193  	coords := structs.Coordinates{
  2194  		&structs.Coordinate{
  2195  			Node:  "node1",
  2196  			Coord: generateRandomCoordinate(),
  2197  		},
  2198  		&structs.Coordinate{
  2199  			Node:  "node2",
  2200  			Coord: generateRandomCoordinate(),
  2201  		},
  2202  	}
  2203  
  2204  	// Try permissive filtering.
  2205  	filt := newACLFilter(acl.AllowAll(), nil, false)
  2206  	filt.filterCoordinates(&coords)
  2207  	if len(coords) != 2 {
  2208  		t.Fatalf("bad: %#v", coords)
  2209  	}
  2210  
  2211  	// Try restrictive filtering without version 8 ACL enforcement.
  2212  	filt = newACLFilter(acl.DenyAll(), nil, false)
  2213  	filt.filterCoordinates(&coords)
  2214  	if len(coords) != 2 {
  2215  		t.Fatalf("bad: %#v", coords)
  2216  	}
  2217  
  2218  	// Try restrictive filtering with version 8 ACL enforcement.
  2219  	filt = newACLFilter(acl.DenyAll(), nil, true)
  2220  	filt.filterCoordinates(&coords)
  2221  	if len(coords) != 0 {
  2222  		t.Fatalf("bad: %#v", coords)
  2223  	}
  2224  }
  2225  
  2226  func TestACL_filterSessions(t *testing.T) {
  2227  	t.Parallel()
  2228  	// Create a session list.
  2229  	sessions := structs.Sessions{
  2230  		&structs.Session{
  2231  			Node: "foo",
  2232  		},
  2233  		&structs.Session{
  2234  			Node: "bar",
  2235  		},
  2236  	}
  2237  
  2238  	// Try permissive filtering.
  2239  	filt := newACLFilter(acl.AllowAll(), nil, true)
  2240  	filt.filterSessions(&sessions)
  2241  	if len(sessions) != 2 {
  2242  		t.Fatalf("bad: %#v", sessions)
  2243  	}
  2244  
  2245  	// Try restrictive filtering but with version 8 enforcement turned off.
  2246  	filt = newACLFilter(acl.DenyAll(), nil, false)
  2247  	filt.filterSessions(&sessions)
  2248  	if len(sessions) != 2 {
  2249  		t.Fatalf("bad: %#v", sessions)
  2250  	}
  2251  
  2252  	// Try restrictive filtering with version 8 enforcement turned on.
  2253  	filt = newACLFilter(acl.DenyAll(), nil, true)
  2254  	filt.filterSessions(&sessions)
  2255  	if len(sessions) != 0 {
  2256  		t.Fatalf("bad: %#v", sessions)
  2257  	}
  2258  }
  2259  
  2260  func TestACL_filterNodeDump(t *testing.T) {
  2261  	t.Parallel()
  2262  	// Create a node dump.
  2263  	fill := func() structs.NodeDump {
  2264  		return structs.NodeDump{
  2265  			&structs.NodeInfo{
  2266  				Node: "node1",
  2267  				Services: []*structs.NodeService{
  2268  					&structs.NodeService{
  2269  						ID:      "foo",
  2270  						Service: "foo",
  2271  					},
  2272  				},
  2273  				Checks: []*structs.HealthCheck{
  2274  					&structs.HealthCheck{
  2275  						Node:        "node1",
  2276  						CheckID:     "check1",
  2277  						ServiceName: "foo",
  2278  					},
  2279  				},
  2280  			},
  2281  		}
  2282  	}
  2283  
  2284  	// Try permissive filtering.
  2285  	{
  2286  		dump := fill()
  2287  		filt := newACLFilter(acl.AllowAll(), nil, false)
  2288  		filt.filterNodeDump(&dump)
  2289  		if len(dump) != 1 {
  2290  			t.Fatalf("bad: %#v", dump)
  2291  		}
  2292  		if len(dump[0].Services) != 1 {
  2293  			t.Fatalf("bad: %#v", dump[0].Services)
  2294  		}
  2295  		if len(dump[0].Checks) != 1 {
  2296  			t.Fatalf("bad: %#v", dump[0].Checks)
  2297  		}
  2298  	}
  2299  
  2300  	// Try restrictive filtering.
  2301  	{
  2302  		dump := fill()
  2303  		filt := newACLFilter(acl.DenyAll(), nil, false)
  2304  		filt.filterNodeDump(&dump)
  2305  		if len(dump) != 1 {
  2306  			t.Fatalf("bad: %#v", dump)
  2307  		}
  2308  		if len(dump[0].Services) != 0 {
  2309  			t.Fatalf("bad: %#v", dump[0].Services)
  2310  		}
  2311  		if len(dump[0].Checks) != 0 {
  2312  			t.Fatalf("bad: %#v", dump[0].Checks)
  2313  		}
  2314  	}
  2315  
  2316  	// Allowed to see the service but not the node.
  2317  	policy, err := acl.NewPolicyFromSource("", 0, `
  2318  service "foo" {
  2319    policy = "read"
  2320  }
  2321  `, acl.SyntaxLegacy, nil)
  2322  	if err != nil {
  2323  		t.Fatalf("err %v", err)
  2324  	}
  2325  	perms, err := acl.NewPolicyAuthorizer(acl.DenyAll(), []*acl.Policy{policy}, nil)
  2326  	if err != nil {
  2327  		t.Fatalf("err: %v", err)
  2328  	}
  2329  
  2330  	// This will work because version 8 ACLs aren't being enforced.
  2331  	{
  2332  		dump := fill()
  2333  		filt := newACLFilter(perms, nil, false)
  2334  		filt.filterNodeDump(&dump)
  2335  		if len(dump) != 1 {
  2336  			t.Fatalf("bad: %#v", dump)
  2337  		}
  2338  		if len(dump[0].Services) != 1 {
  2339  			t.Fatalf("bad: %#v", dump[0].Services)
  2340  		}
  2341  		if len(dump[0].Checks) != 1 {
  2342  			t.Fatalf("bad: %#v", dump[0].Checks)
  2343  		}
  2344  	}
  2345  
  2346  	// But with version 8 the node will block it.
  2347  	{
  2348  		dump := fill()
  2349  		filt := newACLFilter(perms, nil, true)
  2350  		filt.filterNodeDump(&dump)
  2351  		if len(dump) != 0 {
  2352  			t.Fatalf("bad: %#v", dump)
  2353  		}
  2354  	}
  2355  
  2356  	// Chain on access to the node.
  2357  	policy, err = acl.NewPolicyFromSource("", 0, `
  2358  node "node1" {
  2359    policy = "read"
  2360  }
  2361  `, acl.SyntaxLegacy, nil)
  2362  	if err != nil {
  2363  		t.Fatalf("err %v", err)
  2364  	}
  2365  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  2366  	if err != nil {
  2367  		t.Fatalf("err: %v", err)
  2368  	}
  2369  
  2370  	// Now it should go through.
  2371  	{
  2372  		dump := fill()
  2373  		filt := newACLFilter(perms, nil, true)
  2374  		filt.filterNodeDump(&dump)
  2375  		if len(dump) != 1 {
  2376  			t.Fatalf("bad: %#v", dump)
  2377  		}
  2378  		if len(dump[0].Services) != 1 {
  2379  			t.Fatalf("bad: %#v", dump[0].Services)
  2380  		}
  2381  		if len(dump[0].Checks) != 1 {
  2382  			t.Fatalf("bad: %#v", dump[0].Checks)
  2383  		}
  2384  	}
  2385  }
  2386  
  2387  func TestACL_filterNodes(t *testing.T) {
  2388  	t.Parallel()
  2389  	// Create a nodes list.
  2390  	nodes := structs.Nodes{
  2391  		&structs.Node{
  2392  			Node: "foo",
  2393  		},
  2394  		&structs.Node{
  2395  			Node: "bar",
  2396  		},
  2397  	}
  2398  
  2399  	// Try permissive filtering.
  2400  	filt := newACLFilter(acl.AllowAll(), nil, true)
  2401  	filt.filterNodes(&nodes)
  2402  	if len(nodes) != 2 {
  2403  		t.Fatalf("bad: %#v", nodes)
  2404  	}
  2405  
  2406  	// Try restrictive filtering but with version 8 enforcement turned off.
  2407  	filt = newACLFilter(acl.DenyAll(), nil, false)
  2408  	filt.filterNodes(&nodes)
  2409  	if len(nodes) != 2 {
  2410  		t.Fatalf("bad: %#v", nodes)
  2411  	}
  2412  
  2413  	// Try restrictive filtering with version 8 enforcement turned on.
  2414  	filt = newACLFilter(acl.DenyAll(), nil, true)
  2415  	filt.filterNodes(&nodes)
  2416  	if len(nodes) != 0 {
  2417  		t.Fatalf("bad: %#v", nodes)
  2418  	}
  2419  }
  2420  
  2421  func TestACL_redactPreparedQueryTokens(t *testing.T) {
  2422  	t.Parallel()
  2423  	query := &structs.PreparedQuery{
  2424  		ID:    "f004177f-2c28-83b7-4229-eacc25fe55d1",
  2425  		Token: "root",
  2426  	}
  2427  
  2428  	expected := &structs.PreparedQuery{
  2429  		ID:    "f004177f-2c28-83b7-4229-eacc25fe55d1",
  2430  		Token: "root",
  2431  	}
  2432  
  2433  	// Try permissive filtering with a management token. This will allow the
  2434  	// embedded token to be seen.
  2435  	filt := newACLFilter(acl.ManageAll(), nil, false)
  2436  	filt.redactPreparedQueryTokens(&query)
  2437  	if !reflect.DeepEqual(query, expected) {
  2438  		t.Fatalf("bad: %#v", &query)
  2439  	}
  2440  
  2441  	// Hang on to the entry with a token, which needs to survive the next
  2442  	// operation.
  2443  	original := query
  2444  
  2445  	// Now try permissive filtering with a client token, which should cause
  2446  	// the embedded token to get redacted.
  2447  	filt = newACLFilter(acl.AllowAll(), nil, false)
  2448  	filt.redactPreparedQueryTokens(&query)
  2449  	expected.Token = redactedToken
  2450  	if !reflect.DeepEqual(query, expected) {
  2451  		t.Fatalf("bad: %#v", *query)
  2452  	}
  2453  
  2454  	// Make sure that the original object didn't lose its token.
  2455  	if original.Token != "root" {
  2456  		t.Fatalf("bad token: %s", original.Token)
  2457  	}
  2458  }
  2459  
  2460  func TestACL_redactTokenSecret(t *testing.T) {
  2461  	t.Parallel()
  2462  	delegate := &ACLResolverTestDelegate{
  2463  		enabled:       true,
  2464  		datacenter:    "dc1",
  2465  		legacy:        false,
  2466  		localTokens:   true,
  2467  		localPolicies: true,
  2468  		// No need to provide any of the RPC callbacks
  2469  	}
  2470  	r := newTestACLResolver(t, delegate, nil)
  2471  
  2472  	token := &structs.ACLToken{
  2473  		AccessorID: "6a5e25b3-28f2-4085-9012-c3fb754314d1",
  2474  		SecretID:   "6a5e25b3-28f2-4085-9012-c3fb754314d1",
  2475  	}
  2476  
  2477  	err := r.filterACL("acl-wr", &token)
  2478  	require.NoError(t, err)
  2479  	require.Equal(t, "6a5e25b3-28f2-4085-9012-c3fb754314d1", token.SecretID)
  2480  
  2481  	err = r.filterACL("acl-ro", &token)
  2482  	require.NoError(t, err)
  2483  	require.Equal(t, redactedToken, token.SecretID)
  2484  }
  2485  
  2486  func TestACL_redactTokenSecrets(t *testing.T) {
  2487  	t.Parallel()
  2488  	delegate := &ACLResolverTestDelegate{
  2489  		enabled:       true,
  2490  		datacenter:    "dc1",
  2491  		legacy:        false,
  2492  		localTokens:   true,
  2493  		localPolicies: true,
  2494  		// No need to provide any of the RPC callbacks
  2495  	}
  2496  	r := newTestACLResolver(t, delegate, nil)
  2497  
  2498  	tokens := structs.ACLTokens{
  2499  		&structs.ACLToken{
  2500  			AccessorID: "6a5e25b3-28f2-4085-9012-c3fb754314d1",
  2501  			SecretID:   "6a5e25b3-28f2-4085-9012-c3fb754314d1",
  2502  		},
  2503  	}
  2504  
  2505  	err := r.filterACL("acl-wr", &tokens)
  2506  	require.NoError(t, err)
  2507  	require.Equal(t, "6a5e25b3-28f2-4085-9012-c3fb754314d1", tokens[0].SecretID)
  2508  
  2509  	err = r.filterACL("acl-ro", &tokens)
  2510  	require.NoError(t, err)
  2511  	require.Equal(t, redactedToken, tokens[0].SecretID)
  2512  }
  2513  
  2514  func TestACL_filterPreparedQueries(t *testing.T) {
  2515  	t.Parallel()
  2516  	queries := structs.PreparedQueries{
  2517  		&structs.PreparedQuery{
  2518  			ID: "f004177f-2c28-83b7-4229-eacc25fe55d1",
  2519  		},
  2520  		&structs.PreparedQuery{
  2521  			ID:   "f004177f-2c28-83b7-4229-eacc25fe55d2",
  2522  			Name: "query-with-no-token",
  2523  		},
  2524  		&structs.PreparedQuery{
  2525  			ID:    "f004177f-2c28-83b7-4229-eacc25fe55d3",
  2526  			Name:  "query-with-a-token",
  2527  			Token: "root",
  2528  		},
  2529  	}
  2530  
  2531  	expected := structs.PreparedQueries{
  2532  		&structs.PreparedQuery{
  2533  			ID: "f004177f-2c28-83b7-4229-eacc25fe55d1",
  2534  		},
  2535  		&structs.PreparedQuery{
  2536  			ID:   "f004177f-2c28-83b7-4229-eacc25fe55d2",
  2537  			Name: "query-with-no-token",
  2538  		},
  2539  		&structs.PreparedQuery{
  2540  			ID:    "f004177f-2c28-83b7-4229-eacc25fe55d3",
  2541  			Name:  "query-with-a-token",
  2542  			Token: "root",
  2543  		},
  2544  	}
  2545  
  2546  	// Try permissive filtering with a management token. This will allow the
  2547  	// embedded token to be seen.
  2548  	filt := newACLFilter(acl.ManageAll(), nil, false)
  2549  	filt.filterPreparedQueries(&queries)
  2550  	if !reflect.DeepEqual(queries, expected) {
  2551  		t.Fatalf("bad: %#v", queries)
  2552  	}
  2553  
  2554  	// Hang on to the entry with a token, which needs to survive the next
  2555  	// operation.
  2556  	original := queries[2]
  2557  
  2558  	// Now try permissive filtering with a client token, which should cause
  2559  	// the embedded token to get redacted, and the query with no name to get
  2560  	// filtered out.
  2561  	filt = newACLFilter(acl.AllowAll(), nil, false)
  2562  	filt.filterPreparedQueries(&queries)
  2563  	expected[2].Token = redactedToken
  2564  	expected = append(structs.PreparedQueries{}, expected[1], expected[2])
  2565  	if !reflect.DeepEqual(queries, expected) {
  2566  		t.Fatalf("bad: %#v", queries)
  2567  	}
  2568  
  2569  	// Make sure that the original object didn't lose its token.
  2570  	if original.Token != "root" {
  2571  		t.Fatalf("bad token: %s", original.Token)
  2572  	}
  2573  
  2574  	// Now try restrictive filtering.
  2575  	filt = newACLFilter(acl.DenyAll(), nil, false)
  2576  	filt.filterPreparedQueries(&queries)
  2577  	if len(queries) != 0 {
  2578  		t.Fatalf("bad: %#v", queries)
  2579  	}
  2580  }
  2581  
  2582  func TestACL_unhandledFilterType(t *testing.T) {
  2583  	t.Parallel()
  2584  	defer func(t *testing.T) {
  2585  		if recover() == nil {
  2586  			t.Fatalf("should panic")
  2587  		}
  2588  	}(t)
  2589  
  2590  	// Create the server
  2591  	dir, token, srv, client := testACLFilterServer(t)
  2592  	defer os.RemoveAll(dir)
  2593  	defer srv.Shutdown()
  2594  	defer client.Close()
  2595  
  2596  	// Pass an unhandled type into the ACL filter.
  2597  	srv.filterACL(token, &structs.HealthCheck{})
  2598  }
  2599  
  2600  func TestACL_vetRegisterWithACL(t *testing.T) {
  2601  	t.Parallel()
  2602  	args := &structs.RegisterRequest{
  2603  		Node:    "nope",
  2604  		Address: "127.0.0.1",
  2605  	}
  2606  
  2607  	// With a nil ACL, the update should be allowed.
  2608  	if err := vetRegisterWithACL(nil, args, nil); err != nil {
  2609  		t.Fatalf("err: %v", err)
  2610  	}
  2611  
  2612  	// Create a basic node policy.
  2613  	policy, err := acl.NewPolicyFromSource("", 0, `
  2614  node "node" {
  2615    policy = "write"
  2616  }
  2617  `, acl.SyntaxLegacy, nil)
  2618  	if err != nil {
  2619  		t.Fatalf("err %v", err)
  2620  	}
  2621  	perms, err := acl.NewPolicyAuthorizer(acl.DenyAll(), []*acl.Policy{policy}, nil)
  2622  	if err != nil {
  2623  		t.Fatalf("err: %v", err)
  2624  	}
  2625  
  2626  	// With that policy, the update should now be blocked for node reasons.
  2627  	err = vetRegisterWithACL(perms, args, nil)
  2628  	if !acl.IsErrPermissionDenied(err) {
  2629  		t.Fatalf("bad: %v", err)
  2630  	}
  2631  
  2632  	// Now use a permitted node name.
  2633  	args.Node = "node"
  2634  	if err := vetRegisterWithACL(perms, args, nil); err != nil {
  2635  		t.Fatalf("err: %v", err)
  2636  	}
  2637  
  2638  	// Build some node info that matches what we have now.
  2639  	ns := &structs.NodeServices{
  2640  		Node: &structs.Node{
  2641  			Node:    "node",
  2642  			Address: "127.0.0.1",
  2643  		},
  2644  		Services: make(map[string]*structs.NodeService),
  2645  	}
  2646  
  2647  	// Try to register a service, which should be blocked.
  2648  	args.Service = &structs.NodeService{
  2649  		Service: "service",
  2650  		ID:      "my-id",
  2651  	}
  2652  	err = vetRegisterWithACL(perms, args, ns)
  2653  	if !acl.IsErrPermissionDenied(err) {
  2654  		t.Fatalf("bad: %v", err)
  2655  	}
  2656  
  2657  	// Chain on a basic service policy.
  2658  	policy, err = acl.NewPolicyFromSource("", 0, `
  2659  service "service" {
  2660    policy = "write"
  2661  }
  2662  `, acl.SyntaxLegacy, nil)
  2663  	if err != nil {
  2664  		t.Fatalf("err %v", err)
  2665  	}
  2666  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  2667  	if err != nil {
  2668  		t.Fatalf("err: %v", err)
  2669  	}
  2670  
  2671  	// With the service ACL, the update should go through.
  2672  	if err := vetRegisterWithACL(perms, args, ns); err != nil {
  2673  		t.Fatalf("err: %v", err)
  2674  	}
  2675  
  2676  	// Add an existing service that they are clobbering and aren't allowed
  2677  	// to write to.
  2678  	ns.Services["my-id"] = &structs.NodeService{
  2679  		Service: "other",
  2680  		ID:      "my-id",
  2681  	}
  2682  	err = vetRegisterWithACL(perms, args, ns)
  2683  	if !acl.IsErrPermissionDenied(err) {
  2684  		t.Fatalf("bad: %v", err)
  2685  	}
  2686  
  2687  	// Chain on a policy that allows them to write to the other service.
  2688  	policy, err = acl.NewPolicyFromSource("", 0, `
  2689  service "other" {
  2690    policy = "write"
  2691  }
  2692  `, acl.SyntaxLegacy, nil)
  2693  	if err != nil {
  2694  		t.Fatalf("err %v", err)
  2695  	}
  2696  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  2697  	if err != nil {
  2698  		t.Fatalf("err: %v", err)
  2699  	}
  2700  
  2701  	// Now it should go through.
  2702  	if err := vetRegisterWithACL(perms, args, ns); err != nil {
  2703  		t.Fatalf("err: %v", err)
  2704  	}
  2705  
  2706  	// Try creating the node and the service at once by having no existing
  2707  	// node record. This should be ok since we have node and service
  2708  	// permissions.
  2709  	if err := vetRegisterWithACL(perms, args, nil); err != nil {
  2710  		t.Fatalf("err: %v", err)
  2711  	}
  2712  
  2713  	// Add a node-level check to the member, which should be rejected.
  2714  	args.Check = &structs.HealthCheck{
  2715  		Node: "node",
  2716  	}
  2717  	err = vetRegisterWithACL(perms, args, ns)
  2718  	if err == nil || !strings.Contains(err.Error(), "check member must be nil") {
  2719  		t.Fatalf("bad: %v", err)
  2720  	}
  2721  
  2722  	// Move the check into the slice, but give a bad node name.
  2723  	args.Check.Node = "nope"
  2724  	args.Checks = append(args.Checks, args.Check)
  2725  	args.Check = nil
  2726  	err = vetRegisterWithACL(perms, args, ns)
  2727  	if err == nil || !strings.Contains(err.Error(), "doesn't match register request node") {
  2728  		t.Fatalf("bad: %v", err)
  2729  	}
  2730  
  2731  	// Fix the node name, which should now go through.
  2732  	args.Checks[0].Node = "node"
  2733  	if err := vetRegisterWithACL(perms, args, ns); err != nil {
  2734  		t.Fatalf("err: %v", err)
  2735  	}
  2736  
  2737  	// Add a service-level check.
  2738  	args.Checks = append(args.Checks, &structs.HealthCheck{
  2739  		Node:      "node",
  2740  		ServiceID: "my-id",
  2741  	})
  2742  	if err := vetRegisterWithACL(perms, args, ns); err != nil {
  2743  		t.Fatalf("err: %v", err)
  2744  	}
  2745  
  2746  	// Try creating everything at once. This should be ok since we have all
  2747  	// the permissions we need. It also makes sure that we can register a
  2748  	// new node, service, and associated checks.
  2749  	if err := vetRegisterWithACL(perms, args, nil); err != nil {
  2750  		t.Fatalf("err: %v", err)
  2751  	}
  2752  
  2753  	// Nil out the service registration, which'll skip the special case
  2754  	// and force us to look at the ns data (it will look like we are
  2755  	// writing to the "other" service which also has "my-id").
  2756  	args.Service = nil
  2757  	if err := vetRegisterWithACL(perms, args, ns); err != nil {
  2758  		t.Fatalf("err: %v", err)
  2759  	}
  2760  
  2761  	// Chain on a policy that forbids them to write to the other service.
  2762  	policy, err = acl.NewPolicyFromSource("", 0, `
  2763  service "other" {
  2764    policy = "deny"
  2765  }
  2766  `, acl.SyntaxLegacy, nil)
  2767  	if err != nil {
  2768  		t.Fatalf("err %v", err)
  2769  	}
  2770  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  2771  	if err != nil {
  2772  		t.Fatalf("err: %v", err)
  2773  	}
  2774  
  2775  	// This should get rejected.
  2776  	err = vetRegisterWithACL(perms, args, ns)
  2777  	if !acl.IsErrPermissionDenied(err) {
  2778  		t.Fatalf("bad: %v", err)
  2779  	}
  2780  
  2781  	// Change the existing service data to point to a service name they
  2782  	// car write to. This should go through.
  2783  	ns.Services["my-id"] = &structs.NodeService{
  2784  		Service: "service",
  2785  		ID:      "my-id",
  2786  	}
  2787  	if err := vetRegisterWithACL(perms, args, ns); err != nil {
  2788  		t.Fatalf("err: %v", err)
  2789  	}
  2790  
  2791  	// Chain on a policy that forbids them to write to the node.
  2792  	policy, err = acl.NewPolicyFromSource("", 0, `
  2793  node "node" {
  2794    policy = "deny"
  2795  }
  2796  `, acl.SyntaxLegacy, nil)
  2797  	if err != nil {
  2798  		t.Fatalf("err %v", err)
  2799  	}
  2800  	perms, err = acl.NewPolicyAuthorizer(perms, []*acl.Policy{policy}, nil)
  2801  	if err != nil {
  2802  		t.Fatalf("err: %v", err)
  2803  	}
  2804  
  2805  	// This should get rejected because there's a node-level check in here.
  2806  	err = vetRegisterWithACL(perms, args, ns)
  2807  	if !acl.IsErrPermissionDenied(err) {
  2808  		t.Fatalf("bad: %v", err)
  2809  	}
  2810  
  2811  	// Change the node-level check into a service check, and then it should
  2812  	// go through.
  2813  	args.Checks[0].ServiceID = "my-id"
  2814  	if err := vetRegisterWithACL(perms, args, ns); err != nil {
  2815  		t.Fatalf("err: %v", err)
  2816  	}
  2817  
  2818  	// Finally, attempt to update the node part of the data and make sure
  2819  	// that gets rejected since they no longer have permissions.
  2820  	args.Address = "127.0.0.2"
  2821  	err = vetRegisterWithACL(perms, args, ns)
  2822  	if !acl.IsErrPermissionDenied(err) {
  2823  		t.Fatalf("bad: %v", err)
  2824  	}
  2825  }
  2826  
  2827  func TestACL_vetDeregisterWithACL(t *testing.T) {
  2828  	t.Parallel()
  2829  	args := &structs.DeregisterRequest{
  2830  		Node: "nope",
  2831  	}
  2832  
  2833  	// With a nil ACL, the update should be allowed.
  2834  	if err := vetDeregisterWithACL(nil, args, nil, nil); err != nil {
  2835  		t.Fatalf("err: %v", err)
  2836  	}
  2837  
  2838  	// Create a basic node policy.
  2839  	policy, err := acl.NewPolicyFromSource("", 0, `
  2840  node "node" {
  2841    policy = "write"
  2842  }
  2843  service "service" {
  2844    policy = "write"
  2845  }
  2846  `, acl.SyntaxLegacy, nil)
  2847  	if err != nil {
  2848  		t.Fatalf("err %v", err)
  2849  	}
  2850  	perms, err := acl.NewPolicyAuthorizer(acl.DenyAll(), []*acl.Policy{policy}, nil)
  2851  	if err != nil {
  2852  		t.Fatalf("err: %v", err)
  2853  	}
  2854  
  2855  	// With that policy, the update should now be blocked for node reasons.
  2856  	err = vetDeregisterWithACL(perms, args, nil, nil)
  2857  	if !acl.IsErrPermissionDenied(err) {
  2858  		t.Fatalf("bad: %v", err)
  2859  	}
  2860  
  2861  	// Now use a permitted node name.
  2862  	args.Node = "node"
  2863  	if err := vetDeregisterWithACL(perms, args, nil, nil); err != nil {
  2864  		t.Fatalf("err: %v", err)
  2865  	}
  2866  
  2867  	// Try an unknown check.
  2868  	args.CheckID = "check-id"
  2869  	err = vetDeregisterWithACL(perms, args, nil, nil)
  2870  	if err == nil || !strings.Contains(err.Error(), "Unknown check") {
  2871  		t.Fatalf("bad: %v", err)
  2872  	}
  2873  
  2874  	// Now pass in a check that should be blocked.
  2875  	nc := &structs.HealthCheck{
  2876  		Node:        "node",
  2877  		CheckID:     "check-id",
  2878  		ServiceID:   "service-id",
  2879  		ServiceName: "nope",
  2880  	}
  2881  	err = vetDeregisterWithACL(perms, args, nil, nc)
  2882  	if !acl.IsErrPermissionDenied(err) {
  2883  		t.Fatalf("bad: %v", err)
  2884  	}
  2885  
  2886  	// Change it to an allowed service, which should go through.
  2887  	nc.ServiceName = "service"
  2888  	if err := vetDeregisterWithACL(perms, args, nil, nc); err != nil {
  2889  		t.Fatalf("err: %v", err)
  2890  	}
  2891  
  2892  	// Switch to a node check that should be blocked.
  2893  	args.Node = "nope"
  2894  	nc.Node = "nope"
  2895  	nc.ServiceID = ""
  2896  	nc.ServiceName = ""
  2897  	err = vetDeregisterWithACL(perms, args, nil, nc)
  2898  	if !acl.IsErrPermissionDenied(err) {
  2899  		t.Fatalf("bad: %v", err)
  2900  	}
  2901  
  2902  	// Switch to an allowed node check, which should go through.
  2903  	args.Node = "node"
  2904  	nc.Node = "node"
  2905  	if err := vetDeregisterWithACL(perms, args, nil, nc); err != nil {
  2906  		t.Fatalf("err: %v", err)
  2907  	}
  2908  
  2909  	// Try an unknown service.
  2910  	args.ServiceID = "service-id"
  2911  	err = vetDeregisterWithACL(perms, args, nil, nil)
  2912  	if err == nil || !strings.Contains(err.Error(), "Unknown service") {
  2913  		t.Fatalf("bad: %v", err)
  2914  	}
  2915  
  2916  	// Now pass in a service that should be blocked.
  2917  	ns := &structs.NodeService{
  2918  		ID:      "service-id",
  2919  		Service: "nope",
  2920  	}
  2921  	err = vetDeregisterWithACL(perms, args, ns, nil)
  2922  	if !acl.IsErrPermissionDenied(err) {
  2923  		t.Fatalf("bad: %v", err)
  2924  	}
  2925  
  2926  	// Change it to an allowed service, which should go through.
  2927  	ns.Service = "service"
  2928  	if err := vetDeregisterWithACL(perms, args, ns, nil); err != nil {
  2929  		t.Fatalf("err: %v", err)
  2930  	}
  2931  }