Merge pull request #12165 from hashicorp/dnephin/acl-resolve-token

acl: remove some of the duplicate resolve token methods
This commit is contained in:
Daniel Nephin 2022-01-31 13:27:49 -05:00 committed by GitHub
commit 1fb2d49826
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 59 additions and 98 deletions

View File

@ -1160,6 +1160,30 @@ func (r *ACLResolver) ACLsEnabled() bool {
return true
}
func (r *ACLResolver) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) {
identity, authz, err := r.ResolveTokenToIdentityAndAuthorizer(token)
if err != nil {
return nil, err
}
if entMeta == nil {
entMeta = &structs.EnterpriseMeta{}
}
// Default the EnterpriseMeta based on the Tokens meta or actual defaults
// in the case of unknown identity
if identity != nil {
entMeta.Merge(identity.EnterpriseMetadata())
} else {
entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition())
}
// Use the meta to fill in the ACL authorization context
entMeta.FillAuthzContext(authzContext)
return authz, err
}
// aclFilter is used to filter results from our state store based on ACL rules
// configured for the provided token.
type aclFilter struct {

View File

@ -1,7 +1,6 @@
package consul
import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
)
@ -48,35 +47,3 @@ func (c *clientACLResolverBackend) ResolveRoleFromID(roleID string) (bool, *stru
// clients do no local role resolution at the moment
return false, nil, nil
}
func (c *Client) ResolveTokenToIdentity(token string) (structs.ACLIdentity, error) {
// not using ResolveTokenToIdentityAndAuthorizer because in this case we don't
// need to resolve the roles, policies and namespace but just want the identity
// information such as accessor id.
return c.acls.ResolveTokenToIdentity(token)
}
// TODO: Server has an identical implementation, remove duplication
func (c *Client) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) {
identity, authz, err := c.acls.ResolveTokenToIdentityAndAuthorizer(token)
if err != nil {
return nil, err
}
if entMeta == nil {
entMeta = &structs.EnterpriseMeta{}
}
// Default the EnterpriseMeta based on the Tokens meta or actual defaults
// in the case of unknown identity
if identity != nil {
entMeta.Merge(identity.EnterpriseMetadata())
} else {
entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition())
}
// Use the meta to fill in the ACL authorization context
entMeta.FillAuthzContext(authzContext)
return authz, err
}

View File

@ -724,7 +724,7 @@ func (a *ACL) tokenSetInternal(args *structs.ACLTokenSetRequest, reply *structs.
}
// Purge the identity from the cache to prevent using the previous definition of the identity
a.srv.acls.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID))
a.srv.ACLResolver.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID))
// Don't check expiration times here as it doesn't really matter.
if _, updatedToken, err := a.srv.fsm.State().ACLTokenGetByAccessor(nil, token.AccessorID, nil); err == nil && updatedToken != nil {
@ -876,7 +876,7 @@ func (a *ACL) TokenDelete(args *structs.ACLTokenDeleteRequest, reply *string) er
}
// Purge the identity from the cache to prevent using the previous definition of the identity
a.srv.acls.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID))
a.srv.ACLResolver.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID))
if reply != nil {
*reply = token.AccessorID
@ -1198,7 +1198,7 @@ func (a *ACL) PolicySet(args *structs.ACLPolicySetRequest, reply *structs.ACLPol
}
// Remove from the cache to prevent stale cache usage
a.srv.acls.cache.RemovePolicy(policy.ID)
a.srv.ACLResolver.cache.RemovePolicy(policy.ID)
if _, policy, err := a.srv.fsm.State().ACLPolicyGetByID(nil, policy.ID, &policy.EnterpriseMeta); err == nil && policy != nil {
*reply = *policy
@ -1257,7 +1257,7 @@ func (a *ACL) PolicyDelete(args *structs.ACLPolicyDeleteRequest, reply *string)
return fmt.Errorf("Failed to apply policy delete request: %v", err)
}
a.srv.acls.cache.RemovePolicy(policy.ID)
a.srv.ACLResolver.cache.RemovePolicy(policy.ID)
*reply = policy.Name
@ -1318,12 +1318,12 @@ func (a *ACL) PolicyResolve(args *structs.ACLPolicyBatchGetRequest, reply *struc
}
// get full list of policies for this token
identity, policies, err := a.srv.acls.resolveTokenToIdentityAndPolicies(args.Token)
identity, policies, err := a.srv.ACLResolver.resolveTokenToIdentityAndPolicies(args.Token)
if err != nil {
return err
}
entIdentity, entPolicies, err := a.srv.acls.resolveEnterpriseIdentityAndPolicies(identity)
entIdentity, entPolicies, err := a.srv.ACLResolver.resolveEnterpriseIdentityAndPolicies(identity)
if err != nil {
return err
}
@ -1609,7 +1609,7 @@ func (a *ACL) RoleSet(args *structs.ACLRoleSetRequest, reply *structs.ACLRole) e
}
// Remove from the cache to prevent stale cache usage
a.srv.acls.cache.RemoveRole(role.ID)
a.srv.ACLResolver.cache.RemoveRole(role.ID)
if _, role, err := a.srv.fsm.State().ACLRoleGetByID(nil, role.ID, &role.EnterpriseMeta); err == nil && role != nil {
*reply = *role
@ -1664,7 +1664,7 @@ func (a *ACL) RoleDelete(args *structs.ACLRoleDeleteRequest, reply *string) erro
return fmt.Errorf("Failed to apply role delete request: %v", err)
}
a.srv.acls.cache.RemoveRole(role.ID)
a.srv.ACLResolver.cache.RemoveRole(role.ID)
*reply = role.Name
@ -1719,12 +1719,12 @@ func (a *ACL) RoleResolve(args *structs.ACLRoleBatchGetRequest, reply *structs.A
}
// get full list of roles for this token
identity, roles, err := a.srv.acls.resolveTokenToIdentityAndRoles(args.Token)
identity, roles, err := a.srv.ACLResolver.resolveTokenToIdentityAndRoles(args.Token)
if err != nil {
return err
}
entIdentity, entRoles, err := a.srv.acls.resolveEnterpriseIdentityAndRoles(identity)
entIdentity, entRoles, err := a.srv.ACLResolver.resolveEnterpriseIdentityAndRoles(identity)
if err != nil {
return err
}
@ -2481,7 +2481,7 @@ func (a *ACL) Logout(args *structs.ACLLogoutRequest, reply *bool) error {
}
// Purge the identity from the cache to prevent using the previous definition of the identity
a.srv.acls.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID))
a.srv.ACLResolver.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID))
*reply = true

View File

@ -166,46 +166,16 @@ func (s *serverACLResolverBackend) ResolveRoleFromID(roleID string) (bool, *stru
}
func (s *Server) ResolveToken(token string) (acl.Authorizer, error) {
_, authz, err := s.acls.ResolveTokenToIdentityAndAuthorizer(token)
_, authz, err := s.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token)
return authz, err
}
func (s *Server) ResolveTokenToIdentity(token string) (structs.ACLIdentity, error) {
// not using ResolveTokenToIdentityAndAuthorizer because in this case we don't
// need to resolve the roles, policies and namespace but just want the identity
// information such as accessor id.
return s.acls.ResolveTokenToIdentity(token)
}
// TODO: Client has an identical implementation, remove duplication
func (s *Server) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) {
identity, authz, err := s.acls.ResolveTokenToIdentityAndAuthorizer(token)
if err != nil {
return nil, err
}
if entMeta == nil {
entMeta = &structs.EnterpriseMeta{}
}
// Default the EnterpriseMeta based on the Tokens meta or actual defaults
// in the case of unknown identity
if identity != nil {
entMeta.Merge(identity.EnterpriseMetadata())
} else {
entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition())
}
// Use the meta to fill in the ACL authorization context
entMeta.FillAuthzContext(authzContext)
return authz, err
}
func (s *Server) filterACL(token string, subj interface{}) error {
return filterACL(s.acls, token, subj)
return filterACL(s.ACLResolver, token, subj)
}
func (s *Server) filterACLWithAuthorizer(authorizer acl.Authorizer, subj interface{}) {
filterACLWithAuthorizer(s.acls.logger, authorizer, subj)
filterACLWithAuthorizer(s.ACLResolver.logger, authorizer, subj)
}

View File

@ -4065,7 +4065,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t
require.NoError(t, err)
runStep(t, "first resolve", func(t *testing.T) {
_, authz, err := srv.acls.ResolveTokenToIdentityAndAuthorizer(token)
_, authz, err := srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token)
require.NoError(t, err)
require.NotNil(t, authz)
require.Equal(t, acl.Allow, authz.KeyRead("foo", nil))
@ -4084,7 +4084,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t
err := msgpackrpc.CallWithCodec(codec, "ACL.PolicySet", &reqPolicy, &structs.ACLPolicy{})
require.NoError(t, err)
_, authz, err := srv.acls.ResolveTokenToIdentityAndAuthorizer(token)
_, authz, err := srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token)
require.NoError(t, err)
require.NotNil(t, authz)
require.Equal(t, acl.Deny, authz.KeyRead("foo", nil))
@ -4100,7 +4100,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t
err := msgpackrpc.CallWithCodec(codec, "ACL.TokenDelete", &req, &resp)
require.NoError(t, err)
_, _, err = srv.acls.ResolveTokenToIdentityAndAuthorizer(token)
_, _, err = srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token)
require.True(t, acl.IsErrNotFound(err), "Error %v is not acl.ErrNotFound", err)
})
}

View File

@ -107,7 +107,7 @@ func (s *Server) reapExpiredACLTokens(local, global bool) (int, error) {
// Purge the identities from the cache
for _, secretID := range secretIDs {
s.acls.cache.RemoveIdentity(tokenSecretCacheID(secretID))
s.ACLResolver.cache.RemoveIdentity(tokenSecretCacheID(secretID))
}
return len(req.TokenIDs), nil

View File

@ -56,7 +56,7 @@ type Client struct {
config *Config
// acls is used to resolve tokens to effective policies
acls *ACLResolver
*ACLResolver
// Connection pool to consul servers
connPool *pool.ConnPool
@ -127,7 +127,7 @@ func NewClient(config *Config, deps Deps) (*Client, error) {
Tokens: deps.Tokens,
}
var err error
if c.acls, err = NewACLResolver(&aclConfig); err != nil {
if c.ACLResolver, err = NewACLResolver(&aclConfig); err != nil {
c.Shutdown()
return nil, fmt.Errorf("Failed to create ACL resolver: %v", err)
}
@ -172,7 +172,7 @@ func (c *Client) Shutdown() error {
// Close the connection pool
c.connPool.Shutdown()
c.acls.Close()
c.ACLResolver.Close()
return nil
}

View File

@ -100,7 +100,7 @@ func (s *Intention) Apply(args *structs.IntentionRequest, reply *string) error {
}
// Get the ACL token for the request for the checks below.
identity, authz, err := s.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token)
identity, authz, err := s.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}

View File

@ -433,7 +433,7 @@ func (m *Internal) KeyringOperation(
}
// Check ACLs
identity, authz, err := m.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token)
identity, authz, err := m.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}

View File

@ -363,7 +363,7 @@ func (s *Server) initializeACLs(ctx context.Context) error {
// Purge the cache, since it could've changed while we were not the
// leader.
s.acls.cache.Purge()
s.ACLResolver.cache.Purge()
// Purge the auth method validators since they could've changed while we
// were not leader.

View File

@ -17,7 +17,7 @@ func (op *Operator) AutopilotGetConfiguration(args *structs.DCSpecificRequest, r
}
// This action requires operator read access.
identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token)
identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
@ -49,7 +49,7 @@ func (op *Operator) AutopilotSetConfiguration(args *structs.AutopilotSetConfigRe
}
// This action requires operator write access.
identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token)
identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
@ -84,7 +84,7 @@ func (op *Operator) ServerHealth(args *structs.DCSpecificRequest, reply *structs
}
// This action requires operator read access.
identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token)
identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
@ -151,7 +151,7 @@ func (op *Operator) AutopilotState(args *structs.DCSpecificRequest, reply *autop
}
// This action requires operator read access.
identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token)
identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}

View File

@ -81,7 +81,7 @@ func (op *Operator) RaftRemovePeerByAddress(args *structs.RaftRemovePeerRequest,
// This is a super dangerous operation that requires operator write
// access.
identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token)
identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
@ -134,7 +134,7 @@ func (op *Operator) RaftRemovePeerByID(args *structs.RaftRemovePeerRequest, repl
// This is a super dangerous operation that requires operator write
// access.
identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token)
identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}

View File

@ -141,7 +141,7 @@ type Server struct {
aclConfig *acl.Config
// acls is used to resolve tokens to effective policies
acls *ACLResolver
*ACLResolver
aclAuthMethodValidators authmethod.Cache
@ -457,7 +457,7 @@ func NewServer(config *Config, flat Deps) (*Server, error) {
Tokens: flat.Tokens,
}
// Initialize the ACL resolver.
if s.acls, err = NewACLResolver(&aclConfig); err != nil {
if s.ACLResolver, err = NewACLResolver(&aclConfig); err != nil {
s.Shutdown()
return nil, fmt.Errorf("Failed to create ACL resolver: %v", err)
}
@ -994,8 +994,8 @@ func (s *Server) Shutdown() error {
s.connPool.Shutdown()
}
if s.acls != nil {
s.acls.Close()
if s.ACLResolver != nil {
s.ACLResolver.Close()
}
if s.fsm != nil {

View File

@ -121,7 +121,7 @@ func (s *Server) setupSerfConfig(opts setupSerfOptions) (*serf.Config, error) {
// TODO(ACL-Legacy-Compat): remove in phase 2. These are kept for now to
// allow for upgrades.
if s.acls.ACLsEnabled() {
if s.ACLResolver.ACLsEnabled() {
conf.Tags[metadata.TagACLs] = string(structs.ACLModeEnabled)
} else {
conf.Tags[metadata.TagACLs] = string(structs.ACLModeDisabled)