mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
This patch adds metrics to support instrumenting the accesscontrols package. It also instruments the accesscontrol evaluator and the permissions function. Co-authored-by: Vardan Torosyan <vardants@gmail.com>
73 lines
1.6 KiB
Go
73 lines
1.6 KiB
Go
package evaluator
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/gobwas/glob"
|
|
|
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
// Evaluate evaluates access to the given resource, using provided AccessControl instance.
|
|
// Scopes are evaluated with an `OR` relationship.
|
|
func Evaluate(ctx context.Context, ac accesscontrol.AccessControl, user *models.SignedInUser, action string, scope ...string) (bool, error) {
|
|
timer := prometheus.NewTimer(metrics.MAccessEvaluationsSummary)
|
|
defer timer.ObserveDuration()
|
|
metrics.MAccessEvaluationCount.Inc()
|
|
userPermissions, err := ac.GetUserPermissions(ctx, user)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
ok, dbScopes := extractScopes(userPermissions, action)
|
|
if !ok {
|
|
return false, nil
|
|
}
|
|
|
|
res, err := evaluateScope(dbScopes, scope...)
|
|
return res, err
|
|
}
|
|
|
|
func evaluateScope(dbScopes map[string]struct{}, targetScopes ...string) (bool, error) {
|
|
if len(targetScopes) == 0 {
|
|
return true, nil
|
|
}
|
|
|
|
for _, s := range targetScopes {
|
|
var match bool
|
|
for dbScope := range dbScopes {
|
|
rule, err := glob.Compile(dbScope, ':', '/')
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
match = rule.Match(s)
|
|
if match {
|
|
return true, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
func extractScopes(permissions []*accesscontrol.Permission, targetAction string) (bool, map[string]struct{}) {
|
|
scopes := map[string]struct{}{}
|
|
ok := false
|
|
|
|
for _, p := range permissions {
|
|
if p == nil {
|
|
continue
|
|
}
|
|
if p.Action == targetAction {
|
|
ok = true
|
|
scopes[p.Scope] = struct{}{}
|
|
}
|
|
}
|
|
|
|
return ok, scopes
|
|
}
|