mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Add access control to receiver status API (#94287)
This commit is contained in:
@@ -110,6 +110,7 @@ func (api *API) RegisterAPIEndpoints(m *metrics.API) {
|
|||||||
api.RuleStore,
|
api.RuleStore,
|
||||||
ruleAuthzService,
|
ruleAuthzService,
|
||||||
),
|
),
|
||||||
|
receiverAuthz: accesscontrol.NewReceiverAccess[ReceiverStatus](api.AccessControl, false),
|
||||||
},
|
},
|
||||||
), m)
|
), m)
|
||||||
// Register endpoints for proxying to Prometheus-compatible backends.
|
// Register endpoints for proxying to Prometheus-compatible backends.
|
||||||
|
|||||||
@@ -12,12 +12,14 @@ import (
|
|||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingNotify "github.com/grafana/alerting/notify"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/response"
|
"github.com/grafana/grafana/pkg/api/response"
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/notifier/legacy_storage"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
@@ -28,6 +30,10 @@ const (
|
|||||||
maxTestReceiversTimeout = 30 * time.Second
|
maxTestReceiversTimeout = 30 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type receiversAuthz interface {
|
||||||
|
FilterRead(ctx context.Context, user identity.Requester, receivers ...ReceiverStatus) ([]ReceiverStatus, error)
|
||||||
|
}
|
||||||
|
|
||||||
type AlertmanagerSrv struct {
|
type AlertmanagerSrv struct {
|
||||||
log log.Logger
|
log log.Logger
|
||||||
ac accesscontrol.AccessControl
|
ac accesscontrol.AccessControl
|
||||||
@@ -35,6 +41,7 @@ type AlertmanagerSrv struct {
|
|||||||
crypto notifier.Crypto
|
crypto notifier.Crypto
|
||||||
silenceSvc SilenceService
|
silenceSvc SilenceService
|
||||||
featureManager featuremgmt.FeatureToggles
|
featureManager featuremgmt.FeatureToggles
|
||||||
|
receiverAuthz receiversAuthz
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnknownReceiverError struct {
|
type UnknownReceiverError struct {
|
||||||
@@ -237,7 +244,15 @@ func (srv AlertmanagerSrv) RouteGetReceivers(c *contextmodel.ReqContext) respons
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrResp(http.StatusInternalServerError, err, "failed to retrieve receivers")
|
return ErrResp(http.StatusInternalServerError, err, "failed to retrieve receivers")
|
||||||
}
|
}
|
||||||
return response.JSON(http.StatusOK, rcvs)
|
statuses := make([]ReceiverStatus, 0, len(rcvs))
|
||||||
|
for _, rcv := range rcvs { // TODO this is temporary so we can use authz filter logic.
|
||||||
|
statuses = append(statuses, ReceiverStatus(rcv))
|
||||||
|
}
|
||||||
|
statuses, err = srv.receiverAuthz.FilterRead(c.Req.Context(), c.SignedInUser, statuses...)
|
||||||
|
if err != nil {
|
||||||
|
response.ErrOrFallback(http.StatusInternalServerError, "failed to apply permissions to the receivers", err)
|
||||||
|
}
|
||||||
|
return response.JSON(http.StatusOK, statuses)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv AlertmanagerSrv) RoutePostTestReceivers(c *contextmodel.ReqContext, body apimodels.TestReceiversConfigBodyParams) response.Response {
|
func (srv AlertmanagerSrv) RoutePostTestReceivers(c *contextmodel.ReqContext, body apimodels.TestReceiversConfigBodyParams) response.Response {
|
||||||
@@ -368,3 +383,9 @@ func (srv AlertmanagerSrv) AlertmanagerFor(orgID int64) (notifier.Alertmanager,
|
|||||||
srv.log.Error("Unable to obtain the org's Alertmanager", "error", err)
|
srv.log.Error("Unable to obtain the org's Alertmanager", "error", err)
|
||||||
return nil, response.Error(http.StatusInternalServerError, "unable to obtain org's Alertmanager", err)
|
return nil, response.Error(http.StatusInternalServerError, "unable to obtain org's Alertmanager", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReceiverStatus apimodels.Receiver
|
||||||
|
|
||||||
|
func (rs ReceiverStatus) GetUID() string {
|
||||||
|
return legacy_storage.NameToUid(rs.Name)
|
||||||
|
}
|
||||||
|
|||||||
@@ -210,7 +210,11 @@ func (api *API) authorize(method, path string) web.Handler {
|
|||||||
case http.MethodPost + "/api/alertmanager/grafana/config/history/{id}/_activate":
|
case http.MethodPost + "/api/alertmanager/grafana/config/history/{id}/_activate":
|
||||||
eval = ac.EvalAny(ac.EvalPermission(ac.ActionAlertingNotificationsWrite))
|
eval = ac.EvalAny(ac.EvalPermission(ac.ActionAlertingNotificationsWrite))
|
||||||
case http.MethodGet + "/api/alertmanager/grafana/config/api/v1/receivers":
|
case http.MethodGet + "/api/alertmanager/grafana/config/api/v1/receivers":
|
||||||
eval = ac.EvalPermission(ac.ActionAlertingNotificationsRead)
|
eval = ac.EvalAny(
|
||||||
|
ac.EvalPermission(ac.ActionAlertingNotificationsRead),
|
||||||
|
ac.EvalPermission(ac.ActionAlertingReceiversRead),
|
||||||
|
ac.EvalPermission(ac.ActionAlertingReceiversReadSecrets),
|
||||||
|
)
|
||||||
case http.MethodPost + "/api/alertmanager/grafana/config/api/v1/receivers/test":
|
case http.MethodPost + "/api/alertmanager/grafana/config/api/v1/receivers/test":
|
||||||
eval = ac.EvalAny(
|
eval = ac.EvalAny(
|
||||||
ac.EvalPermission(ac.ActionAlertingNotificationsWrite),
|
ac.EvalPermission(ac.ActionAlertingNotificationsWrite),
|
||||||
|
|||||||
Reference in New Issue
Block a user