Alerting: Migrate notifications API to app-platform SDK application (#104424)
* introduce alerting notification app * move code as is and remove from old registry * update api server registration * update make file and remove unnecessary args, copy some useful make commands from dashboards * update codeowners * move constants inside module and remove dependency from grafana * add support for selectors to the app builder
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package receiver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
)
|
||||
|
||||
// AccessControlService provides access control for receivers.
|
||||
type AccessControlService interface {
|
||||
AuthorizeReadSome(ctx context.Context, user identity.Requester) error
|
||||
AuthorizeReadByUID(context.Context, identity.Requester, string) error
|
||||
AuthorizeCreate(context.Context, identity.Requester) error
|
||||
AuthorizeUpdateByUID(context.Context, identity.Requester, string) error
|
||||
AuthorizeDeleteByUID(context.Context, identity.Requester, string) error
|
||||
}
|
||||
|
||||
func Authorize(ctx context.Context, ac AccessControlService, attr authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
if attr.GetResource() != ResourceInfo.GroupResource().Resource {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return authorizer.DecisionDeny, "valid user is required", err
|
||||
}
|
||||
|
||||
uid := attr.GetName()
|
||||
|
||||
deny := func(err error) (authorizer.Decision, string, error) {
|
||||
var utilErr errutil.Error
|
||||
if errors.As(err, &utilErr) && utilErr.Reason.Status() == errutil.StatusForbidden {
|
||||
if errors.Is(err, accesscontrol.ErrAuthorizationBase) {
|
||||
return authorizer.DecisionDeny, fmt.Sprintf("required permissions: %s", utilErr.PublicPayload["permissions"]), nil
|
||||
}
|
||||
return authorizer.DecisionDeny, utilErr.PublicMessage, nil
|
||||
}
|
||||
|
||||
return authorizer.DecisionDeny, "", err
|
||||
}
|
||||
|
||||
switch attr.GetVerb() {
|
||||
case "get":
|
||||
if uid == "" {
|
||||
return authorizer.DecisionDeny, "", nil
|
||||
}
|
||||
if err := ac.AuthorizeReadByUID(ctx, user, uid); err != nil {
|
||||
return deny(err)
|
||||
}
|
||||
case "list":
|
||||
return authorizer.DecisionAllow, "", nil // Always allow listing, receivers are filtered downstream.
|
||||
case "create":
|
||||
if err := ac.AuthorizeCreate(ctx, user); err != nil {
|
||||
return deny(err)
|
||||
}
|
||||
case "patch":
|
||||
fallthrough
|
||||
case "update":
|
||||
if uid == "" {
|
||||
return deny(err)
|
||||
}
|
||||
if err := ac.AuthorizeUpdateByUID(ctx, user, uid); err != nil {
|
||||
return deny(err)
|
||||
}
|
||||
case "delete":
|
||||
if uid == "" {
|
||||
return deny(err)
|
||||
}
|
||||
if err := ac.AuthorizeDeleteByUID(ctx, user, uid); err != nil {
|
||||
return deny(err)
|
||||
}
|
||||
default:
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
Reference in New Issue
Block a user