Zanzana: Evaluate access with Check request (server-side) (#96213)

* Zanzana: Evaluate access with Check request (server-side)

* Pass parent folder for checking access

* Review suggestions

* remove fixme comment
This commit is contained in:
Alexander Zobnin
2024-11-11 16:39:21 +01:00
committed by GitHub
parent 27a0491f30
commit b1fb581ab1
4 changed files with 83 additions and 22 deletions
@@ -8,6 +8,8 @@ import (
"github.com/prometheus/client_golang/prometheus"
"go.opentelemetry.io/otel"
"github.com/grafana/authlib/claims"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/metrics"
@@ -116,9 +118,36 @@ func (a *AccessControl) evaluateZanzana(ctx context.Context, user identity.Reque
eval = evaluator
}
return eval.EvaluateCustom(func(action, scope string) (bool, error) {
// FIXME: Implement using new schema / apis
return false, nil
return eval.EvaluateCustom(func(action string, scopes ...string) (bool, error) {
// FIXME: handle action with no scopes
if len(scopes) == 0 {
return false, nil
}
resourceScope := scopes[0]
kind, _, identifier := accesscontrol.SplitScope(resourceScope)
// Parent folder always returned by scope resolver as a second value
var parentFolder string
if len(scopes) > 1 {
_, _, parentFolder = accesscontrol.SplitScope(scopes[1])
}
namespace := claims.OrgNamespaceFormatter(user.GetOrgID())
req, ok := zanzana.TranslateToCheckRequest(namespace, action, kind, parentFolder, identifier)
if !ok {
// unsupported translation
return false, errAccessNotImplemented
}
a.log.Debug("evaluating zanzana", "user", user.GetUID(), "namespace", req.Namespace, "verb", req.Verb, "resource", req.Resource, "name", req.Name)
res, err := a.zclient.Check(ctx, user, *req)
if err != nil {
return false, err
}
return res.Allowed, nil
})
}
+5 -11
View File
@@ -11,7 +11,7 @@ import (
var logger = log.New("accesscontrol.evaluator")
type CheckerFn func(action string, scope string) (bool, error)
type CheckerFn func(action string, scopes ...string) (bool, error)
type Evaluator interface {
// Evaluate permissions that are grouped by action
@@ -89,18 +89,12 @@ func (p permissionEvaluator) EvaluateCustom(fn CheckerFn) (bool, error) {
return fn(p.Action, "")
}
for _, target := range p.Scopes {
matches, err := fn(p.Action, target)
if err != nil {
return false, err
}
if matches {
return true, nil
}
matches, err := fn(p.Action, p.Scopes...)
if err != nil {
return false, err
}
return false, nil
return matches, nil
}
func (p permissionEvaluator) MutateScopes(ctx context.Context, mutate ScopeAttributeMutator) (Evaluator, error) {