Files
grafana/apps/example/pkg/app/authorizer.go
Austin Pond bf65c43783 Apps: Add Example App to ./apps (#112069)
* [API Server] Add Example App for reference use.

* Remove Printlns.

* Upgrade app-sdk to v0.46.0, update apps to handle breaking changes.

* Only start the reconciler for the example app if the v1alpha1 API version is enabled.

* Some comment doc updates.

* Run make update-workspace

* Set codeowner for /apps/example

* Run make gofmt and make update-workspace

* Run prettier on apps/example/README.md

* Add COPY apps/example to Dockerfile

* Add an authorizer to the example app.

* Fix import ordering.

* Update apps/example/kinds/manifest.cue

Co-authored-by: Owen Diehl <ow.diehl@gmail.com>

* Run make update-workspace

* Re-run make gen-go for enterprise import updates

* Run make update-workspace

---------

Co-authored-by: Owen Diehl <ow.diehl@gmail.com>
2025-10-27 12:01:10 -04:00

56 lines
1.7 KiB
Go

package app
import (
"context"
"fmt"
"regexp"
"k8s.io/apiserver/pkg/authorization/authorizer"
"github.com/grafana/grafana/apps/example/pkg/apis/example/v1alpha1"
"github.com/grafana/grafana/pkg/apimachinery/identity"
)
var namespacedSomethingRouteMatcher = regexp.MustCompile(fmt.Sprintf(`^/apis/%s/%s/namespaces/([^\/]+)/something$`, v1alpha1.APIGroup, v1alpha1.APIVersion))
// GetAuthorizer returns an authorizer for all kinds managed by the example app.
// It must be added to the installer in pkg/registry/apps/example/register.go to be used
func GetAuthorizer() authorizer.Authorizer {
return authorizer.AuthorizerFunc(
func(ctx context.Context, attr authorizer.Attributes) (authorizer.Decision, string, error) {
if !attr.IsResourceRequest() {
return authorizer.DecisionNoOpinion, "", nil
}
// require a user
u, err := identity.GetRequester(ctx)
if err != nil {
return authorizer.DecisionDeny, "valid user is required", err
}
// check if is admin
if u.GetIsGrafanaAdmin() {
return authorizer.DecisionAllow, "", nil
}
// Only allow admins to call the custom subresource
if attr.GetSubresource() == "custom" {
return authorizer.DecisionDeny, "forbidden", nil
}
// Only allow admins to call the namespaced and cluster routes
// There's no easy way to check that from attrs like with GetSubresource(),
// so we look at the full path and check
if namespacedSomethingRouteMatcher.MatchString(attr.GetPath()) {
return authorizer.DecisionDeny, "forbidden", nil
}
if attr.GetPath() == fmt.Sprintf("/apis/%s/%s/other", v1alpha1.APIGroup, v1alpha1.APIVersion) {
return authorizer.DecisionDeny, "forbidden", nil
}
// Otherwise, allow
return authorizer.DecisionAllow, "", nil
},
)
}