github.com/clly/consul@v1.4.5/agent/consul/acl_endpoint_test.go (about)

     1  package consul
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/rpc"
     7  	"os"
     8  	"path/filepath"
     9  	"reflect"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/hashicorp/consul/acl"
    15  	"github.com/hashicorp/consul/agent/structs"
    16  	tokenStore "github.com/hashicorp/consul/agent/token"
    17  	"github.com/hashicorp/consul/lib"
    18  	"github.com/hashicorp/consul/testrpc"
    19  	"github.com/hashicorp/consul/testutil/retry"
    20  	uuid "github.com/hashicorp/go-uuid"
    21  	msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  func TestACLEndpoint_Bootstrap(t *testing.T) {
    26  	t.Parallel()
    27  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
    28  		c.Build = "0.8.0" // Too low for auto init of bootstrap.
    29  		c.ACLDatacenter = "dc1"
    30  		c.ACLsEnabled = true
    31  	})
    32  	defer os.RemoveAll(dir1)
    33  	defer s1.Shutdown()
    34  	codec := rpcClient(t, s1)
    35  	defer codec.Close()
    36  
    37  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
    38  
    39  	// Expect an error initially since ACL bootstrap is not initialized.
    40  	arg := structs.DCSpecificRequest{
    41  		Datacenter: "dc1",
    42  	}
    43  	var out structs.ACL
    44  	// We can only do some high
    45  	// level checks on the ACL since we don't have control over the UUID or
    46  	// Raft indexes at this level.
    47  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", &arg, &out); err != nil {
    48  		t.Fatalf("err: %v", err)
    49  	}
    50  	if len(out.ID) != len("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") ||
    51  		!strings.HasPrefix(out.Name, "Bootstrap Token") ||
    52  		out.Type != structs.ACLTokenTypeManagement ||
    53  		out.CreateIndex == 0 || out.ModifyIndex == 0 {
    54  		t.Fatalf("bad: %#v", out)
    55  	}
    56  
    57  	// Finally, make sure that another attempt is rejected.
    58  	err := msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", &arg, &out)
    59  	if err.Error() != structs.ACLBootstrapNotAllowedErr.Error() {
    60  		t.Fatalf("err: %v", err)
    61  	}
    62  }
    63  
    64  func TestACLEndpoint_BootstrapTokens(t *testing.T) {
    65  	t.Parallel()
    66  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
    67  		c.ACLDatacenter = "dc1"
    68  		c.ACLsEnabled = true
    69  		c.ACLsEnabled = true
    70  	})
    71  	defer os.RemoveAll(dir1)
    72  	defer s1.Shutdown()
    73  	codec := rpcClient(t, s1)
    74  	defer codec.Close()
    75  
    76  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
    77  
    78  	// Expect an error initially since ACL bootstrap is not initialized.
    79  	arg := structs.DCSpecificRequest{
    80  		Datacenter: "dc1",
    81  	}
    82  	var out structs.ACLToken
    83  	// We can only do some high
    84  	// level checks on the ACL since we don't have control over the UUID or
    85  	// Raft indexes at this level.
    86  	require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.BootstrapTokens", &arg, &out))
    87  	require.Equal(t, 36, len(out.AccessorID))
    88  	require.True(t, strings.HasPrefix(out.Description, "Bootstrap Token"))
    89  	require.Equal(t, out.Type, structs.ACLTokenTypeManagement)
    90  	require.True(t, out.CreateIndex > 0)
    91  	require.Equal(t, out.CreateIndex, out.ModifyIndex)
    92  
    93  	// Finally, make sure that another attempt is rejected.
    94  	err := msgpackrpc.CallWithCodec(codec, "ACL.BootstrapTokens", &arg, &out)
    95  	require.Error(t, err)
    96  	require.True(t, strings.HasPrefix(err.Error(), structs.ACLBootstrapNotAllowedErr.Error()))
    97  
    98  	_, resetIdx, err := s1.fsm.State().CanBootstrapACLToken()
    99  
   100  	resetPath := filepath.Join(dir1, "acl-bootstrap-reset")
   101  	require.NoError(t, ioutil.WriteFile(resetPath, []byte(fmt.Sprintf("%d", resetIdx)), 0600))
   102  
   103  	oldID := out.AccessorID
   104  	// Finally, make sure that another attempt is rejected.
   105  	require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.BootstrapTokens", &arg, &out))
   106  	require.Equal(t, 36, len(out.AccessorID))
   107  	require.NotEqual(t, oldID, out.AccessorID)
   108  	require.True(t, strings.HasPrefix(out.Description, "Bootstrap Token"))
   109  	require.Equal(t, out.Type, structs.ACLTokenTypeManagement)
   110  	require.True(t, out.CreateIndex > 0)
   111  	require.Equal(t, out.CreateIndex, out.ModifyIndex)
   112  }
   113  
   114  func TestACLEndpoint_Apply(t *testing.T) {
   115  	t.Parallel()
   116  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   117  		c.ACLDatacenter = "dc1"
   118  		c.ACLsEnabled = true
   119  		c.ACLMasterToken = "root"
   120  	})
   121  	defer os.RemoveAll(dir1)
   122  	defer s1.Shutdown()
   123  	codec := rpcClient(t, s1)
   124  	defer codec.Close()
   125  
   126  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   127  
   128  	arg := structs.ACLRequest{
   129  		Datacenter: "dc1",
   130  		Op:         structs.ACLSet,
   131  		ACL: structs.ACL{
   132  			Name: "User token",
   133  			Type: structs.ACLTokenTypeClient,
   134  		},
   135  		WriteRequest: structs.WriteRequest{Token: "root"},
   136  	}
   137  	var out string
   138  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   139  		t.Fatalf("err: %v", err)
   140  	}
   141  	id := out
   142  
   143  	// Verify
   144  	state := s1.fsm.State()
   145  	_, s, err := state.ACLTokenGetBySecret(nil, out)
   146  	if err != nil {
   147  		t.Fatalf("err: %v", err)
   148  	}
   149  	if s == nil {
   150  		t.Fatalf("should not be nil")
   151  	}
   152  	if s.SecretID != out {
   153  		t.Fatalf("bad: %v", s)
   154  	}
   155  	if s.Description != "User token" {
   156  		t.Fatalf("bad: %v", s)
   157  	}
   158  
   159  	// Do a delete
   160  	arg.Op = structs.ACLDelete
   161  	arg.ACL.ID = out
   162  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   163  		t.Fatalf("err: %v", err)
   164  	}
   165  
   166  	// Verify
   167  	_, s, err = state.ACLTokenGetBySecret(nil, id)
   168  	if err != nil {
   169  		t.Fatalf("err: %v", err)
   170  	}
   171  	if s != nil {
   172  		t.Fatalf("bad: %v", s)
   173  	}
   174  }
   175  
   176  func TestACLEndpoint_Update_PurgeCache(t *testing.T) {
   177  	t.Parallel()
   178  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   179  		c.ACLDatacenter = "dc1"
   180  		c.ACLsEnabled = true
   181  		c.ACLMasterToken = "root"
   182  	})
   183  	defer os.RemoveAll(dir1)
   184  	defer s1.Shutdown()
   185  	codec := rpcClient(t, s1)
   186  	defer codec.Close()
   187  
   188  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   189  
   190  	arg := structs.ACLRequest{
   191  		Datacenter: "dc1",
   192  		Op:         structs.ACLSet,
   193  		ACL: structs.ACL{
   194  			Name: "User token",
   195  			Type: structs.ACLTokenTypeClient,
   196  		},
   197  		WriteRequest: structs.WriteRequest{Token: "root"},
   198  	}
   199  	var out string
   200  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   201  		t.Fatalf("err: %v", err)
   202  	}
   203  	id := out
   204  
   205  	// Resolve
   206  	acl1, err := s1.ResolveToken(id)
   207  	if err != nil {
   208  		t.Fatalf("err: %v", err)
   209  	}
   210  	if acl1 == nil {
   211  		t.Fatalf("should not be nil")
   212  	}
   213  	if !acl1.KeyRead("foo") {
   214  		t.Fatalf("should be allowed")
   215  	}
   216  
   217  	// Do an update
   218  	arg.ACL.ID = out
   219  	arg.ACL.Rules = `{"key": {"": {"policy": "deny"}}}`
   220  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   221  		t.Fatalf("err: %v", err)
   222  	}
   223  
   224  	// Resolve again
   225  	acl2, err := s1.ResolveToken(id)
   226  	if err != nil {
   227  		t.Fatalf("err: %v", err)
   228  	}
   229  	if acl2 == nil {
   230  		t.Fatalf("should not be nil")
   231  	}
   232  	if acl2 == acl1 {
   233  		t.Fatalf("should not be cached")
   234  	}
   235  	if acl2.KeyRead("foo") {
   236  		t.Fatalf("should not be allowed")
   237  	}
   238  
   239  	// Do a delete
   240  	arg.Op = structs.ACLDelete
   241  	arg.ACL.Rules = ""
   242  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   243  		t.Fatalf("err: %v", err)
   244  	}
   245  
   246  	// Resolve again
   247  	acl3, err := s1.ResolveToken(id)
   248  	if !acl.IsErrNotFound(err) {
   249  		t.Fatalf("err: %v", err)
   250  	}
   251  	if acl3 != nil {
   252  		t.Fatalf("should be nil")
   253  	}
   254  }
   255  
   256  func TestACLEndpoint_Apply_CustomID(t *testing.T) {
   257  	t.Parallel()
   258  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   259  		c.ACLDatacenter = "dc1"
   260  		c.ACLsEnabled = true
   261  		c.ACLMasterToken = "root"
   262  	})
   263  	defer os.RemoveAll(dir1)
   264  	defer s1.Shutdown()
   265  	codec := rpcClient(t, s1)
   266  	defer codec.Close()
   267  
   268  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   269  
   270  	arg := structs.ACLRequest{
   271  		Datacenter: "dc1",
   272  		Op:         structs.ACLSet,
   273  		ACL: structs.ACL{
   274  			ID:   "foobarbaz", // Specify custom ID, does not exist
   275  			Name: "User token",
   276  			Type: structs.ACLTokenTypeClient,
   277  		},
   278  		WriteRequest: structs.WriteRequest{Token: "root"},
   279  	}
   280  	var out string
   281  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   282  		t.Fatalf("err: %v", err)
   283  	}
   284  	if out != "foobarbaz" {
   285  		t.Fatalf("bad token ID: %s", out)
   286  	}
   287  
   288  	// Verify
   289  	state := s1.fsm.State()
   290  	_, s, err := state.ACLTokenGetBySecret(nil, out)
   291  	if err != nil {
   292  		t.Fatalf("err: %v", err)
   293  	}
   294  	if s == nil {
   295  		t.Fatalf("should not be nil")
   296  	}
   297  	if s.SecretID != out {
   298  		t.Fatalf("bad: %v", s)
   299  	}
   300  	if s.Description != "User token" {
   301  		t.Fatalf("bad: %v", s)
   302  	}
   303  }
   304  
   305  func TestACLEndpoint_Apply_Denied(t *testing.T) {
   306  	t.Parallel()
   307  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   308  		c.ACLDatacenter = "dc1"
   309  		c.ACLsEnabled = true
   310  	})
   311  	defer os.RemoveAll(dir1)
   312  	defer s1.Shutdown()
   313  	codec := rpcClient(t, s1)
   314  	defer codec.Close()
   315  
   316  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   317  
   318  	arg := structs.ACLRequest{
   319  		Datacenter: "dc1",
   320  		Op:         structs.ACLSet,
   321  		ACL: structs.ACL{
   322  			Name: "User token",
   323  			Type: structs.ACLTokenTypeClient,
   324  		},
   325  	}
   326  	var out string
   327  	err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out)
   328  	if !acl.IsErrPermissionDenied(err) {
   329  		t.Fatalf("err: %v", err)
   330  	}
   331  }
   332  
   333  func TestACLEndpoint_Apply_DeleteAnon(t *testing.T) {
   334  	t.Parallel()
   335  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   336  		c.ACLDatacenter = "dc1"
   337  		c.ACLsEnabled = true
   338  		c.ACLMasterToken = "root"
   339  	})
   340  	defer os.RemoveAll(dir1)
   341  	defer s1.Shutdown()
   342  	codec := rpcClient(t, s1)
   343  	defer codec.Close()
   344  
   345  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   346  
   347  	arg := structs.ACLRequest{
   348  		Datacenter: "dc1",
   349  		Op:         structs.ACLDelete,
   350  		ACL: structs.ACL{
   351  			ID:   anonymousToken,
   352  			Name: "User token",
   353  			Type: structs.ACLTokenTypeClient,
   354  		},
   355  		WriteRequest: structs.WriteRequest{Token: "root"},
   356  	}
   357  	var out string
   358  	err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out)
   359  	if err == nil || !strings.Contains(err.Error(), "delete anonymous") {
   360  		t.Fatalf("err: %v", err)
   361  	}
   362  }
   363  
   364  func TestACLEndpoint_Apply_RootChange(t *testing.T) {
   365  	t.Parallel()
   366  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   367  		c.ACLDatacenter = "dc1"
   368  		c.ACLsEnabled = true
   369  		c.ACLMasterToken = "root"
   370  	})
   371  	defer os.RemoveAll(dir1)
   372  	defer s1.Shutdown()
   373  	codec := rpcClient(t, s1)
   374  	defer codec.Close()
   375  
   376  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   377  
   378  	arg := structs.ACLRequest{
   379  		Datacenter: "dc1",
   380  		Op:         structs.ACLSet,
   381  		ACL: structs.ACL{
   382  			ID:   "manage",
   383  			Name: "User token",
   384  			Type: structs.ACLTokenTypeClient,
   385  		},
   386  		WriteRequest: structs.WriteRequest{Token: "root"},
   387  	}
   388  	var out string
   389  	err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out)
   390  	if err == nil || !strings.Contains(err.Error(), "root ACL") {
   391  		t.Fatalf("err: %v", err)
   392  	}
   393  }
   394  
   395  func TestACLEndpoint_Get(t *testing.T) {
   396  	t.Parallel()
   397  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   398  		c.ACLDatacenter = "dc1"
   399  		c.ACLsEnabled = true
   400  		c.ACLMasterToken = "root"
   401  	})
   402  	defer os.RemoveAll(dir1)
   403  	defer s1.Shutdown()
   404  	codec := rpcClient(t, s1)
   405  	defer codec.Close()
   406  
   407  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   408  
   409  	arg := structs.ACLRequest{
   410  		Datacenter: "dc1",
   411  		Op:         structs.ACLSet,
   412  		ACL: structs.ACL{
   413  			Name: "User token",
   414  			Type: structs.ACLTokenTypeClient,
   415  		},
   416  		WriteRequest: structs.WriteRequest{Token: "root"},
   417  	}
   418  	var out string
   419  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   420  		t.Fatalf("err: %v", err)
   421  	}
   422  
   423  	getR := structs.ACLSpecificRequest{
   424  		Datacenter: "dc1",
   425  		ACL:        out,
   426  	}
   427  	var acls structs.IndexedACLs
   428  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Get", &getR, &acls); err != nil {
   429  		t.Fatalf("err: %v", err)
   430  	}
   431  
   432  	if acls.Index == 0 {
   433  		t.Fatalf("Bad: %v", acls)
   434  	}
   435  	if len(acls.ACLs) != 1 {
   436  		t.Fatalf("Bad: %v", acls)
   437  	}
   438  	s := acls.ACLs[0]
   439  	if s.ID != out {
   440  		t.Fatalf("bad: %v", s)
   441  	}
   442  }
   443  
   444  func TestACLEndpoint_GetPolicy(t *testing.T) {
   445  	t.Parallel()
   446  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   447  		c.ACLDatacenter = "dc1"
   448  		c.ACLsEnabled = true
   449  		c.ACLMasterToken = "root"
   450  	})
   451  	defer os.RemoveAll(dir1)
   452  	defer s1.Shutdown()
   453  	codec := rpcClient(t, s1)
   454  	defer codec.Close()
   455  
   456  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   457  
   458  	arg := structs.ACLRequest{
   459  		Datacenter: "dc1",
   460  		Op:         structs.ACLSet,
   461  		ACL: structs.ACL{
   462  			Name: "User token",
   463  			Type: structs.ACLTokenTypeClient,
   464  		},
   465  		WriteRequest: structs.WriteRequest{Token: "root"},
   466  	}
   467  	var out string
   468  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   469  		t.Fatalf("err: %v", err)
   470  	}
   471  
   472  	getR := structs.ACLPolicyResolveLegacyRequest{
   473  		Datacenter: "dc1",
   474  		ACL:        out,
   475  	}
   476  
   477  	var acls structs.ACLPolicyResolveLegacyResponse
   478  	retry.Run(t, func(r *retry.R) {
   479  
   480  		if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", &getR, &acls); err != nil {
   481  			t.Fatalf("err: %v", err)
   482  		}
   483  
   484  		if acls.Policy == nil {
   485  			t.Fatalf("Bad: %v", acls)
   486  		}
   487  		if acls.TTL != 30*time.Second {
   488  			t.Fatalf("bad: %v", acls)
   489  		}
   490  	})
   491  
   492  	// Do a conditional lookup with etag
   493  	getR.ETag = acls.ETag
   494  	var out2 structs.ACLPolicyResolveLegacyResponse
   495  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", &getR, &out2); err != nil {
   496  		t.Fatalf("err: %v", err)
   497  	}
   498  
   499  	if out2.Policy != nil {
   500  		t.Fatalf("Bad: %v", out2)
   501  	}
   502  	if out2.TTL != 30*time.Second {
   503  		t.Fatalf("bad: %v", out2)
   504  	}
   505  }
   506  
   507  func TestACLEndpoint_List(t *testing.T) {
   508  	t.Parallel()
   509  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   510  		c.ACLDatacenter = "dc1"
   511  		c.ACLsEnabled = true
   512  		c.ACLMasterToken = "root"
   513  	})
   514  	defer os.RemoveAll(dir1)
   515  	defer s1.Shutdown()
   516  	codec := rpcClient(t, s1)
   517  	defer codec.Close()
   518  
   519  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   520  
   521  	ids := []string{}
   522  	for i := 0; i < 5; i++ {
   523  		arg := structs.ACLRequest{
   524  			Datacenter: "dc1",
   525  			Op:         structs.ACLSet,
   526  			ACL: structs.ACL{
   527  				Name: "User token",
   528  				Type: structs.ACLTokenTypeClient,
   529  			},
   530  			WriteRequest: structs.WriteRequest{Token: "root"},
   531  		}
   532  		var out string
   533  		if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
   534  			t.Fatalf("err: %v", err)
   535  		}
   536  		ids = append(ids, out)
   537  	}
   538  
   539  	getR := structs.DCSpecificRequest{
   540  		Datacenter:   "dc1",
   541  		QueryOptions: structs.QueryOptions{Token: "root"},
   542  	}
   543  	var acls structs.IndexedACLs
   544  	if err := msgpackrpc.CallWithCodec(codec, "ACL.List", &getR, &acls); err != nil {
   545  		t.Fatalf("err: %v", err)
   546  	}
   547  
   548  	if acls.Index == 0 {
   549  		t.Fatalf("Bad: %v", acls)
   550  	}
   551  
   552  	// 5  + master
   553  	if len(acls.ACLs) != 6 {
   554  		t.Fatalf("Bad: %v", acls.ACLs)
   555  	}
   556  	for i := 0; i < len(acls.ACLs); i++ {
   557  		s := acls.ACLs[i]
   558  		if s.ID == anonymousToken || s.ID == "root" {
   559  			continue
   560  		}
   561  		if !lib.StrContains(ids, s.ID) {
   562  			t.Fatalf("bad: %v", s)
   563  		}
   564  		if s.Name != "User token" {
   565  			t.Fatalf("bad: %v", s)
   566  		}
   567  	}
   568  }
   569  
   570  func TestACLEndpoint_List_Denied(t *testing.T) {
   571  	t.Parallel()
   572  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   573  		c.ACLDatacenter = "dc1"
   574  		c.ACLsEnabled = true
   575  	})
   576  	defer os.RemoveAll(dir1)
   577  	defer s1.Shutdown()
   578  	codec := rpcClient(t, s1)
   579  	defer codec.Close()
   580  
   581  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   582  
   583  	getR := structs.DCSpecificRequest{
   584  		Datacenter: "dc1",
   585  	}
   586  	var acls structs.IndexedACLs
   587  	err := msgpackrpc.CallWithCodec(codec, "ACL.List", &getR, &acls)
   588  	if !acl.IsErrPermissionDenied(err) {
   589  		t.Fatalf("err: %v", err)
   590  	}
   591  }
   592  
   593  func TestACLEndpoint_ReplicationStatus(t *testing.T) {
   594  	t.Parallel()
   595  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   596  		c.ACLDatacenter = "dc2"
   597  		c.ACLsEnabled = true
   598  		c.ACLTokenReplication = true
   599  		c.ACLReplicationRate = 100
   600  		c.ACLReplicationBurst = 100
   601  	})
   602  	s1.tokens.UpdateReplicationToken("secret", tokenStore.TokenSourceConfig)
   603  	defer os.RemoveAll(dir1)
   604  	defer s1.Shutdown()
   605  	codec := rpcClient(t, s1)
   606  	defer codec.Close()
   607  
   608  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   609  
   610  	getR := structs.DCSpecificRequest{
   611  		Datacenter: "dc1",
   612  	}
   613  
   614  	retry.Run(t, func(r *retry.R) {
   615  		var status structs.ACLReplicationStatus
   616  		err := msgpackrpc.CallWithCodec(codec, "ACL.ReplicationStatus", &getR, &status)
   617  		if err != nil {
   618  			r.Fatalf("err: %v", err)
   619  		}
   620  		if !status.Enabled || !status.Running || status.SourceDatacenter != "dc2" {
   621  			r.Fatalf("bad: %#v", status)
   622  		}
   623  	})
   624  }
   625  
   626  func TestACLEndpoint_TokenRead(t *testing.T) {
   627  	t.Parallel()
   628  
   629  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   630  		c.ACLDatacenter = "dc1"
   631  		c.ACLsEnabled = true
   632  		c.ACLMasterToken = "root"
   633  	})
   634  	defer os.RemoveAll(dir1)
   635  	defer s1.Shutdown()
   636  	codec := rpcClient(t, s1)
   637  	defer codec.Close()
   638  
   639  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   640  
   641  	token, err := upsertTestToken(codec, "root", "dc1")
   642  	if err != nil {
   643  		t.Fatalf("err: %v", err)
   644  	}
   645  
   646  	acl := ACL{srv: s1}
   647  
   648  	t.Run("exists and matches what we created", func(t *testing.T) {
   649  		req := structs.ACLTokenGetRequest{
   650  			Datacenter:   "dc1",
   651  			TokenID:      token.AccessorID,
   652  			TokenIDType:  structs.ACLTokenAccessor,
   653  			QueryOptions: structs.QueryOptions{Token: "root"},
   654  		}
   655  
   656  		resp := structs.ACLTokenResponse{}
   657  
   658  		err := acl.TokenRead(&req, &resp)
   659  		require.NoError(t, err)
   660  
   661  		if !reflect.DeepEqual(resp.Token, token) {
   662  			t.Fatalf("tokens are not equal: %v != %v", resp.Token, token)
   663  		}
   664  	})
   665  
   666  	t.Run("nil when token does not exist", func(t *testing.T) {
   667  		fakeID, err := uuid.GenerateUUID()
   668  		require.NoError(t, err)
   669  
   670  		req := structs.ACLTokenGetRequest{
   671  			Datacenter:   "dc1",
   672  			TokenID:      fakeID,
   673  			TokenIDType:  structs.ACLTokenAccessor,
   674  			QueryOptions: structs.QueryOptions{Token: "root"},
   675  		}
   676  
   677  		resp := structs.ACLTokenResponse{}
   678  
   679  		err = acl.TokenRead(&req, &resp)
   680  		require.Nil(t, resp.Token)
   681  		require.NoError(t, err)
   682  	})
   683  
   684  	t.Run("validates ID format", func(t *testing.T) {
   685  		req := structs.ACLTokenGetRequest{
   686  			Datacenter:   "dc1",
   687  			TokenID:      "definitely-really-certainly-not-a-uuid",
   688  			TokenIDType:  structs.ACLTokenAccessor,
   689  			QueryOptions: structs.QueryOptions{Token: "root"},
   690  		}
   691  
   692  		resp := structs.ACLTokenResponse{}
   693  
   694  		err := acl.TokenRead(&req, &resp)
   695  		require.Nil(t, resp.Token)
   696  		require.EqualError(t, err, "failed acl token lookup: failed acl token lookup: index error: UUID must be 36 characters")
   697  	})
   698  }
   699  
   700  func TestACLEndpoint_TokenClone(t *testing.T) {
   701  	t.Parallel()
   702  
   703  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   704  		c.ACLDatacenter = "dc1"
   705  		c.ACLsEnabled = true
   706  		c.ACLMasterToken = "root"
   707  	})
   708  	defer os.RemoveAll(dir1)
   709  	defer s1.Shutdown()
   710  	codec := rpcClient(t, s1)
   711  	defer codec.Close()
   712  
   713  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   714  
   715  	t1, err := upsertTestToken(codec, "root", "dc1")
   716  	require.NoError(t, err)
   717  
   718  	acl := ACL{srv: s1}
   719  
   720  	req := structs.ACLTokenSetRequest{
   721  		Datacenter:   "dc1",
   722  		ACLToken:     structs.ACLToken{AccessorID: t1.AccessorID},
   723  		WriteRequest: structs.WriteRequest{Token: "root"},
   724  	}
   725  
   726  	t2 := structs.ACLToken{}
   727  
   728  	err = acl.TokenClone(&req, &t2)
   729  	require.NoError(t, err)
   730  
   731  	require.Equal(t, t1.Description, t2.Description)
   732  	require.Equal(t, t1.Policies, t2.Policies)
   733  	require.Equal(t, t1.Rules, t2.Rules)
   734  	require.Equal(t, t1.Local, t2.Local)
   735  	require.NotEqual(t, t1.AccessorID, t2.AccessorID)
   736  	require.NotEqual(t, t1.SecretID, t2.SecretID)
   737  }
   738  
   739  func TestACLEndpoint_TokenSet(t *testing.T) {
   740  	t.Parallel()
   741  
   742  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   743  		c.ACLDatacenter = "dc1"
   744  		c.ACLsEnabled = true
   745  		c.ACLMasterToken = "root"
   746  	})
   747  	defer os.RemoveAll(dir1)
   748  	defer s1.Shutdown()
   749  	codec := rpcClient(t, s1)
   750  	defer codec.Close()
   751  
   752  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   753  
   754  	acl := ACL{srv: s1}
   755  	var tokenID string
   756  
   757  	t.Run("Create it", func(t *testing.T) {
   758  		req := structs.ACLTokenSetRequest{
   759  			Datacenter: "dc1",
   760  			ACLToken: structs.ACLToken{
   761  				Description: "foobar",
   762  				Policies:    nil,
   763  				Local:       false,
   764  			},
   765  			WriteRequest: structs.WriteRequest{Token: "root"},
   766  		}
   767  
   768  		resp := structs.ACLToken{}
   769  
   770  		err := acl.TokenSet(&req, &resp)
   771  		require.NoError(t, err)
   772  
   773  		// Get the token directly to validate that it exists
   774  		tokenResp, err := retrieveTestToken(codec, "root", "dc1", resp.AccessorID)
   775  		require.NoError(t, err)
   776  		token := tokenResp.Token
   777  
   778  		require.NotNil(t, token.AccessorID)
   779  		require.Equal(t, token.Description, "foobar")
   780  		require.Equal(t, token.AccessorID, resp.AccessorID)
   781  
   782  		tokenID = token.AccessorID
   783  	})
   784  
   785  	t.Run("Update it", func(t *testing.T) {
   786  		req := structs.ACLTokenSetRequest{
   787  			Datacenter: "dc1",
   788  			ACLToken: structs.ACLToken{
   789  				Description: "new-description",
   790  				AccessorID:  tokenID,
   791  			},
   792  			WriteRequest: structs.WriteRequest{Token: "root"},
   793  		}
   794  
   795  		resp := structs.ACLToken{}
   796  
   797  		err := acl.TokenSet(&req, &resp)
   798  		require.NoError(t, err)
   799  
   800  		// Get the token directly to validate that it exists
   801  		tokenResp, err := retrieveTestToken(codec, "root", "dc1", resp.AccessorID)
   802  		require.NoError(t, err)
   803  		token := tokenResp.Token
   804  
   805  		require.NotNil(t, token.AccessorID)
   806  		require.Equal(t, token.Description, "new-description")
   807  		require.Equal(t, token.AccessorID, resp.AccessorID)
   808  	})
   809  }
   810  
   811  func TestACLEndpoint_TokenSet_anon(t *testing.T) {
   812  	t.Parallel()
   813  
   814  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   815  		c.ACLDatacenter = "dc1"
   816  		c.ACLsEnabled = true
   817  		c.ACLMasterToken = "root"
   818  	})
   819  	defer os.RemoveAll(dir1)
   820  	defer s1.Shutdown()
   821  	codec := rpcClient(t, s1)
   822  	defer codec.Close()
   823  
   824  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   825  	policy, err := upsertTestPolicy(codec, "root", "dc1")
   826  	require.NoError(t, err)
   827  
   828  	acl := ACL{srv: s1}
   829  
   830  	// Assign the policies to a token
   831  	tokenUpsertReq := structs.ACLTokenSetRequest{
   832  		Datacenter: "dc1",
   833  		ACLToken: structs.ACLToken{
   834  			AccessorID: structs.ACLTokenAnonymousID,
   835  			Policies: []structs.ACLTokenPolicyLink{
   836  				structs.ACLTokenPolicyLink{
   837  					ID: policy.ID,
   838  				},
   839  			},
   840  		},
   841  		WriteRequest: structs.WriteRequest{Token: "root"},
   842  	}
   843  	token := structs.ACLToken{}
   844  	err = acl.TokenSet(&tokenUpsertReq, &token)
   845  	require.NoError(t, err)
   846  	require.NotEmpty(t, token.SecretID)
   847  
   848  	tokenResp, err := retrieveTestToken(codec, "root", "dc1", structs.ACLTokenAnonymousID)
   849  	require.Equal(t, len(tokenResp.Token.Policies), 1)
   850  	require.Equal(t, tokenResp.Token.Policies[0].ID, policy.ID)
   851  }
   852  
   853  func TestACLEndpoint_TokenDelete(t *testing.T) {
   854  	t.Parallel()
   855  
   856  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   857  		c.ACLDatacenter = "dc1"
   858  		c.ACLsEnabled = true
   859  		c.ACLMasterToken = "root"
   860  	})
   861  	defer os.RemoveAll(dir1)
   862  	defer s1.Shutdown()
   863  	codec := rpcClient(t, s1)
   864  	defer codec.Close()
   865  
   866  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   867  
   868  	dir2, s2 := testServerWithConfig(t, func(c *Config) {
   869  		c.ACLDatacenter = "dc1"
   870  		c.ACLsEnabled = true
   871  		c.Datacenter = "dc2"
   872  		// token replication is required to test deleting non-local tokens in secondary dc
   873  		c.ACLTokenReplication = true
   874  	})
   875  	defer os.RemoveAll(dir2)
   876  	defer s2.Shutdown()
   877  	codec2 := rpcClient(t, s2)
   878  	defer codec2.Close()
   879  
   880  	s2.tokens.UpdateReplicationToken("root", tokenStore.TokenSourceConfig)
   881  
   882  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   883  	testrpc.WaitForLeader(t, s2.RPC, "dc2")
   884  
   885  	// Try to join
   886  	joinWAN(t, s2, s1)
   887  
   888  	existingToken, err := upsertTestToken(codec, "root", "dc1")
   889  	require.NoError(t, err)
   890  
   891  	acl := ACL{srv: s1}
   892  	acl2 := ACL{srv: s2}
   893  
   894  	t.Run("deletes a token", func(t *testing.T) {
   895  		req := structs.ACLTokenDeleteRequest{
   896  			Datacenter:   "dc1",
   897  			TokenID:      existingToken.AccessorID,
   898  			WriteRequest: structs.WriteRequest{Token: "root"},
   899  		}
   900  
   901  		var resp string
   902  
   903  		err = acl.TokenDelete(&req, &resp)
   904  		require.NoError(t, err)
   905  
   906  		// Make sure the token is gone
   907  		tokenResp, err := retrieveTestToken(codec, "root", "dc1", existingToken.AccessorID)
   908  		require.Nil(t, tokenResp.Token)
   909  		require.NoError(t, err)
   910  	})
   911  
   912  	t.Run("can't delete itself", func(t *testing.T) {
   913  		readReq := structs.ACLTokenGetRequest{
   914  			Datacenter:   "dc1",
   915  			TokenID:      "root",
   916  			TokenIDType:  structs.ACLTokenSecret,
   917  			QueryOptions: structs.QueryOptions{Token: "root"},
   918  		}
   919  
   920  		var out structs.ACLTokenResponse
   921  
   922  		err := msgpackrpc.CallWithCodec(codec, "ACL.TokenRead", &readReq, &out)
   923  
   924  		require.NoError(t, err)
   925  
   926  		req := structs.ACLTokenDeleteRequest{
   927  			Datacenter:   "dc1",
   928  			TokenID:      out.Token.AccessorID,
   929  			WriteRequest: structs.WriteRequest{Token: "root"},
   930  		}
   931  
   932  		var resp string
   933  		err = acl.TokenDelete(&req, &resp)
   934  		require.EqualError(t, err, "Deletion of the request's authorization token is not permitted")
   935  	})
   936  
   937  	t.Run("errors when token doesn't exist", func(t *testing.T) {
   938  		fakeID, err := uuid.GenerateUUID()
   939  		require.NoError(t, err)
   940  
   941  		req := structs.ACLTokenDeleteRequest{
   942  			Datacenter:   "dc1",
   943  			TokenID:      fakeID,
   944  			WriteRequest: structs.WriteRequest{Token: "root"},
   945  		}
   946  
   947  		var resp string
   948  
   949  		err = acl.TokenDelete(&req, &resp)
   950  		require.NoError(t, err)
   951  
   952  		// token should be nil
   953  		tokenResp, err := retrieveTestToken(codec, "root", "dc1", existingToken.AccessorID)
   954  		require.Nil(t, tokenResp.Token)
   955  		require.NoError(t, err)
   956  	})
   957  
   958  	t.Run("don't segfault when attempting to delete non existent token in secondary dc", func(t *testing.T) {
   959  		fakeID, err := uuid.GenerateUUID()
   960  		require.NoError(t, err)
   961  
   962  		req := structs.ACLTokenDeleteRequest{
   963  			Datacenter:   "dc2",
   964  			TokenID:      fakeID,
   965  			WriteRequest: structs.WriteRequest{Token: "root"},
   966  		}
   967  
   968  		var resp string
   969  
   970  		waitForNewACLs(t, s2)
   971  
   972  		err = acl2.TokenDelete(&req, &resp)
   973  		require.NoError(t, err)
   974  
   975  		// token should be nil
   976  		tokenResp, err := retrieveTestToken(codec2, "root", "dc1", existingToken.AccessorID)
   977  		require.Nil(t, tokenResp.Token)
   978  		require.NoError(t, err)
   979  	})
   980  }
   981  
   982  func TestACLEndpoint_TokenDelete_anon(t *testing.T) {
   983  	t.Parallel()
   984  
   985  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   986  		c.ACLDatacenter = "dc1"
   987  		c.ACLsEnabled = true
   988  		c.ACLMasterToken = "root"
   989  	})
   990  	defer os.RemoveAll(dir1)
   991  	defer s1.Shutdown()
   992  	codec := rpcClient(t, s1)
   993  	defer codec.Close()
   994  
   995  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   996  
   997  	acl := ACL{srv: s1}
   998  
   999  	req := structs.ACLTokenDeleteRequest{
  1000  		Datacenter:   "dc1",
  1001  		TokenID:      structs.ACLTokenAnonymousID,
  1002  		WriteRequest: structs.WriteRequest{Token: "root"},
  1003  	}
  1004  
  1005  	var resp string
  1006  
  1007  	err := acl.TokenDelete(&req, &resp)
  1008  	require.EqualError(t, err, "Delete operation not permitted on the anonymous token")
  1009  
  1010  	// Make sure the token is still there
  1011  	tokenResp, err := retrieveTestToken(codec, "root", "dc1", structs.ACLTokenAnonymousID)
  1012  	require.NotNil(t, tokenResp.Token)
  1013  }
  1014  
  1015  func TestACLEndpoint_TokenList(t *testing.T) {
  1016  	t.Parallel()
  1017  
  1018  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1019  		c.ACLDatacenter = "dc1"
  1020  		c.ACLsEnabled = true
  1021  		c.ACLMasterToken = "root"
  1022  	})
  1023  	defer os.RemoveAll(dir1)
  1024  	defer s1.Shutdown()
  1025  	codec := rpcClient(t, s1)
  1026  	defer codec.Close()
  1027  
  1028  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1029  
  1030  	t1, err := upsertTestToken(codec, "root", "dc1")
  1031  	require.NoError(t, err)
  1032  
  1033  	t2, err := upsertTestToken(codec, "root", "dc1")
  1034  	require.NoError(t, err)
  1035  
  1036  	acl := ACL{srv: s1}
  1037  
  1038  	req := structs.ACLTokenListRequest{
  1039  		Datacenter:   "dc1",
  1040  		QueryOptions: structs.QueryOptions{Token: "root"},
  1041  	}
  1042  
  1043  	resp := structs.ACLTokenListResponse{}
  1044  
  1045  	err = acl.TokenList(&req, &resp)
  1046  	require.NoError(t, err)
  1047  
  1048  	tokens := []string{t1.AccessorID, t2.AccessorID}
  1049  	var retrievedTokens []string
  1050  
  1051  	for _, v := range resp.Tokens {
  1052  		retrievedTokens = append(retrievedTokens, v.AccessorID)
  1053  	}
  1054  	require.Subset(t, retrievedTokens, tokens)
  1055  }
  1056  
  1057  func TestACLEndpoint_TokenBatchRead(t *testing.T) {
  1058  	t.Parallel()
  1059  
  1060  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1061  		c.ACLDatacenter = "dc1"
  1062  		c.ACLsEnabled = true
  1063  		c.ACLMasterToken = "root"
  1064  	})
  1065  	defer os.RemoveAll(dir1)
  1066  	defer s1.Shutdown()
  1067  	codec := rpcClient(t, s1)
  1068  	defer codec.Close()
  1069  
  1070  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1071  
  1072  	t1, err := upsertTestToken(codec, "root", "dc1")
  1073  	require.NoError(t, err)
  1074  
  1075  	t2, err := upsertTestToken(codec, "root", "dc1")
  1076  	require.NoError(t, err)
  1077  
  1078  	acl := ACL{srv: s1}
  1079  	tokens := []string{t1.AccessorID, t2.AccessorID}
  1080  
  1081  	req := structs.ACLTokenBatchGetRequest{
  1082  		Datacenter:   "dc1",
  1083  		AccessorIDs:  tokens,
  1084  		QueryOptions: structs.QueryOptions{Token: "root"},
  1085  	}
  1086  
  1087  	resp := structs.ACLTokenBatchResponse{}
  1088  
  1089  	err = acl.TokenBatchRead(&req, &resp)
  1090  	require.NoError(t, err)
  1091  
  1092  	var retrievedTokens []string
  1093  
  1094  	for _, v := range resp.Tokens {
  1095  		retrievedTokens = append(retrievedTokens, v.AccessorID)
  1096  	}
  1097  	require.EqualValues(t, retrievedTokens, tokens)
  1098  }
  1099  
  1100  func TestACLEndpoint_PolicyRead(t *testing.T) {
  1101  	t.Parallel()
  1102  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1103  		c.ACLDatacenter = "dc1"
  1104  		c.ACLsEnabled = true
  1105  		c.ACLMasterToken = "root"
  1106  	})
  1107  	defer os.RemoveAll(dir1)
  1108  	defer s1.Shutdown()
  1109  	codec := rpcClient(t, s1)
  1110  	defer codec.Close()
  1111  
  1112  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1113  
  1114  	policy, err := upsertTestPolicy(codec, "root", "dc1")
  1115  	if err != nil {
  1116  		t.Fatalf("err: %v", err)
  1117  	}
  1118  
  1119  	acl := ACL{srv: s1}
  1120  
  1121  	req := structs.ACLPolicyGetRequest{
  1122  		Datacenter:   "dc1",
  1123  		PolicyID:     policy.ID,
  1124  		QueryOptions: structs.QueryOptions{Token: "root"},
  1125  	}
  1126  
  1127  	resp := structs.ACLPolicyResponse{}
  1128  
  1129  	err = acl.PolicyRead(&req, &resp)
  1130  	if err != nil {
  1131  		t.Fatalf("err: %v", err)
  1132  	}
  1133  
  1134  	if !reflect.DeepEqual(resp.Policy, policy) {
  1135  		t.Fatalf("tokens are not equal: %v != %v", resp.Policy, policy)
  1136  	}
  1137  }
  1138  
  1139  func TestACLEndpoint_PolicyBatchRead(t *testing.T) {
  1140  	t.Parallel()
  1141  
  1142  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1143  		c.ACLDatacenter = "dc1"
  1144  		c.ACLsEnabled = true
  1145  		c.ACLMasterToken = "root"
  1146  	})
  1147  	defer os.RemoveAll(dir1)
  1148  	defer s1.Shutdown()
  1149  	codec := rpcClient(t, s1)
  1150  	defer codec.Close()
  1151  
  1152  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1153  
  1154  	p1, err := upsertTestPolicy(codec, "root", "dc1")
  1155  	require.NoError(t, err)
  1156  
  1157  	p2, err := upsertTestPolicy(codec, "root", "dc1")
  1158  	require.NoError(t, err)
  1159  
  1160  	acl := ACL{srv: s1}
  1161  	policies := []string{p1.ID, p2.ID}
  1162  
  1163  	req := structs.ACLPolicyBatchGetRequest{
  1164  		Datacenter:   "dc1",
  1165  		PolicyIDs:    policies,
  1166  		QueryOptions: structs.QueryOptions{Token: "root"},
  1167  	}
  1168  
  1169  	resp := structs.ACLPolicyBatchResponse{}
  1170  
  1171  	err = acl.PolicyBatchRead(&req, &resp)
  1172  	require.NoError(t, err)
  1173  
  1174  	var retrievedPolicies []string
  1175  
  1176  	for _, v := range resp.Policies {
  1177  		retrievedPolicies = append(retrievedPolicies, v.ID)
  1178  	}
  1179  	require.EqualValues(t, retrievedPolicies, policies)
  1180  }
  1181  
  1182  func TestACLEndpoint_PolicySet(t *testing.T) {
  1183  	t.Parallel()
  1184  
  1185  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1186  		c.ACLDatacenter = "dc1"
  1187  		c.ACLsEnabled = true
  1188  		c.ACLMasterToken = "root"
  1189  	})
  1190  	defer os.RemoveAll(dir1)
  1191  	defer s1.Shutdown()
  1192  	codec := rpcClient(t, s1)
  1193  	defer codec.Close()
  1194  
  1195  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1196  
  1197  	acl := ACL{srv: s1}
  1198  	var policyID string
  1199  
  1200  	// Create it
  1201  	{
  1202  		req := structs.ACLPolicySetRequest{
  1203  			Datacenter: "dc1",
  1204  			Policy: structs.ACLPolicy{
  1205  				Description: "foobar",
  1206  				Name:        "baz",
  1207  				Rules:       "service \"\" { policy = \"read\" }",
  1208  			},
  1209  			WriteRequest: structs.WriteRequest{Token: "root"},
  1210  		}
  1211  		resp := structs.ACLPolicy{}
  1212  
  1213  		err := acl.PolicySet(&req, &resp)
  1214  		require.NoError(t, err)
  1215  		require.NotNil(t, resp.ID)
  1216  
  1217  		// Get the policy directly to validate that it exists
  1218  		policyResp, err := retrieveTestPolicy(codec, "root", "dc1", resp.ID)
  1219  		require.NoError(t, err)
  1220  		policy := policyResp.Policy
  1221  
  1222  		require.NotNil(t, policy.ID)
  1223  		require.Equal(t, policy.Description, "foobar")
  1224  		require.Equal(t, policy.Name, "baz")
  1225  		require.Equal(t, policy.Rules, "service \"\" { policy = \"read\" }")
  1226  
  1227  		policyID = policy.ID
  1228  	}
  1229  
  1230  	// Update it
  1231  	{
  1232  		req := structs.ACLPolicySetRequest{
  1233  			Datacenter: "dc1",
  1234  			Policy: structs.ACLPolicy{
  1235  				ID:          policyID,
  1236  				Description: "bat",
  1237  				Name:        "bar",
  1238  				Rules:       "service \"\" { policy = \"write\" }",
  1239  			},
  1240  			WriteRequest: structs.WriteRequest{Token: "root"},
  1241  		}
  1242  		resp := structs.ACLPolicy{}
  1243  
  1244  		err := acl.PolicySet(&req, &resp)
  1245  		require.NoError(t, err)
  1246  		require.NotNil(t, resp.ID)
  1247  
  1248  		// Get the policy directly to validate that it exists
  1249  		policyResp, err := retrieveTestPolicy(codec, "root", "dc1", resp.ID)
  1250  		require.NoError(t, err)
  1251  		policy := policyResp.Policy
  1252  
  1253  		require.NotNil(t, policy.ID)
  1254  		require.Equal(t, policy.Description, "bat")
  1255  		require.Equal(t, policy.Name, "bar")
  1256  		require.Equal(t, policy.Rules, "service \"\" { policy = \"write\" }")
  1257  	}
  1258  }
  1259  
  1260  func TestACLEndpoint_PolicySet_globalManagement(t *testing.T) {
  1261  	t.Parallel()
  1262  
  1263  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1264  		c.ACLDatacenter = "dc1"
  1265  		c.ACLsEnabled = true
  1266  		c.ACLMasterToken = "root"
  1267  	})
  1268  	defer os.RemoveAll(dir1)
  1269  	defer s1.Shutdown()
  1270  	codec := rpcClient(t, s1)
  1271  	defer codec.Close()
  1272  
  1273  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1274  
  1275  	acl := ACL{srv: s1}
  1276  
  1277  	// Can't change the rules
  1278  	{
  1279  
  1280  		req := structs.ACLPolicySetRequest{
  1281  			Datacenter: "dc1",
  1282  			Policy: structs.ACLPolicy{
  1283  				ID:    structs.ACLPolicyGlobalManagementID,
  1284  				Name:  "foobar", // This is required to get past validation
  1285  				Rules: "service \"\" { policy = \"write\" }",
  1286  			},
  1287  			WriteRequest: structs.WriteRequest{Token: "root"},
  1288  		}
  1289  		resp := structs.ACLPolicy{}
  1290  
  1291  		err := acl.PolicySet(&req, &resp)
  1292  		require.EqualError(t, err, "Changing the Rules for the builtin global-management policy is not permitted")
  1293  	}
  1294  
  1295  	// Can rename it
  1296  	{
  1297  		req := structs.ACLPolicySetRequest{
  1298  			Datacenter: "dc1",
  1299  			Policy: structs.ACLPolicy{
  1300  				ID:    structs.ACLPolicyGlobalManagementID,
  1301  				Name:  "foobar",
  1302  				Rules: structs.ACLPolicyGlobalManagement,
  1303  			},
  1304  			WriteRequest: structs.WriteRequest{Token: "root"},
  1305  		}
  1306  		resp := structs.ACLPolicy{}
  1307  
  1308  		err := acl.PolicySet(&req, &resp)
  1309  		require.NoError(t, err)
  1310  
  1311  		// Get the policy again
  1312  		policyResp, err := retrieveTestPolicy(codec, "root", "dc1", structs.ACLPolicyGlobalManagementID)
  1313  		require.NoError(t, err)
  1314  		policy := policyResp.Policy
  1315  
  1316  		require.Equal(t, policy.ID, structs.ACLPolicyGlobalManagementID)
  1317  		require.Equal(t, policy.Name, "foobar")
  1318  
  1319  	}
  1320  }
  1321  
  1322  func TestACLEndpoint_PolicyDelete(t *testing.T) {
  1323  	t.Parallel()
  1324  
  1325  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1326  		c.ACLDatacenter = "dc1"
  1327  		c.ACLsEnabled = true
  1328  		c.ACLMasterToken = "root"
  1329  	})
  1330  	defer os.RemoveAll(dir1)
  1331  	defer s1.Shutdown()
  1332  	codec := rpcClient(t, s1)
  1333  	defer codec.Close()
  1334  
  1335  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1336  
  1337  	existingPolicy, err := upsertTestPolicy(codec, "root", "dc1")
  1338  	if err != nil {
  1339  		t.Fatalf("err: %v", err)
  1340  	}
  1341  
  1342  	acl := ACL{srv: s1}
  1343  
  1344  	req := structs.ACLPolicyDeleteRequest{
  1345  		Datacenter:   "dc1",
  1346  		PolicyID:     existingPolicy.ID,
  1347  		WriteRequest: structs.WriteRequest{Token: "root"},
  1348  	}
  1349  
  1350  	var resp string
  1351  
  1352  	err = acl.PolicyDelete(&req, &resp)
  1353  	require.NoError(t, err)
  1354  
  1355  	// Make sure the policy is gone
  1356  	tokenResp, err := retrieveTestPolicy(codec, "root", "dc1", existingPolicy.ID)
  1357  	require.Nil(t, tokenResp.Policy)
  1358  }
  1359  
  1360  func TestACLEndpoint_PolicyDelete_globalManagement(t *testing.T) {
  1361  	t.Parallel()
  1362  
  1363  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1364  		c.ACLDatacenter = "dc1"
  1365  		c.ACLsEnabled = true
  1366  		c.ACLMasterToken = "root"
  1367  	})
  1368  	defer os.RemoveAll(dir1)
  1369  	defer s1.Shutdown()
  1370  	codec := rpcClient(t, s1)
  1371  	defer codec.Close()
  1372  
  1373  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1374  
  1375  	acl := ACL{srv: s1}
  1376  
  1377  	req := structs.ACLPolicyDeleteRequest{
  1378  		Datacenter:   "dc1",
  1379  		PolicyID:     structs.ACLPolicyGlobalManagementID,
  1380  		WriteRequest: structs.WriteRequest{Token: "root"},
  1381  	}
  1382  	var resp string
  1383  
  1384  	err := acl.PolicyDelete(&req, &resp)
  1385  
  1386  	require.EqualError(t, err, "Delete operation not permitted on the builtin global-management policy")
  1387  }
  1388  
  1389  func TestACLEndpoint_PolicyList(t *testing.T) {
  1390  	t.Parallel()
  1391  
  1392  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1393  		c.ACLDatacenter = "dc1"
  1394  		c.ACLsEnabled = true
  1395  		c.ACLMasterToken = "root"
  1396  	})
  1397  	defer os.RemoveAll(dir1)
  1398  	defer s1.Shutdown()
  1399  	codec := rpcClient(t, s1)
  1400  	defer codec.Close()
  1401  
  1402  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1403  
  1404  	p1, err := upsertTestPolicy(codec, "root", "dc1")
  1405  	require.NoError(t, err)
  1406  
  1407  	p2, err := upsertTestPolicy(codec, "root", "dc1")
  1408  	require.NoError(t, err)
  1409  
  1410  	acl := ACL{srv: s1}
  1411  
  1412  	req := structs.ACLPolicyListRequest{
  1413  		Datacenter:   "dc1",
  1414  		QueryOptions: structs.QueryOptions{Token: "root"},
  1415  	}
  1416  
  1417  	resp := structs.ACLPolicyListResponse{}
  1418  
  1419  	err = acl.PolicyList(&req, &resp)
  1420  	require.NoError(t, err)
  1421  
  1422  	policies := []string{p1.ID, p2.ID}
  1423  	var retrievedPolicies []string
  1424  
  1425  	for _, v := range resp.Policies {
  1426  		retrievedPolicies = append(retrievedPolicies, v.ID)
  1427  	}
  1428  	require.Subset(t, retrievedPolicies, policies)
  1429  }
  1430  
  1431  func TestACLEndpoint_PolicyResolve(t *testing.T) {
  1432  	t.Parallel()
  1433  
  1434  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1435  		c.ACLDatacenter = "dc1"
  1436  		c.ACLsEnabled = true
  1437  		c.ACLMasterToken = "root"
  1438  	})
  1439  	defer os.RemoveAll(dir1)
  1440  	defer s1.Shutdown()
  1441  	codec := rpcClient(t, s1)
  1442  	defer codec.Close()
  1443  
  1444  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1445  
  1446  	p1, err := upsertTestPolicy(codec, "root", "dc1")
  1447  	require.NoError(t, err)
  1448  
  1449  	p2, err := upsertTestPolicy(codec, "root", "dc1")
  1450  	require.NoError(t, err)
  1451  
  1452  	acl := ACL{srv: s1}
  1453  
  1454  	policies := []string{p1.ID, p2.ID}
  1455  
  1456  	// Assign the policies to a token
  1457  	tokenUpsertReq := structs.ACLTokenSetRequest{
  1458  		Datacenter: "dc1",
  1459  		ACLToken: structs.ACLToken{
  1460  			Policies: []structs.ACLTokenPolicyLink{
  1461  				structs.ACLTokenPolicyLink{
  1462  					ID: p1.ID,
  1463  				},
  1464  				structs.ACLTokenPolicyLink{
  1465  					ID: p2.ID,
  1466  				},
  1467  			},
  1468  		},
  1469  		WriteRequest: structs.WriteRequest{Token: "root"},
  1470  	}
  1471  	token := structs.ACLToken{}
  1472  	err = acl.TokenSet(&tokenUpsertReq, &token)
  1473  	require.NoError(t, err)
  1474  	require.NotEmpty(t, token.SecretID)
  1475  
  1476  	resp := structs.ACLPolicyBatchResponse{}
  1477  	req := structs.ACLPolicyBatchGetRequest{
  1478  		Datacenter:   "dc1",
  1479  		PolicyIDs:    []string{p1.ID, p2.ID},
  1480  		QueryOptions: structs.QueryOptions{Token: token.SecretID},
  1481  	}
  1482  	err = acl.PolicyResolve(&req, &resp)
  1483  	require.NoError(t, err)
  1484  
  1485  	var retrievedPolicies []string
  1486  
  1487  	for _, v := range resp.Policies {
  1488  		retrievedPolicies = append(retrievedPolicies, v.ID)
  1489  	}
  1490  	require.EqualValues(t, retrievedPolicies, policies)
  1491  }
  1492  
  1493  // upsertTestToken creates a token for testing purposes
  1494  func upsertTestToken(codec rpc.ClientCodec, masterToken string, datacenter string) (*structs.ACLToken, error) {
  1495  	arg := structs.ACLTokenSetRequest{
  1496  		Datacenter: datacenter,
  1497  		ACLToken: structs.ACLToken{
  1498  			Description: "User token",
  1499  			Local:       false,
  1500  			Policies:    nil,
  1501  		},
  1502  		WriteRequest: structs.WriteRequest{Token: masterToken},
  1503  	}
  1504  
  1505  	var out structs.ACLToken
  1506  
  1507  	err := msgpackrpc.CallWithCodec(codec, "ACL.TokenSet", &arg, &out)
  1508  
  1509  	if err != nil {
  1510  		return nil, err
  1511  	}
  1512  
  1513  	if out.AccessorID == "" {
  1514  		return nil, fmt.Errorf("AccessorID is nil: %v", out)
  1515  	}
  1516  
  1517  	return &out, nil
  1518  }
  1519  
  1520  // retrieveTestToken returns a policy for testing purposes
  1521  func retrieveTestToken(codec rpc.ClientCodec, masterToken string, datacenter string, id string) (*structs.ACLTokenResponse, error) {
  1522  	arg := structs.ACLTokenGetRequest{
  1523  		Datacenter:   datacenter,
  1524  		TokenID:      id,
  1525  		TokenIDType:  structs.ACLTokenAccessor,
  1526  		QueryOptions: structs.QueryOptions{Token: masterToken},
  1527  	}
  1528  
  1529  	var out structs.ACLTokenResponse
  1530  
  1531  	err := msgpackrpc.CallWithCodec(codec, "ACL.TokenRead", &arg, &out)
  1532  
  1533  	if err != nil {
  1534  		return nil, err
  1535  	}
  1536  
  1537  	return &out, nil
  1538  }
  1539  
  1540  // upsertTestPolicy creates a policy for testing purposes
  1541  func upsertTestPolicy(codec rpc.ClientCodec, masterToken string, datacenter string) (*structs.ACLPolicy, error) {
  1542  	// Make sure test policies can't collide
  1543  	policyUnq, err := uuid.GenerateUUID()
  1544  	if err != nil {
  1545  		return nil, err
  1546  	}
  1547  
  1548  	arg := structs.ACLPolicySetRequest{
  1549  		Datacenter: datacenter,
  1550  		Policy: structs.ACLPolicy{
  1551  			Name: fmt.Sprintf("test-policy-%s", policyUnq),
  1552  		},
  1553  		WriteRequest: structs.WriteRequest{Token: masterToken},
  1554  	}
  1555  
  1556  	var out structs.ACLPolicy
  1557  
  1558  	err = msgpackrpc.CallWithCodec(codec, "ACL.PolicySet", &arg, &out)
  1559  
  1560  	if err != nil {
  1561  		return nil, err
  1562  	}
  1563  
  1564  	if out.ID == "" {
  1565  		return nil, fmt.Errorf("ID is nil: %v", out)
  1566  	}
  1567  
  1568  	return &out, nil
  1569  }
  1570  
  1571  // retrieveTestPolicy returns a policy for testing purposes
  1572  func retrieveTestPolicy(codec rpc.ClientCodec, masterToken string, datacenter string, id string) (*structs.ACLPolicyResponse, error) {
  1573  	arg := structs.ACLPolicyGetRequest{
  1574  		Datacenter:   datacenter,
  1575  		PolicyID:     id,
  1576  		QueryOptions: structs.QueryOptions{Token: masterToken},
  1577  	}
  1578  
  1579  	var out structs.ACLPolicyResponse
  1580  
  1581  	err := msgpackrpc.CallWithCodec(codec, "ACL.PolicyRead", &arg, &out)
  1582  
  1583  	if err != nil {
  1584  		return nil, err
  1585  	}
  1586  
  1587  	return &out, nil
  1588  }