From 2894f07f05a76bc683ac97847f0968a5a871568f Mon Sep 17 00:00:00 2001 From: J Guerreiro Date: Fri, 28 Jan 2022 11:17:24 +0000 Subject: [PATCH] AccessControl: improve denied message (#44551) * AccessControl: improve denied message * AccessControl: tweak permission denied --- pkg/services/accesscontrol/evaluator.go | 27 ++++++++++++++++++- .../accesscontrol/middleware/middleware.go | 4 +-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/pkg/services/accesscontrol/evaluator.go b/pkg/services/accesscontrol/evaluator.go index 68d29246fd9..52be2d80549 100644 --- a/pkg/services/accesscontrol/evaluator.go +++ b/pkg/services/accesscontrol/evaluator.go @@ -16,7 +16,8 @@ type Evaluator interface { // MutateScopes executes a sequence of ScopeModifier functions on all embedded scopes of an evaluator and returns a new Evaluator MutateScopes(context.Context, ...ScopeMutator) (Evaluator, error) // String returns a string representation of permission required by the evaluator - String() string + fmt.Stringer + fmt.GoStringer } var _ Evaluator = new(permissionEvaluator) @@ -109,6 +110,10 @@ func (p permissionEvaluator) MutateScopes(ctx context.Context, modifiers ...Scop } func (p permissionEvaluator) String() string { + return p.Action +} + +func (p permissionEvaluator) GoString() string { return fmt.Sprintf("action:%s scopes:%s", p.Action, strings.Join(p.Scopes, ", ")) } @@ -149,6 +154,16 @@ func (a allEvaluator) String() string { for _, e := range a.allOf { permissions = append(permissions, e.String()) } + + return fmt.Sprintf("all of %s", strings.Join(permissions, ", ")) +} + +func (a allEvaluator) GoString() string { + permissions := make([]string, 0, len(a.allOf)) + for _, e := range a.allOf { + permissions = append(permissions, e.GoString()) + } + return fmt.Sprintf("all(%s)", strings.Join(permissions, " ")) } @@ -193,5 +208,15 @@ func (a anyEvaluator) String() string { for _, e := range a.anyOf { permissions = append(permissions, e.String()) } + + return fmt.Sprintf("any of %s", strings.Join(permissions, ", ")) +} + +func (a anyEvaluator) GoString() string { + permissions := make([]string, 0, len(a.anyOf)) + for _, e := range a.anyOf { + permissions = append(permissions, e.String()) + } + return fmt.Sprintf("any(%s)", strings.Join(permissions, " ")) } diff --git a/pkg/services/accesscontrol/middleware/middleware.go b/pkg/services/accesscontrol/middleware/middleware.go index 4cd60ee69d2..ca5427b2c3b 100644 --- a/pkg/services/accesscontrol/middleware/middleware.go +++ b/pkg/services/accesscontrol/middleware/middleware.go @@ -49,7 +49,7 @@ func Deny(c *models.ReqContext, evaluator accesscontrol.Evaluator, err error) { "Access denied", "userID", c.UserId, "accessErrorID", id, - "permissions", evaluator.String(), + "permissions", evaluator.GoString(), ) } @@ -65,7 +65,7 @@ func Deny(c *models.ReqContext, evaluator accesscontrol.Evaluator, err error) { // internal server error or access denied. c.JSON(http.StatusForbidden, map[string]string{ "title": "Access denied", // the component needs to pick this up - "message": fmt.Sprintf("You'll need additional permissions to perform this action. Refer your administrator to a Grafana log with the reference %s to identify which permissions to add.", id), + "message": fmt.Sprintf("You'll need additional permissions to perform this action. Permissions needed: %s", evaluator.String()), "accessErrorId": id, }) }