Merge pull request #10738 from hashicorp/dnephin/remove-authorizer-nil-checks-2

acl: remove the last of the authz == nil checks
This commit is contained in:
Daniel Nephin 2021-08-04 17:41:40 -04:00 committed by GitHub
commit 3dc113ada6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 132 additions and 162 deletions

View File

@ -391,7 +391,7 @@ func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request)
} }
var authzContext acl.AuthorizerContext var authzContext acl.AuthorizerContext
svc.FillAuthzContext(&authzContext) svc.FillAuthzContext(&authzContext)
if authz != nil && authz.ServiceRead(svc.Service, &authzContext) != acl.Allow { if authz.ServiceRead(svc.Service, &authzContext) != acl.Allow {
return "", nil, acl.ErrPermissionDenied return "", nil, acl.ErrPermissionDenied
} }
@ -837,7 +837,7 @@ func (s *HTTPHandlers) AgentHealthServiceByID(resp http.ResponseWriter, req *htt
dc := s.agent.config.Datacenter dc := s.agent.config.Datacenter
if service := s.agent.State.Service(sid); service != nil { if service := s.agent.State.Service(sid); service != nil {
if authz != nil && authz.ServiceRead(service.Service, &authzContext) != acl.Allow { if authz.ServiceRead(service.Service, &authzContext) != acl.Allow {
return nil, acl.ErrPermissionDenied return nil, acl.ErrPermissionDenied
} }
code, status, healthChecks := agentHealthService(sid, s) code, status, healthChecks := agentHealthService(sid, s)
@ -886,7 +886,7 @@ func (s *HTTPHandlers) AgentHealthServiceByName(resp http.ResponseWriter, req *h
return nil, err return nil, err
} }
if authz != nil && authz.ServiceRead(serviceName, &authzContext) != acl.Allow { if authz.ServiceRead(serviceName, &authzContext) != acl.Allow {
return nil, acl.ErrPermissionDenied return nil, acl.ErrPermissionDenied
} }

View File

@ -65,7 +65,7 @@ func (a *Agent) ConnectAuthorize(token string,
return returnErr(err) return returnErr(err)
} }
if authz != nil && authz.ServiceWrite(req.Target, &authzContext) != acl.Allow { if authz.ServiceWrite(req.Target, &authzContext) != acl.Allow {
return returnErr(acl.ErrPermissionDenied) return returnErr(acl.ErrPermissionDenied)
} }

View File

@ -118,14 +118,14 @@ func servicePreApply(service *structs.NodeService, authz acl.Authorizer) error {
// later if version 0.8 is enabled, so we can eventually just // later if version 0.8 is enabled, so we can eventually just
// delete this and do all the ACL checks down there. // delete this and do all the ACL checks down there.
if service.Service != structs.ConsulServiceName { if service.Service != structs.ConsulServiceName {
if authz != nil && authz.ServiceWrite(service.Service, &authzContext) != acl.Allow { if authz.ServiceWrite(service.Service, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }
} }
// Proxies must have write permission on their destination // Proxies must have write permission on their destination
if service.Kind == structs.ServiceKindConnectProxy { if service.Kind == structs.ServiceKindConnectProxy {
if authz != nil && authz.ServiceWrite(service.Proxy.DestinationServiceName, &authzContext) != acl.Allow { if authz.ServiceWrite(service.Proxy.DestinationServiceName, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }
} }
@ -200,15 +200,12 @@ func (c *Catalog) Register(args *structs.RegisterRequest, reply *struct{}) error
} }
// Check the complete register request against the given ACL policy. // Check the complete register request against the given ACL policy.
if authz != nil { _, ns, err := state.NodeServices(nil, args.Node, entMeta)
state := c.srv.fsm.State() if err != nil {
_, ns, err := state.NodeServices(nil, args.Node, entMeta) return fmt.Errorf("Node lookup failed: %v", err)
if err != nil { }
return fmt.Errorf("Node lookup failed: %v", err) if err := vetRegisterWithACL(authz, args, ns); err != nil {
} return err
if err := vetRegisterWithACL(authz, args, ns); err != nil {
return err
}
} }
_, err = c.srv.raftApply(structs.RegisterRequestType, args) _, err = c.srv.raftApply(structs.RegisterRequestType, args)
@ -238,29 +235,26 @@ func (c *Catalog) Deregister(args *structs.DeregisterRequest, reply *struct{}) e
} }
// Check the complete deregister request against the given ACL policy. // Check the complete deregister request against the given ACL policy.
if authz != nil { state := c.srv.fsm.State()
state := c.srv.fsm.State()
var ns *structs.NodeService var ns *structs.NodeService
if args.ServiceID != "" { if args.ServiceID != "" {
_, ns, err = state.NodeService(args.Node, args.ServiceID, &args.EnterpriseMeta) _, ns, err = state.NodeService(args.Node, args.ServiceID, &args.EnterpriseMeta)
if err != nil { if err != nil {
return fmt.Errorf("Service lookup failed: %v", err) return fmt.Errorf("Service lookup failed: %v", err)
}
} }
}
var nc *structs.HealthCheck var nc *structs.HealthCheck
if args.CheckID != "" { if args.CheckID != "" {
_, nc, err = state.NodeCheck(args.Node, args.CheckID, &args.EnterpriseMeta) _, nc, err = state.NodeCheck(args.Node, args.CheckID, &args.EnterpriseMeta)
if err != nil { if err != nil {
return fmt.Errorf("Check lookup failed: %v", err) return fmt.Errorf("Check lookup failed: %v", err)
}
}
if err := vetDeregisterWithACL(authz, args, ns, nc); err != nil {
return err
} }
}
if err := vetDeregisterWithACL(authz, args, ns, nc); err != nil {
return err
} }
_, err = c.srv.raftApply(structs.DeregisterRequestType, args) _, err = c.srv.raftApply(structs.DeregisterRequestType, args)
@ -456,7 +450,7 @@ func (c *Catalog) ServiceNodes(args *structs.ServiceSpecificRequest, reply *stru
// If we're doing a connect query, we need read access to the service // If we're doing a connect query, we need read access to the service
// we're trying to find proxies for, so check that. // we're trying to find proxies for, so check that.
if args.Connect { if args.Connect {
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow { if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
// Just return nil, which will return an empty response (tested) // Just return nil, which will return an empty response (tested)
return nil return nil
} }
@ -659,7 +653,7 @@ func (c *Catalog) GatewayServices(args *structs.ServiceSpecificRequest, reply *s
return err return err
} }
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow { if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }

View File

@ -81,7 +81,7 @@ func (c *ConfigEntry) Apply(args *structs.ConfigEntryRequest, reply *bool) error
return err return err
} }
if authz != nil && !args.Entry.CanWrite(authz) { if !args.Entry.CanWrite(authz) {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }
@ -122,7 +122,7 @@ func (c *ConfigEntry) Get(args *structs.ConfigEntryQuery, reply *structs.ConfigE
} }
lookupEntry.GetEnterpriseMeta().Merge(&args.EnterpriseMeta) lookupEntry.GetEnterpriseMeta().Merge(&args.EnterpriseMeta)
if authz != nil && !lookupEntry.CanRead(authz) { if !lookupEntry.CanRead(authz) {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }
@ -180,7 +180,7 @@ func (c *ConfigEntry) List(args *structs.ConfigEntryQuery, reply *structs.Indexe
// Filter the entries returned by ACL permissions. // Filter the entries returned by ACL permissions.
filteredEntries := make([]structs.ConfigEntry, 0, len(entries)) filteredEntries := make([]structs.ConfigEntry, 0, len(entries))
for _, entry := range entries { for _, entry := range entries {
if authz != nil && !entry.CanRead(authz) { if !entry.CanRead(authz) {
continue continue
} }
filteredEntries = append(filteredEntries, entry) filteredEntries = append(filteredEntries, entry)
@ -240,7 +240,7 @@ func (c *ConfigEntry) ListAll(args *structs.ConfigEntryListAllRequest, reply *st
// Filter the entries returned by ACL permissions or by the provided kinds. // Filter the entries returned by ACL permissions or by the provided kinds.
filteredEntries := make([]structs.ConfigEntry, 0, len(entries)) filteredEntries := make([]structs.ConfigEntry, 0, len(entries))
for _, entry := range entries { for _, entry := range entries {
if authz != nil && !entry.CanRead(authz) { if !entry.CanRead(authz) {
continue continue
} }
// Doing this filter outside of memdb isn't terribly // Doing this filter outside of memdb isn't terribly
@ -290,7 +290,7 @@ func (c *ConfigEntry) Delete(args *structs.ConfigEntryRequest, reply *struct{})
return err return err
} }
if authz != nil && !args.Entry.CanWrite(authz) { if !args.Entry.CanWrite(authz) {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }
@ -315,7 +315,7 @@ func (c *ConfigEntry) ResolveServiceConfig(args *structs.ServiceConfigRequest, r
if err != nil { if err != nil {
return err return err
} }
if authz != nil && authz.ServiceRead(args.Name, &authzContext) != acl.Allow { if authz.ServiceRead(args.Name, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }

View File

@ -142,12 +142,10 @@ func (c *Coordinate) Update(args *structs.CoordinateUpdateRequest, reply *struct
if err != nil { if err != nil {
return err return err
} }
if authz != nil { var authzContext acl.AuthorizerContext
var authzContext acl.AuthorizerContext structs.DefaultEnterpriseMetaInDefaultPartition().FillAuthzContext(&authzContext)
structs.DefaultEnterpriseMetaInDefaultPartition().FillAuthzContext(&authzContext) if authz.NodeWrite(args.Node, &authzContext) != acl.Allow {
if authz.NodeWrite(args.Node, &authzContext) != acl.Allow { return acl.ErrPermissionDenied
return acl.ErrPermissionDenied
}
} }
// Add the coordinate to the map of pending updates. // Add the coordinate to the map of pending updates.
@ -226,12 +224,10 @@ func (c *Coordinate) Node(args *structs.NodeSpecificRequest, reply *structs.Inde
if err != nil { if err != nil {
return err return err
} }
if authz != nil { var authzContext acl.AuthorizerContext
var authzContext acl.AuthorizerContext structs.WildcardEnterpriseMetaInDefaultPartition().FillAuthzContext(&authzContext)
structs.WildcardEnterpriseMetaInDefaultPartition().FillAuthzContext(&authzContext) if authz.NodeRead(args.Node, &authzContext) != acl.Allow {
if authz.NodeRead(args.Node, &authzContext) != acl.Allow { return acl.ErrPermissionDenied
return acl.ErrPermissionDenied
}
} }
return c.srv.blockingQuery(&args.QueryOptions, return c.srv.blockingQuery(&args.QueryOptions,

View File

@ -207,7 +207,7 @@ func (h *Health) ServiceNodes(args *structs.ServiceSpecificRequest, reply *struc
// If we're doing a connect or ingress query, we need read access to the service // If we're doing a connect or ingress query, we need read access to the service
// we're trying to find proxies for, so check that. // we're trying to find proxies for, so check that.
if args.Connect || args.Ingress { if args.Connect || args.Ingress {
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow { if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
// Just return nil, which will return an empty response (tested) // Just return nil, which will return an empty response (tested)
return nil return nil
} }

View File

@ -593,24 +593,22 @@ func (s *Intention) Match(args *structs.IntentionQueryRequest, reply *structs.In
} }
} }
if authz != nil { var authzContext acl.AuthorizerContext
var authzContext acl.AuthorizerContext // Go through each entry to ensure we have intention:read for the resource.
// Go through each entry to ensure we have intention:read for the resource.
// TODO - should we do this instead of filtering the result set? This will only allow // TODO - should we do this instead of filtering the result set? This will only allow
// queries for which the token has intention:read permissions on the requested side // queries for which the token has intention:read permissions on the requested side
// of the service. Should it instead return all matches that it would be able to list. // of the service. Should it instead return all matches that it would be able to list.
// if so we should remove this and call filterACL instead. Based on how this is used // if so we should remove this and call filterACL instead. Based on how this is used
// its probably fine. If you have intention read on the source just do a source type // its probably fine. If you have intention read on the source just do a source type
// matching, if you have it on the dest then perform a dest type match. // matching, if you have it on the dest then perform a dest type match.
for _, entry := range args.Match.Entries { for _, entry := range args.Match.Entries {
entry.FillAuthzContext(&authzContext) entry.FillAuthzContext(&authzContext)
if prefix := entry.Name; prefix != "" && authz.IntentionRead(prefix, &authzContext) != acl.Allow { if prefix := entry.Name; prefix != "" && authz.IntentionRead(prefix, &authzContext) != acl.Allow {
accessorID := s.aclAccessorID(args.Token) accessorID := s.aclAccessorID(args.Token)
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it // todo(kit) Migrate intention access denial logging over to audit logging when we implement it
s.logger.Warn("Operation on intention prefix denied due to ACLs", "prefix", prefix, "accessorID", accessorID) s.logger.Warn("Operation on intention prefix denied due to ACLs", "prefix", prefix, "accessorID", accessorID)
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
}
} }
} }
@ -690,7 +688,7 @@ func (s *Intention) Check(args *structs.IntentionQueryRequest, reply *structs.In
if prefix, ok := query.GetACLPrefix(); ok { if prefix, ok := query.GetACLPrefix(); ok {
var authzContext acl.AuthorizerContext var authzContext acl.AuthorizerContext
query.FillAuthzContext(&authzContext) query.FillAuthzContext(&authzContext)
if authz != nil && authz.ServiceRead(prefix, &authzContext) != acl.Allow { if authz.ServiceRead(prefix, &authzContext) != acl.Allow {
accessorID := s.aclAccessorID(args.Token) accessorID := s.aclAccessorID(args.Token)
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it // todo(kit) Migrate intention access denial logging over to audit logging when we implement it
s.logger.Warn("test on intention denied due to ACLs", "prefix", prefix, "accessorID", accessorID) s.logger.Warn("test on intention denied due to ACLs", "prefix", prefix, "accessorID", accessorID)
@ -710,10 +708,7 @@ func (s *Intention) Check(args *structs.IntentionQueryRequest, reply *structs.In
// NOTE(mitchellh): This is the same behavior as the agent authorize // NOTE(mitchellh): This is the same behavior as the agent authorize
// endpoint. If this behavior is incorrect, we should also change it there // endpoint. If this behavior is incorrect, we should also change it there
// which is much more important. // which is much more important.
defaultDecision := acl.Allow defaultDecision := authz.IntentionDefaultAllow(nil)
if authz != nil {
defaultDecision = authz.IntentionDefaultAllow(nil)
}
state := s.srv.fsm.State() state := s.srv.fsm.State()

View File

@ -161,7 +161,7 @@ func (m *Internal) ServiceTopology(args *structs.ServiceSpecificRequest, reply *
if err := m.srv.validateEnterpriseRequest(&args.EnterpriseMeta, false); err != nil { if err := m.srv.validateEnterpriseRequest(&args.EnterpriseMeta, false); err != nil {
return err return err
} }
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow { if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }
@ -169,10 +169,7 @@ func (m *Internal) ServiceTopology(args *structs.ServiceSpecificRequest, reply *
&args.QueryOptions, &args.QueryOptions,
&reply.QueryMeta, &reply.QueryMeta,
func(ws memdb.WatchSet, state *state.Store) error { func(ws memdb.WatchSet, state *state.Store) error {
defaultAllow := acl.Allow defaultAllow := authz.IntentionDefaultAllow(nil)
if authz != nil {
defaultAllow = authz.IntentionDefaultAllow(nil)
}
index, topology, err := state.ServiceTopology(ws, args.Datacenter, args.ServiceName, args.ServiceKind, defaultAllow, &args.EnterpriseMeta) index, topology, err := state.ServiceTopology(ws, args.Datacenter, args.ServiceName, args.ServiceKind, defaultAllow, &args.EnterpriseMeta)
if err != nil { if err != nil {
@ -216,10 +213,7 @@ func (m *Internal) IntentionUpstreams(args *structs.ServiceSpecificRequest, repl
&args.QueryOptions, &args.QueryOptions,
&reply.QueryMeta, &reply.QueryMeta,
func(ws memdb.WatchSet, state *state.Store) error { func(ws memdb.WatchSet, state *state.Store) error {
defaultDecision := acl.Allow defaultDecision := authz.IntentionDefaultAllow(nil)
if authz != nil {
defaultDecision = authz.IntentionDefaultAllow(nil)
}
sn := structs.NewServiceName(args.ServiceName, &args.EnterpriseMeta) sn := structs.NewServiceName(args.ServiceName, &args.EnterpriseMeta)
index, services, err := state.IntentionTopology(ws, sn, false, defaultDecision) index, services, err := state.IntentionTopology(ws, sn, false, defaultDecision)
@ -254,7 +248,7 @@ func (m *Internal) GatewayServiceDump(args *structs.ServiceSpecificRequest, repl
} }
// We need read access to the gateway we're trying to find services for, so check that first. // We need read access to the gateway we're trying to find services for, so check that first.
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow { if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }
@ -338,7 +332,7 @@ func (m *Internal) GatewayIntentions(args *structs.IntentionQueryRequest, reply
} }
// We need read access to the gateway we're trying to find intentions for, so check that first. // We need read access to the gateway we're trying to find intentions for, so check that first.
if authz != nil && authz.ServiceRead(args.Match.Entries[0].Name, &authzContext) != acl.Allow { if authz.ServiceRead(args.Match.Entries[0].Name, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }

View File

@ -39,37 +39,35 @@ func kvsPreApply(logger hclog.Logger, srv *Server, authz acl.Authorizer, op api.
} }
// Apply the ACL policy if any. // Apply the ACL policy if any.
if authz != nil { switch op {
switch op { case api.KVDeleteTree:
case api.KVDeleteTree: var authzContext acl.AuthorizerContext
var authzContext acl.AuthorizerContext dirEnt.FillAuthzContext(&authzContext)
dirEnt.FillAuthzContext(&authzContext)
if authz.KeyWritePrefix(dirEnt.Key, &authzContext) != acl.Allow { if authz.KeyWritePrefix(dirEnt.Key, &authzContext) != acl.Allow {
return false, acl.ErrPermissionDenied return false, acl.ErrPermissionDenied
} }
case api.KVGet, api.KVGetTree: case api.KVGet, api.KVGetTree:
// Filtering for GETs is done on the output side. // Filtering for GETs is done on the output side.
case api.KVCheckSession, api.KVCheckIndex: case api.KVCheckSession, api.KVCheckIndex:
// These could reveal information based on the outcome // These could reveal information based on the outcome
// of the transaction, and they operate on individual // of the transaction, and they operate on individual
// keys so we check them here. // keys so we check them here.
var authzContext acl.AuthorizerContext var authzContext acl.AuthorizerContext
dirEnt.FillAuthzContext(&authzContext) dirEnt.FillAuthzContext(&authzContext)
if authz.KeyRead(dirEnt.Key, &authzContext) != acl.Allow { if authz.KeyRead(dirEnt.Key, &authzContext) != acl.Allow {
return false, acl.ErrPermissionDenied return false, acl.ErrPermissionDenied
} }
default: default:
var authzContext acl.AuthorizerContext var authzContext acl.AuthorizerContext
dirEnt.FillAuthzContext(&authzContext) dirEnt.FillAuthzContext(&authzContext)
if authz.KeyWrite(dirEnt.Key, &authzContext) != acl.Allow { if authz.KeyWrite(dirEnt.Key, &authzContext) != acl.Allow {
return false, acl.ErrPermissionDenied return false, acl.ErrPermissionDenied
}
} }
} }
@ -244,7 +242,7 @@ func (k *KVS) ListKeys(args *structs.KeyListRequest, reply *structs.IndexedKeyLi
return err return err
} }
if authz != nil && k.srv.config.ACLEnableKeyListPolicy && authz.KeyList(args.Prefix, &authzContext) != acl.Allow { if k.srv.config.ACLEnableKeyListPolicy && authz.KeyList(args.Prefix, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }
@ -265,9 +263,7 @@ func (k *KVS) ListKeys(args *structs.KeyListRequest, reply *structs.IndexedKeyLi
reply.Index = index reply.Index = index
} }
if authz != nil { entries = FilterDirEnt(authz, entries)
entries = FilterDirEnt(authz, entries)
}
// Collect the keys from the filtered entries // Collect the keys from the filtered entries
prefixLen := len(args.Prefix) prefixLen := len(args.Prefix)

View File

@ -72,29 +72,27 @@ func (s *Session) Apply(args *structs.SessionRequest, reply *string) error {
return err return err
} }
if authz != nil { switch args.Op {
switch args.Op { case structs.SessionDestroy:
case structs.SessionDestroy: state := s.srv.fsm.State()
state := s.srv.fsm.State() _, existing, err := state.SessionGet(nil, args.Session.ID, &args.Session.EnterpriseMeta)
_, existing, err := state.SessionGet(nil, args.Session.ID, &args.Session.EnterpriseMeta) if err != nil {
if err != nil { return fmt.Errorf("Session lookup failed: %v", err)
return fmt.Errorf("Session lookup failed: %v", err)
}
if existing == nil {
return nil
}
if authz.SessionWrite(existing.Node, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied
}
case structs.SessionCreate:
if authz.SessionWrite(args.Session.Node, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied
}
default:
return fmt.Errorf("Invalid session operation %q", args.Op)
} }
if existing == nil {
return nil
}
if authz.SessionWrite(existing.Node, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied
}
case structs.SessionCreate:
if authz.SessionWrite(args.Session.Node, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied
}
default:
return fmt.Errorf("Invalid session operation %q", args.Op)
} }
// Ensure that the specified behavior is allowed // Ensure that the specified behavior is allowed
@ -310,7 +308,7 @@ func (s *Session) Renew(args *structs.SessionSpecificRequest,
return nil return nil
} }
if authz != nil && authz.SessionWrite(session.Node, &authzContext) != acl.Allow { if authz.SessionWrite(session.Node, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }

View File

@ -81,9 +81,9 @@ func (t *Txn) preCheck(authorizer acl.Authorizer, ops structs.TxnOps) structs.Tx
} }
service := &op.Service.Service service := &op.Service.Service
// This is intentionally nil as we will authorize the request // acl.ManageAll is used here because the request will be authorized
// using vetServiceTxnOp next instead of doing it in servicePreApply // later using vetServiceTxnOp.
if err := servicePreApply(service, nil); err != nil { if err := servicePreApply(service, acl.ManageAll()); err != nil {
errors = append(errors, &structs.TxnError{ errors = append(errors, &structs.TxnError{
OpIndex: i, OpIndex: i,
What: err.Error(), What: err.Error(),

View File

@ -128,16 +128,14 @@ RUN_QUERY:
events := s.agent.UserEvents() events := s.agent.UserEvents()
// Filter the events using the ACL, if present // Filter the events using the ACL, if present
if authz != nil { for i := 0; i < len(events); i++ {
for i := 0; i < len(events); i++ { name := events[i].Name
name := events[i].Name if authz.EventRead(name, nil) == acl.Allow {
if authz.EventRead(name, nil) == acl.Allow { continue
continue
}
s.agent.logger.Debug("dropping event from result due to ACLs", "event", name)
events = append(events[:i], events[i+1:]...)
i--
} }
s.agent.logger.Debug("dropping event from result due to ACLs", "event", name)
events = append(events[:i], events[i+1:]...)
i--
} }
// Filter the events if requested // Filter the events if requested

View File

@ -9,12 +9,13 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/config" "github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/logging"
"github.com/hashicorp/go-hclog"
) )
// ServiceSummary is used to summarize a service // ServiceSummary is used to summarize a service
@ -607,17 +608,15 @@ func (s *HTTPHandlers) UIMetricsProxy(resp http.ResponseWriter, req *http.Reques
return nil, err return nil, err
} }
if authz != nil { // This endpoint requires wildcard read on all services and all nodes.
// This endpoint requires wildcard read on all services and all nodes. //
// // In enterprise it requires this _in all namespaces_ too.
// In enterprise it requires this _in all namespaces_ too. wildMeta := structs.WildcardEnterpriseMetaInDefaultPartition()
wildMeta := structs.WildcardEnterpriseMetaInDefaultPartition() var authzContext acl.AuthorizerContext
var authzContext acl.AuthorizerContext wildMeta.FillAuthzContext(&authzContext)
wildMeta.FillAuthzContext(&authzContext)
if authz.NodeReadAll(&authzContext) != acl.Allow || authz.ServiceReadAll(&authzContext) != acl.Allow { if authz.NodeReadAll(&authzContext) != acl.Allow || authz.ServiceReadAll(&authzContext) != acl.Allow {
return nil, acl.ErrPermissionDenied return nil, acl.ErrPermissionDenied
}
} }
log := s.agent.logger.Named(logging.UIMetricsProxy) log := s.agent.logger.Named(logging.UIMetricsProxy)