Nested folders: Fix search query for empty self-contained permissions (#72727)

* Add tests

* Fix query for nested folders with zero self-contained permissions

* Fix query behind  permissionsFilterRemoveSubquery flag

* Apply suggestion from code review
This commit is contained in:
Sofia Papagiannaki
2023-08-02 14:12:46 +03:00
committed by GitHub
parent dbef9899ac
commit 8a24e891fe
3 changed files with 129 additions and 46 deletions

View File

@ -194,17 +194,22 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
switch f.features.IsEnabled(featuremgmt.FlagNestedFolders) { switch f.features.IsEnabled(featuremgmt.FlagNestedFolders) {
case true: case true:
switch f.recursiveQueriesAreSupported { if len(permSelectorArgs) > 0 {
case true: switch f.recursiveQueriesAreSupported {
recQueryName := fmt.Sprintf("RecQry%d", len(f.recQueries)) case true:
f.addRecQry(recQueryName, permSelector.String(), permSelectorArgs) builder.WriteString("(dashboard.folder_id IN (SELECT d.id FROM dashboard as d ")
recQueryName := fmt.Sprintf("RecQry%d", len(f.recQueries))
f.addRecQry(recQueryName, permSelector.String(), permSelectorArgs)
builder.WriteString(fmt.Sprintf("WHERE d.uid IN (SELECT uid FROM %s)", recQueryName))
default:
nestedFoldersSelectors, nestedFoldersArgs := f.nestedFoldersSelectors(permSelector.String(), permSelectorArgs, "dashboard.folder_id", "d.id")
builder.WriteRune('(')
builder.WriteString(nestedFoldersSelectors)
args = append(args, nestedFoldersArgs...)
}
} else {
builder.WriteString("(dashboard.folder_id IN (SELECT d.id FROM dashboard as d ") builder.WriteString("(dashboard.folder_id IN (SELECT d.id FROM dashboard as d ")
builder.WriteString(fmt.Sprintf("WHERE d.uid IN (SELECT uid FROM %s)", recQueryName)) builder.WriteString("WHERE 1 = 0")
default:
nestedFoldersSelectors, nestedFoldersArgs := f.nestedFoldersSelectors(permSelector.String(), permSelectorArgs, "dashboard.folder_id", "d.id")
builder.WriteRune('(')
builder.WriteString(nestedFoldersSelectors)
args = append(args, nestedFoldersArgs...)
} }
default: default:
builder.WriteString("(dashboard.folder_id IN (SELECT d.id FROM dashboard as d ") builder.WriteString("(dashboard.folder_id IN (SELECT d.id FROM dashboard as d ")
@ -261,18 +266,22 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
switch f.features.IsEnabled(featuremgmt.FlagNestedFolders) { switch f.features.IsEnabled(featuremgmt.FlagNestedFolders) {
case true: case true:
switch f.recursiveQueriesAreSupported { if len(permSelectorArgs) > 0 {
case true: switch f.recursiveQueriesAreSupported {
recQueryName := fmt.Sprintf("RecQry%d", len(f.recQueries)) case true:
f.addRecQry(recQueryName, permSelector.String(), permSelectorArgs) recQueryName := fmt.Sprintf("RecQry%d", len(f.recQueries))
builder.WriteString("(dashboard.uid IN ") f.addRecQry(recQueryName, permSelector.String(), permSelectorArgs)
builder.WriteString(fmt.Sprintf("(SELECT uid FROM %s)", recQueryName)) builder.WriteString("(dashboard.uid IN ")
default: builder.WriteString(fmt.Sprintf("(SELECT uid FROM %s)", recQueryName))
nestedFoldersSelectors, nestedFoldersArgs := f.nestedFoldersSelectors(permSelector.String(), permSelectorArgs, "dashboard.uid", "d.uid") default:
builder.WriteRune('(') nestedFoldersSelectors, nestedFoldersArgs := f.nestedFoldersSelectors(permSelector.String(), permSelectorArgs, "dashboard.uid", "d.uid")
builder.WriteString(nestedFoldersSelectors) builder.WriteRune('(')
builder.WriteRune(')') builder.WriteString(nestedFoldersSelectors)
args = append(args, nestedFoldersArgs...) builder.WriteRune(')')
args = append(args, nestedFoldersArgs...)
}
} else {
builder.WriteString("(1 = 0")
} }
default: default:
if len(permSelectorArgs) > 0 { if len(permSelectorArgs) > 0 {

View File

@ -109,19 +109,23 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
switch f.features.IsEnabled(featuremgmt.FlagNestedFolders) { switch f.features.IsEnabled(featuremgmt.FlagNestedFolders) {
case true: case true:
switch f.recursiveQueriesAreSupported { if len(permSelectorArgs) > 0 {
case true: switch f.recursiveQueriesAreSupported {
recQueryName := fmt.Sprintf("RecQry%d", len(f.recQueries)) case true:
f.addRecQry(recQueryName, permSelector.String(), permSelectorArgs) recQueryName := fmt.Sprintf("RecQry%d", len(f.recQueries))
builder.WriteString("(folder.uid IN (SELECT uid FROM " + recQueryName) f.addRecQry(recQueryName, permSelector.String(), permSelectorArgs)
default: builder.WriteString("(folder.uid IN (SELECT uid FROM " + recQueryName)
nestedFoldersSelectors, nestedFoldersArgs := f.nestedFoldersSelectors(permSelector.String(), permSelectorArgs, "folder.uid", "") default:
builder.WriteRune('(') nestedFoldersSelectors, nestedFoldersArgs := f.nestedFoldersSelectors(permSelector.String(), permSelectorArgs, "folder.uid", "")
builder.WriteString(nestedFoldersSelectors) builder.WriteRune('(')
args = append(args, nestedFoldersArgs...) builder.WriteString(nestedFoldersSelectors)
args = append(args, nestedFoldersArgs...)
}
f.folderIsRequired = true
builder.WriteString(") AND NOT dashboard.is_folder)")
} else {
builder.WriteString("( 1 = 0 AND NOT dashboard.is_folder)")
} }
f.folderIsRequired = true
builder.WriteString(") AND NOT dashboard.is_folder)")
default: default:
builder.WriteString("(") builder.WriteString("(")
if len(permSelectorArgs) > 0 { if len(permSelectorArgs) > 0 {
@ -177,18 +181,22 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
switch f.features.IsEnabled(featuremgmt.FlagNestedFolders) { switch f.features.IsEnabled(featuremgmt.FlagNestedFolders) {
case true: case true:
switch f.recursiveQueriesAreSupported { if len(permSelectorArgs) > 0 {
case true: switch f.recursiveQueriesAreSupported {
recQueryName := fmt.Sprintf("RecQry%d", len(f.recQueries)) case true:
f.addRecQry(recQueryName, permSelector.String(), permSelectorArgs) recQueryName := fmt.Sprintf("RecQry%d", len(f.recQueries))
builder.WriteString("(dashboard.uid IN ") f.addRecQry(recQueryName, permSelector.String(), permSelectorArgs)
builder.WriteString(fmt.Sprintf("(SELECT uid FROM %s)", recQueryName)) builder.WriteString("(dashboard.uid IN ")
default: builder.WriteString(fmt.Sprintf("(SELECT uid FROM %s)", recQueryName))
nestedFoldersSelectors, nestedFoldersArgs := f.nestedFoldersSelectors(permSelector.String(), permSelectorArgs, "dashboard.uid", "") default:
builder.WriteRune('(') nestedFoldersSelectors, nestedFoldersArgs := f.nestedFoldersSelectors(permSelector.String(), permSelectorArgs, "dashboard.uid", "")
builder.WriteString(nestedFoldersSelectors) builder.WriteRune('(')
builder.WriteRune(')') builder.WriteString(nestedFoldersSelectors)
args = append(args, nestedFoldersArgs...) builder.WriteRune(')')
args = append(args, nestedFoldersArgs...)
}
} else {
builder.WriteString("(1 = 0")
} }
default: default:
if len(permSelectorArgs) > 0 { if len(permSelectorArgs) > 0 {

View File

@ -382,6 +382,39 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
expectedResult []string expectedResult []string
features []interface{} features []interface{}
}{ }{
{
desc: "Should not be able to view dashboards under inherited folders with no permissions if nested folders are enabled",
queryType: searchstore.TypeDashboard,
permission: dashboards.PERMISSION_VIEW,
permissions: nil,
features: []interface{}{featuremgmt.FlagNestedFolders},
expectedResult: nil,
},
{
desc: "Should not be able to view inherited folders with no permissions if nested folders are enabled",
queryType: searchstore.TypeFolder,
permission: dashboards.PERMISSION_VIEW,
permissions: nil,
features: []interface{}{featuremgmt.FlagNestedFolders},
expectedResult: nil,
},
{
desc: "Should not be able to view inherited dashboards and folders with no permissions if nested folders are enabled",
permission: dashboards.PERMISSION_VIEW,
permissions: nil,
features: []interface{}{featuremgmt.FlagNestedFolders},
expectedResult: nil,
},
{
desc: "Should be able to view dashboards under inherited folders with wildcard scope if nested folders are enabled",
queryType: searchstore.TypeDashboard,
permission: dashboards.PERMISSION_VIEW,
permissions: []accesscontrol.Permission{
{Action: dashboards.ActionDashboardsRead, Scope: dashboards.ScopeFoldersAll},
},
features: []interface{}{featuremgmt.FlagNestedFolders},
expectedResult: []string{"dashboard under parent folder", "dashboard under subfolder"},
},
{ {
desc: "Should be able to view dashboards under inherited folders if nested folders are enabled", desc: "Should be able to view dashboards under inherited folders if nested folders are enabled",
queryType: searchstore.TypeDashboard, queryType: searchstore.TypeDashboard,
@ -502,6 +535,39 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
expectedResult []string expectedResult []string
features []interface{} features []interface{}
}{ }{
{
desc: "Should not be able to view dashboards under inherited folders with no permissions if nested folders are enabled",
queryType: searchstore.TypeDashboard,
permission: dashboards.PERMISSION_VIEW,
signedInUserPermissions: nil,
features: []interface{}{featuremgmt.FlagNestedFolders},
expectedResult: nil,
},
{
desc: "Should not be able to view inherited folders with no permissions if nested folders are enabled",
queryType: searchstore.TypeFolder,
permission: dashboards.PERMISSION_VIEW,
signedInUserPermissions: nil,
features: []interface{}{featuremgmt.FlagNestedFolders},
expectedResult: nil,
},
{
desc: "Should not be able to view inherited dashboards and folders with no permissions if nested folders are enabled",
permission: dashboards.PERMISSION_VIEW,
signedInUserPermissions: nil,
features: []interface{}{featuremgmt.FlagNestedFolders},
expectedResult: nil,
},
{
desc: "Should be able to view dashboards under inherited folders with wildcard scope if nested folders are enabled",
queryType: searchstore.TypeDashboard,
permission: dashboards.PERMISSION_VIEW,
signedInUserPermissions: []accesscontrol.Permission{
{Action: dashboards.ActionDashboardsRead, Scope: dashboards.ScopeFoldersAll},
},
features: []interface{}{featuremgmt.FlagNestedFolders},
expectedResult: []string{"dashboard under parent folder", "dashboard under subfolder"},
},
{ {
desc: "Should be able to view dashboards under inherited folders if nested folders are enabled", desc: "Should be able to view dashboards under inherited folders if nested folders are enabled",
queryType: searchstore.TypeDashboard, queryType: searchstore.TypeDashboard,