Merge pull request #11184 from hashicorp/dnephin/acl-legacy-remove-state-store
acl: remove legacy type constants, and remove state store support for setting legacy ACLs
This commit is contained in:
commit
376342aa3f
|
@ -18,11 +18,6 @@ func DefaultSource() Source {
|
|||
serfLAN := cfg.SerfLANConfig.MemberlistConfig
|
||||
serfWAN := cfg.SerfWANConfig.MemberlistConfig
|
||||
|
||||
// DEPRECATED (ACL-Legacy-Compat) - when legacy ACL support is removed these defaults
|
||||
// the acl_* config entries here should be transitioned to their counterparts in the
|
||||
// acl stanza for now we need to be able to detect the new entries not being set (not
|
||||
// just set to the defaults here) so that we can use the old entries. So the true
|
||||
// default still needs to reside in the original config values
|
||||
return FileSource{
|
||||
Name: "default",
|
||||
Format: "hcl",
|
||||
|
|
|
@ -100,10 +100,6 @@ func (id *missingIdentity) RoleIDs() []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (id *missingIdentity) EmbeddedPolicy() *structs.ACLPolicy {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (id *missingIdentity) ServiceIdentityList() []*structs.ACLServiceIdentity {
|
||||
return nil
|
||||
}
|
||||
|
@ -124,13 +120,6 @@ func (id *missingIdentity) EnterpriseMetadata() *structs.EnterpriseMeta {
|
|||
return structs.DefaultEnterpriseMetaInDefaultPartition()
|
||||
}
|
||||
|
||||
func minTTL(a time.Duration, b time.Duration) time.Duration {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
type ACLRemoteError struct {
|
||||
Err error
|
||||
}
|
||||
|
@ -149,7 +138,7 @@ func tokenSecretCacheID(token string) string {
|
|||
}
|
||||
|
||||
type ACLResolverDelegate interface {
|
||||
ACLDatacenter(legacy bool) string
|
||||
ACLDatacenter() string
|
||||
ResolveIdentityFromToken(token string) (bool, structs.ACLIdentity, error)
|
||||
ResolvePolicyFromID(policyID string) (bool, *structs.ACLPolicy, error)
|
||||
ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error)
|
||||
|
@ -365,7 +354,7 @@ func (r *ACLResolver) fetchAndCacheIdentityFromToken(token string, cached *struc
|
|||
cacheID := tokenSecretCacheID(token)
|
||||
|
||||
req := structs.ACLTokenGetRequest{
|
||||
Datacenter: r.delegate.ACLDatacenter(false),
|
||||
Datacenter: r.delegate.ACLDatacenter(),
|
||||
TokenID: token,
|
||||
TokenIDType: structs.ACLTokenSecret,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
|
@ -453,7 +442,7 @@ func (r *ACLResolver) resolveIdentityFromToken(token string) (structs.ACLIdentit
|
|||
|
||||
func (r *ACLResolver) fetchAndCachePoliciesForIdentity(identity structs.ACLIdentity, policyIDs []string, cached map[string]*structs.PolicyCacheEntry) (map[string]*structs.ACLPolicy, error) {
|
||||
req := structs.ACLPolicyBatchGetRequest{
|
||||
Datacenter: r.delegate.ACLDatacenter(false),
|
||||
Datacenter: r.delegate.ACLDatacenter(),
|
||||
PolicyIDs: policyIDs,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Token: identity.SecretToken(),
|
||||
|
@ -508,7 +497,7 @@ func (r *ACLResolver) fetchAndCachePoliciesForIdentity(identity structs.ACLIdent
|
|||
|
||||
func (r *ACLResolver) fetchAndCacheRolesForIdentity(identity structs.ACLIdentity, roleIDs []string, cached map[string]*structs.RoleCacheEntry) (map[string]*structs.ACLRole, error) {
|
||||
req := structs.ACLRoleBatchGetRequest{
|
||||
Datacenter: r.delegate.ACLDatacenter(false),
|
||||
Datacenter: r.delegate.ACLDatacenter(),
|
||||
RoleIDs: roleIDs,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Token: identity.SecretToken(),
|
||||
|
@ -616,11 +605,6 @@ func (r *ACLResolver) resolvePoliciesForIdentity(identity structs.ACLIdentity) (
|
|||
)
|
||||
|
||||
if len(policyIDs) == 0 && len(serviceIdentities) == 0 && len(roleIDs) == 0 && len(nodeIdentities) == 0 {
|
||||
policy := identity.EmbeddedPolicy()
|
||||
if policy != nil {
|
||||
return []*structs.ACLPolicy{policy}, nil
|
||||
}
|
||||
|
||||
// In this case the default policy will be all that is in effect.
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -23,17 +23,9 @@ var clientACLCacheConfig *structs.ACLCachesConfig = &structs.ACLCachesConfig{
|
|||
Roles: 128,
|
||||
}
|
||||
|
||||
func (c *Client) ACLDatacenter(legacy bool) string {
|
||||
// For resolution running on clients, when not in
|
||||
// legacy mode the servers within the current datacenter
|
||||
// must be queried first to pick up local tokens. When
|
||||
// in legacy mode the clients should directly query the
|
||||
// ACL Datacenter. When no ACL datacenter has been set
|
||||
// then we assume that the local DC is the ACL DC
|
||||
if legacy && c.config.PrimaryDatacenter != "" {
|
||||
return c.config.PrimaryDatacenter
|
||||
}
|
||||
|
||||
func (c *Client) ACLDatacenter() string {
|
||||
// For resolution running on clients, servers within the current datacenter
|
||||
// must be queried first to pick up local tokens.
|
||||
return c.config.Datacenter
|
||||
}
|
||||
|
||||
|
|
|
@ -235,10 +235,8 @@ func (a *ACL) BootstrapTokens(args *structs.DCSpecificRequest, reply *structs.AC
|
|||
ID: structs.ACLPolicyGlobalManagementID,
|
||||
},
|
||||
},
|
||||
CreateTime: time.Now(),
|
||||
Local: false,
|
||||
// DEPRECATED (ACL-Legacy-Compat) - This is used so that the bootstrap token is still visible via the v1 acl APIs
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
CreateTime: time.Now(),
|
||||
Local: false,
|
||||
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
||||
},
|
||||
ResetIndex: specifiedIndex,
|
||||
|
|
|
@ -48,7 +48,6 @@ func TestACLEndpoint_BootstrapTokens(t *testing.T) {
|
|||
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.BootstrapTokens", &arg, &out))
|
||||
require.Equal(t, 36, len(out.AccessorID))
|
||||
require.True(t, strings.HasPrefix(out.Description, "Bootstrap Token"))
|
||||
require.Equal(t, out.Type, structs.ACLTokenTypeManagement)
|
||||
require.True(t, out.CreateIndex > 0)
|
||||
require.Equal(t, out.CreateIndex, out.ModifyIndex)
|
||||
|
||||
|
@ -69,7 +68,6 @@ func TestACLEndpoint_BootstrapTokens(t *testing.T) {
|
|||
require.Equal(t, 36, len(out.AccessorID))
|
||||
require.NotEqual(t, oldID, out.AccessorID)
|
||||
require.True(t, strings.HasPrefix(out.Description, "Bootstrap Token"))
|
||||
require.Equal(t, out.Type, structs.ACLTokenTypeManagement)
|
||||
require.True(t, out.CreateIndex > 0)
|
||||
require.Equal(t, out.CreateIndex, out.ModifyIndex)
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ func (s *Server) LocalTokensEnabled() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (s *Server) ACLDatacenter(legacy bool) string {
|
||||
func (s *Server) ACLDatacenter() string {
|
||||
// For resolution running on servers the only option
|
||||
// is to contact the configured ACL Datacenter
|
||||
if s.config.PrimaryDatacenter != "" {
|
||||
|
|
|
@ -613,7 +613,7 @@ func (d *ACLResolverTestDelegate) plainRoleResolveFn(args *structs.ACLRoleBatchG
|
|||
return nil
|
||||
}
|
||||
|
||||
func (d *ACLResolverTestDelegate) ACLDatacenter(legacy bool) string {
|
||||
func (d *ACLResolverTestDelegate) ACLDatacenter() string {
|
||||
return d.datacenter
|
||||
}
|
||||
|
||||
|
@ -2112,38 +2112,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
|||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||
})
|
||||
|
||||
runTwiceAndReset("legacy-management", func(t *testing.T) {
|
||||
delegate.UseTestLocalData([]interface{}{
|
||||
&structs.ACLToken{
|
||||
AccessorID: "d109a033-99d1-47e2-a711-d6593373a973",
|
||||
SecretID: "legacy-management",
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
},
|
||||
})
|
||||
authz, err := r.ResolveToken("legacy-management")
|
||||
require.NotNil(t, authz)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, acl.Allow, authz.ACLWrite(nil))
|
||||
require.Equal(t, acl.Allow, authz.KeyRead("foo", nil))
|
||||
})
|
||||
|
||||
runTwiceAndReset("legacy-client", func(t *testing.T) {
|
||||
delegate.UseTestLocalData([]interface{}{
|
||||
&structs.ACLToken{
|
||||
AccessorID: "b7375838-b104-4a25-b457-329d939bf257",
|
||||
SecretID: "legacy-client",
|
||||
Type: structs.ACLTokenTypeClient,
|
||||
Rules: `service "" { policy = "read" }`,
|
||||
},
|
||||
})
|
||||
authz, err := r.ResolveToken("legacy-client")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, authz)
|
||||
require.Equal(t, acl.Deny, authz.MeshRead(nil))
|
||||
require.Equal(t, acl.Deny, authz.OperatorRead(nil))
|
||||
require.Equal(t, acl.Allow, authz.ServiceRead("foo", nil))
|
||||
})
|
||||
|
||||
runTwiceAndReset("service and intention wildcard write", func(t *testing.T) {
|
||||
delegate.UseTestLocalData([]interface{}{
|
||||
&structs.ACLToken{
|
||||
|
|
|
@ -111,8 +111,7 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) {
|
|||
},
|
||||
CreateTime: time.Now(),
|
||||
Local: false,
|
||||
// DEPRECATED (ACL-Legacy-Compat) - This is used so that the bootstrap token is still visible via the v1 acl APIs
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
Type: "management",
|
||||
}
|
||||
require.NoError(t, fsm.state.ACLBootstrap(10, 0, token))
|
||||
|
||||
|
|
|
@ -452,11 +452,8 @@ func (s *Server) initializeACLs(ctx context.Context) error {
|
|||
ID: structs.ACLPolicyGlobalManagementID,
|
||||
},
|
||||
},
|
||||
CreateTime: time.Now(),
|
||||
Local: false,
|
||||
|
||||
// DEPRECATED (ACL-Legacy-Compat) - only needed for compatibility
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
CreateTime: time.Now(),
|
||||
Local: false,
|
||||
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
||||
}
|
||||
|
||||
|
@ -501,35 +498,24 @@ func (s *Server) initializeACLs(ctx context.Context) error {
|
|||
}
|
||||
// Ignoring expiration times to avoid an insertion collision.
|
||||
if token == nil {
|
||||
// DEPRECATED (ACL-Legacy-Compat) - Don't need to query for previous "anonymous" token
|
||||
// check for legacy token that needs an upgrade
|
||||
_, legacyToken, err := state.ACLTokenGetBySecret(nil, anonymousToken, nil)
|
||||
token = &structs.ACLToken{
|
||||
AccessorID: structs.ACLTokenAnonymousID,
|
||||
SecretID: anonymousToken,
|
||||
Description: "Anonymous Token",
|
||||
CreateTime: time.Now(),
|
||||
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
||||
}
|
||||
token.SetHash(true)
|
||||
|
||||
req := structs.ACLTokenBatchSetRequest{
|
||||
Tokens: structs.ACLTokens{token},
|
||||
CAS: false,
|
||||
}
|
||||
_, err := s.raftApply(structs.ACLTokenSetRequestType, &req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get anonymous token: %v", err)
|
||||
}
|
||||
// Ignoring expiration times to avoid an insertion collision.
|
||||
|
||||
// the token upgrade routine will take care of upgrading the token if a legacy version exists
|
||||
if legacyToken == nil {
|
||||
token = &structs.ACLToken{
|
||||
AccessorID: structs.ACLTokenAnonymousID,
|
||||
SecretID: anonymousToken,
|
||||
Description: "Anonymous Token",
|
||||
CreateTime: time.Now(),
|
||||
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
||||
}
|
||||
token.SetHash(true)
|
||||
|
||||
req := structs.ACLTokenBatchSetRequest{
|
||||
Tokens: structs.ACLTokens{token},
|
||||
CAS: false,
|
||||
}
|
||||
_, err := s.raftApply(structs.ACLTokenSetRequestType, &req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create anonymous token: %v", err)
|
||||
}
|
||||
s.logger.Info("Created ACL anonymous token from configuration")
|
||||
return fmt.Errorf("failed to create anonymous token: %v", err)
|
||||
}
|
||||
s.logger.Info("Created ACL anonymous token from configuration")
|
||||
}
|
||||
// launch the upgrade go routine to generate accessors for everything
|
||||
s.startACLUpgrade(ctx)
|
||||
|
@ -599,7 +585,7 @@ func (s *Server) legacyACLTokenUpgrade(ctx context.Context) error {
|
|||
len(newToken.ServiceIdentities) == 0 &&
|
||||
len(newToken.NodeIdentities) == 0 &&
|
||||
len(newToken.Roles) == 0 &&
|
||||
newToken.Type == structs.ACLTokenTypeManagement {
|
||||
newToken.Type == "management" {
|
||||
newToken.Policies = append(newToken.Policies, structs.ACLTokenPolicyLink{ID: structs.ACLPolicyGlobalManagementID})
|
||||
}
|
||||
|
||||
|
|
|
@ -411,18 +411,10 @@ func fixupRolePolicyLinks(tx ReadTxn, original *structs.ACLRole) (*structs.ACLRo
|
|||
return role, nil
|
||||
}
|
||||
|
||||
// ACLTokenSet is used to insert an ACL rule into the state store.
|
||||
// Deprecated (ACL-Legacy-Compat)
|
||||
func (s *Store) ACLTokenSet(idx uint64, token *structs.ACLToken, legacy bool) error {
|
||||
tx := s.db.WriteTxn(idx)
|
||||
defer tx.Abort()
|
||||
|
||||
// Call set on the ACL
|
||||
if err := aclTokenSetTxn(tx, idx, token, ACLTokenSetOptions{Legacy: legacy}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
// ACLTokenSet is used in many tests to set a single ACL token. It is now a shim
|
||||
// for calling ACLTokenBatchSet with default options.
|
||||
func (s *Store) ACLTokenSet(idx uint64, token *structs.ACLToken) error {
|
||||
return s.ACLTokenBatchSet(idx, structs.ACLTokens{token}, ACLTokenSetOptions{})
|
||||
}
|
||||
|
||||
type ACLTokenSetOptions struct {
|
||||
|
@ -506,11 +498,7 @@ func aclTokenSetTxn(tx WriteTxn, idx uint64, token *structs.ACLToken, opts ACLTo
|
|||
}
|
||||
|
||||
if opts.Legacy && original != nil {
|
||||
if original.UsesNonLegacyFields() {
|
||||
return fmt.Errorf("failed inserting acl token: cannot use legacy endpoint to modify a non-legacy token")
|
||||
}
|
||||
|
||||
token.AccessorID = original.AccessorID
|
||||
return fmt.Errorf("legacy tokens can not be modified")
|
||||
}
|
||||
|
||||
if err := aclTokenUpsertValidateEnterprise(tx, token, original); err != nil {
|
||||
|
|
|
@ -46,7 +46,7 @@ func setupAnonymous(t *testing.T, s *Store) {
|
|||
Description: "Anonymous Token",
|
||||
}
|
||||
token.SetHash(true)
|
||||
require.NoError(t, s.ACLTokenSet(1, &token, false))
|
||||
require.NoError(t, s.ACLTokenSet(1, &token))
|
||||
}
|
||||
|
||||
func testACLStateStore(t *testing.T) *Store {
|
||||
|
@ -171,8 +171,6 @@ func TestStateStore_ACLBootstrap(t *testing.T) {
|
|||
},
|
||||
CreateTime: time.Now(),
|
||||
Local: false,
|
||||
// DEPRECATED (ACL-Legacy-Compat) - This is used so that the bootstrap token is still visible via the v1 acl APIs
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
}
|
||||
|
||||
token2 := &structs.ACLToken{
|
||||
|
@ -186,8 +184,6 @@ func TestStateStore_ACLBootstrap(t *testing.T) {
|
|||
},
|
||||
CreateTime: time.Now(),
|
||||
Local: false,
|
||||
// DEPRECATED (ACL-Legacy-Compat) - This is used so that the bootstrap token is still visible via the v1 acl APIs
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
}
|
||||
|
||||
s := testStateStore(t)
|
||||
|
@ -238,103 +234,6 @@ func TestStateStore_ACLBootstrap(t *testing.T) {
|
|||
require.Len(t, tokens, 2)
|
||||
}
|
||||
|
||||
func TestStateStore_ACLToken_SetGet_Legacy(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Legacy - Existing With Policies", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := testACLTokensStateStore(t)
|
||||
|
||||
token := &structs.ACLToken{
|
||||
AccessorID: "c8d0378c-566a-4535-8fc9-c883a8cc9849",
|
||||
SecretID: "6d48ce91-2558-4098-bdab-8737e4e57d5f",
|
||||
Policies: []structs.ACLTokenPolicyLink{
|
||||
{
|
||||
ID: testPolicyID_A,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone(), false))
|
||||
|
||||
// legacy flag is set so it should disallow setting this token
|
||||
err := s.ACLTokenSet(3, token.Clone(), true)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("Legacy - Empty Type", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := testACLTokensStateStore(t)
|
||||
token := &structs.ACLToken{
|
||||
AccessorID: "271cd056-0038-4fd3-90e5-f97f50fb3ac8",
|
||||
SecretID: "c0056225-5785-43b3-9b77-3954f06d6aee",
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone(), false))
|
||||
|
||||
// legacy flag is set so it should disallow setting this token
|
||||
err := s.ACLTokenSet(3, token.Clone(), true)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("Legacy - New", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := testACLTokensStateStore(t)
|
||||
token := &structs.ACLToken{
|
||||
SecretID: "2989e271-6169-4f34-8fec-4618d70008fb",
|
||||
Type: structs.ACLTokenTypeClient,
|
||||
Rules: `service "" { policy = "read" }`,
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone(), true))
|
||||
|
||||
idx, rtoken, err := s.ACLTokenGetBySecret(nil, token.SecretID, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), idx)
|
||||
require.NotNil(t, rtoken)
|
||||
require.Equal(t, "", rtoken.AccessorID)
|
||||
require.Equal(t, "2989e271-6169-4f34-8fec-4618d70008fb", rtoken.SecretID)
|
||||
require.Equal(t, "", rtoken.Description)
|
||||
require.Len(t, rtoken.Policies, 0)
|
||||
require.Equal(t, structs.ACLTokenTypeClient, rtoken.Type)
|
||||
require.Equal(t, uint64(2), rtoken.CreateIndex)
|
||||
require.Equal(t, uint64(2), rtoken.ModifyIndex)
|
||||
})
|
||||
|
||||
t.Run("Legacy - Update", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := testACLTokensStateStore(t)
|
||||
original := &structs.ACLToken{
|
||||
SecretID: "2989e271-6169-4f34-8fec-4618d70008fb",
|
||||
Type: structs.ACLTokenTypeClient,
|
||||
Rules: `service "" { policy = "read" }`,
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, original.Clone(), true))
|
||||
|
||||
updatedRules := `service "" { policy = "read" } service "foo" { policy = "deny"}`
|
||||
update := &structs.ACLToken{
|
||||
SecretID: "2989e271-6169-4f34-8fec-4618d70008fb",
|
||||
Type: structs.ACLTokenTypeClient,
|
||||
Rules: updatedRules,
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(3, update.Clone(), true))
|
||||
|
||||
idx, rtoken, err := s.ACLTokenGetBySecret(nil, original.SecretID, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(3), idx)
|
||||
require.NotNil(t, rtoken)
|
||||
require.Equal(t, "", rtoken.AccessorID)
|
||||
require.Equal(t, "2989e271-6169-4f34-8fec-4618d70008fb", rtoken.SecretID)
|
||||
require.Equal(t, "", rtoken.Description)
|
||||
require.Len(t, rtoken.Policies, 0)
|
||||
require.Equal(t, structs.ACLTokenTypeClient, rtoken.Type)
|
||||
require.Equal(t, updatedRules, rtoken.Rules)
|
||||
require.Equal(t, uint64(2), rtoken.CreateIndex)
|
||||
require.Equal(t, uint64(3), rtoken.ModifyIndex)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Missing Secret", func(t *testing.T) {
|
||||
|
@ -344,7 +243,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
AccessorID: "39171632-6f34-4411-827f-9416403687f4",
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token.Clone(), false)
|
||||
err := s.ACLTokenSet(2, token.Clone())
|
||||
require.Error(t, err)
|
||||
require.Equal(t, ErrMissingACLTokenSecret, err)
|
||||
})
|
||||
|
@ -356,7 +255,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
SecretID: "39171632-6f34-4411-827f-9416403687f4",
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token.Clone(), false)
|
||||
err := s.ACLTokenSet(2, token.Clone())
|
||||
require.Error(t, err)
|
||||
require.Equal(t, ErrMissingACLTokenAccessor, err)
|
||||
})
|
||||
|
@ -372,7 +271,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token, false)
|
||||
err := s.ACLTokenSet(2, token)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -389,7 +288,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token, false)
|
||||
err := s.ACLTokenSet(2, token)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -406,7 +305,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token.Clone(), false)
|
||||
err := s.ACLTokenSet(2, token.Clone())
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -423,7 +322,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token, false)
|
||||
err := s.ACLTokenSet(2, token)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -440,7 +339,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token.Clone(), false)
|
||||
err := s.ACLTokenSet(2, token.Clone())
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -457,7 +356,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token, false)
|
||||
err := s.ACLTokenSet(2, token)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -470,7 +369,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
AuthMethod: "test",
|
||||
}
|
||||
|
||||
err := s.ACLTokenSet(2, token, false)
|
||||
err := s.ACLTokenSet(2, token)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -497,7 +396,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone(), false))
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone()))
|
||||
|
||||
idx, rtoken, err := s.ACLTokenGetByAccessor(nil, "daf37c07-d04d-4fd5-9678-a8206a57d61a", nil)
|
||||
require.NoError(t, err)
|
||||
|
@ -532,7 +431,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone(), false))
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone()))
|
||||
|
||||
updated := &structs.ACLToken{
|
||||
AccessorID: "daf37c07-d04d-4fd5-9678-a8206a57d61a",
|
||||
|
@ -554,7 +453,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(3, updated.Clone(), false))
|
||||
require.NoError(t, s.ACLTokenSet(3, updated.Clone()))
|
||||
|
||||
idx, rtoken, err := s.ACLTokenGetByAccessor(nil, "daf37c07-d04d-4fd5-9678-a8206a57d61a", nil)
|
||||
require.NoError(t, err)
|
||||
|
@ -588,7 +487,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone(), false))
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone()))
|
||||
|
||||
idx, rtoken, err := s.ACLTokenGetByAccessor(nil, "daf37c07-d04d-4fd5-9678-a8206a57d61a", nil)
|
||||
require.NoError(t, err)
|
||||
|
@ -873,30 +772,44 @@ func TestStateStore_ACLTokens_ListUpgradeable(t *testing.T) {
|
|||
t.Parallel()
|
||||
s := testACLTokensStateStore(t)
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, &structs.ACLToken{
|
||||
aclTokenSetLegacy := func(idx uint64, token *structs.ACLToken) error {
|
||||
tx := s.db.WriteTxn(idx)
|
||||
defer tx.Abort()
|
||||
|
||||
opts := ACLTokenSetOptions{Legacy: true}
|
||||
if err := aclTokenSetTxn(tx, idx, token, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
const ACLTokenTypeManagement = "management"
|
||||
|
||||
require.NoError(t, aclTokenSetLegacy(2, &structs.ACLToken{
|
||||
SecretID: "34ec8eb3-095d-417a-a937-b439af7a8e8b",
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
}, true))
|
||||
Type: ACLTokenTypeManagement,
|
||||
}))
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(3, &structs.ACLToken{
|
||||
require.NoError(t, aclTokenSetLegacy(3, &structs.ACLToken{
|
||||
SecretID: "8de2dd39-134d-4cb1-950b-b7ab96ea20ba",
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
}, true))
|
||||
Type: ACLTokenTypeManagement,
|
||||
}))
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(4, &structs.ACLToken{
|
||||
require.NoError(t, aclTokenSetLegacy(4, &structs.ACLToken{
|
||||
SecretID: "548bdb8e-c0d6-477b-bcc4-67fb836e9e61",
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
}, true))
|
||||
Type: ACLTokenTypeManagement,
|
||||
}))
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(5, &structs.ACLToken{
|
||||
require.NoError(t, aclTokenSetLegacy(5, &structs.ACLToken{
|
||||
SecretID: "3ee33676-d9b8-4144-bf0b-92618cff438b",
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
}, true))
|
||||
Type: ACLTokenTypeManagement,
|
||||
}))
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(6, &structs.ACLToken{
|
||||
require.NoError(t, aclTokenSetLegacy(6, &structs.ACLToken{
|
||||
SecretID: "fa9d658a-6e26-42ab-a5f0-1ea05c893dee",
|
||||
Type: structs.ACLTokenTypeManagement,
|
||||
}, true))
|
||||
Type: ACLTokenTypeManagement,
|
||||
}))
|
||||
|
||||
tokens, _, err := s.ACLTokenListUpgradeable(3)
|
||||
require.NoError(t, err)
|
||||
|
@ -1246,7 +1159,7 @@ func TestStateStore_ACLToken_FixupPolicyLinks(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token, false))
|
||||
require.NoError(t, s.ACLTokenSet(2, token))
|
||||
|
||||
_, retrieved, err := s.ACLTokenGetByAccessor(nil, token.AccessorID, nil)
|
||||
require.NoError(t, err)
|
||||
|
@ -1372,7 +1285,7 @@ func TestStateStore_ACLToken_FixupRoleLinks(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token, false))
|
||||
require.NoError(t, s.ACLTokenSet(2, token))
|
||||
|
||||
_, retrieved, err := s.ACLTokenGetByAccessor(nil, token.AccessorID, nil)
|
||||
require.NoError(t, err)
|
||||
|
@ -1498,7 +1411,7 @@ func TestStateStore_ACLToken_Delete(t *testing.T) {
|
|||
Local: true,
|
||||
}
|
||||
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone(), false))
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone()))
|
||||
|
||||
_, rtoken, err := s.ACLTokenGetByAccessor(nil, "f1093997-b6c7-496d-bfb8-6b1b1895641b", nil)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -52,7 +52,7 @@ func TestStore_IntegrationWithEventPublisher_ACLTokenUpdate(t *testing.T) {
|
|||
SecretID: "72e81982-7a0f-491f-a60e-c9c802ac1402",
|
||||
}
|
||||
token2.SetHash(false)
|
||||
require.NoError(s.ACLTokenSet(3, token2.Clone(), false))
|
||||
require.NoError(s.ACLTokenSet(3, token2.Clone()))
|
||||
|
||||
// Ensure there's no reset event.
|
||||
assertNoEvent(t, eventCh)
|
||||
|
@ -64,7 +64,7 @@ func TestStore_IntegrationWithEventPublisher_ACLTokenUpdate(t *testing.T) {
|
|||
Description: "something else",
|
||||
}
|
||||
token3.SetHash(false)
|
||||
require.NoError(s.ACLTokenSet(4, token3.Clone(), false))
|
||||
require.NoError(s.ACLTokenSet(4, token3.Clone()))
|
||||
|
||||
// Ensure the reset event was sent.
|
||||
err = assertErr(t, eventCh)
|
||||
|
@ -484,7 +484,7 @@ func createTokenAndWaitForACLEventPublish(t *testing.T, s *Store) *structs.ACLTo
|
|||
eventCh := testRunSub(sub)
|
||||
|
||||
// Create the ACL token to be used in the subscription.
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone(), false))
|
||||
require.NoError(t, s.ACLTokenSet(2, token.Clone()))
|
||||
|
||||
// Wait for the pre-subscription to be reset
|
||||
assertReset(t, eventCh, true)
|
||||
|
|
|
@ -857,7 +857,7 @@ node "node1" {
|
|||
SecretID: token,
|
||||
Rules: "",
|
||||
}
|
||||
require.NoError(t, backend.store.ACLTokenSet(ids.Next("update"), aclToken, false))
|
||||
require.NoError(t, backend.store.ACLTokenSet(ids.Next("update"), aclToken))
|
||||
|
||||
select {
|
||||
case item := <-chEvents:
|
||||
|
|
|
@ -95,7 +95,6 @@ type ACLIdentity interface {
|
|||
SecretToken() string
|
||||
PolicyIDs() []string
|
||||
RoleIDs() []string
|
||||
EmbeddedPolicy() *ACLPolicy
|
||||
ServiceIdentityList() []*ACLServiceIdentity
|
||||
NodeIdentityList() []*ACLNodeIdentity
|
||||
IsExpired(asOf time.Time) bool
|
||||
|
@ -413,48 +412,6 @@ func (t *ACLToken) HasExpirationTime() bool {
|
|||
return t.ExpirationTime != nil && !t.ExpirationTime.IsZero()
|
||||
}
|
||||
|
||||
// TODO(ACL-Legacy-Compat): remove
|
||||
func (t *ACLToken) UsesNonLegacyFields() bool {
|
||||
return len(t.Policies) > 0 ||
|
||||
len(t.ServiceIdentities) > 0 ||
|
||||
len(t.NodeIdentities) > 0 ||
|
||||
len(t.Roles) > 0 ||
|
||||
t.Type == "" ||
|
||||
t.HasExpirationTime() ||
|
||||
t.ExpirationTTL != 0 ||
|
||||
t.AuthMethod != ""
|
||||
}
|
||||
|
||||
func (t *ACLToken) EmbeddedPolicy() *ACLPolicy {
|
||||
// DEPRECATED (ACL-Legacy-Compat)
|
||||
//
|
||||
// For legacy tokens with embedded rules this provides a way to map those
|
||||
// rules to an ACLPolicy. This function can just return nil once legacy
|
||||
// acl compatibility is no longer needed.
|
||||
//
|
||||
// Additionally for management tokens we must embed the policy rules
|
||||
// as well
|
||||
policy := &ACLPolicy{}
|
||||
if t.Type == ACLTokenTypeManagement {
|
||||
hasher := fnv.New128a()
|
||||
policy.ID = fmt.Sprintf("%x", hasher.Sum([]byte(ACLPolicyGlobalManagement)))
|
||||
policy.Name = "legacy-management"
|
||||
policy.Rules = ACLPolicyGlobalManagement
|
||||
policy.Syntax = acl.SyntaxCurrent
|
||||
} else if t.Rules != "" || t.Type == ACLTokenTypeClient {
|
||||
hasher := fnv.New128a()
|
||||
policy.ID = fmt.Sprintf("%x", hasher.Sum([]byte(t.Rules)))
|
||||
policy.Name = fmt.Sprintf("legacy-policy-%s", policy.ID)
|
||||
policy.Rules = t.Rules
|
||||
policy.Syntax = acl.SyntaxLegacy
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
policy.SetHash(true)
|
||||
return policy
|
||||
}
|
||||
|
||||
func (t *ACLToken) EnterpriseMetadata() *EnterpriseMeta {
|
||||
return &t.EnterpriseMeta
|
||||
}
|
||||
|
@ -1799,10 +1756,6 @@ func (id *AgentMasterTokenIdentity) RoleIDs() []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (id *AgentMasterTokenIdentity) EmbeddedPolicy() *ACLPolicy {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (id *AgentMasterTokenIdentity) ServiceIdentityList() []*ACLServiceIdentity {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
// DEPRECATED (ACL-Legacy-Compat)
|
||||
//
|
||||
// Everything within this file is deprecated and related to the original ACL
|
||||
// implementation. Once support for v1 ACLs are removed this whole file can
|
||||
// be deleted.
|
||||
|
||||
package structs
|
||||
|
||||
const (
|
||||
// ACLTokenTypeClient tokens have rules applied
|
||||
ACLTokenTypeClient = "client"
|
||||
|
||||
// ACLTokenTypeManagement tokens have an always allow policy, so they can
|
||||
// make other tokens and can access all resources.
|
||||
ACLTokenTypeManagement = "management"
|
||||
)
|
|
@ -44,56 +44,6 @@ func TestStructs_ACLToken_PolicyIDs(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestStructs_ACLToken_EmbeddedPolicy(t *testing.T) {
|
||||
|
||||
t.Run("No Rules", func(t *testing.T) {
|
||||
|
||||
token := &ACLToken{}
|
||||
require.Nil(t, token.EmbeddedPolicy())
|
||||
})
|
||||
|
||||
t.Run("Legacy Client", func(t *testing.T) {
|
||||
|
||||
// None of the other fields should be considered
|
||||
token := &ACLToken{
|
||||
Type: ACLTokenTypeClient,
|
||||
Rules: `acl = "read"`,
|
||||
}
|
||||
|
||||
policy := token.EmbeddedPolicy()
|
||||
require.NotNil(t, policy)
|
||||
require.NotEqual(t, "", policy.ID)
|
||||
require.True(t, strings.HasPrefix(policy.Name, "legacy-policy-"))
|
||||
require.Equal(t, token.Rules, policy.Rules)
|
||||
require.Equal(t, policy.Syntax, acl.SyntaxLegacy)
|
||||
require.NotNil(t, policy.Hash)
|
||||
require.NotEqual(t, []byte{}, policy.Hash)
|
||||
})
|
||||
|
||||
t.Run("Same Policy for Tokens with same Rules", func(t *testing.T) {
|
||||
|
||||
token1 := &ACLToken{
|
||||
AccessorID: "f55b260c-5e05-418e-ab19-d421d1ab4b52",
|
||||
SecretID: "b2165bac-7006-459b-8a72-7f549f0f06d6",
|
||||
Description: "token 1",
|
||||
Type: ACLTokenTypeClient,
|
||||
Rules: `acl = "read"`,
|
||||
}
|
||||
|
||||
token2 := &ACLToken{
|
||||
AccessorID: "09d1c059-961a-46bd-a2e4-76adebe35fa5",
|
||||
SecretID: "65e98e67-9b29-470c-8ffa-7c5a23cc67c8",
|
||||
Description: "token 2",
|
||||
Type: ACLTokenTypeClient,
|
||||
Rules: `acl = "read"`,
|
||||
}
|
||||
|
||||
policy1 := token1.EmbeddedPolicy()
|
||||
policy2 := token2.EmbeddedPolicy()
|
||||
require.Equal(t, policy1, policy2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStructs_ACLServiceIdentity_SyntheticPolicy(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
|
@ -205,7 +155,6 @@ func TestStructs_ACLToken_EstimateSize(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStructs_ACLToken_Stub(t *testing.T) {
|
||||
|
||||
t.Run("Basic", func(t *testing.T) {
|
||||
|
||||
token := ACLToken{
|
||||
|
@ -238,28 +187,6 @@ func TestStructs_ACLToken_Stub(t *testing.T) {
|
|||
require.Equal(t, token.ModifyIndex, stub.ModifyIndex)
|
||||
require.False(t, stub.Legacy)
|
||||
})
|
||||
|
||||
t.Run("Legacy", func(t *testing.T) {
|
||||
token := ACLToken{
|
||||
AccessorID: "09d1c059-961a-46bd-a2e4-76adebe35fa5",
|
||||
SecretID: "65e98e67-9b29-470c-8ffa-7c5a23cc67c8",
|
||||
Description: "test",
|
||||
Type: ACLTokenTypeClient,
|
||||
Rules: `key "" { policy = "read" }`,
|
||||
}
|
||||
|
||||
stub := token.Stub()
|
||||
require.Equal(t, token.AccessorID, stub.AccessorID)
|
||||
require.Equal(t, token.SecretID, stub.SecretID)
|
||||
require.Equal(t, token.Description, stub.Description)
|
||||
require.Equal(t, token.Policies, stub.Policies)
|
||||
require.Equal(t, token.Local, stub.Local)
|
||||
require.Equal(t, token.CreateTime, stub.CreateTime)
|
||||
require.Equal(t, token.Hash, stub.Hash)
|
||||
require.Equal(t, token.CreateIndex, stub.CreateIndex)
|
||||
require.Equal(t, token.ModifyIndex, stub.ModifyIndex)
|
||||
require.True(t, stub.Legacy)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStructs_ACLTokens_Sort(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue