mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
RBAC: Move resource permissions store to service package (#53815)
* Rename file to store * Move resource permission specific database functions to resourcepermissions package * Wire: Remove interface bind * RBAC: Remove injection of resourcepermission Store * RBAC: Export store constructor * Tests: Use resource permission package to initiate store used in tests * RBAC: Remove internal types package and move to resourcepermissions package * RBAC: Run database tests as itegration tests
This commit is contained in:
@@ -380,7 +380,7 @@ func setupHTTPServerWithCfgDb(
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
teamPermissionService, err := ossaccesscontrol.ProvideTeamPermissions(cfg, routeRegister, db, ac, database.ProvideService(db), license)
|
teamPermissionService, err := ossaccesscontrol.ProvideTeamPermissions(cfg, routeRegister, db, ac, license)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create minimal HTTP Server
|
// Create minimal HTTP Server
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
|
||||||
"github.com/grafana/grafana/pkg/services/auth"
|
"github.com/grafana/grafana/pkg/services/auth"
|
||||||
"github.com/grafana/grafana/pkg/services/datasources"
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
"github.com/grafana/grafana/pkg/services/datasources/permissions"
|
"github.com/grafana/grafana/pkg/services/datasources/permissions"
|
||||||
@@ -76,7 +75,6 @@ var wireExtsSet = wire.NewSet(
|
|||||||
provider.ProvideService,
|
provider.ProvideService,
|
||||||
wire.Bind(new(plugins.BackendFactoryProvider), new(*provider.Service)),
|
wire.Bind(new(plugins.BackendFactoryProvider), new(*provider.Service)),
|
||||||
acdb.ProvideService,
|
acdb.ProvideService,
|
||||||
wire.Bind(new(resourcepermissions.Store), new(*acdb.AccessControlStore)),
|
|
||||||
wire.Bind(new(accesscontrol.PermissionsStore), new(*acdb.AccessControlStore)),
|
wire.Bind(new(accesscontrol.PermissionsStore), new(*acdb.AccessControlStore)),
|
||||||
ldap.ProvideGroupsService,
|
ldap.ProvideGroupsService,
|
||||||
wire.Bind(new(ldap.Groups), new(*ldap.OSSGroups)),
|
wire.Bind(new(ldap.Groups), new(*ldap.OSSGroups)),
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
|
||||||
"github.com/grafana/grafana/pkg/services/auth"
|
"github.com/grafana/grafana/pkg/services/auth"
|
||||||
"github.com/grafana/grafana/pkg/services/datasources"
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
"github.com/grafana/grafana/pkg/services/datasources/permissions"
|
"github.com/grafana/grafana/pkg/services/datasources/permissions"
|
||||||
@@ -75,7 +74,6 @@ var wireExtsBasicSet = wire.NewSet(
|
|||||||
provider.ProvideService,
|
provider.ProvideService,
|
||||||
wire.Bind(new(plugins.BackendFactoryProvider), new(*provider.Service)),
|
wire.Bind(new(plugins.BackendFactoryProvider), new(*provider.Service)),
|
||||||
acdb.ProvideService,
|
acdb.ProvideService,
|
||||||
wire.Bind(new(resourcepermissions.Store), new(*acdb.AccessControlStore)),
|
|
||||||
wire.Bind(new(accesscontrol.PermissionsStore), new(*acdb.AccessControlStore)),
|
wire.Bind(new(accesscontrol.PermissionsStore), new(*acdb.AccessControlStore)),
|
||||||
osskmsproviders.ProvideService,
|
osskmsproviders.ProvideService,
|
||||||
wire.Bind(new(kmsproviders.Service), new(osskmsproviders.Service)),
|
wire.Bind(new(kmsproviders.Service), new(osskmsproviders.Service)),
|
||||||
|
|||||||
@@ -111,26 +111,6 @@ func userRolesFilter(orgID, userID int64, teamIDs []int64, roles []string) (stri
|
|||||||
return "INNER JOIN (" + builder.String() + ") as all_role ON role.id = all_role.role_id", params
|
return "INNER JOIN (" + builder.String() + ") as all_role ON role.id = all_role.role_id", params
|
||||||
}
|
}
|
||||||
|
|
||||||
func deletePermissions(sess *sqlstore.DBSession, ids []int64) error {
|
|
||||||
if len(ids) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rawSQL := "DELETE FROM permission WHERE id IN(?" + strings.Repeat(",?", len(ids)-1) + ")"
|
|
||||||
args := make([]interface{}, 0, len(ids)+1)
|
|
||||||
args = append(args, rawSQL)
|
|
||||||
for _, id := range ids {
|
|
||||||
args = append(args, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := sess.Exec(args...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AccessControlStore) DeleteUserPermissions(ctx context.Context, orgID, userID int64) error {
|
func (s *AccessControlStore) DeleteUserPermissions(ctx context.Context, orgID, userID int64) error {
|
||||||
err := s.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := s.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
roleDeleteQuery := "DELETE FROM user_role WHERE user_id = ?"
|
roleDeleteQuery := "DELETE FROM user_role WHERE user_id = ?"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
|
rs "github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
@@ -79,12 +79,12 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
store, sql := setupTestEnv(t)
|
store, permissionStore, sql := setupTestEnv(t)
|
||||||
|
|
||||||
user, team := createUserAndTeam(t, sql, tt.orgID)
|
user, team := createUserAndTeam(t, sql, tt.orgID)
|
||||||
|
|
||||||
for _, id := range tt.userPermissions {
|
for _, id := range tt.userPermissions {
|
||||||
_, err := store.SetUserResourcePermission(context.Background(), tt.orgID, accesscontrol.User{ID: user.ID}, types.SetResourcePermissionCommand{
|
_, err := permissionStore.SetUserResourcePermission(context.Background(), tt.orgID, accesscontrol.User{ID: user.ID}, rs.SetResourcePermissionCommand{
|
||||||
Actions: []string{"dashboards:write"},
|
Actions: []string{"dashboards:write"},
|
||||||
Resource: "dashboards",
|
Resource: "dashboards",
|
||||||
ResourceID: id,
|
ResourceID: id,
|
||||||
@@ -93,7 +93,7 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, id := range tt.teamPermissions {
|
for _, id := range tt.teamPermissions {
|
||||||
_, err := store.SetTeamResourcePermission(context.Background(), tt.orgID, team.Id, types.SetResourcePermissionCommand{
|
_, err := permissionStore.SetTeamResourcePermission(context.Background(), tt.orgID, team.Id, rs.SetResourcePermissionCommand{
|
||||||
Actions: []string{"dashboards:read"},
|
Actions: []string{"dashboards:read"},
|
||||||
Resource: "dashboards",
|
Resource: "dashboards",
|
||||||
ResourceID: id,
|
ResourceID: id,
|
||||||
@@ -102,7 +102,7 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, id := range tt.builtinPermissions {
|
for _, id := range tt.builtinPermissions {
|
||||||
_, err := store.SetBuiltInResourcePermission(context.Background(), tt.orgID, "Admin", types.SetResourcePermissionCommand{
|
_, err := permissionStore.SetBuiltInResourcePermission(context.Background(), tt.orgID, "Admin", rs.SetResourcePermissionCommand{
|
||||||
Actions: []string{"dashboards:read"},
|
Actions: []string{"dashboards:read"},
|
||||||
Resource: "dashboards",
|
Resource: "dashboards",
|
||||||
ResourceID: id,
|
ResourceID: id,
|
||||||
@@ -142,11 +142,11 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
|
|||||||
|
|
||||||
func TestAccessControlStore_DeleteUserPermissions(t *testing.T) {
|
func TestAccessControlStore_DeleteUserPermissions(t *testing.T) {
|
||||||
t.Run("expect permissions in all orgs to be deleted", func(t *testing.T) {
|
t.Run("expect permissions in all orgs to be deleted", func(t *testing.T) {
|
||||||
store, sql := setupTestEnv(t)
|
store, permissionsStore, sql := setupTestEnv(t)
|
||||||
user, _ := createUserAndTeam(t, sql, 1)
|
user, _ := createUserAndTeam(t, sql, 1)
|
||||||
|
|
||||||
// generate permissions in org 1
|
// generate permissions in org 1
|
||||||
_, err := store.SetUserResourcePermission(context.Background(), 1, accesscontrol.User{ID: user.ID}, types.SetResourcePermissionCommand{
|
_, err := permissionsStore.SetUserResourcePermission(context.Background(), 1, accesscontrol.User{ID: user.ID}, rs.SetResourcePermissionCommand{
|
||||||
Actions: []string{"dashboards:write"},
|
Actions: []string{"dashboards:write"},
|
||||||
Resource: "dashboards",
|
Resource: "dashboards",
|
||||||
ResourceID: "1",
|
ResourceID: "1",
|
||||||
@@ -154,7 +154,7 @@ func TestAccessControlStore_DeleteUserPermissions(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// generate permissions in org 2
|
// generate permissions in org 2
|
||||||
_, err = store.SetUserResourcePermission(context.Background(), 2, accesscontrol.User{ID: user.ID}, types.SetResourcePermissionCommand{
|
_, err = permissionsStore.SetUserResourcePermission(context.Background(), 2, accesscontrol.User{ID: user.ID}, rs.SetResourcePermissionCommand{
|
||||||
Actions: []string{"dashboards:write"},
|
Actions: []string{"dashboards:write"},
|
||||||
Resource: "dashboards",
|
Resource: "dashboards",
|
||||||
ResourceID: "1",
|
ResourceID: "1",
|
||||||
@@ -182,11 +182,11 @@ func TestAccessControlStore_DeleteUserPermissions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("expect permissions in org 1 to be deleted", func(t *testing.T) {
|
t.Run("expect permissions in org 1 to be deleted", func(t *testing.T) {
|
||||||
store, sql := setupTestEnv(t)
|
store, permissionsStore, sql := setupTestEnv(t)
|
||||||
user, _ := createUserAndTeam(t, sql, 1)
|
user, _ := createUserAndTeam(t, sql, 1)
|
||||||
|
|
||||||
// generate permissions in org 1
|
// generate permissions in org 1
|
||||||
_, err := store.SetUserResourcePermission(context.Background(), 1, accesscontrol.User{ID: user.ID}, types.SetResourcePermissionCommand{
|
_, err := permissionsStore.SetUserResourcePermission(context.Background(), 1, accesscontrol.User{ID: user.ID}, rs.SetResourcePermissionCommand{
|
||||||
Actions: []string{"dashboards:write"},
|
Actions: []string{"dashboards:write"},
|
||||||
Resource: "dashboards",
|
Resource: "dashboards",
|
||||||
ResourceID: "1",
|
ResourceID: "1",
|
||||||
@@ -194,7 +194,7 @@ func TestAccessControlStore_DeleteUserPermissions(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// generate permissions in org 2
|
// generate permissions in org 2
|
||||||
_, err = store.SetUserResourcePermission(context.Background(), 2, accesscontrol.User{ID: user.ID}, types.SetResourcePermissionCommand{
|
_, err = permissionsStore.SetUserResourcePermission(context.Background(), 2, accesscontrol.User{ID: user.ID}, rs.SetResourcePermissionCommand{
|
||||||
Actions: []string{"dashboards:write"},
|
Actions: []string{"dashboards:write"},
|
||||||
Resource: "dashboards",
|
Resource: "dashboards",
|
||||||
ResourceID: "1",
|
ResourceID: "1",
|
||||||
@@ -240,7 +240,9 @@ func createUserAndTeam(t *testing.T, sql *sqlstore.SQLStore, orgID int64) (*user
|
|||||||
return user, team
|
return user, team
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTestEnv(t testing.TB) (*AccessControlStore, *sqlstore.SQLStore) {
|
func setupTestEnv(t testing.TB) (*AccessControlStore, rs.Store, *sqlstore.SQLStore) {
|
||||||
store := sqlstore.InitTestDB(t)
|
sql := sqlstore.InitTestDB(t)
|
||||||
return ProvideService(store), store
|
acstore := ProvideService(sql)
|
||||||
|
permissionStore := rs.NewStore(sql)
|
||||||
|
return acstore, permissionStore, sql
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
|
||||||
"github.com/grafana/grafana/pkg/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
func generateNewRoleUID(sess *sqlstore.DBSession, orgID int64) (string, error) {
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
uid := util.GenerateShortUID()
|
|
||||||
|
|
||||||
exists, err := sess.Where("org_id=? AND uid=?", orgID, uid).Get(&accesscontrol.Role{})
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !exists {
|
|
||||||
return uid, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", fmt.Errorf("failed to generate uid")
|
|
||||||
}
|
|
||||||
@@ -37,7 +37,7 @@ var (
|
|||||||
|
|
||||||
func ProvideTeamPermissions(
|
func ProvideTeamPermissions(
|
||||||
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
|
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
|
||||||
ac accesscontrol.AccessControl, store resourcepermissions.Store, license models.Licensing,
|
ac accesscontrol.AccessControl, license models.Licensing,
|
||||||
) (*TeamPermissionsService, error) {
|
) (*TeamPermissionsService, error) {
|
||||||
options := resourcepermissions.Options{
|
options := resourcepermissions.Options{
|
||||||
Resource: "teams",
|
Resource: "teams",
|
||||||
@@ -93,7 +93,7 @@ func ProvideTeamPermissions(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
srv, err := resourcepermissions.New(options, cfg, router, license, ac, store, sql)
|
srv, err := resourcepermissions.New(options, cfg, router, license, ac, sql)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -110,8 +110,7 @@ var DashboardAdminActions = append(DashboardEditActions, []string{dashboards.Act
|
|||||||
|
|
||||||
func ProvideDashboardPermissions(
|
func ProvideDashboardPermissions(
|
||||||
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
|
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
|
||||||
ac accesscontrol.AccessControl, store resourcepermissions.Store,
|
ac accesscontrol.AccessControl, license models.Licensing, dashboardStore dashboards.Store,
|
||||||
license models.Licensing, dashboardStore dashboards.Store,
|
|
||||||
) (*DashboardPermissionsService, error) {
|
) (*DashboardPermissionsService, error) {
|
||||||
getDashboard := func(ctx context.Context, orgID int64, resourceID string) (*models.Dashboard, error) {
|
getDashboard := func(ctx context.Context, orgID int64, resourceID string) (*models.Dashboard, error) {
|
||||||
query := &models.GetDashboardQuery{Uid: resourceID, OrgId: orgID}
|
query := &models.GetDashboardQuery{Uid: resourceID, OrgId: orgID}
|
||||||
@@ -165,7 +164,7 @@ func ProvideDashboardPermissions(
|
|||||||
RoleGroup: "Dashboards",
|
RoleGroup: "Dashboards",
|
||||||
}
|
}
|
||||||
|
|
||||||
srv, err := resourcepermissions.New(options, cfg, router, license, ac, store, sql)
|
srv, err := resourcepermissions.New(options, cfg, router, license, ac, sql)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -189,8 +188,7 @@ var FolderAdminActions = append(FolderEditActions, []string{dashboards.ActionFol
|
|||||||
|
|
||||||
func ProvideFolderPermissions(
|
func ProvideFolderPermissions(
|
||||||
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
|
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
|
||||||
accesscontrol accesscontrol.AccessControl, store resourcepermissions.Store,
|
accesscontrol accesscontrol.AccessControl, license models.Licensing, dashboardStore dashboards.Store,
|
||||||
license models.Licensing, dashboardStore dashboards.Store,
|
|
||||||
) (*FolderPermissionsService, error) {
|
) (*FolderPermissionsService, error) {
|
||||||
options := resourcepermissions.Options{
|
options := resourcepermissions.Options{
|
||||||
Resource: "folders",
|
Resource: "folders",
|
||||||
@@ -221,7 +219,7 @@ func ProvideFolderPermissions(
|
|||||||
WriterRoleName: "Folder permission writer",
|
WriterRoleName: "Folder permission writer",
|
||||||
RoleGroup: "Folders",
|
RoleGroup: "Folders",
|
||||||
}
|
}
|
||||||
srv, err := resourcepermissions.New(options, cfg, router, license, accesscontrol, store, sql)
|
srv, err := resourcepermissions.New(options, cfg, router, license, accesscontrol, sql)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -266,8 +264,7 @@ type ServiceAccountPermissionsService struct {
|
|||||||
|
|
||||||
func ProvideServiceAccountPermissions(
|
func ProvideServiceAccountPermissions(
|
||||||
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
|
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
|
||||||
ac accesscontrol.AccessControl, store resourcepermissions.Store,
|
ac accesscontrol.AccessControl, license models.Licensing, serviceAccountStore serviceaccounts.Store,
|
||||||
license models.Licensing, serviceAccountStore serviceaccounts.Store,
|
|
||||||
) (*ServiceAccountPermissionsService, error) {
|
) (*ServiceAccountPermissionsService, error) {
|
||||||
options := resourcepermissions.Options{
|
options := resourcepermissions.Options{
|
||||||
Resource: "serviceaccounts",
|
Resource: "serviceaccounts",
|
||||||
@@ -294,7 +291,7 @@ func ProvideServiceAccountPermissions(
|
|||||||
RoleGroup: "Service accounts",
|
RoleGroup: "Service accounts",
|
||||||
}
|
}
|
||||||
|
|
||||||
srv, err := resourcepermissions.New(options, cfg, router, license, ac, store, sql)
|
srv, err := resourcepermissions.New(options, cfg, router, license, ac, sql)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package types
|
package resourcepermissions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package types
|
package resourcepermissions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
|
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
@@ -20,37 +19,37 @@ type Store interface {
|
|||||||
SetUserResourcePermission(
|
SetUserResourcePermission(
|
||||||
ctx context.Context, orgID int64,
|
ctx context.Context, orgID int64,
|
||||||
user accesscontrol.User,
|
user accesscontrol.User,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.UserResourceHookFunc,
|
hook UserResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error)
|
) (*accesscontrol.ResourcePermission, error)
|
||||||
|
|
||||||
// SetTeamResourcePermission sets permission for managed team role on a resource
|
// SetTeamResourcePermission sets permission for managed team role on a resource
|
||||||
SetTeamResourcePermission(
|
SetTeamResourcePermission(
|
||||||
ctx context.Context, orgID, teamID int64,
|
ctx context.Context, orgID, teamID int64,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.TeamResourceHookFunc,
|
hook TeamResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error)
|
) (*accesscontrol.ResourcePermission, error)
|
||||||
|
|
||||||
// SetBuiltInResourcePermission sets permissions for managed builtin role on a resource
|
// SetBuiltInResourcePermission sets permissions for managed builtin role on a resource
|
||||||
SetBuiltInResourcePermission(
|
SetBuiltInResourcePermission(
|
||||||
ctx context.Context, orgID int64, builtinRole string,
|
ctx context.Context, orgID int64, builtinRole string,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.BuiltinResourceHookFunc,
|
hook BuiltinResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error)
|
) (*accesscontrol.ResourcePermission, error)
|
||||||
|
|
||||||
SetResourcePermissions(
|
SetResourcePermissions(
|
||||||
ctx context.Context, orgID int64,
|
ctx context.Context, orgID int64,
|
||||||
commands []types.SetResourcePermissionsCommand,
|
commands []SetResourcePermissionsCommand,
|
||||||
hooks types.ResourceHooks,
|
hooks ResourceHooks,
|
||||||
) ([]accesscontrol.ResourcePermission, error)
|
) ([]accesscontrol.ResourcePermission, error)
|
||||||
|
|
||||||
// GetResourcePermissions will return all permission for supplied resource id
|
// GetResourcePermissions will return all permission for supplied resource id
|
||||||
GetResourcePermissions(ctx context.Context, orgID int64, query types.GetResourcePermissionsQuery) ([]accesscontrol.ResourcePermission, error)
|
GetResourcePermissions(ctx context.Context, orgID int64, query GetResourcePermissionsQuery) ([]accesscontrol.ResourcePermission, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(
|
func New(
|
||||||
options Options, cfg *setting.Cfg, router routing.RouteRegister, license models.Licensing,
|
options Options, cfg *setting.Cfg, router routing.RouteRegister,
|
||||||
ac accesscontrol.AccessControl, store Store, sqlStore *sqlstore.SQLStore,
|
license models.Licensing, ac accesscontrol.AccessControl, sqlStore *sqlstore.SQLStore,
|
||||||
) (*Service, error) {
|
) (*Service, error) {
|
||||||
var permissions []string
|
var permissions []string
|
||||||
actionSet := make(map[string]struct{})
|
actionSet := make(map[string]struct{})
|
||||||
@@ -74,7 +73,7 @@ func New(
|
|||||||
s := &Service{
|
s := &Service{
|
||||||
ac: ac,
|
ac: ac,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
store: store,
|
store: NewStore(sqlStore),
|
||||||
options: options,
|
options: options,
|
||||||
license: license,
|
license: license,
|
||||||
permissions: permissions,
|
permissions: permissions,
|
||||||
@@ -117,7 +116,7 @@ func (s *Service) GetPermissions(ctx context.Context, user *user.SignedInUser, r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.store.GetResourcePermissions(ctx, user.OrgID, types.GetResourcePermissionsQuery{
|
return s.store.GetResourcePermissions(ctx, user.OrgID, GetResourcePermissionsQuery{
|
||||||
User: user,
|
User: user,
|
||||||
Actions: s.actions,
|
Actions: s.actions,
|
||||||
Resource: s.options.Resource,
|
Resource: s.options.Resource,
|
||||||
@@ -142,7 +141,7 @@ func (s *Service) SetUserPermission(ctx context.Context, orgID int64, user acces
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.store.SetUserResourcePermission(ctx, orgID, user, types.SetResourcePermissionCommand{
|
return s.store.SetUserResourcePermission(ctx, orgID, user, SetResourcePermissionCommand{
|
||||||
Actions: actions,
|
Actions: actions,
|
||||||
Permission: permission,
|
Permission: permission,
|
||||||
Resource: s.options.Resource,
|
Resource: s.options.Resource,
|
||||||
@@ -165,7 +164,7 @@ func (s *Service) SetTeamPermission(ctx context.Context, orgID, teamID int64, re
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.store.SetTeamResourcePermission(ctx, orgID, teamID, types.SetResourcePermissionCommand{
|
return s.store.SetTeamResourcePermission(ctx, orgID, teamID, SetResourcePermissionCommand{
|
||||||
Actions: actions,
|
Actions: actions,
|
||||||
Permission: permission,
|
Permission: permission,
|
||||||
Resource: s.options.Resource,
|
Resource: s.options.Resource,
|
||||||
@@ -188,7 +187,7 @@ func (s *Service) SetBuiltInRolePermission(ctx context.Context, orgID int64, bui
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.store.SetBuiltInResourcePermission(ctx, orgID, builtInRole, types.SetResourcePermissionCommand{
|
return s.store.SetBuiltInResourcePermission(ctx, orgID, builtInRole, SetResourcePermissionCommand{
|
||||||
Actions: actions,
|
Actions: actions,
|
||||||
Permission: permission,
|
Permission: permission,
|
||||||
Resource: s.options.Resource,
|
Resource: s.options.Resource,
|
||||||
@@ -205,7 +204,7 @@ func (s *Service) SetPermissions(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dbCommands := make([]types.SetResourcePermissionsCommand, 0, len(commands))
|
dbCommands := make([]SetResourcePermissionsCommand, 0, len(commands))
|
||||||
for _, cmd := range commands {
|
for _, cmd := range commands {
|
||||||
if cmd.UserID != 0 {
|
if cmd.UserID != 0 {
|
||||||
if err := s.validateUser(ctx, orgID, cmd.UserID); err != nil {
|
if err := s.validateUser(ctx, orgID, cmd.UserID); err != nil {
|
||||||
@@ -226,11 +225,11 @@ func (s *Service) SetPermissions(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dbCommands = append(dbCommands, types.SetResourcePermissionsCommand{
|
dbCommands = append(dbCommands, SetResourcePermissionsCommand{
|
||||||
User: accesscontrol.User{ID: cmd.UserID},
|
User: accesscontrol.User{ID: cmd.UserID},
|
||||||
TeamID: cmd.TeamID,
|
TeamID: cmd.TeamID,
|
||||||
BuiltinRole: cmd.BuiltinRole,
|
BuiltinRole: cmd.BuiltinRole,
|
||||||
SetResourcePermissionCommand: types.SetResourcePermissionCommand{
|
SetResourcePermissionCommand: SetResourcePermissionCommand{
|
||||||
Actions: actions,
|
Actions: actions,
|
||||||
Resource: s.options.Resource,
|
Resource: s.options.Resource,
|
||||||
ResourceID: resourceID,
|
ResourceID: resourceID,
|
||||||
@@ -240,7 +239,7 @@ func (s *Service) SetPermissions(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.store.SetResourcePermissions(ctx, orgID, dbCommands, types.ResourceHooks{
|
return s.store.SetResourcePermissions(ctx, orgID, dbCommands, ResourceHooks{
|
||||||
User: s.options.OnSetUser,
|
User: s.options.OnSetUser,
|
||||||
Team: s.options.OnSetTeam,
|
Team: s.options.OnSetTeam,
|
||||||
BuiltInRole: s.options.OnSetBuiltInRole,
|
BuiltInRole: s.options.OnSetBuiltInRole,
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
|
||||||
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
"github.com/grafana/grafana/pkg/services/licensing/licensingtest"
|
"github.com/grafana/grafana/pkg/services/licensing/licensingtest"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
@@ -220,13 +219,12 @@ func setupTestEnvironment(t *testing.T, permissions []accesscontrol.Permission,
|
|||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
sql := sqlstore.InitTestDB(t)
|
sql := sqlstore.InitTestDB(t)
|
||||||
store := database.ProvideService(sql)
|
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
license := licensingtest.NewFakeLicensing()
|
license := licensingtest.NewFakeLicensing()
|
||||||
license.On("FeatureEnabled", "accesscontrol.enforcement").Return(true).Maybe()
|
license.On("FeatureEnabled", "accesscontrol.enforcement").Return(true).Maybe()
|
||||||
service, err := New(
|
service, err := New(
|
||||||
ops, cfg, routing.NewRouteRegister(), license,
|
ops, cfg, routing.NewRouteRegister(), license,
|
||||||
accesscontrolmock.New().WithPermissions(permissions), store, sql,
|
accesscontrolmock.New().WithPermissions(permissions), sql,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package resourcepermissions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -6,14 +6,23 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
|
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewStore(sql *sqlstore.SQLStore) *store {
|
||||||
|
return &store{sql}
|
||||||
|
}
|
||||||
|
|
||||||
|
type store struct {
|
||||||
|
sql *sqlstore.SQLStore
|
||||||
|
}
|
||||||
|
|
||||||
type flatResourcePermission struct {
|
type flatResourcePermission struct {
|
||||||
ID int64 `xorm:"id"`
|
ID int64 `xorm:"id"`
|
||||||
RoleName string
|
RoleName string
|
||||||
@@ -38,10 +47,10 @@ func (p *flatResourcePermission) IsInherited(scope string) bool {
|
|||||||
return p.Scope != scope
|
return p.Scope != scope
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) SetUserResourcePermission(
|
func (s *store) SetUserResourcePermission(
|
||||||
ctx context.Context, orgID int64, usr accesscontrol.User,
|
ctx context.Context, orgID int64, usr accesscontrol.User,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.UserResourceHookFunc,
|
hook UserResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error) {
|
) (*accesscontrol.ResourcePermission, error) {
|
||||||
if usr.ID == 0 {
|
if usr.ID == 0 {
|
||||||
return nil, user.ErrUserNotFound
|
return nil, user.ErrUserNotFound
|
||||||
@@ -56,10 +65,10 @@ func (s *AccessControlStore) SetUserResourcePermission(
|
|||||||
|
|
||||||
return permission, err
|
return permission, err
|
||||||
}
|
}
|
||||||
func (s *AccessControlStore) setUserResourcePermission(
|
func (s *store) setUserResourcePermission(
|
||||||
sess *sqlstore.DBSession, orgID int64, user accesscontrol.User,
|
sess *sqlstore.DBSession, orgID int64, user accesscontrol.User,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.UserResourceHookFunc,
|
hook UserResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error) {
|
) (*accesscontrol.ResourcePermission, error) {
|
||||||
permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedUserRoleName(user.ID), s.userAdder(sess, orgID, user.ID), cmd)
|
permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedUserRoleName(user.ID), s.userAdder(sess, orgID, user.ID), cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -75,10 +84,10 @@ func (s *AccessControlStore) setUserResourcePermission(
|
|||||||
return permission, nil
|
return permission, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) SetTeamResourcePermission(
|
func (s *store) SetTeamResourcePermission(
|
||||||
ctx context.Context, orgID, teamID int64,
|
ctx context.Context, orgID, teamID int64,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.TeamResourceHookFunc,
|
hook TeamResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error) {
|
) (*accesscontrol.ResourcePermission, error) {
|
||||||
if teamID == 0 {
|
if teamID == 0 {
|
||||||
return nil, models.ErrTeamNotFound
|
return nil, models.ErrTeamNotFound
|
||||||
@@ -95,10 +104,10 @@ func (s *AccessControlStore) SetTeamResourcePermission(
|
|||||||
return permission, err
|
return permission, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) setTeamResourcePermission(
|
func (s *store) setTeamResourcePermission(
|
||||||
sess *sqlstore.DBSession, orgID, teamID int64,
|
sess *sqlstore.DBSession, orgID, teamID int64,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.TeamResourceHookFunc,
|
hook TeamResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error) {
|
) (*accesscontrol.ResourcePermission, error) {
|
||||||
permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedTeamRoleName(teamID), s.teamAdder(sess, orgID, teamID), cmd)
|
permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedTeamRoleName(teamID), s.teamAdder(sess, orgID, teamID), cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -114,10 +123,10 @@ func (s *AccessControlStore) setTeamResourcePermission(
|
|||||||
return permission, nil
|
return permission, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) SetBuiltInResourcePermission(
|
func (s *store) SetBuiltInResourcePermission(
|
||||||
ctx context.Context, orgID int64, builtInRole string,
|
ctx context.Context, orgID int64, builtInRole string,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.BuiltinResourceHookFunc,
|
hook BuiltinResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error) {
|
) (*accesscontrol.ResourcePermission, error) {
|
||||||
if !org.RoleType(builtInRole).IsValid() || builtInRole == accesscontrol.RoleGrafanaAdmin {
|
if !org.RoleType(builtInRole).IsValid() || builtInRole == accesscontrol.RoleGrafanaAdmin {
|
||||||
return nil, fmt.Errorf("invalid role: %s", builtInRole)
|
return nil, fmt.Errorf("invalid role: %s", builtInRole)
|
||||||
@@ -138,10 +147,10 @@ func (s *AccessControlStore) SetBuiltInResourcePermission(
|
|||||||
return permission, nil
|
return permission, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) setBuiltInResourcePermission(
|
func (s *store) setBuiltInResourcePermission(
|
||||||
sess *sqlstore.DBSession, orgID int64, builtInRole string,
|
sess *sqlstore.DBSession, orgID int64, builtInRole string,
|
||||||
cmd types.SetResourcePermissionCommand,
|
cmd SetResourcePermissionCommand,
|
||||||
hook types.BuiltinResourceHookFunc,
|
hook BuiltinResourceHookFunc,
|
||||||
) (*accesscontrol.ResourcePermission, error) {
|
) (*accesscontrol.ResourcePermission, error) {
|
||||||
permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedBuiltInRoleName(builtInRole), s.builtInRoleAdder(sess, orgID, builtInRole), cmd)
|
permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedBuiltInRoleName(builtInRole), s.builtInRoleAdder(sess, orgID, builtInRole), cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -157,10 +166,10 @@ func (s *AccessControlStore) setBuiltInResourcePermission(
|
|||||||
return permission, nil
|
return permission, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) SetResourcePermissions(
|
func (s *store) SetResourcePermissions(
|
||||||
ctx context.Context, orgID int64,
|
ctx context.Context, orgID int64,
|
||||||
commands []types.SetResourcePermissionsCommand,
|
commands []SetResourcePermissionsCommand,
|
||||||
hooks types.ResourceHooks,
|
hooks ResourceHooks,
|
||||||
) ([]accesscontrol.ResourcePermission, error) {
|
) ([]accesscontrol.ResourcePermission, error) {
|
||||||
var err error
|
var err error
|
||||||
var permissions []accesscontrol.ResourcePermission
|
var permissions []accesscontrol.ResourcePermission
|
||||||
@@ -191,8 +200,8 @@ func (s *AccessControlStore) SetResourcePermissions(
|
|||||||
|
|
||||||
type roleAdder func(roleID int64) error
|
type roleAdder func(roleID int64) error
|
||||||
|
|
||||||
func (s *AccessControlStore) setResourcePermission(
|
func (s *store) setResourcePermission(
|
||||||
sess *sqlstore.DBSession, orgID int64, roleName string, adder roleAdder, cmd types.SetResourcePermissionCommand,
|
sess *sqlstore.DBSession, orgID int64, roleName string, adder roleAdder, cmd SetResourcePermissionCommand,
|
||||||
) (*accesscontrol.ResourcePermission, error) {
|
) (*accesscontrol.ResourcePermission, error) {
|
||||||
role, err := s.getOrCreateManagedRole(sess, orgID, roleName, adder)
|
role, err := s.getOrCreateManagedRole(sess, orgID, roleName, adder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -255,7 +264,7 @@ func (s *AccessControlStore) setResourcePermission(
|
|||||||
return permission, nil
|
return permission, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) GetResourcePermissions(ctx context.Context, orgID int64, query types.GetResourcePermissionsQuery) ([]accesscontrol.ResourcePermission, error) {
|
func (s *store) GetResourcePermissions(ctx context.Context, orgID int64, query GetResourcePermissionsQuery) ([]accesscontrol.ResourcePermission, error) {
|
||||||
var result []accesscontrol.ResourcePermission
|
var result []accesscontrol.ResourcePermission
|
||||||
|
|
||||||
err := s.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := s.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
@@ -267,7 +276,7 @@ func (s *AccessControlStore) GetResourcePermissions(ctx context.Context, orgID i
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) createResourcePermission(sess *sqlstore.DBSession, roleID int64, action, resource, resourceID, resourceAttribute string) (int64, error) {
|
func (s *store) createResourcePermission(sess *sqlstore.DBSession, roleID int64, action, resource, resourceID, resourceAttribute string) (int64, error) {
|
||||||
permission := managedPermission(action, resource, resourceID, resourceAttribute)
|
permission := managedPermission(action, resource, resourceID, resourceAttribute)
|
||||||
permission.RoleID = roleID
|
permission.RoleID = roleID
|
||||||
permission.Created = time.Now()
|
permission.Created = time.Now()
|
||||||
@@ -279,7 +288,7 @@ func (s *AccessControlStore) createResourcePermission(sess *sqlstore.DBSession,
|
|||||||
return permission.ID, nil
|
return permission.ID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) getResourcePermissions(sess *sqlstore.DBSession, orgID int64, query types.GetResourcePermissionsQuery) ([]accesscontrol.ResourcePermission, error) {
|
func (s *store) getResourcePermissions(sess *sqlstore.DBSession, orgID int64, query GetResourcePermissionsQuery) ([]accesscontrol.ResourcePermission, error) {
|
||||||
if len(query.Actions) == 0 {
|
if len(query.Actions) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -476,7 +485,7 @@ func flatPermissionsToResourcePermission(scope string, permissions []flatResourc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) userAdder(sess *sqlstore.DBSession, orgID, userID int64) roleAdder {
|
func (s *store) userAdder(sess *sqlstore.DBSession, orgID, userID int64) roleAdder {
|
||||||
return func(roleID int64) error {
|
return func(roleID int64) error {
|
||||||
if res, err := sess.Query("SELECT 1 FROM user_role WHERE org_id=? AND user_id=? AND role_id=?", orgID, userID, roleID); err != nil {
|
if res, err := sess.Query("SELECT 1 FROM user_role WHERE org_id=? AND user_id=? AND role_id=?", orgID, userID, roleID); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -497,7 +506,7 @@ func (s *AccessControlStore) userAdder(sess *sqlstore.DBSession, orgID, userID i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) teamAdder(sess *sqlstore.DBSession, orgID, teamID int64) roleAdder {
|
func (s *store) teamAdder(sess *sqlstore.DBSession, orgID, teamID int64) roleAdder {
|
||||||
return func(roleID int64) error {
|
return func(roleID int64) error {
|
||||||
if res, err := sess.Query("SELECT 1 FROM team_role WHERE org_id=? AND team_id=? AND role_id=?", orgID, teamID, roleID); err != nil {
|
if res, err := sess.Query("SELECT 1 FROM team_role WHERE org_id=? AND team_id=? AND role_id=?", orgID, teamID, roleID); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -517,7 +526,7 @@ func (s *AccessControlStore) teamAdder(sess *sqlstore.DBSession, orgID, teamID i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) builtInRoleAdder(sess *sqlstore.DBSession, orgID int64, builtinRole string) roleAdder {
|
func (s *store) builtInRoleAdder(sess *sqlstore.DBSession, orgID int64, builtinRole string) roleAdder {
|
||||||
return func(roleID int64) error {
|
return func(roleID int64) error {
|
||||||
if res, err := sess.Query("SELECT 1 FROM builtin_role WHERE role_id=? AND role=? AND org_id=?", roleID, builtinRole, orgID); err != nil {
|
if res, err := sess.Query("SELECT 1 FROM builtin_role WHERE role_id=? AND role=? AND org_id=?", roleID, builtinRole, orgID); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -537,7 +546,7 @@ func (s *AccessControlStore) builtInRoleAdder(sess *sqlstore.DBSession, orgID in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) getOrCreateManagedRole(sess *sqlstore.DBSession, orgID int64, name string, add roleAdder) (*accesscontrol.Role, error) {
|
func (s *store) getOrCreateManagedRole(sess *sqlstore.DBSession, orgID int64, name string, add roleAdder) (*accesscontrol.Role, error) {
|
||||||
role := accesscontrol.Role{OrgID: orgID, Name: name}
|
role := accesscontrol.Role{OrgID: orgID, Name: name}
|
||||||
has, err := sess.Where("org_id = ? AND name = ?", orgID, name).Get(&role)
|
has, err := sess.Where("org_id = ? AND name = ?", orgID, name).Get(&role)
|
||||||
|
|
||||||
@@ -572,7 +581,7 @@ func (s *AccessControlStore) getOrCreateManagedRole(sess *sqlstore.DBSession, or
|
|||||||
return &role, nil
|
return &role, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccessControlStore) getResourcePermissionsByIds(sess *sqlstore.DBSession, resource, resourceID, resourceAttribute string, ids []int64) ([]flatResourcePermission, error) {
|
func (s *store) getResourcePermissionsByIds(sess *sqlstore.DBSession, resource, resourceID, resourceAttribute string, ids []int64) ([]flatResourcePermission, error) {
|
||||||
var result []flatResourcePermission
|
var result []flatResourcePermission
|
||||||
if len(ids) == 0 {
|
if len(ids) == 0 {
|
||||||
return result, nil
|
return result, nil
|
||||||
@@ -610,6 +619,43 @@ func (s *AccessControlStore) getResourcePermissionsByIds(sess *sqlstore.DBSessio
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateNewRoleUID(sess *sqlstore.DBSession, orgID int64) (string, error) {
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
uid := util.GenerateShortUID()
|
||||||
|
|
||||||
|
exists, err := sess.Where("org_id=? AND uid=?", orgID, uid).Get(&accesscontrol.Role{})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return uid, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("failed to generate uid")
|
||||||
|
}
|
||||||
|
|
||||||
|
func deletePermissions(sess *sqlstore.DBSession, ids []int64) error {
|
||||||
|
if len(ids) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rawSQL := "DELETE FROM permission WHERE id IN(?" + strings.Repeat(",?", len(ids)-1) + ")"
|
||||||
|
args := make([]interface{}, 0, len(ids)+1)
|
||||||
|
args = append(args, rawSQL)
|
||||||
|
for _, id := range ids {
|
||||||
|
args = append(args, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := sess.Exec(args...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func managedPermission(action, resource string, resourceID, resourceAttribute string) accesscontrol.Permission {
|
func managedPermission(action, resource string, resourceID, resourceAttribute string) accesscontrol.Permission {
|
||||||
return accesscontrol.Permission{
|
return accesscontrol.Permission{
|
||||||
Action: action,
|
Action: action,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package resourcepermissions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
|
|
||||||
"github.com/grafana/grafana/pkg/services/datasources"
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
@@ -53,10 +52,10 @@ func benchmarkDSPermissions(b *testing.B, dsNum, usersNum int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDSPermissions(b *testing.B, store *AccessControlStore, dataSources []int64) {
|
func getDSPermissions(b *testing.B, store *store, dataSources []int64) {
|
||||||
dsId := dataSources[0]
|
dsId := dataSources[0]
|
||||||
|
|
||||||
permissions, err := store.GetResourcePermissions(context.Background(), accesscontrol.GlobalOrgID, types.GetResourcePermissionsQuery{
|
permissions, err := store.GetResourcePermissions(context.Background(), accesscontrol.GlobalOrgID, GetResourcePermissionsQuery{
|
||||||
User: &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{1: {"org.users:read": {"users:*"}, "teams:read": {"teams:*"}}}},
|
User: &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{1: {"org.users:read": {"users:*"}, "teams:read": {"teams:*"}}}},
|
||||||
Actions: []string{dsAction},
|
Actions: []string{dsAction},
|
||||||
Resource: dsResource,
|
Resource: dsResource,
|
||||||
@@ -67,13 +66,13 @@ func getDSPermissions(b *testing.B, store *AccessControlStore, dataSources []int
|
|||||||
assert.GreaterOrEqual(b, len(permissions), 2)
|
assert.GreaterOrEqual(b, len(permissions), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupResourceBenchmark(b *testing.B, dsNum, usersNum int) (*AccessControlStore, []int64) {
|
func setupResourceBenchmark(b *testing.B, dsNum, usersNum int) (*store, []int64) {
|
||||||
ac, sql := setupTestEnv(b)
|
ac, sql := setupTestEnv(b)
|
||||||
dataSources := GenerateDatasourcePermissions(b, sql, ac, dsNum, usersNum, permissionsPerDs)
|
dataSources := GenerateDatasourcePermissions(b, sql, ac, dsNum, usersNum, permissionsPerDs)
|
||||||
return ac, dataSources
|
return ac, dataSources
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateDatasourcePermissions(b *testing.B, db *sqlstore.SQLStore, ac *AccessControlStore, dsNum, usersNum, permissionsPerDs int) []int64 {
|
func GenerateDatasourcePermissions(b *testing.B, db *sqlstore.SQLStore, ac *store, dsNum, usersNum, permissionsPerDs int) []int64 {
|
||||||
dataSources := make([]int64, 0)
|
dataSources := make([]int64, 0)
|
||||||
for i := 0; i < dsNum; i++ {
|
for i := 0; i < dsNum; i++ {
|
||||||
addDSCommand := &datasources.AddDataSourceCommand{
|
addDSCommand := &datasources.AddDataSourceCommand{
|
||||||
@@ -98,7 +97,7 @@ func GenerateDatasourcePermissions(b *testing.B, db *sqlstore.SQLStore, ac *Acce
|
|||||||
context.Background(),
|
context.Background(),
|
||||||
accesscontrol.GlobalOrgID,
|
accesscontrol.GlobalOrgID,
|
||||||
accesscontrol.User{ID: userIds[i]},
|
accesscontrol.User{ID: userIds[i]},
|
||||||
types.SetResourcePermissionCommand{
|
SetResourcePermissionCommand{
|
||||||
Actions: []string{dsAction},
|
Actions: []string{dsAction},
|
||||||
Resource: dsResource,
|
Resource: dsResource,
|
||||||
ResourceID: strconv.Itoa(int(dsID)),
|
ResourceID: strconv.Itoa(int(dsID)),
|
||||||
@@ -116,7 +115,7 @@ func GenerateDatasourcePermissions(b *testing.B, db *sqlstore.SQLStore, ac *Acce
|
|||||||
context.Background(),
|
context.Background(),
|
||||||
accesscontrol.GlobalOrgID,
|
accesscontrol.GlobalOrgID,
|
||||||
teamIds[i],
|
teamIds[i],
|
||||||
types.SetResourcePermissionCommand{
|
SetResourcePermissionCommand{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
ResourceID: strconv.Itoa(int(dsID)),
|
ResourceID: strconv.Itoa(int(dsID)),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package resourcepermissions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
|
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
)
|
)
|
||||||
@@ -23,10 +22,10 @@ type setUserResourcePermissionTest struct {
|
|||||||
resource string
|
resource string
|
||||||
resourceID string
|
resourceID string
|
||||||
resourceAttribute string
|
resourceAttribute string
|
||||||
seeds []types.SetResourcePermissionCommand
|
seeds []SetResourcePermissionCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessControlStore_SetUserResourcePermission(t *testing.T) {
|
func TestIntegrationStore_SetUserResourcePermission(t *testing.T) {
|
||||||
tests := []setUserResourcePermissionTest{
|
tests := []setUserResourcePermissionTest{
|
||||||
{
|
{
|
||||||
desc: "should set resource permission for user",
|
desc: "should set resource permission for user",
|
||||||
@@ -44,7 +43,7 @@ func TestAccessControlStore_SetUserResourcePermission(t *testing.T) {
|
|||||||
resource: "datasources",
|
resource: "datasources",
|
||||||
resourceID: "1",
|
resourceID: "1",
|
||||||
resourceAttribute: "uid",
|
resourceAttribute: "uid",
|
||||||
seeds: []types.SetResourcePermissionCommand{
|
seeds: []SetResourcePermissionCommand{
|
||||||
{
|
{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
@@ -60,7 +59,7 @@ func TestAccessControlStore_SetUserResourcePermission(t *testing.T) {
|
|||||||
resource: "datasources",
|
resource: "datasources",
|
||||||
resourceID: "1",
|
resourceID: "1",
|
||||||
resourceAttribute: "uid",
|
resourceAttribute: "uid",
|
||||||
seeds: []types.SetResourcePermissionCommand{
|
seeds: []SetResourcePermissionCommand{
|
||||||
{
|
{
|
||||||
Actions: []string{"datasources:write"},
|
Actions: []string{"datasources:write"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
@@ -79,7 +78,7 @@ func TestAccessControlStore_SetUserResourcePermission(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
added, err := store.SetUserResourcePermission(context.Background(), test.userID, accesscontrol.User{ID: test.userID}, types.SetResourcePermissionCommand{
|
added, err := store.SetUserResourcePermission(context.Background(), test.userID, accesscontrol.User{ID: test.userID}, SetResourcePermissionCommand{
|
||||||
Actions: test.actions,
|
Actions: test.actions,
|
||||||
Resource: test.resource,
|
Resource: test.resource,
|
||||||
ResourceID: test.resourceID,
|
ResourceID: test.resourceID,
|
||||||
@@ -105,10 +104,10 @@ type setTeamResourcePermissionTest struct {
|
|||||||
resource string
|
resource string
|
||||||
resourceID string
|
resourceID string
|
||||||
resourceAttribute string
|
resourceAttribute string
|
||||||
seeds []types.SetResourcePermissionCommand
|
seeds []SetResourcePermissionCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessControlStore_SetTeamResourcePermission(t *testing.T) {
|
func TestIntegrationStore_SetTeamResourcePermission(t *testing.T) {
|
||||||
tests := []setTeamResourcePermissionTest{
|
tests := []setTeamResourcePermissionTest{
|
||||||
{
|
{
|
||||||
desc: "should add new resource permission for team",
|
desc: "should add new resource permission for team",
|
||||||
@@ -127,7 +126,7 @@ func TestAccessControlStore_SetTeamResourcePermission(t *testing.T) {
|
|||||||
resource: "datasources",
|
resource: "datasources",
|
||||||
resourceID: "1",
|
resourceID: "1",
|
||||||
resourceAttribute: "uid",
|
resourceAttribute: "uid",
|
||||||
seeds: []types.SetResourcePermissionCommand{
|
seeds: []SetResourcePermissionCommand{
|
||||||
{
|
{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
@@ -144,7 +143,7 @@ func TestAccessControlStore_SetTeamResourcePermission(t *testing.T) {
|
|||||||
resource: "datasources",
|
resource: "datasources",
|
||||||
resourceID: "1",
|
resourceID: "1",
|
||||||
resourceAttribute: "uid",
|
resourceAttribute: "uid",
|
||||||
seeds: []types.SetResourcePermissionCommand{
|
seeds: []SetResourcePermissionCommand{
|
||||||
{
|
{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
@@ -164,7 +163,7 @@ func TestAccessControlStore_SetTeamResourcePermission(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
added, err := store.SetTeamResourcePermission(context.Background(), test.orgID, test.teamID, types.SetResourcePermissionCommand{
|
added, err := store.SetTeamResourcePermission(context.Background(), test.orgID, test.teamID, SetResourcePermissionCommand{
|
||||||
Actions: test.actions,
|
Actions: test.actions,
|
||||||
Resource: test.resource,
|
Resource: test.resource,
|
||||||
ResourceID: test.resourceID,
|
ResourceID: test.resourceID,
|
||||||
@@ -190,10 +189,10 @@ type setBuiltInResourcePermissionTest struct {
|
|||||||
resource string
|
resource string
|
||||||
resourceID string
|
resourceID string
|
||||||
resourceAttribute string
|
resourceAttribute string
|
||||||
seeds []types.SetResourcePermissionCommand
|
seeds []SetResourcePermissionCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessControlStore_SetBuiltInResourcePermission(t *testing.T) {
|
func TestIntegrationStore_SetBuiltInResourcePermission(t *testing.T) {
|
||||||
tests := []setBuiltInResourcePermissionTest{
|
tests := []setBuiltInResourcePermissionTest{
|
||||||
{
|
{
|
||||||
desc: "should add new resource permission for builtin role",
|
desc: "should add new resource permission for builtin role",
|
||||||
@@ -212,7 +211,7 @@ func TestAccessControlStore_SetBuiltInResourcePermission(t *testing.T) {
|
|||||||
resource: "datasources",
|
resource: "datasources",
|
||||||
resourceID: "1",
|
resourceID: "1",
|
||||||
resourceAttribute: "uid",
|
resourceAttribute: "uid",
|
||||||
seeds: []types.SetResourcePermissionCommand{
|
seeds: []SetResourcePermissionCommand{
|
||||||
{
|
{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
@@ -229,7 +228,7 @@ func TestAccessControlStore_SetBuiltInResourcePermission(t *testing.T) {
|
|||||||
resource: "datasources",
|
resource: "datasources",
|
||||||
resourceID: "1",
|
resourceID: "1",
|
||||||
resourceAttribute: "uid",
|
resourceAttribute: "uid",
|
||||||
seeds: []types.SetResourcePermissionCommand{
|
seeds: []SetResourcePermissionCommand{
|
||||||
{
|
{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
@@ -249,7 +248,7 @@ func TestAccessControlStore_SetBuiltInResourcePermission(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
added, err := store.SetBuiltInResourcePermission(context.Background(), test.orgID, test.builtInRole, types.SetResourcePermissionCommand{
|
added, err := store.SetBuiltInResourcePermission(context.Background(), test.orgID, test.builtInRole, SetResourcePermissionCommand{
|
||||||
Actions: test.actions,
|
Actions: test.actions,
|
||||||
Resource: test.resource,
|
Resource: test.resource,
|
||||||
ResourceID: test.resourceID,
|
ResourceID: test.resourceID,
|
||||||
@@ -271,19 +270,19 @@ type setResourcePermissionsTest struct {
|
|||||||
desc string
|
desc string
|
||||||
orgID int64
|
orgID int64
|
||||||
resourceAttribute string
|
resourceAttribute string
|
||||||
commands []types.SetResourcePermissionsCommand
|
commands []SetResourcePermissionsCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessControlStore_SetResourcePermissions(t *testing.T) {
|
func TestIntegrationStore_SetResourcePermissions(t *testing.T) {
|
||||||
tests := []setResourcePermissionsTest{
|
tests := []setResourcePermissionsTest{
|
||||||
{
|
{
|
||||||
desc: "should set all permissions provided",
|
desc: "should set all permissions provided",
|
||||||
orgID: 1,
|
orgID: 1,
|
||||||
resourceAttribute: "uid",
|
resourceAttribute: "uid",
|
||||||
commands: []types.SetResourcePermissionsCommand{
|
commands: []SetResourcePermissionsCommand{
|
||||||
{
|
{
|
||||||
User: accesscontrol.User{ID: 1},
|
User: accesscontrol.User{ID: 1},
|
||||||
SetResourcePermissionCommand: types.SetResourcePermissionCommand{
|
SetResourcePermissionCommand: SetResourcePermissionCommand{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
ResourceID: "1",
|
ResourceID: "1",
|
||||||
@@ -292,7 +291,7 @@ func TestAccessControlStore_SetResourcePermissions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
TeamID: 3,
|
TeamID: 3,
|
||||||
SetResourcePermissionCommand: types.SetResourcePermissionCommand{
|
SetResourcePermissionCommand: SetResourcePermissionCommand{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
ResourceID: "1",
|
ResourceID: "1",
|
||||||
@@ -301,7 +300,7 @@ func TestAccessControlStore_SetResourcePermissions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
BuiltinRole: "Admin",
|
BuiltinRole: "Admin",
|
||||||
SetResourcePermissionCommand: types.SetResourcePermissionCommand{
|
SetResourcePermissionCommand: SetResourcePermissionCommand{
|
||||||
Actions: []string{"datasources:query"},
|
Actions: []string{"datasources:query"},
|
||||||
Resource: "datasources",
|
Resource: "datasources",
|
||||||
ResourceID: "1",
|
ResourceID: "1",
|
||||||
@@ -316,7 +315,7 @@ func TestAccessControlStore_SetResourcePermissions(t *testing.T) {
|
|||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
store, _ := setupTestEnv(t)
|
store, _ := setupTestEnv(t)
|
||||||
|
|
||||||
permissions, err := store.SetResourcePermissions(context.Background(), tt.orgID, tt.commands, types.ResourceHooks{})
|
permissions, err := store.SetResourcePermissions(context.Background(), tt.orgID, tt.commands, ResourceHooks{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, permissions, len(tt.commands))
|
require.Len(t, permissions, len(tt.commands))
|
||||||
@@ -346,7 +345,7 @@ type getResourcePermissionsTest struct {
|
|||||||
onlyManaged bool
|
onlyManaged bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessControlStore_GetResourcePermissions(t *testing.T) {
|
func TestIntegrationStore_GetResourcePermissions(t *testing.T) {
|
||||||
tests := []getResourcePermissionsTest{
|
tests := []getResourcePermissionsTest{
|
||||||
{
|
{
|
||||||
desc: "should return permissions for resource id",
|
desc: "should return permissions for resource id",
|
||||||
@@ -418,7 +417,7 @@ func TestAccessControlStore_GetResourcePermissions(t *testing.T) {
|
|||||||
|
|
||||||
seedResourcePermissions(t, store, sql, test.actions, test.resource, test.resourceID, test.resourceAttribute, test.numUsers)
|
seedResourcePermissions(t, store, sql, test.actions, test.resource, test.resourceID, test.resourceAttribute, test.numUsers)
|
||||||
|
|
||||||
permissions, err := store.GetResourcePermissions(context.Background(), test.user.OrgID, types.GetResourcePermissionsQuery{
|
permissions, err := store.GetResourcePermissions(context.Background(), test.user.OrgID, GetResourcePermissionsQuery{
|
||||||
User: test.user,
|
User: test.user,
|
||||||
Actions: test.actions,
|
Actions: test.actions,
|
||||||
Resource: test.resource,
|
Resource: test.resource,
|
||||||
@@ -437,7 +436,7 @@ func TestAccessControlStore_GetResourcePermissions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func seedResourcePermissions(t *testing.T, store *AccessControlStore, sql *sqlstore.SQLStore, actions []string, resource, resourceID, resourceAttribute string, numUsers int) {
|
func seedResourcePermissions(t *testing.T, store *store, sql *sqlstore.SQLStore, actions []string, resource, resourceID, resourceAttribute string, numUsers int) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
for i := 0; i < numUsers; i++ {
|
for i := 0; i < numUsers; i++ {
|
||||||
org, _ := sql.GetOrgByName("test")
|
org, _ := sql.GetOrgByName("test")
|
||||||
@@ -454,7 +453,7 @@ func seedResourcePermissions(t *testing.T, store *AccessControlStore, sql *sqlst
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = store.SetUserResourcePermission(context.Background(), 1, accesscontrol.User{ID: u.ID}, types.SetResourcePermissionCommand{
|
_, err = store.SetUserResourcePermission(context.Background(), 1, accesscontrol.User{ID: u.ID}, SetResourcePermissionCommand{
|
||||||
Actions: actions,
|
Actions: actions,
|
||||||
Resource: resource,
|
Resource: resource,
|
||||||
ResourceID: resourceID,
|
ResourceID: resourceID,
|
||||||
@@ -463,3 +462,8 @@ func seedResourcePermissions(t *testing.T, store *AccessControlStore, sql *sqlst
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupTestEnv(t testing.TB) (*store, *sqlstore.SQLStore) {
|
||||||
|
sql := sqlstore.InitTestDB(t)
|
||||||
|
return NewStore(sql), sql
|
||||||
|
}
|
||||||
@@ -15,7 +15,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
|
||||||
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
@@ -603,10 +602,10 @@ func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []acce
|
|||||||
license.On("FeatureEnabled", "accesscontrol.enforcement").Return(true).Maybe()
|
license.On("FeatureEnabled", "accesscontrol.enforcement").Return(true).Maybe()
|
||||||
|
|
||||||
folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions(
|
folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions(
|
||||||
setting.NewCfg(), routing.NewRouteRegister(), store, ac, database.ProvideService(store), license, &dashboards.FakeDashboardStore{})
|
setting.NewCfg(), routing.NewRouteRegister(), store, ac, license, &dashboards.FakeDashboardStore{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions(
|
dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions(
|
||||||
setting.NewCfg(), routing.NewRouteRegister(), store, ac, database.ProvideService(store), license, &dashboards.FakeDashboardStore{})
|
setting.NewCfg(), routing.NewRouteRegister(), store, ac, license, &dashboards.FakeDashboardStore{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
if dashboardSvc == nil {
|
if dashboardSvc == nil {
|
||||||
dashboardSvc = &dashboards.FakeDashboardService{}
|
dashboardSvc = &dashboards.FakeDashboardService{}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
acDatabase "github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
|
||||||
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/apikey/apikeyimpl"
|
"github.com/grafana/grafana/pkg/services/apikey/apikeyimpl"
|
||||||
@@ -279,7 +278,7 @@ func setupTestServer(t *testing.T, svc *tests.ServiceAccountMock,
|
|||||||
acmock *accesscontrolmock.Mock,
|
acmock *accesscontrolmock.Mock,
|
||||||
sqlStore *sqlstore.SQLStore, saStore serviceaccounts.Store) (*web.Mux, *ServiceAccountsAPI) {
|
sqlStore *sqlstore.SQLStore, saStore serviceaccounts.Store) (*web.Mux, *ServiceAccountsAPI) {
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
saPermissionService, err := ossaccesscontrol.ProvideServiceAccountPermissions(cfg, routing.NewRouteRegister(), sqlStore, acmock, acDatabase.ProvideService(sqlStore), &licensing.OSSLicensingService{}, saStore)
|
saPermissionService, err := ossaccesscontrol.ProvideServiceAccountPermissions(cfg, routing.NewRouteRegister(), sqlStore, acmock, &licensing.OSSLicensingService{}, saStore)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
a := NewServiceAccountsAPI(cfg, svc, acmock, routerRegister, saStore, saPermissionService)
|
a := NewServiceAccountsAPI(cfg, svc, acmock, routerRegister, saStore, saPermissionService)
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
|
|
||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
@@ -633,7 +632,7 @@ func TestPrometheusRulesPermissions(t *testing.T) {
|
|||||||
apiClient := newAlertingApiClient(grafanaListedAddr, "grafana", "password")
|
apiClient := newAlertingApiClient(grafanaListedAddr, "grafana", "password")
|
||||||
|
|
||||||
// access control permissions store
|
// access control permissions store
|
||||||
permissionsStore := acdb.ProvideService(store)
|
permissionsStore := resourcepermissions.NewStore(store)
|
||||||
|
|
||||||
// Create the namespace we'll save our alerts to.
|
// Create the namespace we'll save our alerts to.
|
||||||
apiClient.CreateFolder(t, "folder1", "folder1")
|
apiClient.CreateFolder(t, "folder1", "folder1")
|
||||||
@@ -726,17 +725,17 @@ func TestPrometheusRulesPermissions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeFolderPermission(t *testing.T, store *acdb.AccessControlStore, orgID, userID int64, role org.RoleType, uid string) {
|
func removeFolderPermission(t *testing.T, store resourcepermissions.Store, orgID, userID int64, role org.RoleType, uid string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
// remove user permissions on folder
|
// remove user permissions on folder
|
||||||
_, _ = store.SetUserResourcePermission(context.Background(), orgID, accesscontrol.User{ID: userID}, types.SetResourcePermissionCommand{
|
_, _ = store.SetUserResourcePermission(context.Background(), orgID, accesscontrol.User{ID: userID}, resourcepermissions.SetResourcePermissionCommand{
|
||||||
Resource: "folders",
|
Resource: "folders",
|
||||||
ResourceID: uid,
|
ResourceID: uid,
|
||||||
ResourceAttribute: "uid",
|
ResourceAttribute: "uid",
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
// remove org role permissions from folder
|
// remove org role permissions from folder
|
||||||
_, _ = store.SetBuiltInResourcePermission(context.Background(), orgID, string(role), types.SetResourcePermissionCommand{
|
_, _ = store.SetBuiltInResourcePermission(context.Background(), orgID, string(role), resourcepermissions.SetResourcePermissionCommand{
|
||||||
Resource: "folders",
|
Resource: "folders",
|
||||||
ResourceID: uid,
|
ResourceID: uid,
|
||||||
ResourceAttribute: "uid",
|
ResourceAttribute: "uid",
|
||||||
@@ -744,7 +743,7 @@ func removeFolderPermission(t *testing.T, store *acdb.AccessControlStore, orgID,
|
|||||||
|
|
||||||
// remove org role children permissions from folder
|
// remove org role children permissions from folder
|
||||||
for _, c := range role.Children() {
|
for _, c := range role.Children() {
|
||||||
_, _ = store.SetBuiltInResourcePermission(context.Background(), orgID, string(c), types.SetResourcePermissionCommand{
|
_, _ = store.SetBuiltInResourcePermission(context.Background(), orgID, string(c), resourcepermissions.SetResourcePermissionCommand{
|
||||||
Resource: "folders",
|
Resource: "folders",
|
||||||
ResourceID: uid,
|
ResourceID: uid,
|
||||||
ResourceAttribute: "uid",
|
ResourceAttribute: "uid",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
@@ -32,7 +32,7 @@ func TestAlertRulePermissions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
|
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
|
||||||
permissionsStore := acdb.ProvideService(store)
|
permissionsStore := resourcepermissions.NewStore(store)
|
||||||
|
|
||||||
// Create a user to make authenticated requests
|
// Create a user to make authenticated requests
|
||||||
userID := createUser(t, store, user.CreateUserCommand{
|
userID := createUser(t, store, user.CreateUserCommand{
|
||||||
|
|||||||
Reference in New Issue
Block a user