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