mirror of
https://github.com/status-im/consul.git
synced 2025-02-18 08:36:46 +00:00
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
c841c76373
@ -18,11 +18,6 @@ func DefaultSource() Source {
|
|||||||
serfLAN := cfg.SerfLANConfig.MemberlistConfig
|
serfLAN := cfg.SerfLANConfig.MemberlistConfig
|
||||||
serfWAN := cfg.SerfWANConfig.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{
|
return FileSource{
|
||||||
Name: "default",
|
Name: "default",
|
||||||
Format: "hcl",
|
Format: "hcl",
|
||||||
|
@ -100,10 +100,6 @@ func (id *missingIdentity) RoleIDs() []string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (id *missingIdentity) EmbeddedPolicy() *structs.ACLPolicy {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (id *missingIdentity) ServiceIdentityList() []*structs.ACLServiceIdentity {
|
func (id *missingIdentity) ServiceIdentityList() []*structs.ACLServiceIdentity {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -124,13 +120,6 @@ func (id *missingIdentity) EnterpriseMetadata() *structs.EnterpriseMeta {
|
|||||||
return structs.DefaultEnterpriseMetaInDefaultPartition()
|
return structs.DefaultEnterpriseMetaInDefaultPartition()
|
||||||
}
|
}
|
||||||
|
|
||||||
func minTTL(a time.Duration, b time.Duration) time.Duration {
|
|
||||||
if a < b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
type ACLRemoteError struct {
|
type ACLRemoteError struct {
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
@ -149,7 +138,7 @@ func tokenSecretCacheID(token string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ACLResolverDelegate interface {
|
type ACLResolverDelegate interface {
|
||||||
ACLDatacenter(legacy bool) string
|
ACLDatacenter() string
|
||||||
ResolveIdentityFromToken(token string) (bool, structs.ACLIdentity, error)
|
ResolveIdentityFromToken(token string) (bool, structs.ACLIdentity, error)
|
||||||
ResolvePolicyFromID(policyID string) (bool, *structs.ACLPolicy, error)
|
ResolvePolicyFromID(policyID string) (bool, *structs.ACLPolicy, error)
|
||||||
ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error)
|
ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error)
|
||||||
@ -365,7 +354,7 @@ func (r *ACLResolver) fetchAndCacheIdentityFromToken(token string, cached *struc
|
|||||||
cacheID := tokenSecretCacheID(token)
|
cacheID := tokenSecretCacheID(token)
|
||||||
|
|
||||||
req := structs.ACLTokenGetRequest{
|
req := structs.ACLTokenGetRequest{
|
||||||
Datacenter: r.delegate.ACLDatacenter(false),
|
Datacenter: r.delegate.ACLDatacenter(),
|
||||||
TokenID: token,
|
TokenID: token,
|
||||||
TokenIDType: structs.ACLTokenSecret,
|
TokenIDType: structs.ACLTokenSecret,
|
||||||
QueryOptions: structs.QueryOptions{
|
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) {
|
func (r *ACLResolver) fetchAndCachePoliciesForIdentity(identity structs.ACLIdentity, policyIDs []string, cached map[string]*structs.PolicyCacheEntry) (map[string]*structs.ACLPolicy, error) {
|
||||||
req := structs.ACLPolicyBatchGetRequest{
|
req := structs.ACLPolicyBatchGetRequest{
|
||||||
Datacenter: r.delegate.ACLDatacenter(false),
|
Datacenter: r.delegate.ACLDatacenter(),
|
||||||
PolicyIDs: policyIDs,
|
PolicyIDs: policyIDs,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: identity.SecretToken(),
|
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) {
|
func (r *ACLResolver) fetchAndCacheRolesForIdentity(identity structs.ACLIdentity, roleIDs []string, cached map[string]*structs.RoleCacheEntry) (map[string]*structs.ACLRole, error) {
|
||||||
req := structs.ACLRoleBatchGetRequest{
|
req := structs.ACLRoleBatchGetRequest{
|
||||||
Datacenter: r.delegate.ACLDatacenter(false),
|
Datacenter: r.delegate.ACLDatacenter(),
|
||||||
RoleIDs: roleIDs,
|
RoleIDs: roleIDs,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: identity.SecretToken(),
|
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 {
|
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.
|
// In this case the default policy will be all that is in effect.
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -23,17 +23,9 @@ var clientACLCacheConfig *structs.ACLCachesConfig = &structs.ACLCachesConfig{
|
|||||||
Roles: 128,
|
Roles: 128,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ACLDatacenter(legacy bool) string {
|
func (c *Client) ACLDatacenter() string {
|
||||||
// For resolution running on clients, when not in
|
// For resolution running on clients, servers within the current datacenter
|
||||||
// legacy mode the servers within the current datacenter
|
// must be queried first to pick up local tokens.
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.config.Datacenter
|
return c.config.Datacenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,10 +235,8 @@ func (a *ACL) BootstrapTokens(args *structs.DCSpecificRequest, reply *structs.AC
|
|||||||
ID: structs.ACLPolicyGlobalManagementID,
|
ID: structs.ACLPolicyGlobalManagementID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
Local: false,
|
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,
|
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
||||||
},
|
},
|
||||||
ResetIndex: specifiedIndex,
|
ResetIndex: specifiedIndex,
|
||||||
|
@ -48,7 +48,6 @@ func TestACLEndpoint_BootstrapTokens(t *testing.T) {
|
|||||||
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.BootstrapTokens", &arg, &out))
|
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.BootstrapTokens", &arg, &out))
|
||||||
require.Equal(t, 36, len(out.AccessorID))
|
require.Equal(t, 36, len(out.AccessorID))
|
||||||
require.True(t, strings.HasPrefix(out.Description, "Bootstrap Token"))
|
require.True(t, strings.HasPrefix(out.Description, "Bootstrap Token"))
|
||||||
require.Equal(t, out.Type, structs.ACLTokenTypeManagement)
|
|
||||||
require.True(t, out.CreateIndex > 0)
|
require.True(t, out.CreateIndex > 0)
|
||||||
require.Equal(t, out.CreateIndex, out.ModifyIndex)
|
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.Equal(t, 36, len(out.AccessorID))
|
||||||
require.NotEqual(t, oldID, out.AccessorID)
|
require.NotEqual(t, oldID, out.AccessorID)
|
||||||
require.True(t, strings.HasPrefix(out.Description, "Bootstrap Token"))
|
require.True(t, strings.HasPrefix(out.Description, "Bootstrap Token"))
|
||||||
require.Equal(t, out.Type, structs.ACLTokenTypeManagement)
|
|
||||||
require.True(t, out.CreateIndex > 0)
|
require.True(t, out.CreateIndex > 0)
|
||||||
require.Equal(t, out.CreateIndex, out.ModifyIndex)
|
require.Equal(t, out.CreateIndex, out.ModifyIndex)
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ func (s *Server) LocalTokensEnabled() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ACLDatacenter(legacy bool) string {
|
func (s *Server) ACLDatacenter() string {
|
||||||
// For resolution running on servers the only option
|
// For resolution running on servers the only option
|
||||||
// is to contact the configured ACL Datacenter
|
// is to contact the configured ACL Datacenter
|
||||||
if s.config.PrimaryDatacenter != "" {
|
if s.config.PrimaryDatacenter != "" {
|
||||||
|
@ -613,7 +613,7 @@ func (d *ACLResolverTestDelegate) plainRoleResolveFn(args *structs.ACLRoleBatchG
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ACLResolverTestDelegate) ACLDatacenter(legacy bool) string {
|
func (d *ACLResolverTestDelegate) ACLDatacenter() string {
|
||||||
return d.datacenter
|
return d.datacenter
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2112,38 +2112,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
|||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
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) {
|
runTwiceAndReset("service and intention wildcard write", func(t *testing.T) {
|
||||||
delegate.UseTestLocalData([]interface{}{
|
delegate.UseTestLocalData([]interface{}{
|
||||||
&structs.ACLToken{
|
&structs.ACLToken{
|
||||||
|
@ -111,8 +111,7 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) {
|
|||||||
},
|
},
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
Local: false,
|
Local: false,
|
||||||
// DEPRECATED (ACL-Legacy-Compat) - This is used so that the bootstrap token is still visible via the v1 acl APIs
|
Type: "management",
|
||||||
Type: structs.ACLTokenTypeManagement,
|
|
||||||
}
|
}
|
||||||
require.NoError(t, fsm.state.ACLBootstrap(10, 0, token))
|
require.NoError(t, fsm.state.ACLBootstrap(10, 0, token))
|
||||||
|
|
||||||
|
@ -452,11 +452,8 @@ func (s *Server) initializeACLs(ctx context.Context) error {
|
|||||||
ID: structs.ACLPolicyGlobalManagementID,
|
ID: structs.ACLPolicyGlobalManagementID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
Local: false,
|
Local: false,
|
||||||
|
|
||||||
// DEPRECATED (ACL-Legacy-Compat) - only needed for compatibility
|
|
||||||
Type: structs.ACLTokenTypeManagement,
|
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,35 +498,24 @@ func (s *Server) initializeACLs(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
// Ignoring expiration times to avoid an insertion collision.
|
// Ignoring expiration times to avoid an insertion collision.
|
||||||
if token == nil {
|
if token == nil {
|
||||||
// DEPRECATED (ACL-Legacy-Compat) - Don't need to query for previous "anonymous" token
|
token = &structs.ACLToken{
|
||||||
// check for legacy token that needs an upgrade
|
AccessorID: structs.ACLTokenAnonymousID,
|
||||||
_, legacyToken, err := state.ACLTokenGetBySecret(nil, anonymousToken, nil)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get anonymous token: %v", err)
|
return fmt.Errorf("failed to create 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")
|
|
||||||
}
|
}
|
||||||
|
s.logger.Info("Created ACL anonymous token from configuration")
|
||||||
}
|
}
|
||||||
// launch the upgrade go routine to generate accessors for everything
|
// launch the upgrade go routine to generate accessors for everything
|
||||||
s.startACLUpgrade(ctx)
|
s.startACLUpgrade(ctx)
|
||||||
@ -599,7 +585,7 @@ func (s *Server) legacyACLTokenUpgrade(ctx context.Context) error {
|
|||||||
len(newToken.ServiceIdentities) == 0 &&
|
len(newToken.ServiceIdentities) == 0 &&
|
||||||
len(newToken.NodeIdentities) == 0 &&
|
len(newToken.NodeIdentities) == 0 &&
|
||||||
len(newToken.Roles) == 0 &&
|
len(newToken.Roles) == 0 &&
|
||||||
newToken.Type == structs.ACLTokenTypeManagement {
|
newToken.Type == "management" {
|
||||||
newToken.Policies = append(newToken.Policies, structs.ACLTokenPolicyLink{ID: structs.ACLPolicyGlobalManagementID})
|
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
|
return role, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACLTokenSet is used to insert an ACL rule into the state store.
|
// ACLTokenSet is used in many tests to set a single ACL token. It is now a shim
|
||||||
// Deprecated (ACL-Legacy-Compat)
|
// for calling ACLTokenBatchSet with default options.
|
||||||
func (s *Store) ACLTokenSet(idx uint64, token *structs.ACLToken, legacy bool) error {
|
func (s *Store) ACLTokenSet(idx uint64, token *structs.ACLToken) error {
|
||||||
tx := s.db.WriteTxn(idx)
|
return s.ACLTokenBatchSet(idx, structs.ACLTokens{token}, ACLTokenSetOptions{})
|
||||||
defer tx.Abort()
|
|
||||||
|
|
||||||
// Call set on the ACL
|
|
||||||
if err := aclTokenSetTxn(tx, idx, token, ACLTokenSetOptions{Legacy: legacy}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return tx.Commit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ACLTokenSetOptions struct {
|
type ACLTokenSetOptions struct {
|
||||||
@ -506,11 +498,7 @@ func aclTokenSetTxn(tx WriteTxn, idx uint64, token *structs.ACLToken, opts ACLTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if opts.Legacy && original != nil {
|
if opts.Legacy && original != nil {
|
||||||
if original.UsesNonLegacyFields() {
|
return fmt.Errorf("legacy tokens can not be modified")
|
||||||
return fmt.Errorf("failed inserting acl token: cannot use legacy endpoint to modify a non-legacy token")
|
|
||||||
}
|
|
||||||
|
|
||||||
token.AccessorID = original.AccessorID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := aclTokenUpsertValidateEnterprise(tx, token, original); err != nil {
|
if err := aclTokenUpsertValidateEnterprise(tx, token, original); err != nil {
|
||||||
|
@ -46,7 +46,7 @@ func setupAnonymous(t *testing.T, s *Store) {
|
|||||||
Description: "Anonymous Token",
|
Description: "Anonymous Token",
|
||||||
}
|
}
|
||||||
token.SetHash(true)
|
token.SetHash(true)
|
||||||
require.NoError(t, s.ACLTokenSet(1, &token, false))
|
require.NoError(t, s.ACLTokenSet(1, &token))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testACLStateStore(t *testing.T) *Store {
|
func testACLStateStore(t *testing.T) *Store {
|
||||||
@ -171,8 +171,6 @@ func TestStateStore_ACLBootstrap(t *testing.T) {
|
|||||||
},
|
},
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
Local: false,
|
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{
|
token2 := &structs.ACLToken{
|
||||||
@ -186,8 +184,6 @@ func TestStateStore_ACLBootstrap(t *testing.T) {
|
|||||||
},
|
},
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
Local: false,
|
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)
|
s := testStateStore(t)
|
||||||
@ -238,103 +234,6 @@ func TestStateStore_ACLBootstrap(t *testing.T) {
|
|||||||
require.Len(t, tokens, 2)
|
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) {
|
func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
t.Run("Missing Secret", func(t *testing.T) {
|
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",
|
AccessorID: "39171632-6f34-4411-827f-9416403687f4",
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.ACLTokenSet(2, token.Clone(), false)
|
err := s.ACLTokenSet(2, token.Clone())
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Equal(t, ErrMissingACLTokenSecret, err)
|
require.Equal(t, ErrMissingACLTokenSecret, err)
|
||||||
})
|
})
|
||||||
@ -356,7 +255,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||||||
SecretID: "39171632-6f34-4411-827f-9416403687f4",
|
SecretID: "39171632-6f34-4411-827f-9416403687f4",
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.ACLTokenSet(2, token.Clone(), false)
|
err := s.ACLTokenSet(2, token.Clone())
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Equal(t, ErrMissingACLTokenAccessor, 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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -470,7 +369,7 @@ func TestStateStore_ACLToken_SetGet(t *testing.T) {
|
|||||||
AuthMethod: "test",
|
AuthMethod: "test",
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.ACLTokenSet(2, token, false)
|
err := s.ACLTokenSet(2, token)
|
||||||
require.Error(t, err)
|
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)
|
idx, rtoken, err := s.ACLTokenGetByAccessor(nil, "daf37c07-d04d-4fd5-9678-a8206a57d61a", nil)
|
||||||
require.NoError(t, err)
|
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{
|
updated := &structs.ACLToken{
|
||||||
AccessorID: "daf37c07-d04d-4fd5-9678-a8206a57d61a",
|
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)
|
idx, rtoken, err := s.ACLTokenGetByAccessor(nil, "daf37c07-d04d-4fd5-9678-a8206a57d61a", nil)
|
||||||
require.NoError(t, err)
|
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)
|
idx, rtoken, err := s.ACLTokenGetByAccessor(nil, "daf37c07-d04d-4fd5-9678-a8206a57d61a", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -873,30 +772,44 @@ func TestStateStore_ACLTokens_ListUpgradeable(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
s := testACLTokensStateStore(t)
|
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",
|
SecretID: "34ec8eb3-095d-417a-a937-b439af7a8e8b",
|
||||||
Type: structs.ACLTokenTypeManagement,
|
Type: ACLTokenTypeManagement,
|
||||||
}, true))
|
}))
|
||||||
|
|
||||||
require.NoError(t, s.ACLTokenSet(3, &structs.ACLToken{
|
require.NoError(t, aclTokenSetLegacy(3, &structs.ACLToken{
|
||||||
SecretID: "8de2dd39-134d-4cb1-950b-b7ab96ea20ba",
|
SecretID: "8de2dd39-134d-4cb1-950b-b7ab96ea20ba",
|
||||||
Type: structs.ACLTokenTypeManagement,
|
Type: ACLTokenTypeManagement,
|
||||||
}, true))
|
}))
|
||||||
|
|
||||||
require.NoError(t, s.ACLTokenSet(4, &structs.ACLToken{
|
require.NoError(t, aclTokenSetLegacy(4, &structs.ACLToken{
|
||||||
SecretID: "548bdb8e-c0d6-477b-bcc4-67fb836e9e61",
|
SecretID: "548bdb8e-c0d6-477b-bcc4-67fb836e9e61",
|
||||||
Type: structs.ACLTokenTypeManagement,
|
Type: ACLTokenTypeManagement,
|
||||||
}, true))
|
}))
|
||||||
|
|
||||||
require.NoError(t, s.ACLTokenSet(5, &structs.ACLToken{
|
require.NoError(t, aclTokenSetLegacy(5, &structs.ACLToken{
|
||||||
SecretID: "3ee33676-d9b8-4144-bf0b-92618cff438b",
|
SecretID: "3ee33676-d9b8-4144-bf0b-92618cff438b",
|
||||||
Type: structs.ACLTokenTypeManagement,
|
Type: ACLTokenTypeManagement,
|
||||||
}, true))
|
}))
|
||||||
|
|
||||||
require.NoError(t, s.ACLTokenSet(6, &structs.ACLToken{
|
require.NoError(t, aclTokenSetLegacy(6, &structs.ACLToken{
|
||||||
SecretID: "fa9d658a-6e26-42ab-a5f0-1ea05c893dee",
|
SecretID: "fa9d658a-6e26-42ab-a5f0-1ea05c893dee",
|
||||||
Type: structs.ACLTokenTypeManagement,
|
Type: ACLTokenTypeManagement,
|
||||||
}, true))
|
}))
|
||||||
|
|
||||||
tokens, _, err := s.ACLTokenListUpgradeable(3)
|
tokens, _, err := s.ACLTokenListUpgradeable(3)
|
||||||
require.NoError(t, err)
|
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)
|
_, retrieved, err := s.ACLTokenGetByAccessor(nil, token.AccessorID, nil)
|
||||||
require.NoError(t, err)
|
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)
|
_, retrieved, err := s.ACLTokenGetByAccessor(nil, token.AccessorID, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -1498,7 +1411,7 @@ func TestStateStore_ACLToken_Delete(t *testing.T) {
|
|||||||
Local: true,
|
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)
|
_, rtoken, err := s.ACLTokenGetByAccessor(nil, "f1093997-b6c7-496d-bfb8-6b1b1895641b", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -52,7 +52,7 @@ func TestStore_IntegrationWithEventPublisher_ACLTokenUpdate(t *testing.T) {
|
|||||||
SecretID: "72e81982-7a0f-491f-a60e-c9c802ac1402",
|
SecretID: "72e81982-7a0f-491f-a60e-c9c802ac1402",
|
||||||
}
|
}
|
||||||
token2.SetHash(false)
|
token2.SetHash(false)
|
||||||
require.NoError(s.ACLTokenSet(3, token2.Clone(), false))
|
require.NoError(s.ACLTokenSet(3, token2.Clone()))
|
||||||
|
|
||||||
// Ensure there's no reset event.
|
// Ensure there's no reset event.
|
||||||
assertNoEvent(t, eventCh)
|
assertNoEvent(t, eventCh)
|
||||||
@ -64,7 +64,7 @@ func TestStore_IntegrationWithEventPublisher_ACLTokenUpdate(t *testing.T) {
|
|||||||
Description: "something else",
|
Description: "something else",
|
||||||
}
|
}
|
||||||
token3.SetHash(false)
|
token3.SetHash(false)
|
||||||
require.NoError(s.ACLTokenSet(4, token3.Clone(), false))
|
require.NoError(s.ACLTokenSet(4, token3.Clone()))
|
||||||
|
|
||||||
// Ensure the reset event was sent.
|
// Ensure the reset event was sent.
|
||||||
err = assertErr(t, eventCh)
|
err = assertErr(t, eventCh)
|
||||||
@ -484,7 +484,7 @@ func createTokenAndWaitForACLEventPublish(t *testing.T, s *Store) *structs.ACLTo
|
|||||||
eventCh := testRunSub(sub)
|
eventCh := testRunSub(sub)
|
||||||
|
|
||||||
// Create the ACL token to be used in the subscription.
|
// 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
|
// Wait for the pre-subscription to be reset
|
||||||
assertReset(t, eventCh, true)
|
assertReset(t, eventCh, true)
|
||||||
|
@ -857,7 +857,7 @@ node "node1" {
|
|||||||
SecretID: token,
|
SecretID: token,
|
||||||
Rules: "",
|
Rules: "",
|
||||||
}
|
}
|
||||||
require.NoError(t, backend.store.ACLTokenSet(ids.Next("update"), aclToken, false))
|
require.NoError(t, backend.store.ACLTokenSet(ids.Next("update"), aclToken))
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case item := <-chEvents:
|
case item := <-chEvents:
|
||||||
|
@ -95,7 +95,6 @@ type ACLIdentity interface {
|
|||||||
SecretToken() string
|
SecretToken() string
|
||||||
PolicyIDs() []string
|
PolicyIDs() []string
|
||||||
RoleIDs() []string
|
RoleIDs() []string
|
||||||
EmbeddedPolicy() *ACLPolicy
|
|
||||||
ServiceIdentityList() []*ACLServiceIdentity
|
ServiceIdentityList() []*ACLServiceIdentity
|
||||||
NodeIdentityList() []*ACLNodeIdentity
|
NodeIdentityList() []*ACLNodeIdentity
|
||||||
IsExpired(asOf time.Time) bool
|
IsExpired(asOf time.Time) bool
|
||||||
@ -413,48 +412,6 @@ func (t *ACLToken) HasExpirationTime() bool {
|
|||||||
return t.ExpirationTime != nil && !t.ExpirationTime.IsZero()
|
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 {
|
func (t *ACLToken) EnterpriseMetadata() *EnterpriseMeta {
|
||||||
return &t.EnterpriseMeta
|
return &t.EnterpriseMeta
|
||||||
}
|
}
|
||||||
@ -1799,10 +1756,6 @@ func (id *AgentMasterTokenIdentity) RoleIDs() []string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (id *AgentMasterTokenIdentity) EmbeddedPolicy() *ACLPolicy {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (id *AgentMasterTokenIdentity) ServiceIdentityList() []*ACLServiceIdentity {
|
func (id *AgentMasterTokenIdentity) ServiceIdentityList() []*ACLServiceIdentity {
|
||||||
return nil
|
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) {
|
func TestStructs_ACLServiceIdentity_SyntheticPolicy(t *testing.T) {
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
@ -205,7 +155,6 @@ func TestStructs_ACLToken_EstimateSize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStructs_ACLToken_Stub(t *testing.T) {
|
func TestStructs_ACLToken_Stub(t *testing.T) {
|
||||||
|
|
||||||
t.Run("Basic", func(t *testing.T) {
|
t.Run("Basic", func(t *testing.T) {
|
||||||
|
|
||||||
token := ACLToken{
|
token := ACLToken{
|
||||||
@ -238,28 +187,6 @@ func TestStructs_ACLToken_Stub(t *testing.T) {
|
|||||||
require.Equal(t, token.ModifyIndex, stub.ModifyIndex)
|
require.Equal(t, token.ModifyIndex, stub.ModifyIndex)
|
||||||
require.False(t, stub.Legacy)
|
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) {
|
func TestStructs_ACLTokens_Sort(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user