2017-08-25 00:03:29 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2022-07-20 08:06:23 +00:00
|
|
|
"time"
|
2017-08-25 00:03:29 +00:00
|
|
|
|
2022-03-17 13:34:57 +00:00
|
|
|
"github.com/hashicorp/nomad/api/internal/testutil"
|
2022-11-23 08:38:02 +00:00
|
|
|
"github.com/shoenig/test/must"
|
2017-08-25 00:03:29 +00:00
|
|
|
)
|
|
|
|
|
2017-08-25 00:10:10 +00:00
|
|
|
func TestACLPolicies_ListUpsert(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2017-08-25 00:03:29 +00:00
|
|
|
c, s, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer s.Stop()
|
|
|
|
ap := c.ACLPolicies()
|
|
|
|
|
|
|
|
// Listing when nothing exists returns empty
|
|
|
|
result, qm, err := ap.List(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
must.One(t, qm.LastIndex)
|
|
|
|
must.Len(t, 0, result)
|
2017-08-25 00:03:29 +00:00
|
|
|
|
|
|
|
// Register a policy
|
|
|
|
policy := &ACLPolicy{
|
|
|
|
Name: "test",
|
|
|
|
Description: "test",
|
|
|
|
Rules: `namespace "default" {
|
|
|
|
policy = "read"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}
|
|
|
|
wm, err := ap.Upsert(policy, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:03:29 +00:00
|
|
|
assertWriteMeta(t, wm)
|
|
|
|
|
|
|
|
// Check the list again
|
|
|
|
result, qm, err = ap.List(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
|
2017-08-25 00:03:29 +00:00
|
|
|
assertQueryMeta(t, qm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Len(t, 1, result)
|
2017-08-25 00:03:29 +00:00
|
|
|
}
|
2017-08-25 00:10:10 +00:00
|
|
|
|
|
|
|
func TestACLPolicies_Delete(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2017-08-25 00:10:10 +00:00
|
|
|
c, s, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer s.Stop()
|
|
|
|
ap := c.ACLPolicies()
|
|
|
|
|
|
|
|
// Register a policy
|
|
|
|
policy := &ACLPolicy{
|
|
|
|
Name: "test",
|
|
|
|
Description: "test",
|
|
|
|
Rules: `namespace "default" {
|
|
|
|
policy = "read"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}
|
|
|
|
wm, err := ap.Upsert(policy, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:10:10 +00:00
|
|
|
assertWriteMeta(t, wm)
|
|
|
|
|
|
|
|
// Delete the policy
|
|
|
|
wm, err = ap.Delete(policy.Name, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:10:10 +00:00
|
|
|
assertWriteMeta(t, wm)
|
|
|
|
|
|
|
|
// Check the list again
|
|
|
|
result, qm, err := ap.List(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
|
2017-08-25 00:10:10 +00:00
|
|
|
assertQueryMeta(t, qm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Len(t, 0, result)
|
2017-08-25 00:10:10 +00:00
|
|
|
}
|
2017-08-25 00:12:53 +00:00
|
|
|
|
|
|
|
func TestACLPolicies_Info(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2017-08-25 00:12:53 +00:00
|
|
|
c, s, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer s.Stop()
|
|
|
|
ap := c.ACLPolicies()
|
|
|
|
|
|
|
|
// Register a policy
|
|
|
|
policy := &ACLPolicy{
|
|
|
|
Name: "test",
|
|
|
|
Description: "test",
|
|
|
|
Rules: `namespace "default" {
|
|
|
|
policy = "read"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}
|
|
|
|
wm, err := ap.Upsert(policy, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:12:53 +00:00
|
|
|
assertWriteMeta(t, wm)
|
|
|
|
|
|
|
|
// Query the policy
|
|
|
|
out, qm, err := ap.Info(policy.Name, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:12:53 +00:00
|
|
|
assertQueryMeta(t, qm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, policy.Name, out.Name)
|
2017-08-25 00:12:53 +00:00
|
|
|
}
|
2017-08-25 00:15:47 +00:00
|
|
|
|
|
|
|
func TestACLTokens_List(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2017-08-25 00:15:47 +00:00
|
|
|
c, s, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer s.Stop()
|
|
|
|
at := c.ACLTokens()
|
|
|
|
|
2022-09-12 13:50:35 +00:00
|
|
|
// Expect the bootstrap token.
|
2017-08-25 00:15:47 +00:00
|
|
|
result, qm, err := at.List(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
must.NonZero(t, qm.LastIndex)
|
|
|
|
must.Len(t, 1, result)
|
|
|
|
must.Nil(t, result[0].ExpirationTime)
|
2022-09-12 13:50:35 +00:00
|
|
|
|
|
|
|
// Create a token with an expiry.
|
|
|
|
token := &ACLToken{
|
|
|
|
Name: "token-with-expiry",
|
|
|
|
Type: "client",
|
|
|
|
Policies: []string{"foo1"},
|
|
|
|
ExpirationTTL: 1 * time.Hour,
|
|
|
|
}
|
|
|
|
createExpirationResp, _, err := at.Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-09-12 13:50:35 +00:00
|
|
|
|
|
|
|
// Perform the listing again and ensure we have two entries along with the
|
|
|
|
// expiration correctly set and available.
|
|
|
|
listResp, qm, err := at.List(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Nil(t, err)
|
2022-09-12 13:50:35 +00:00
|
|
|
assertQueryMeta(t, qm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Len(t, 2, listResp)
|
2022-09-12 13:50:35 +00:00
|
|
|
|
|
|
|
for _, tokenStub := range listResp {
|
|
|
|
if tokenStub.AccessorID == createExpirationResp.AccessorID {
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, tokenStub.ExpirationTime)
|
2022-09-12 13:50:35 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-25 00:15:47 +00:00
|
|
|
}
|
2017-08-25 00:26:13 +00:00
|
|
|
|
|
|
|
func TestACLTokens_CreateUpdate(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2017-08-25 00:26:13 +00:00
|
|
|
c, s, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer s.Stop()
|
|
|
|
at := c.ACLTokens()
|
|
|
|
|
|
|
|
token := &ACLToken{
|
|
|
|
Name: "foo",
|
|
|
|
Type: "client",
|
|
|
|
Policies: []string{"foo1"},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the token
|
|
|
|
out, wm, err := at.Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:26:13 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out)
|
2017-08-25 00:26:13 +00:00
|
|
|
|
|
|
|
// Update the token
|
|
|
|
out.Name = "other"
|
|
|
|
out2, wm, err := at.Update(out, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:26:13 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out2)
|
2017-08-25 00:26:13 +00:00
|
|
|
|
|
|
|
// Verify the change took hold
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, out.Name, out2.Name)
|
2022-07-20 08:06:23 +00:00
|
|
|
|
|
|
|
// Try updating the token to include a TTL which is not allowed.
|
|
|
|
out2.ExpirationTTL = 10 * time.Minute
|
|
|
|
out3, _, err := at.Update(out2, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Error(t, err)
|
|
|
|
must.Nil(t, out3)
|
2022-08-17 13:45:32 +00:00
|
|
|
|
|
|
|
// Try adding a role link to our token, which should be possible. For this
|
|
|
|
// we need to create a policy and link to this from a role.
|
|
|
|
aclPolicy := ACLPolicy{
|
|
|
|
Name: "acl-role-api-test",
|
|
|
|
Rules: `namespace "default" { policy = "read" }`,
|
|
|
|
}
|
|
|
|
writeMeta, err := c.ACLPolicies().Upsert(&aclPolicy, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Create an ACL role referencing the previously created
|
|
|
|
// policy.
|
|
|
|
role := ACLRole{
|
|
|
|
Name: "acl-role-api-test",
|
|
|
|
Policies: []*ACLRolePolicyLink{{Name: aclPolicy.Name}},
|
|
|
|
}
|
|
|
|
aclRoleCreateResp, writeMeta, err := c.ACLRoles().Create(&role, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.UUIDv4(t, aclRoleCreateResp.ID)
|
|
|
|
must.Eq(t, role.Name, aclRoleCreateResp.Name)
|
2022-08-17 13:45:32 +00:00
|
|
|
|
|
|
|
out2.Roles = []*ACLTokenRoleLink{{Name: aclRoleCreateResp.Name}}
|
|
|
|
out2.ExpirationTTL = 0
|
|
|
|
|
2022-11-29 06:36:36 +00:00
|
|
|
out3, _, err = at.Update(out2, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
must.NotNil(t, out3)
|
|
|
|
must.Len(t, 1, out3.Policies)
|
|
|
|
must.Eq(t, "foo1", out3.Policies[0])
|
|
|
|
must.Len(t, 1, out3.Roles)
|
|
|
|
must.Eq(t, role.Name, out3.Roles[0].Name)
|
2017-08-25 00:26:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestACLTokens_Info(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2017-08-25 00:26:13 +00:00
|
|
|
|
2022-07-20 08:06:23 +00:00
|
|
|
testClient, testServer, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer testServer.Stop()
|
2017-08-25 00:26:13 +00:00
|
|
|
|
2022-07-20 08:06:23 +00:00
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
testFn func(client *Client)
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "token without expiry",
|
|
|
|
testFn: func(client *Client) {
|
2017-08-25 00:26:13 +00:00
|
|
|
|
2022-07-20 08:06:23 +00:00
|
|
|
token := &ACLToken{
|
|
|
|
Name: "foo",
|
|
|
|
Type: "client",
|
|
|
|
Policies: []string{"foo1"},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the token
|
|
|
|
out, wm, err := client.ACLTokens().Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-07-20 08:06:23 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out)
|
2022-07-20 08:06:23 +00:00
|
|
|
|
|
|
|
// Query the token
|
|
|
|
out2, qm, err := client.ACLTokens().Info(out.AccessorID, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-07-20 08:06:23 +00:00
|
|
|
assertQueryMeta(t, qm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, out, out2)
|
2022-07-20 08:06:23 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "token with expiry",
|
|
|
|
testFn: func(client *Client) {
|
|
|
|
|
|
|
|
token := &ACLToken{
|
|
|
|
Name: "token-with-expiry",
|
|
|
|
Type: "client",
|
|
|
|
Policies: []string{"foo1"},
|
|
|
|
ExpirationTTL: 10 * time.Minute,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the token
|
|
|
|
out, wm, err := client.ACLTokens().Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-07-20 08:06:23 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out)
|
2022-07-20 08:06:23 +00:00
|
|
|
|
|
|
|
// Query the token and ensure it matches what was returned
|
|
|
|
// during the creation as well as ensuring the expiration time
|
|
|
|
// is set.
|
|
|
|
out2, qm, err := client.ACLTokens().Info(out.AccessorID, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-07-20 08:06:23 +00:00
|
|
|
assertQueryMeta(t, qm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, out, out2)
|
|
|
|
must.NotNil(t, out2.ExpirationTime)
|
2022-07-20 08:06:23 +00:00
|
|
|
},
|
|
|
|
},
|
2022-08-17 13:45:32 +00:00
|
|
|
{
|
|
|
|
name: "token with role link",
|
|
|
|
testFn: func(client *Client) {
|
|
|
|
|
|
|
|
// Create an ACL policy that can be referenced within the ACL
|
|
|
|
// role.
|
|
|
|
aclPolicy := ACLPolicy{
|
|
|
|
Name: "acl-role-api-test",
|
|
|
|
Rules: `namespace "default" { policy = "read" }`,
|
|
|
|
}
|
|
|
|
writeMeta, err := testClient.ACLPolicies().Upsert(&aclPolicy, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Create an ACL role referencing the previously created
|
|
|
|
// policy.
|
|
|
|
role := ACLRole{
|
|
|
|
Name: "acl-role-api-test",
|
|
|
|
Policies: []*ACLRolePolicyLink{{Name: aclPolicy.Name}},
|
|
|
|
}
|
|
|
|
aclRoleCreateResp, writeMeta, err := testClient.ACLRoles().Create(&role, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.UUIDv4(t, aclRoleCreateResp.ID)
|
|
|
|
must.Eq(t, role.Name, aclRoleCreateResp.Name)
|
2022-08-17 13:45:32 +00:00
|
|
|
|
|
|
|
// Create a token with a role linking.
|
|
|
|
token := &ACLToken{
|
|
|
|
Name: "token-with-role-link",
|
|
|
|
Type: "client",
|
|
|
|
Roles: []*ACLTokenRoleLink{{Name: role.Name}},
|
|
|
|
}
|
|
|
|
|
|
|
|
out, wm, err := client.ACLTokens().Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out)
|
2022-08-17 13:45:32 +00:00
|
|
|
|
|
|
|
// Query the token and ensure it matches what was returned
|
|
|
|
// during the creation.
|
|
|
|
out2, qm, err := client.ACLTokens().Info(out.AccessorID, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertQueryMeta(t, qm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, out, out2)
|
|
|
|
must.Len(t, 1, out.Roles)
|
|
|
|
must.Eq(t, out.Roles[0].Name, aclPolicy.Name)
|
2022-08-17 13:45:32 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "token with role and policy link",
|
|
|
|
testFn: func(client *Client) {
|
|
|
|
|
|
|
|
// Create an ACL policy that can be referenced within the ACL
|
|
|
|
// role.
|
|
|
|
aclPolicy1 := ACLPolicy{
|
|
|
|
Name: "acl-role-api-test-1",
|
|
|
|
Rules: `namespace "default" { policy = "read" }`,
|
|
|
|
}
|
|
|
|
writeMeta, err := testClient.ACLPolicies().Upsert(&aclPolicy1, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Create another that can be referenced within the ACL token
|
|
|
|
// directly.
|
|
|
|
aclPolicy2 := ACLPolicy{
|
|
|
|
Name: "acl-role-api-test-2",
|
|
|
|
Rules: `namespace "fawlty" { policy = "read" }`,
|
|
|
|
}
|
|
|
|
writeMeta, err = testClient.ACLPolicies().Upsert(&aclPolicy2, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Create an ACL role referencing the previously created
|
|
|
|
// policy.
|
|
|
|
role := ACLRole{
|
2022-08-25 08:20:43 +00:00
|
|
|
Name: "acl-role-api-test-role-and-policy",
|
2022-08-17 13:45:32 +00:00
|
|
|
Policies: []*ACLRolePolicyLink{{Name: aclPolicy1.Name}},
|
|
|
|
}
|
|
|
|
aclRoleCreateResp, writeMeta, err := testClient.ACLRoles().Create(&role, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotEq(t, "", aclRoleCreateResp.ID)
|
|
|
|
must.Eq(t, role.Name, aclRoleCreateResp.Name)
|
2022-08-17 13:45:32 +00:00
|
|
|
|
|
|
|
// Create a token with a role linking.
|
|
|
|
token := &ACLToken{
|
2022-08-25 08:20:43 +00:00
|
|
|
Name: "token-with-role-and-policy-link",
|
2022-08-17 13:45:32 +00:00
|
|
|
Type: "client",
|
|
|
|
Policies: []string{aclPolicy2.Name},
|
|
|
|
Roles: []*ACLTokenRoleLink{{Name: role.Name}},
|
|
|
|
}
|
|
|
|
|
|
|
|
out, wm, err := client.ACLTokens().Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out)
|
|
|
|
must.Len(t, 1, out.Policies)
|
|
|
|
must.Eq(t, out.Policies[0], aclPolicy2.Name)
|
|
|
|
must.Len(t, 1, out.Roles)
|
|
|
|
must.Eq(t, out.Roles[0].Name, role.Name)
|
2022-08-17 13:45:32 +00:00
|
|
|
|
|
|
|
// Query the token and ensure it matches what was returned
|
|
|
|
// during the creation.
|
|
|
|
out2, qm, err := client.ACLTokens().Info(out.AccessorID, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-17 13:45:32 +00:00
|
|
|
assertQueryMeta(t, qm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, out, out2)
|
2022-08-17 13:45:32 +00:00
|
|
|
},
|
|
|
|
},
|
2022-07-20 08:06:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
tc.testFn(testClient)
|
|
|
|
})
|
|
|
|
}
|
2017-08-25 00:26:13 +00:00
|
|
|
}
|
|
|
|
|
2017-10-13 20:10:26 +00:00
|
|
|
func TestACLTokens_Self(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2017-10-13 20:10:26 +00:00
|
|
|
c, s, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer s.Stop()
|
|
|
|
at := c.ACLTokens()
|
|
|
|
|
|
|
|
token := &ACLToken{
|
|
|
|
Name: "foo",
|
|
|
|
Type: "client",
|
|
|
|
Policies: []string{"foo1"},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the token
|
|
|
|
out, wm, err := at.Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-10-13 20:10:26 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out)
|
2017-10-13 20:10:26 +00:00
|
|
|
|
|
|
|
// Set the clients token to the new token
|
|
|
|
c.SetSecretID(out.SecretID)
|
|
|
|
at = c.ACLTokens()
|
|
|
|
|
|
|
|
// Query the token
|
|
|
|
out2, qm, err := at.Self(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
assertQueryMeta(t, qm)
|
|
|
|
must.Eq(t, out, out2)
|
2017-10-13 20:10:26 +00:00
|
|
|
}
|
|
|
|
|
2017-08-25 00:26:13 +00:00
|
|
|
func TestACLTokens_Delete(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2017-08-25 00:26:13 +00:00
|
|
|
c, s, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer s.Stop()
|
|
|
|
at := c.ACLTokens()
|
|
|
|
|
|
|
|
token := &ACLToken{
|
|
|
|
Name: "foo",
|
|
|
|
Type: "client",
|
|
|
|
Policies: []string{"foo1"},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the token
|
|
|
|
out, wm, err := at.Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:26:13 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out)
|
2017-08-25 00:26:13 +00:00
|
|
|
|
|
|
|
// Delete the token
|
|
|
|
wm, err = at.Delete(out.AccessorID, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2017-08-25 00:26:13 +00:00
|
|
|
assertWriteMeta(t, wm)
|
|
|
|
}
|
2021-02-25 21:41:00 +00:00
|
|
|
|
|
|
|
func TestACL_OneTimeToken(t *testing.T) {
|
2022-03-17 13:34:57 +00:00
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2021-02-25 21:41:00 +00:00
|
|
|
c, s, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer s.Stop()
|
|
|
|
at := c.ACLTokens()
|
|
|
|
|
|
|
|
token := &ACLToken{
|
|
|
|
Name: "foo",
|
|
|
|
Type: "client",
|
|
|
|
Policies: []string{"foo1"},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the ACL token
|
|
|
|
out, wm, err := at.Create(token, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2021-02-25 21:41:00 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out)
|
2021-02-25 21:41:00 +00:00
|
|
|
|
|
|
|
// Get a one-time token
|
|
|
|
c.SetSecretID(out.SecretID)
|
|
|
|
out2, wm, err := at.UpsertOneTimeToken(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2021-02-25 21:41:00 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out2)
|
2021-02-25 21:41:00 +00:00
|
|
|
|
|
|
|
// Exchange the one-time token
|
|
|
|
out3, wm, err := at.ExchangeOneTimeToken(out2.OneTimeSecretID, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2021-02-25 21:41:00 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NotNil(t, out3)
|
|
|
|
must.Eq(t, out.AccessorID, out3.AccessorID)
|
2021-02-25 21:41:00 +00:00
|
|
|
}
|
2022-06-03 11:37:24 +00:00
|
|
|
|
|
|
|
func TestACLTokens_BootstrapInvalidToken(t *testing.T) {
|
|
|
|
testutil.Parallel(t)
|
2023-01-01 18:57:26 +00:00
|
|
|
|
2022-06-03 11:37:24 +00:00
|
|
|
c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) {
|
|
|
|
c.ACL.Enabled = true
|
|
|
|
})
|
|
|
|
defer s.Stop()
|
|
|
|
at := c.ACLTokens()
|
|
|
|
|
|
|
|
bootkn := "badtoken"
|
|
|
|
// Bootstrap with invalid token
|
|
|
|
_, _, err := at.BootstrapOpts(bootkn, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.EqError(t, err, "Unexpected response code: 400 (invalid acl token)")
|
2022-06-03 11:37:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestACLTokens_BootstrapValidToken(t *testing.T) {
|
|
|
|
testutil.Parallel(t)
|
|
|
|
c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) {
|
|
|
|
c.ACL.Enabled = true
|
|
|
|
})
|
|
|
|
defer s.Stop()
|
|
|
|
at := c.ACLTokens()
|
|
|
|
|
|
|
|
bootkn := "2b778dd9-f5f1-6f29-b4b4-9a5fa948757a"
|
|
|
|
// Bootstrap with Valid token
|
|
|
|
out, wm, err := at.BootstrapOpts(bootkn, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-06-03 11:37:24 +00:00
|
|
|
assertWriteMeta(t, wm)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, bootkn, out.SecretID)
|
2022-06-03 11:37:24 +00:00
|
|
|
}
|
2022-08-11 07:44:37 +00:00
|
|
|
|
|
|
|
func TestACLRoles(t *testing.T) {
|
|
|
|
testutil.Parallel(t)
|
|
|
|
|
|
|
|
testClient, testServer, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer testServer.Stop()
|
|
|
|
|
|
|
|
// An initial listing shouldn't return any results.
|
|
|
|
aclRoleListResp, queryMeta, err := testClient.ACLRoles().List(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
must.SliceEmpty(t, aclRoleListResp)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
|
|
|
|
// Create an ACL policy that can be referenced within the ACL role.
|
|
|
|
aclPolicy := ACLPolicy{
|
|
|
|
Name: "acl-role-api-test",
|
|
|
|
Rules: `namespace "default" {
|
|
|
|
policy = "read"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}
|
|
|
|
writeMeta, err := testClient.ACLPolicies().Upsert(&aclPolicy, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Create an ACL role referencing the previously created policy.
|
|
|
|
role := ACLRole{
|
|
|
|
Name: "acl-role-api-test",
|
|
|
|
Policies: []*ACLRolePolicyLink{{Name: aclPolicy.Name}},
|
|
|
|
}
|
|
|
|
aclRoleCreateResp, writeMeta, err := testClient.ACLRoles().Create(&role, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.UUIDv4(t, aclRoleCreateResp.ID)
|
|
|
|
must.Eq(t, role.Name, aclRoleCreateResp.Name)
|
2022-08-11 07:44:37 +00:00
|
|
|
|
|
|
|
// Another listing should return one result.
|
|
|
|
aclRoleListResp, queryMeta, err = testClient.ACLRoles().List(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
must.Len(t, 1, aclRoleListResp)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
|
|
|
|
// Read the role using its ID.
|
|
|
|
aclRoleReadResp, queryMeta, err := testClient.ACLRoles().Get(aclRoleCreateResp.ID, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertQueryMeta(t, queryMeta)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, aclRoleCreateResp, aclRoleReadResp)
|
2022-08-11 07:44:37 +00:00
|
|
|
|
|
|
|
// Read the role using its name.
|
|
|
|
aclRoleReadResp, queryMeta, err = testClient.ACLRoles().GetByName(aclRoleCreateResp.Name, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertQueryMeta(t, queryMeta)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, aclRoleCreateResp, aclRoleReadResp)
|
2022-08-11 07:44:37 +00:00
|
|
|
|
|
|
|
// Update the role name.
|
|
|
|
role.Name = "acl-role-api-test-badger-badger-badger"
|
|
|
|
role.ID = aclRoleCreateResp.ID
|
|
|
|
aclRoleUpdateResp, writeMeta, err := testClient.ACLRoles().Update(&role, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.Eq(t, role.Name, aclRoleUpdateResp.Name)
|
|
|
|
must.Eq(t, role.ID, aclRoleUpdateResp.ID)
|
2022-08-11 07:44:37 +00:00
|
|
|
|
|
|
|
// Delete the role.
|
|
|
|
writeMeta, err = testClient.ACLRoles().Delete(aclRoleCreateResp.ID, nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Make sure there are no ACL roles now present.
|
|
|
|
aclRoleListResp, queryMeta, err = testClient.ACLRoles().List(nil)
|
2023-01-01 18:57:26 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
must.SliceEmpty(t, aclRoleListResp)
|
2022-08-11 07:44:37 +00:00
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
}
|
2022-11-23 08:38:02 +00:00
|
|
|
|
|
|
|
func TestACLAuthMethods(t *testing.T) {
|
|
|
|
testutil.Parallel(t)
|
|
|
|
|
|
|
|
testClient, testServer, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer testServer.Stop()
|
|
|
|
|
|
|
|
// An initial listing shouldn't return any results.
|
|
|
|
aclAuthMethodsListResp, queryMeta, err := testClient.ACLAuthMethods().List(nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
must.Len(t, 0, aclAuthMethodsListResp)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
|
|
|
|
// Create an ACL auth-method.
|
|
|
|
authMethod := ACLAuthMethod{
|
|
|
|
Name: "acl-auth-method-api-test",
|
|
|
|
Type: ACLAuthMethodTypeOIDC,
|
|
|
|
TokenLocality: ACLAuthMethodTokenLocalityLocal,
|
|
|
|
MaxTokenTTL: 15 * time.Minute,
|
|
|
|
Default: true,
|
|
|
|
}
|
2022-11-29 06:36:36 +00:00
|
|
|
_, writeMeta, err := testClient.ACLAuthMethods().Create(&authMethod, nil)
|
2022-11-23 08:38:02 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Another listing should return one result.
|
|
|
|
aclAuthMethodsListResp, queryMeta, err = testClient.ACLAuthMethods().List(nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
must.Len(t, 1, aclAuthMethodsListResp)
|
|
|
|
must.Eq(t, authMethod.Name, aclAuthMethodsListResp[0].Name)
|
|
|
|
must.True(t, aclAuthMethodsListResp[0].Default)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
|
|
|
|
// Read the auth-method.
|
|
|
|
aclAuthMethodReadResp, queryMeta, err := testClient.ACLAuthMethods().Get(authMethod.Name, nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
must.NotNil(t, aclAuthMethodReadResp)
|
|
|
|
must.Eq(t, authMethod.Name, aclAuthMethodReadResp.Name)
|
|
|
|
must.Eq(t, authMethod.TokenLocality, aclAuthMethodReadResp.TokenLocality)
|
|
|
|
must.Eq(t, authMethod.Type, aclAuthMethodReadResp.Type)
|
|
|
|
|
|
|
|
// Update the auth-method token locality.
|
|
|
|
authMethod.TokenLocality = ACLAuthMethodTokenLocalityGlobal
|
2022-11-29 06:36:36 +00:00
|
|
|
_, writeMeta, err = testClient.ACLAuthMethods().Update(&authMethod, nil)
|
2022-11-23 08:38:02 +00:00
|
|
|
must.NoError(t, err)
|
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Re-read the auth-method and check the locality.
|
|
|
|
aclAuthMethodReadResp, queryMeta, err = testClient.ACLAuthMethods().Get(authMethod.Name, nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
must.NotNil(t, aclAuthMethodReadResp)
|
|
|
|
must.Eq(t, authMethod.Name, aclAuthMethodReadResp.Name)
|
|
|
|
must.Eq(t, authMethod.TokenLocality, aclAuthMethodReadResp.TokenLocality)
|
|
|
|
|
|
|
|
// Delete the role.
|
|
|
|
writeMeta, err = testClient.ACLAuthMethods().Delete(authMethod.Name, nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Make sure there are no ACL auth-methods now present.
|
|
|
|
aclAuthMethodsListResp, queryMeta, err = testClient.ACLAuthMethods().List(nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
must.Len(t, 0, aclAuthMethodsListResp)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
}
|
2022-12-15 08:18:55 +00:00
|
|
|
|
|
|
|
func TestACLBindingRules(t *testing.T) {
|
|
|
|
testutil.Parallel(t)
|
|
|
|
|
|
|
|
testClient, testServer, _ := makeACLClient(t, nil, nil)
|
|
|
|
defer testServer.Stop()
|
|
|
|
|
|
|
|
//
|
|
|
|
aclAuthMethod := ACLAuthMethod{
|
|
|
|
Name: "auth0",
|
|
|
|
Type: ACLAuthMethodTypeOIDC,
|
|
|
|
TokenLocality: ACLAuthMethodTokenLocalityGlobal,
|
|
|
|
MaxTokenTTL: 10 * time.Hour,
|
|
|
|
Default: true,
|
|
|
|
}
|
|
|
|
_, _, err := testClient.ACLAuthMethods().Create(&aclAuthMethod, nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
|
|
|
|
// An initial listing shouldn't return any results.
|
|
|
|
aclBindingRulesListResp, queryMeta, err := testClient.ACLBindingRules().List(nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
must.Len(t, 0, aclBindingRulesListResp)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
|
|
|
|
// Create an ACL auth-method.
|
|
|
|
bindingRule := ACLBindingRule{
|
|
|
|
Description: "my-binding-rule",
|
|
|
|
AuthMethod: "auth0",
|
|
|
|
Selector: "nomad-engineering-team in list.groups",
|
|
|
|
BindType: "role",
|
|
|
|
BindName: "cluster-admin",
|
|
|
|
}
|
|
|
|
_, writeMeta, err := testClient.ACLBindingRules().Create(&bindingRule, nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Another listing should return one result.
|
|
|
|
aclBindingRulesListResp, queryMeta, err = testClient.ACLBindingRules().List(nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
must.Len(t, 1, aclBindingRulesListResp)
|
|
|
|
must.NotEq(t, "", aclBindingRulesListResp[0].ID)
|
|
|
|
must.Eq(t, "auth0", aclBindingRulesListResp[0].AuthMethod)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
|
|
|
|
bindingRuleID := aclBindingRulesListResp[0].ID
|
|
|
|
|
|
|
|
// Read the binding rule.
|
|
|
|
aclBindingRuleReadResp, queryMeta, err := testClient.ACLBindingRules().Get(bindingRuleID, nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
must.NotNil(t, aclBindingRuleReadResp)
|
|
|
|
must.Eq(t, bindingRuleID, aclBindingRuleReadResp.ID)
|
|
|
|
must.Eq(t, bindingRule.Description, aclBindingRuleReadResp.Description)
|
|
|
|
must.Eq(t, bindingRule.AuthMethod, aclBindingRuleReadResp.AuthMethod)
|
|
|
|
must.Eq(t, bindingRule.Selector, aclBindingRuleReadResp.Selector)
|
|
|
|
must.Eq(t, bindingRule.BindType, aclBindingRuleReadResp.BindType)
|
|
|
|
must.Eq(t, bindingRule.BindName, aclBindingRuleReadResp.BindName)
|
|
|
|
|
|
|
|
// Update the binding rule description.
|
|
|
|
bindingRule.ID = bindingRuleID
|
|
|
|
bindingRule.Description = "my-binding-rule-updated"
|
|
|
|
aclBindingRuleUpdateResp, writeMeta, err := testClient.ACLBindingRules().Update(&bindingRule, nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
must.Eq(t, bindingRuleID, aclBindingRuleUpdateResp.ID)
|
|
|
|
must.Eq(t, bindingRule.Description, aclBindingRuleUpdateResp.Description)
|
|
|
|
must.Eq(t, bindingRule.AuthMethod, aclBindingRuleUpdateResp.AuthMethod)
|
|
|
|
must.Eq(t, bindingRule.Selector, aclBindingRuleUpdateResp.Selector)
|
|
|
|
must.Eq(t, bindingRule.BindType, aclBindingRuleUpdateResp.BindType)
|
|
|
|
must.Eq(t, bindingRule.BindName, aclBindingRuleUpdateResp.BindName)
|
|
|
|
|
|
|
|
// Delete the role.
|
|
|
|
writeMeta, err = testClient.ACLBindingRules().Delete(bindingRuleID, nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
assertWriteMeta(t, writeMeta)
|
|
|
|
|
|
|
|
// Make sure there are no ACL auth-methods now present.
|
|
|
|
aclBindingRulesListResp, queryMeta, err = testClient.ACLBindingRules().List(nil)
|
|
|
|
must.NoError(t, err)
|
|
|
|
must.Len(t, 0, aclBindingRulesListResp)
|
|
|
|
assertQueryMeta(t, queryMeta)
|
|
|
|
}
|