diff --git a/pkg/services/accesscontrol/database/resource_permissions.go b/pkg/services/accesscontrol/database/resource_permissions.go index c8880aab974..0e690e0d867 100644 --- a/pkg/services/accesscontrol/database/resource_permissions.go +++ b/pkg/services/accesscontrol/database/resource_permissions.go @@ -169,7 +169,7 @@ func (s *AccessControlStore) GetResourcesPermissions(ctx context.Context, orgID err := s.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { var err error - result, err = getResourcesPermissions(sess, orgID, query, false) + result, err = getResourcesPermissions(sess, orgID, query) return err }) @@ -214,7 +214,7 @@ func createResourcePermission(sess *sqlstore.DBSession, roleID int64, action, re return p, nil } -func getResourcesPermissions(sess *sqlstore.DBSession, orgID int64, query accesscontrol.GetResourcesPermissionsQuery, managed bool) ([]accesscontrol.ResourcePermission, error) { +func getResourcesPermissions(sess *sqlstore.DBSession, orgID int64, query accesscontrol.GetResourcesPermissionsQuery) ([]accesscontrol.ResourcePermission, error) { if len(query.Actions) == 0 { return nil, nil } @@ -281,7 +281,7 @@ func getResourcesPermissions(sess *sqlstore.DBSession, orgID int64, query access AND p.action IN (?` + strings.Repeat(",?", len(query.Actions)-1) + `) ` - if managed { + if query.OnlyManaged { where += `AND r.name LIKE 'managed:%'` } diff --git a/pkg/services/accesscontrol/database/resource_permissions_test.go b/pkg/services/accesscontrol/database/resource_permissions_test.go index 67511b944b7..1499ad3d366 100644 --- a/pkg/services/accesscontrol/database/resource_permissions_test.go +++ b/pkg/services/accesscontrol/database/resource_permissions_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -252,6 +253,7 @@ type getResourcesPermissionsTest struct { actions []string resource string resourceIDs []string + onlyManaged bool } func TestAccessControlStore_GetResourcesPermissions(t *testing.T) { @@ -263,12 +265,55 @@ func TestAccessControlStore_GetResourcesPermissions(t *testing.T) { resource: "datasources", resourceIDs: []string{"1", "2"}, }, + { + desc: "should return manage permissions for all resource ids", + numUsers: 3, + actions: []string{"datasources:query"}, + resource: "datasources", + resourceIDs: []string{"1", "2"}, + onlyManaged: true, + }, } for _, test := range tests { t.Run(test.desc, func(t *testing.T) { store, sql := setupTestEnv(t) + err := sql.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { + role := &accesscontrol.Role{ + OrgID: 1, + UID: "seeded", + Name: "seeded", + Updated: time.Now(), + Created: time.Now(), + } + _, err := sess.Insert(role) + require.NoError(t, err) + + permission := &accesscontrol.Permission{ + RoleID: role.ID, + Action: "datasources:query", + Scope: "datasources:*", + Updated: time.Now(), + Created: time.Now(), + } + _, err = sess.Insert(permission) + require.NoError(t, err) + + builtInRole := &accesscontrol.BuiltinRole{ + RoleID: role.ID, + OrgID: 1, + Role: "Viewer", + Updated: time.Now(), + Created: time.Now(), + } + _, err = sess.Insert(builtInRole) + require.NoError(t, err) + + return nil + }) + require.NoError(t, err) + for _, id := range test.resourceIDs { seedResourcePermissions(t, store, sql, test.actions, test.resource, id, test.numUsers) } @@ -277,10 +322,14 @@ func TestAccessControlStore_GetResourcesPermissions(t *testing.T) { Actions: test.actions, Resource: test.resource, ResourceIDs: test.resourceIDs, + OnlyManaged: test.onlyManaged, }) require.NoError(t, err) expectedLen := test.numUsers * len(test.resourceIDs) + if !test.onlyManaged { + expectedLen += len(test.resourceIDs) + } assert.Len(t, permissions, expectedLen) }) } diff --git a/pkg/services/accesscontrol/models.go b/pkg/services/accesscontrol/models.go index f618610b63e..0ed854b80cf 100644 --- a/pkg/services/accesscontrol/models.go +++ b/pkg/services/accesscontrol/models.go @@ -243,6 +243,7 @@ type GetResourcesPermissionsQuery struct { Actions []string Resource string ResourceIDs []string + OnlyManaged bool } const ( diff --git a/pkg/services/accesscontrol/resourcepermissions/options.go b/pkg/services/accesscontrol/resourcepermissions/options.go index 4697389126a..15e0590870e 100644 --- a/pkg/services/accesscontrol/resourcepermissions/options.go +++ b/pkg/services/accesscontrol/resourcepermissions/options.go @@ -9,6 +9,8 @@ type ResourceValidator func(ctx context.Context, orgID int64, resourceID string) type Options struct { // Resource is the action and scope prefix that is generated Resource string + // OnlyManaged will tell the service to return all permissions if set to false and only managed permissions if set to true + OnlyManaged bool // ResourceValidator is a validator function that will be called before each assignment. // If set to nil the validator will be skipped ResourceValidator ResourceValidator diff --git a/pkg/services/accesscontrol/resourcepermissions/service.go b/pkg/services/accesscontrol/resourcepermissions/service.go index 8084d630c1c..d4f91f5b4a0 100644 --- a/pkg/services/accesscontrol/resourcepermissions/service.go +++ b/pkg/services/accesscontrol/resourcepermissions/service.go @@ -69,6 +69,7 @@ func (s *Service) GetPermissions(ctx context.Context, orgID int64, resourceID st Actions: s.actions, Resource: s.options.Resource, ResourceIDs: []string{resourceID}, + OnlyManaged: s.options.OnlyManaged, }) }