AccessControl: Create own interface and impl for each permission service (#48871)

* Create own interfaces for team, folder, dashboard and data source permissions services
* Remove service container and inject them individually
This commit is contained in:
Karl Persson
2022-05-10 15:48:47 +02:00
committed by GitHub
parent 31ff23f542
commit 61772a66b6
31 changed files with 266 additions and 255 deletions
+15 -5
View File
@@ -43,11 +43,21 @@ type PermissionsProvider interface {
GetUserPermissions(ctx context.Context, query GetUserPermissionsQuery) ([]*Permission, error)
}
type PermissionsServices interface {
GetTeamService() PermissionsService
GetFolderService() PermissionsService
GetDashboardService() PermissionsService
GetDataSourceService() PermissionsService
type TeamPermissionsService interface {
GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]ResourcePermission, error)
SetUserPermission(ctx context.Context, orgID int64, user User, resourceID, permission string) (*ResourcePermission, error)
}
type FolderPermissionsService interface {
PermissionsService
}
type DashboardPermissionsService interface {
PermissionsService
}
type DatasourcePermissionsService interface {
PermissionsService
}
type PermissionsService interface {
@@ -1,39 +0,0 @@
package mock
import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
)
var _ accesscontrol.PermissionsServices = new(PermissionsServicesMock)
func NewPermissionsServicesMock() *PermissionsServicesMock {
return &PermissionsServicesMock{
Teams: &MockPermissionsService{},
Folders: &MockPermissionsService{},
Dashboards: &MockPermissionsService{},
Datasources: &MockPermissionsService{},
}
}
type PermissionsServicesMock struct {
Teams *MockPermissionsService
Folders *MockPermissionsService
Dashboards *MockPermissionsService
Datasources *MockPermissionsService
}
func (p PermissionsServicesMock) GetTeamService() accesscontrol.PermissionsService {
return p.Teams
}
func (p PermissionsServicesMock) GetFolderService() accesscontrol.PermissionsService {
return p.Folders
}
func (p PermissionsServicesMock) GetDashboardService() accesscontrol.PermissionsService {
return p.Dashboards
}
func (p PermissionsServicesMock) GetDataSourceService() accesscontrol.PermissionsService {
return p.Datasources
}
@@ -11,6 +11,10 @@ import (
var _ accesscontrol.PermissionsService = new(MockPermissionsService)
func NewMockedPermissionsService() *MockPermissionsService {
return &MockPermissionsService{}
}
type MockPermissionsService struct {
mock.Mock
}
@@ -15,52 +15,8 @@ import (
"github.com/grafana/grafana/pkg/setting"
)
func ProvidePermissionsServices(
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
ac accesscontrol.AccessControl, store resourcepermissions.Store,
) (*PermissionsServices, error) {
teamPermissions, err := ProvideTeamPermissions(cfg, router, sql, ac, store)
if err != nil {
return nil, err
}
folderPermissions, err := ProvideFolderPermissions(cfg, router, sql, ac, store)
if err != nil {
return nil, err
}
dashboardPermissions, err := ProvideDashboardPermissions(cfg, router, sql, ac, store)
if err != nil {
return nil, err
}
return &PermissionsServices{
teams: teamPermissions,
folder: folderPermissions,
dashboard: dashboardPermissions,
datasources: provideEmptyPermissionsService(),
}, nil
}
type PermissionsServices struct {
teams accesscontrol.PermissionsService
folder accesscontrol.PermissionsService
dashboard accesscontrol.PermissionsService
datasources accesscontrol.PermissionsService
}
func (s *PermissionsServices) GetTeamService() accesscontrol.PermissionsService {
return s.teams
}
func (s *PermissionsServices) GetFolderService() accesscontrol.PermissionsService {
return s.folder
}
func (s *PermissionsServices) GetDashboardService() accesscontrol.PermissionsService {
return s.dashboard
}
func (s *PermissionsServices) GetDataSourceService() accesscontrol.PermissionsService {
return s.datasources
type TeamPermissionsService struct {
*resourcepermissions.Service
}
var (
@@ -80,7 +36,7 @@ var (
func ProvideTeamPermissions(
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
ac accesscontrol.AccessControl, store resourcepermissions.Store,
) (*resourcepermissions.Service, error) {
) (*TeamPermissionsService, error) {
options := resourcepermissions.Options{
Resource: "teams",
ResourceAttribute: "id",
@@ -135,7 +91,15 @@ func ProvideTeamPermissions(
},
}
return resourcepermissions.New(options, cfg, router, ac, store, sql)
srv, err := resourcepermissions.New(options, cfg, router, ac, store, sql)
if err != nil {
return nil, err
}
return &TeamPermissionsService{srv}, nil
}
type DashboardPermissionsService struct {
*resourcepermissions.Service
}
var DashboardViewActions = []string{dashboards.ActionDashboardsRead}
@@ -145,7 +109,7 @@ var DashboardAdminActions = append(DashboardEditActions, []string{dashboards.Act
func ProvideDashboardPermissions(
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
ac accesscontrol.AccessControl, store resourcepermissions.Store,
) (*resourcepermissions.Service, error) {
) (*DashboardPermissionsService, error) {
getDashboard := func(ctx context.Context, orgID int64, resourceID string) (*models.Dashboard, error) {
query := &models.GetDashboardQuery{Uid: resourceID, OrgId: orgID}
if err := sql.GetDashboard(ctx, query); err != nil {
@@ -199,7 +163,15 @@ func ProvideDashboardPermissions(
RoleGroup: "Dashboards",
}
return resourcepermissions.New(options, cfg, router, ac, store, sql)
srv, err := resourcepermissions.New(options, cfg, router, ac, store, sql)
if err != nil {
return nil, err
}
return &DashboardPermissionsService{srv}, nil
}
type FolderPermissionsService struct {
*resourcepermissions.Service
}
var FolderViewActions = []string{dashboards.ActionFoldersRead}
@@ -209,7 +181,7 @@ var FolderAdminActions = append(FolderEditActions, []string{dashboards.ActionFol
func ProvideFolderPermissions(
cfg *setting.Cfg, router routing.RouteRegister, sql *sqlstore.SQLStore,
accesscontrol accesscontrol.AccessControl, store resourcepermissions.Store,
) (*resourcepermissions.Service, error) {
) (*FolderPermissionsService, error) {
options := resourcepermissions.Options{
Resource: "folders",
ResourceAttribute: "uid",
@@ -239,38 +211,41 @@ func ProvideFolderPermissions(
WriterRoleName: "Folder permission writer",
RoleGroup: "Folders",
}
return resourcepermissions.New(options, cfg, router, accesscontrol, store, sql)
srv, err := resourcepermissions.New(options, cfg, router, accesscontrol, store, sql)
if err != nil {
return nil, err
}
return &FolderPermissionsService{srv}, nil
}
func provideEmptyPermissionsService() accesscontrol.PermissionsService {
return &emptyPermissionsService{}
func ProvideDatasourcePermissionsService() *DatasourcePermissionsService {
return &DatasourcePermissionsService{}
}
var _ accesscontrol.PermissionsService = new(emptyPermissionsService)
var _ accesscontrol.DatasourcePermissionsService = new(DatasourcePermissionsService)
type emptyPermissionsService struct{}
type DatasourcePermissionsService struct{}
func (e emptyPermissionsService) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) SetUserPermission(ctx context.Context, orgID int64, user accesscontrol.User, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) SetUserPermission(ctx context.Context, orgID int64, user accesscontrol.User, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) SetTeamPermission(ctx context.Context, orgID, teamID int64, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) SetTeamPermission(ctx context.Context, orgID, teamID int64, resourceID, permission string) (*accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) SetBuiltInRolePermission(ctx context.Context, orgID int64, builtInRole string, resourceID string, permission string) (*accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) SetBuiltInRolePermission(ctx context.Context, orgID int64, builtInRole string, resourceID string, permission string) (*accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) SetPermissions(ctx context.Context, orgID int64, resourceID string, commands ...accesscontrol.SetResourcePermissionCommand) ([]accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) SetPermissions(ctx context.Context, orgID int64, resourceID string, commands ...accesscontrol.SetResourcePermissionCommand) ([]accesscontrol.ResourcePermission, error) {
return nil, nil
}
func (e emptyPermissionsService) MapActions(permission accesscontrol.ResourcePermission) string {
func (e DatasourcePermissionsService) MapActions(permission accesscontrol.ResourcePermission) string {
return ""
}
@@ -65,9 +65,15 @@ func (a *api) registerEndpoints() {
readEvaluator, writeEvaluator := a.getEvaluators(actionRead, actionWrite, scope)
r.Get("/description", auth(disable, accesscontrol.EvalPermission(actionRead)), routing.Wrap(a.getDescription))
r.Get("/:resourceID", inheritanceSolver, auth(disable, readEvaluator), routing.Wrap(a.getPermissions))
r.Post("/:resourceID/users/:userID", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setUserPermission))
r.Post("/:resourceID/teams/:teamID", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setTeamPermission))
r.Post("/:resourceID/builtInRoles/:builtInRole", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setBuiltinRolePermission))
if a.service.options.Assignments.Users {
r.Post("/:resourceID/users/:userID", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setUserPermission))
}
if a.service.options.Assignments.Teams {
r.Post("/:resourceID/teams/:teamID", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setTeamPermission))
}
if a.service.options.Assignments.BuiltInRoles {
r.Post("/:resourceID/builtInRoles/:builtInRole", inheritanceSolver, auth(disable, writeEvaluator), routing.Wrap(a.setBuiltinRolePermission))
}
})
}