Auth: Move access control API to SignedInUser interface (#73144)

* move access control api to SignedInUser interface

* remove unused code

* add logic for reading perms from a specific org

* move the specific org logic to org_user.go

* add a comment

---------

Co-authored-by: IevaVasiljeva <ieva.vasiljeva@grafana.com>
This commit is contained in:
Jo
2023-08-18 11:42:18 +01:00
committed by GitHub
co-authored by IevaVasiljeva
parent 4c9469fc9e
commit 26339f978b
17 changed files with 50 additions and 41 deletions
+4 -9
View File
@@ -463,25 +463,20 @@ func (hs *HTTPServer) declareFixedRoles() error {
func (hs *HTTPServer) getAccessControlMetadata(c *contextmodel.ReqContext,
orgID int64, prefix string, resourceID string) ac.Metadata {
ids := map[string]bool{resourceID: true}
return hs.getMultiAccessControlMetadata(c, orgID, prefix, ids)[resourceID]
return hs.getMultiAccessControlMetadata(c, prefix, ids)[resourceID]
}
// getMultiAccessControlMetadata returns the accesscontrol metadata associated with a given set of resources
// Context must contain permissions in the given org (see LoadPermissionsMiddleware or AuthorizeInOrgMiddleware)
func (hs *HTTPServer) getMultiAccessControlMetadata(c *contextmodel.ReqContext,
orgID int64, prefix string, resourceIDs map[string]bool) map[string]ac.Metadata {
prefix string, resourceIDs map[string]bool) map[string]ac.Metadata {
if !c.QueryBool("accesscontrol") {
return map[string]ac.Metadata{}
}
if c.SignedInUser.Permissions == nil {
if len(c.SignedInUser.GetPermissions()) == 0 {
return map[string]ac.Metadata{}
}
permissions, ok := c.SignedInUser.Permissions[orgID]
if !ok {
return map[string]ac.Metadata{}
}
return ac.GetResourcesMetadata(c.Req.Context(), permissions, prefix, resourceIDs)
return ac.GetResourcesMetadata(c.Req.Context(), c.SignedInUser.GetPermissions(), prefix, resourceIDs)
}
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"github.com/grafana/grafana/pkg/api/response"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/auth/identity"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/stats"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -67,7 +67,7 @@ func (hs *HTTPServer) AdminGetStats(c *contextmodel.ReqContext) response.Respons
return response.JSON(http.StatusOK, adminStats)
}
func (hs *HTTPServer) getAuthorizedSettings(ctx context.Context, user *user.SignedInUser, bag setting.SettingsBag) (setting.SettingsBag, error) {
func (hs *HTTPServer) getAuthorizedSettings(ctx context.Context, user identity.Requester, bag setting.SettingsBag) (setting.SettingsBag, error) {
eval := func(scope string) (bool, error) {
return hs.AccessControl.Evaluate(ctx, user, ac.EvalPermission(ac.ActionSettingsRead, scope))
}
@@ -108,7 +108,7 @@ func (hs *HTTPServer) getAuthorizedSettings(ctx context.Context, user *user.Sign
return authorizedBag, nil
}
func (hs *HTTPServer) getAuthorizedVerboseSettings(ctx context.Context, user *user.SignedInUser, bag setting.VerboseSettingsBag) (setting.VerboseSettingsBag, error) {
func (hs *HTTPServer) getAuthorizedVerboseSettings(ctx context.Context, user identity.Requester, bag setting.VerboseSettingsBag) (setting.VerboseSettingsBag, error) {
eval := func(scope string) (bool, error) {
return hs.AccessControl.Evaluate(ctx, user, ac.EvalPermission(ac.ActionSettingsRead, scope))
}
+1 -1
View File
@@ -57,7 +57,7 @@ func (hs *HTTPServer) GetAPIKeys(c *contextmodel.ReqContext) response.Response {
}
}
metadata := hs.getMultiAccessControlMetadata(c, c.OrgID, "apikeys:id", ids)
metadata := hs.getMultiAccessControlMetadata(c, "apikeys:id", ids)
if len(metadata) > 0 {
for _, key := range result {
key.AccessControl = metadata[strconv.FormatInt(key.ID, 10)]
+1 -1
View File
@@ -390,7 +390,7 @@ func (hs *HTTPServer) getFolderACMetadata(c *contextmodel.ReqContext, f *folder.
folderIDs[p.UID] = true
}
allMetadata := hs.getMultiAccessControlMetadata(c, c.OrgID, dashboards.ScopeFoldersPrefix, folderIDs)
allMetadata := hs.getMultiAccessControlMetadata(c, dashboards.ScopeFoldersPrefix, folderIDs)
metadata := allMetadata[f.UID]
// Flatten metadata - if any parent has a permission, the child folder inherits it
+9 -1
View File
@@ -310,7 +310,15 @@ func (hs *HTTPServer) searchOrgUsersHelper(c *contextmodel.ReqContext, query *or
}
// Get accesscontrol metadata and IPD labels for users in the target org
accessControlMetadata := hs.getMultiAccessControlMetadata(c, query.OrgID, "users:id:", userIDs)
accessControlMetadata := map[string]accesscontrol.Metadata{}
if c.QueryBool("accesscontrol") && c.SignedInUser.Permissions != nil {
// TODO https://github.com/grafana/grafana-authnz-team/issues/268 - user access control service for fetching permissions from another organization
permissions, ok := c.SignedInUser.Permissions[query.OrgID]
if ok {
accessControlMetadata = accesscontrol.GetResourcesMetadata(c.Req.Context(), permissions, "users:id:", userIDs)
}
}
for i := range filteredUsers {
filteredUsers[i].AccessControl = accessControlMetadata[fmt.Sprint(filteredUsers[i].UserID)]
if module, ok := modules[filteredUsers[i].UserID]; ok {
+1 -2
View File
@@ -121,8 +121,7 @@ func (hs *HTTPServer) GetPluginList(c *contextmodel.ReqContext) response.Respons
}
// Compute metadata
pluginsMetadata := hs.getMultiAccessControlMetadata(c, c.OrgID,
pluginaccesscontrol.ScopeProvider.GetResourceScope(""), filteredPluginIDs)
pluginsMetadata := hs.getMultiAccessControlMetadata(c, pluginaccesscontrol.ScopeProvider.GetResourceScope(""), filteredPluginIDs)
// Prepare DTO
result := make(dtos.PluginList, 0)
+1 -1
View File
@@ -167,7 +167,7 @@ func (hs *HTTPServer) SearchTeams(c *contextmodel.ReqContext) response.Response
teamIDs[strconv.FormatInt(team.ID, 10)] = true
}
metadata := hs.getMultiAccessControlMetadata(c, c.SignedInUser.GetOrgID(), "teams:id:", teamIDs)
metadata := hs.getMultiAccessControlMetadata(c, "teams:id:", teamIDs)
if len(metadata) > 0 {
for _, team := range queryResult.Teams {
team.AccessControl = metadata[strconv.FormatInt(team.ID, 10)]