The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/pkg/services/ngalert/api/authorization.go

165 lines
10 KiB

package api
import (
"fmt"
"net/http"
"github.com/grafana/grafana/pkg/middleware"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
acmiddleware "github.com/grafana/grafana/pkg/services/accesscontrol/middleware"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/web"
)
//nolint:gocyclo
func (api *API) authorize(method, path string) web.Handler {
authorize := acmiddleware.Middleware(api.AccessControl)
var eval ac.Evaluator = nil
switch method + path {
// Alert Rules
// Grafana Paths
case http.MethodDelete + "/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}":
eval = ac.EvalPermission(ac.ActionAlertingRuleDelete, dashboards.ScopeFoldersProvider.GetResourceScopeName(ac.Parameter(":Namespace")))
case http.MethodDelete + "/api/ruler/grafana/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingRuleDelete, dashboards.ScopeFoldersProvider.GetResourceScopeName(ac.Parameter(":Namespace")))
case http.MethodGet + "/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}":
eval = ac.EvalPermission(ac.ActionAlertingRuleRead, dashboards.ScopeFoldersProvider.GetResourceScopeName(ac.Parameter(":Namespace")))
case http.MethodGet + "/api/ruler/grafana/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingRuleRead, dashboards.ScopeFoldersProvider.GetResourceScopeName(ac.Parameter(":Namespace")))
case http.MethodGet + "/api/ruler/grafana/api/v1/rules":
eval = ac.EvalPermission(ac.ActionAlertingRuleRead)
case http.MethodPost + "/api/ruler/grafana/api/v1/rules/{Namespace}":
scope := dashboards.ScopeFoldersProvider.GetResourceScopeName(ac.Parameter(":Namespace"))
// more granular permissions are enforced by the handler via "authorizeRuleChanges"
eval = ac.EvalAny(
ac.EvalPermission(ac.ActionAlertingRuleUpdate, scope),
ac.EvalPermission(ac.ActionAlertingRuleCreate, scope),
ac.EvalPermission(ac.ActionAlertingRuleDelete, scope),
)
// Grafana, Prometheus-compatible Paths
case http.MethodGet + "/api/prometheus/grafana/api/v1/rules":
eval = ac.EvalPermission(ac.ActionAlertingRuleRead)
// Grafana Rules Testing Paths
case http.MethodPost + "/api/v1/rule/test/grafana":
// additional authorization is done in the request handler
eval = ac.EvalPermission(ac.ActionAlertingRuleRead)
case http.MethodPost + "/api/v1/eval":
// additional authorization is done in the request handler
eval = ac.EvalPermission(ac.ActionAlertingRuleRead)
// Lotex Paths
case http.MethodDelete + "/api/ruler/{Recipient}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalWrite, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodDelete + "/api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalWrite, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodGet + "/api/ruler/{Recipient}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodGet + "/api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodGet + "/api/ruler/{Recipient}/api/v1/rules":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodPost + "/api/ruler/{Recipient}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalWrite, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
// Lotex Prometheus-compatible Paths
case http.MethodGet + "/api/prometheus/{Recipient}/api/v1/rules":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
// Lotex Rules testing
case http.MethodPost + "/api/v1/rule/test/{Recipient}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
// Alert Instances and Silences
// Silences. Grafana Paths
case http.MethodDelete + "/api/alertmanager/grafana/api/v2/silence/{SilenceId}":
eval = ac.EvalPermission(ac.ActionAlertingInstanceUpdate) // delete endpoint actually expires silence
case http.MethodGet + "/api/alertmanager/grafana/api/v2/silence/{SilenceId}":
eval = ac.EvalPermission(ac.ActionAlertingInstanceRead)
case http.MethodGet + "/api/alertmanager/grafana/api/v2/silences":
eval = ac.EvalPermission(ac.ActionAlertingInstanceRead)
case http.MethodPost + "/api/alertmanager/grafana/api/v2/silences":
// additional authorization is done in the request handler
eval = ac.EvalAny(ac.EvalPermission(ac.ActionAlertingInstanceCreate), ac.EvalPermission(ac.ActionAlertingInstanceUpdate))
// Alert Instances. Grafana Paths
case http.MethodGet + "/api/alertmanager/grafana/api/v2/alerts/groups":
eval = ac.EvalPermission(ac.ActionAlertingInstanceRead)
case http.MethodGet + "/api/alertmanager/grafana/api/v2/alerts":
eval = ac.EvalPermission(ac.ActionAlertingInstanceRead)
case http.MethodPost + "/api/alertmanager/grafana/api/v2/alerts":
eval = ac.EvalAny(ac.EvalPermission(ac.ActionAlertingInstanceCreate), ac.EvalPermission(ac.ActionAlertingInstanceUpdate))
// Grafana Prometheus-compatible Paths
case http.MethodGet + "/api/prometheus/grafana/api/v1/alerts":
eval = ac.EvalPermission(ac.ActionAlertingInstanceRead)
// Silences. External AM.
case http.MethodDelete + "/api/alertmanager/{Recipient}/api/v2/silence/{SilenceId}":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalWrite, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodPost + "/api/alertmanager/{Recipient}/api/v2/silences":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalWrite, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodGet + "/api/alertmanager/{Recipient}/api/v2/silence/{SilenceId}":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodGet + "/api/alertmanager/{Recipient}/api/v2/silences":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
// Alert instances. External AM.
case http.MethodGet + "/api/alertmanager/{Recipient}/api/v2/alerts/groups":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodGet + "/api/alertmanager/{Recipient}/api/v2/alerts":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodPost + "/api/alertmanager/{Recipient}/api/v2/alerts":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalWrite, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
// Prometheus-compatible Paths
case http.MethodGet + "/api/prometheus/{Recipient}/api/v1/alerts":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
// Notification Policies, Contact Points and Templates
// Grafana Paths
case http.MethodDelete + "/api/alertmanager/grafana/config/api/v1/alerts": // reset alertmanager config to the default
eval = ac.EvalPermission(ac.ActionAlertingNotificationsDelete)
case http.MethodGet + "/api/alertmanager/grafana/config/api/v1/alerts":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsRead)
case http.MethodGet + "/api/alertmanager/grafana/api/v2/status":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsRead)
case http.MethodPost + "/api/alertmanager/grafana/config/api/v1/alerts":
// additional authorization is done in the request handler
eval = ac.EvalAny(ac.EvalPermission(ac.ActionAlertingNotificationsUpdate), ac.EvalPermission(ac.ActionAlertingNotificationsCreate), ac.EvalPermission(ac.ActionAlertingNotificationsDelete))
case http.MethodPost + "/api/alertmanager/grafana/config/api/v1/receivers/test":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsRead)
// External Alertmanager Paths
case http.MethodDelete + "/api/alertmanager/{Recipient}/config/api/v1/alerts":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsDelete, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodGet + "/api/alertmanager/{Recipient}/api/v2/status":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodGet + "/api/alertmanager/{Recipient}/config/api/v1/alerts":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodPost + "/api/alertmanager/{Recipient}/config/api/v1/alerts":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsExternalWrite, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
case http.MethodPost + "/api/alertmanager/{Recipient}/config/api/v1/receivers/test":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead, datasources.ScopeDatasourcesProvider.GetResourceScope(ac.Parameter(":Recipient")))
// Raw Alertmanager Config Paths
case http.MethodDelete + "/api/v1/ngalert/admin_config",
http.MethodGet + "/api/v1/ngalert/admin_config",
http.MethodPost + "/api/v1/ngalert/admin_config",
http.MethodGet + "/api/v1/ngalert/alertmanagers":
return middleware.ReqOrgAdmin
}
if eval != nil {
return authorize(middleware.ReqSignedIn, eval)
}
panic(fmt.Sprintf("no authorization handler for method [%s] of endpoint [%s]", method, path))
}