From 3440e7c8f703209f5b0278f7cb98943cc802bd08 Mon Sep 17 00:00:00 2001 From: Gabriel MABILLE Date: Thu, 24 Mar 2022 08:58:10 +0100 Subject: [PATCH] AccessControl: Fix locked role picker in orgs/edit page (#46539) * AccessControl: Fix locked role picker in orgs/edit page * Use correct org when computing metadata --- pkg/api/accesscontrol.go | 11 +++++++---- pkg/api/datasources.go | 5 +++-- pkg/api/org_users.go | 3 ++- pkg/api/team.go | 4 ++-- pkg/api/user.go | 2 +- pkg/services/accesscontrol/middleware/middleware.go | 3 +++ public/app/features/admin/AdminEditOrgPage.tsx | 3 ++- 7 files changed, 20 insertions(+), 11 deletions(-) diff --git a/pkg/api/accesscontrol.go b/pkg/api/accesscontrol.go index 398229012c3..97e63a8a1ba 100644 --- a/pkg/api/accesscontrol.go +++ b/pkg/api/accesscontrol.go @@ -465,13 +465,16 @@ var teamsEditAccessEvaluator = ac.EvalAll( // Metadata helpers // getAccessControlMetadata returns the accesscontrol metadata associated with a given resource -func (hs *HTTPServer) getAccessControlMetadata(c *models.ReqContext, prefix string, resourceID string) ac.Metadata { +func (hs *HTTPServer) getAccessControlMetadata(c *models.ReqContext, + orgID int64, prefix string, resourceID string) ac.Metadata { ids := map[string]bool{resourceID: true} - return hs.getMultiAccessControlMetadata(c, prefix, ids)[resourceID] + return hs.getMultiAccessControlMetadata(c, orgID, prefix, ids)[resourceID] } // getMultiAccessControlMetadata returns the accesscontrol metadata associated with a given set of resources -func (hs *HTTPServer) getMultiAccessControlMetadata(c *models.ReqContext, prefix string, resourceIDs map[string]bool) map[string]ac.Metadata { +// Context must contain permissions in the given org (see LoadPermissionsMiddleware or AuthorizeInOrgMiddleware) +func (hs *HTTPServer) getMultiAccessControlMetadata(c *models.ReqContext, + orgID int64, prefix string, resourceIDs map[string]bool) map[string]ac.Metadata { if hs.AccessControl.IsDisabled() || !c.QueryBool("accesscontrol") { return map[string]ac.Metadata{} } @@ -480,7 +483,7 @@ func (hs *HTTPServer) getMultiAccessControlMetadata(c *models.ReqContext, prefix return map[string]ac.Metadata{} } - permissions, ok := c.SignedInUser.Permissions[c.OrgId] + permissions, ok := c.SignedInUser.Permissions[orgID] if !ok { return map[string]ac.Metadata{} } diff --git a/pkg/api/datasources.go b/pkg/api/datasources.go index fb746ed45a8..9115827c8be 100644 --- a/pkg/api/datasources.go +++ b/pkg/api/datasources.go @@ -100,7 +100,7 @@ func (hs *HTTPServer) GetDataSourceById(c *models.ReqContext) response.Response dto := convertModelToDtos(filtered[0]) // Add accesscontrol metadata - dto.AccessControl = hs.getAccessControlMetadata(c, "datasources:id:", strconv.FormatInt(dto.Id, 10)) + dto.AccessControl = hs.getAccessControlMetadata(c, c.OrgId, "datasources:id:", strconv.FormatInt(dto.Id, 10)) return response.JSON(200, &dto) } @@ -159,7 +159,8 @@ func (hs *HTTPServer) GetDataSourceByUID(c *models.ReqContext) response.Response dto := convertModelToDtos(filtered[0]) // Add accesscontrol metadata - dto.AccessControl = hs.getAccessControlMetadata(c, "datasources:id:", strconv.FormatInt(dto.Id, 10)) + dto.AccessControl = hs.getAccessControlMetadata(c, c.OrgId, "datasources:id:", strconv.FormatInt(dto.Id, 10)) + return response.JSON(200, &dto) } diff --git a/pkg/api/org_users.go b/pkg/api/org_users.go index 39a7f77ce74..dcd45bbe523 100644 --- a/pkg/api/org_users.go +++ b/pkg/api/org_users.go @@ -150,7 +150,8 @@ func (hs *HTTPServer) getOrgUsersHelper(c *models.ReqContext, query *models.GetO filteredUsers = append(filteredUsers, user) } - accessControlMetadata := hs.getMultiAccessControlMetadata(c, "users:id:", userIDs) + // Get accesscontrol metadata for users in the target org + accessControlMetadata := hs.getMultiAccessControlMetadata(c, query.OrgId, "users:id:", userIDs) if len(accessControlMetadata) > 0 { for i := range filteredUsers { filteredUsers[i].AccessControl = accessControlMetadata[fmt.Sprint(filteredUsers[i].UserId)] diff --git a/pkg/api/team.go b/pkg/api/team.go index f2d0ae1b7ba..77416f5bce8 100644 --- a/pkg/api/team.go +++ b/pkg/api/team.go @@ -141,7 +141,7 @@ func (hs *HTTPServer) SearchTeams(c *models.ReqContext) response.Response { teamIDs[strconv.FormatInt(team.Id, 10)] = true } - metadata := hs.getMultiAccessControlMetadata(c, "teams:id:", teamIDs) + metadata := hs.getMultiAccessControlMetadata(c, c.OrgId, "teams:id:", teamIDs) if len(metadata) > 0 { for _, team := range query.Result.Teams { team.AccessControl = metadata[strconv.FormatInt(team.Id, 10)] @@ -195,7 +195,7 @@ func (hs *HTTPServer) GetTeamByID(c *models.ReqContext) response.Response { } // Add accesscontrol metadata - query.Result.AccessControl = hs.getAccessControlMetadata(c, "teams:id:", strconv.FormatInt(query.Result.Id, 10)) + query.Result.AccessControl = hs.getAccessControlMetadata(c, c.OrgId, "teams:id:", strconv.FormatInt(query.Result.Id, 10)) query.Result.AvatarUrl = dtos.GetGravatarUrlWithDefault(query.Result.Email, query.Result.Name) return response.JSON(200, &query.Result) diff --git a/pkg/api/user.go b/pkg/api/user.go index 050a574413f..95b69d0b462 100644 --- a/pkg/api/user.go +++ b/pkg/api/user.go @@ -46,7 +46,7 @@ func (hs *HTTPServer) getUserUserProfile(c *models.ReqContext, userID int64) res query.Result.IsExternal = true } - query.Result.AccessControl = hs.getAccessControlMetadata(c, "global.users:id:", strconv.FormatInt(userID, 10)) + query.Result.AccessControl = hs.getAccessControlMetadata(c, c.OrgId, "global.users:id:", strconv.FormatInt(userID, 10)) query.Result.AvatarUrl = dtos.GetGravatarUrl(query.Result.Email) return response.JSON(200, query.Result) diff --git a/pkg/services/accesscontrol/middleware/middleware.go b/pkg/services/accesscontrol/middleware/middleware.go index 3242949d0dd..a055433ca4c 100644 --- a/pkg/services/accesscontrol/middleware/middleware.go +++ b/pkg/services/accesscontrol/middleware/middleware.go @@ -121,6 +121,9 @@ func AuthorizeInOrgMiddleware(ac accesscontrol.AccessControl, db sqlstore.Store) } authorize(c, ac, &userCopy, evaluator) + + // Set the signed in user permissions in that org + c.SignedInUser.Permissions = userCopy.Permissions } } } diff --git a/public/app/features/admin/AdminEditOrgPage.tsx b/public/app/features/admin/AdminEditOrgPage.tsx index 455ca42bed5..bad9182189c 100644 --- a/public/app/features/admin/AdminEditOrgPage.tsx +++ b/public/app/features/admin/AdminEditOrgPage.tsx @@ -11,6 +11,7 @@ import { Form, Field, Input, Button, Legend, Alert } from '@grafana/ui'; import { css } from '@emotion/css'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { contextSrv } from 'app/core/core'; +import { accessControlQueryParam } from 'app/core/utils/accessControl'; interface OrgNameDTO { orgName: string; @@ -22,7 +23,7 @@ const getOrg = async (orgId: UrlQueryValue) => { const getOrgUsers = async (orgId: UrlQueryValue) => { if (contextSrv.hasPermission(AccessControlAction.OrgUsersRead)) { - return await getBackendSrv().get(`/api/orgs/${orgId}/users`); + return await getBackendSrv().get(`/api/orgs/${orgId}/users`, accessControlQueryParam()); } return []; };