Auth: Implement requester interface in access control module (#74289)
* Implement requester interface in the access control module
This commit is contained in:
@@ -6,12 +6,12 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/login"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
|
||||
// maximum possible capacity for recursive queries array: one query for folder and one for dashboard actions
|
||||
@@ -23,7 +23,7 @@ type clause struct {
|
||||
}
|
||||
|
||||
type accessControlDashboardPermissionFilter struct {
|
||||
user *user.SignedInUser
|
||||
user identity.Requester
|
||||
dashboardActions []string
|
||||
folderActions []string
|
||||
features featuremgmt.FeatureToggles
|
||||
@@ -46,7 +46,7 @@ type PermissionsFilter interface {
|
||||
// NewAccessControlDashboardPermissionFilter creates a new AccessControlDashboardPermissionFilter that is configured with specific actions calculated based on the dashboards.PermissionType and query type
|
||||
// The filter is configured to use the new permissions filter (without subqueries) if the feature flag is enabled
|
||||
// The filter is configured to use the old permissions filter (with subqueries) if the feature flag is disabled
|
||||
func NewAccessControlDashboardPermissionFilter(user *user.SignedInUser, permissionLevel dashboards.PermissionType, queryType string, features featuremgmt.FeatureToggles, recursiveQueriesAreSupported bool) PermissionsFilter {
|
||||
func NewAccessControlDashboardPermissionFilter(user identity.Requester, permissionLevel dashboards.PermissionType, queryType string, features featuremgmt.FeatureToggles, recursiveQueriesAreSupported bool) PermissionsFilter {
|
||||
needEdit := permissionLevel > dashboards.PERMISSION_VIEW
|
||||
|
||||
var folderActions []string
|
||||
@@ -111,14 +111,21 @@ func (f *accessControlDashboardPermissionFilter) Where() (string, []any) {
|
||||
}
|
||||
|
||||
func (f *accessControlDashboardPermissionFilter) buildClauses() {
|
||||
if f.user == nil || f.user.Permissions == nil || f.user.Permissions[f.user.OrgID] == nil {
|
||||
if f.user == nil || f.user.IsNil() || len(f.user.GetPermissions()) == 0 {
|
||||
f.where = clause{string: "(1 = 0)"}
|
||||
return
|
||||
}
|
||||
dashWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeDashboardsPrefix)
|
||||
folderWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeFoldersPrefix)
|
||||
|
||||
filter, params := accesscontrol.UserRolesFilter(f.user.OrgID, f.user.UserID, f.user.Teams, accesscontrol.GetOrgRoles(f.user))
|
||||
userID := int64(0)
|
||||
namespaceID, identifier := f.user.GetNamespacedID()
|
||||
switch namespaceID {
|
||||
case identity.NamespaceUser, identity.NamespaceServiceAccount:
|
||||
userID, _ = identity.IntIdentifier(namespaceID, identifier)
|
||||
}
|
||||
|
||||
filter, params := accesscontrol.UserRolesFilter(f.user.GetOrgID(), userID, f.user.GetTeams(), accesscontrol.GetOrgRoles(f.user))
|
||||
rolesFilter := " AND role_id IN(SELECT id FROM role " + filter + ") "
|
||||
var args []any
|
||||
builder := strings.Builder{}
|
||||
@@ -129,10 +136,10 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
|
||||
|
||||
// useSelfContainedPermissions is true if the user's permissions are stored and set from the JWT token
|
||||
// currently it's used for the extended JWT module (when the user is authenticated via a JWT token generated by Grafana)
|
||||
useSelfContainedPermissions := f.user.AuthenticatedBy == login.ExtendedJWTModule
|
||||
useSelfContainedPermissions := f.user.GetAuthenticatedBy() == login.ExtendedJWTModule
|
||||
|
||||
if len(f.dashboardActions) > 0 {
|
||||
toCheck := actionsToCheck(f.dashboardActions, f.user.Permissions[f.user.OrgID], dashWildcards, folderWildcards)
|
||||
toCheck := actionsToCheck(f.dashboardActions, f.user.GetPermissions(), dashWildcards, folderWildcards)
|
||||
|
||||
if len(toCheck) > 0 {
|
||||
if !useSelfContainedPermissions {
|
||||
@@ -236,7 +243,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
|
||||
builder.WriteString(" OR ")
|
||||
}
|
||||
|
||||
toCheck := actionsToCheck(f.folderActions, f.user.Permissions[f.user.OrgID], folderWildcards)
|
||||
toCheck := actionsToCheck(f.folderActions, f.user.GetPermissions(), folderWildcards)
|
||||
if len(toCheck) > 0 {
|
||||
if !useSelfContainedPermissions {
|
||||
permSelector.WriteString("(SELECT substr(scope, 13) FROM permission WHERE scope LIKE 'folders:uid:%'")
|
||||
@@ -392,10 +399,10 @@ func parseStringSliceFromInterfaceSlice(slice []any) []string {
|
||||
return result
|
||||
}
|
||||
|
||||
func getAllowedUIDs(actions []string, user *user.SignedInUser, scopePrefix string) []any {
|
||||
func getAllowedUIDs(actions []string, user identity.Requester, scopePrefix string) []any {
|
||||
uidToActions := make(map[string]map[string]struct{})
|
||||
for _, action := range actions {
|
||||
for _, uidScope := range user.Permissions[user.OrgID][action] {
|
||||
for _, uidScope := range user.GetPermissions()[action] {
|
||||
if !strings.HasPrefix(uidScope, scopePrefix) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
@@ -25,14 +26,21 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) LeftJoin() stri
|
||||
}
|
||||
|
||||
func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses() {
|
||||
if f.user == nil || f.user.Permissions == nil || f.user.Permissions[f.user.OrgID] == nil {
|
||||
if f.user == nil || f.user.IsNil() || len(f.user.GetPermissions()) == 0 {
|
||||
f.where = clause{string: "(1 = 0)"}
|
||||
return
|
||||
}
|
||||
dashWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeDashboardsPrefix)
|
||||
folderWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeFoldersPrefix)
|
||||
|
||||
filter, params := accesscontrol.UserRolesFilter(f.user.OrgID, f.user.UserID, f.user.Teams, accesscontrol.GetOrgRoles(f.user))
|
||||
userID := int64(0)
|
||||
namespaceID, identifier := f.user.GetNamespacedID()
|
||||
switch namespaceID {
|
||||
case identity.NamespaceUser, identity.NamespaceServiceAccount:
|
||||
userID, _ = identity.IntIdentifier(namespaceID, identifier)
|
||||
}
|
||||
|
||||
filter, params := accesscontrol.UserRolesFilter(f.user.GetOrgID(), userID, f.user.GetTeams(), accesscontrol.GetOrgRoles(f.user))
|
||||
rolesFilter := " AND role_id IN(SELECT id FROM role " + filter + ") "
|
||||
var args []any
|
||||
builder := strings.Builder{}
|
||||
@@ -43,10 +51,10 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
|
||||
|
||||
// useSelfContainedPermissions is true if the user's permissions are stored and set from the JWT token
|
||||
// currently it's used for the extended JWT module (when the user is authenticated via a JWT token generated by Grafana)
|
||||
useSelfContainedPermissions := f.user.AuthenticatedBy == login.ExtendedJWTModule
|
||||
useSelfContainedPermissions := f.user.GetAuthenticatedBy() == login.ExtendedJWTModule
|
||||
|
||||
if len(f.dashboardActions) > 0 {
|
||||
toCheck := actionsToCheck(f.dashboardActions, f.user.Permissions[f.user.OrgID], dashWildcards, folderWildcards)
|
||||
toCheck := actionsToCheck(f.dashboardActions, f.user.GetPermissions(), dashWildcards, folderWildcards)
|
||||
|
||||
if len(toCheck) > 0 {
|
||||
if !useSelfContainedPermissions {
|
||||
@@ -152,7 +160,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
|
||||
builder.WriteString(" OR ")
|
||||
}
|
||||
|
||||
toCheck := actionsToCheck(f.folderActions, f.user.Permissions[f.user.OrgID], folderWildcards)
|
||||
toCheck := actionsToCheck(f.folderActions, f.user.GetPermissions(), folderWildcards)
|
||||
if len(toCheck) > 0 {
|
||||
if !useSelfContainedPermissions {
|
||||
permSelector.WriteString("(SELECT substr(scope, 13) FROM permission WHERE scope LIKE 'folders:uid:%'")
|
||||
|
||||
Reference in New Issue
Block a user