github.phpd.cn/hashicorp/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 }