Merge pull request #11435 from hashicorp/ent-authorizer-refactor

[OSS] Export ACLs refactor
This commit is contained in:
Freddy 2021-10-27 13:04:40 -06:00 committed by GitHub
commit fbcf9f3f6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 31 additions and 34 deletions

View File

@ -14,9 +14,13 @@ type Config struct {
EnterpriseConfig EnterpriseConfig
} }
type PartitionExportInfo interface { type ExportFetcher interface {
// DownstreamPartitions returns the list of partitions the given service has been exported to. // ExportsForPartition returns the config entry defining exports for a partition
DownstreamPartitions(service string, anyService bool, ctx *AuthorizerContext) []string ExportsForPartition(partition string) PartitionExports
}
type PartitionExports struct {
Data map[string]map[string][]string
} }
// GetWildcardName will retrieve the configured wildcard name or provide a default // GetWildcardName will retrieve the configured wildcard name or provide a default

View File

@ -149,9 +149,6 @@ type Authorizer interface {
// service // service
ServiceWrite(string, *AuthorizerContext) EnforcementDecision ServiceWrite(string, *AuthorizerContext) EnforcementDecision
// ServiceWriteAny checks for permission to read any service
ServiceWriteAny(*AuthorizerContext) EnforcementDecision
// SessionRead checks for permission to read sessions for a given node. // SessionRead checks for permission to read sessions for a given node.
SessionRead(string, *AuthorizerContext) EnforcementDecision SessionRead(string, *AuthorizerContext) EnforcementDecision

View File

@ -185,11 +185,6 @@ func (m *mockAuthorizer) ServiceWrite(segment string, ctx *AuthorizerContext) En
return ret.Get(0).(EnforcementDecision) return ret.Get(0).(EnforcementDecision)
} }
func (m *mockAuthorizer) ServiceWriteAny(ctx *AuthorizerContext) EnforcementDecision {
ret := m.Called(ctx)
return ret.Get(0).(EnforcementDecision)
}
// SessionRead checks for permission to read sessions for a given node. // SessionRead checks for permission to read sessions for a given node.
func (m *mockAuthorizer) SessionRead(segment string, ctx *AuthorizerContext) EnforcementDecision { func (m *mockAuthorizer) SessionRead(segment string, ctx *AuthorizerContext) EnforcementDecision {
ret := m.Called(segment, ctx) ret := m.Called(segment, ctx)

View File

@ -235,12 +235,6 @@ func (c *ChainedAuthorizer) ServiceWrite(name string, entCtx *AuthorizerContext)
}) })
} }
func (c *ChainedAuthorizer) ServiceWriteAny(entCtx *AuthorizerContext) EnforcementDecision {
return c.executeChain(func(authz Authorizer) EnforcementDecision {
return authz.ServiceWriteAny(entCtx)
})
}
// SessionRead checks for permission to read sessions for a given node. // SessionRead checks for permission to read sessions for a given node.
func (c *ChainedAuthorizer) SessionRead(node string, entCtx *AuthorizerContext) EnforcementDecision { func (c *ChainedAuthorizer) SessionRead(node string, entCtx *AuthorizerContext) EnforcementDecision {
return c.executeChain(func(authz Authorizer) EnforcementDecision { return c.executeChain(func(authz Authorizer) EnforcementDecision {

View File

@ -89,9 +89,6 @@ func (authz testAuthorizer) ServiceReadAll(*AuthorizerContext) EnforcementDecisi
func (authz testAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision { func (authz testAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision {
return EnforcementDecision(authz) return EnforcementDecision(authz)
} }
func (authz testAuthorizer) ServiceWriteAny(*AuthorizerContext) EnforcementDecision {
return EnforcementDecision(authz)
}
func (authz testAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision { func (authz testAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision {
return EnforcementDecision(authz) return EnforcementDecision(authz)
} }

View File

@ -325,13 +325,13 @@ func (p *policyAuthorizer) loadRules(policy *PolicyRules) error {
return nil return nil
} }
func newPolicyAuthorizer(policies []*Policy, ent *Config) (Authorizer, error) { func newPolicyAuthorizer(policies []*Policy, ent *Config) (*policyAuthorizer, error) {
policy := MergePolicies(policies) policy := MergePolicies(policies)
return newPolicyAuthorizerFromRules(&policy.PolicyRules, ent) return newPolicyAuthorizerFromRules(&policy.PolicyRules, ent)
} }
func newPolicyAuthorizerFromRules(rules *PolicyRules, ent *Config) (Authorizer, error) { func newPolicyAuthorizerFromRules(rules *PolicyRules, ent *Config) (*policyAuthorizer, error) {
p := &policyAuthorizer{ p := &policyAuthorizer{
agentRules: radix.New(), agentRules: radix.New(),
intentionRules: radix.New(), intentionRules: radix.New(),
@ -767,7 +767,7 @@ func (p *policyAuthorizer) ServiceWrite(name string, _ *AuthorizerContext) Enfor
return Default return Default
} }
func (p *policyAuthorizer) ServiceWriteAny(_ *AuthorizerContext) EnforcementDecision { func (p *policyAuthorizer) serviceWriteAny(_ *AuthorizerContext) EnforcementDecision {
return p.anyAllowed(p.serviceRules, AccessWrite) return p.anyAllowed(p.serviceRules, AccessWrite)
} }

View File

@ -219,13 +219,6 @@ func (s *staticAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementD
return Deny return Deny
} }
func (s *staticAuthorizer) ServiceWriteAny(*AuthorizerContext) EnforcementDecision {
if s.defaultAllow {
return Allow
}
return Deny
}
func (s *staticAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision { func (s *staticAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision {
if s.defaultAllow { if s.defaultAllow {
return Allow return Allow

View File

@ -1906,6 +1906,6 @@ func filterACL(r *ACLResolver, token string, subj interface{}) error {
type partitionInfoNoop struct{} type partitionInfoNoop struct{}
func (p *partitionInfoNoop) DownstreamPartitions(service string, anyService bool, ctx *acl.AuthorizerContext) []string { func (p *partitionInfoNoop) ExportsForPartition(partition string) acl.PartitionExports {
return []string{} return acl.PartitionExports{}
} }

View File

@ -15,11 +15,11 @@ func (s *Server) replicationEnterpriseMeta() *structs.EnterpriseMeta {
return structs.ReplicationEnterpriseMeta() return structs.ReplicationEnterpriseMeta()
} }
func serverPartitionInfo(s *Server) acl.PartitionExportInfo { func serverPartitionInfo(s *Server) acl.ExportFetcher {
return &partitionInfoNoop{} return &partitionInfoNoop{}
} }
func newACLConfig(_ acl.PartitionExportInfo, _ hclog.Logger) *acl.Config { func newACLConfig(_ acl.ExportFetcher, _ hclog.Logger) *acl.Config {
return &acl.Config{ return &acl.Config{
WildcardName: structs.WildcardSpecifier, WildcardName: structs.WildcardSpecifier,
} }

View File

@ -39,6 +39,23 @@ type ServiceConsumer struct {
Partition string Partition string
} }
func (e *PartitionExportsConfigEntry) ToMap() map[string]map[string][]string {
resp := make(map[string]map[string][]string)
for _, svc := range e.Services {
if _, ok := resp[svc.Namespace]; !ok {
resp[svc.Namespace] = make(map[string][]string)
}
if _, ok := resp[svc.Namespace][svc.Name]; !ok {
consumers := make([]string, 0, len(svc.Consumers))
for _, c := range svc.Consumers {
consumers = append(consumers, c.Partition)
}
resp[svc.Namespace][svc.Name] = consumers
}
}
return resp
}
func (e *PartitionExportsConfigEntry) Clone() *PartitionExportsConfigEntry { func (e *PartitionExportsConfigEntry) Clone() *PartitionExportsConfigEntry {
e2 := *e e2 := *e
e2.Services = make([]ExportedService, len(e.Services)) e2.Services = make([]ExportedService, len(e.Services))