mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Access Control: Filter out hidden permissions in access control dashboard guardian (#46177)
* Implement GetHiddenACL to handle legacy api correctly
This commit is contained in:
@@ -8,32 +8,32 @@ var _ accesscontrol.PermissionsServices = new(PermissionsServicesMock)
|
||||
|
||||
func NewPermissionsServicesMock() *PermissionsServicesMock {
|
||||
return &PermissionsServicesMock{
|
||||
teams: &MockPermissionsService{},
|
||||
folders: &MockPermissionsService{},
|
||||
dashboards: &MockPermissionsService{},
|
||||
datasources: &MockPermissionsService{},
|
||||
Teams: &MockPermissionsService{},
|
||||
Folders: &MockPermissionsService{},
|
||||
Dashboards: &MockPermissionsService{},
|
||||
Datasources: &MockPermissionsService{},
|
||||
}
|
||||
}
|
||||
|
||||
type PermissionsServicesMock struct {
|
||||
teams *MockPermissionsService
|
||||
folders *MockPermissionsService
|
||||
dashboards *MockPermissionsService
|
||||
datasources *MockPermissionsService
|
||||
Teams *MockPermissionsService
|
||||
Folders *MockPermissionsService
|
||||
Dashboards *MockPermissionsService
|
||||
Datasources *MockPermissionsService
|
||||
}
|
||||
|
||||
func (p PermissionsServicesMock) GetTeamService() accesscontrol.PermissionsService {
|
||||
return p.teams
|
||||
return p.Teams
|
||||
}
|
||||
|
||||
func (p PermissionsServicesMock) GetFolderService() accesscontrol.PermissionsService {
|
||||
return p.folders
|
||||
return p.Folders
|
||||
}
|
||||
|
||||
func (p PermissionsServicesMock) GetDashboardService() accesscontrol.PermissionsService {
|
||||
return p.dashboards
|
||||
return p.Dashboards
|
||||
}
|
||||
|
||||
func (p PermissionsServicesMock) GetDataSourceService() accesscontrol.PermissionsService {
|
||||
return p.datasources
|
||||
return p.Datasources
|
||||
}
|
||||
|
||||
@@ -203,8 +203,36 @@ func (a *AccessControlDashboardGuardian) GetACLWithoutDuplicates() ([]*models.Da
|
||||
}
|
||||
|
||||
func (a *AccessControlDashboardGuardian) GetHiddenACL(cfg *setting.Cfg) ([]*models.DashboardAcl, error) {
|
||||
// not used with access control
|
||||
return nil, nil
|
||||
var hiddenACL []*models.DashboardAcl
|
||||
if a.user.IsGrafanaAdmin {
|
||||
return hiddenACL, nil
|
||||
}
|
||||
|
||||
existingPermissions, err := a.GetAcl()
|
||||
if err != nil {
|
||||
return hiddenACL, err
|
||||
}
|
||||
|
||||
for _, item := range existingPermissions {
|
||||
if item.Inherited || item.UserLogin == a.user.Login {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, hidden := cfg.HiddenUsers[item.UserLogin]; hidden {
|
||||
hiddenACL = append(hiddenACL, &models.DashboardAcl{
|
||||
OrgID: item.OrgId,
|
||||
DashboardID: item.DashboardId,
|
||||
UserID: item.UserId,
|
||||
TeamID: item.TeamId,
|
||||
Role: item.Role,
|
||||
Permission: item.Permission,
|
||||
Created: item.Created,
|
||||
Updated: item.Updated,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return hiddenACL, nil
|
||||
}
|
||||
|
||||
func (a *AccessControlDashboardGuardian) loadDashboard() error {
|
||||
|
||||
@@ -2,8 +2,11 @@ package guardian
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@@ -537,6 +540,54 @@ func TestAccessControlDashboardGuardian_CanCreate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type accessControlGuardianGetHiddenACLTestCase struct {
|
||||
desc string
|
||||
permissions []accesscontrol.ResourcePermission
|
||||
hiddenUsers map[string]struct{}
|
||||
}
|
||||
|
||||
func TestAccessControlDashboardGuardian_GetHiddenACL(t *testing.T) {
|
||||
tests := []accessControlGuardianGetHiddenACLTestCase{
|
||||
{
|
||||
desc: "should only return permissions containing hidden users",
|
||||
permissions: []accesscontrol.ResourcePermission{
|
||||
{RoleName: "managed:users:1:permissions", UserId: 1, UserLogin: "user1"},
|
||||
{RoleName: "managed:teams:1:permissions", TeamId: 1, Team: "team1"},
|
||||
{RoleName: "managed:users:2:permissions", UserId: 2, UserLogin: "user2"},
|
||||
{RoleName: "managed:users:3:permissions", UserId: 3, UserLogin: "user3"},
|
||||
{RoleName: "managed:users:4:permissions", UserId: 4, UserLogin: "user4"},
|
||||
},
|
||||
hiddenUsers: map[string]struct{}{"user2": {}, "user3": {}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
guardian := setupAccessControlGuardianTest(t, 1, nil)
|
||||
guardian.permissionServices.GetDashboardService()
|
||||
|
||||
mocked := accesscontrolmock.NewPermissionsServicesMock()
|
||||
guardian.permissionServices = mocked
|
||||
mocked.Dashboards.On("MapActions", mock.Anything).Return("View")
|
||||
mocked.Dashboards.On("GetPermissions", mock.Anything, mock.Anything, mock.Anything).Return(tt.permissions, nil)
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
cfg.HiddenUsers = tt.hiddenUsers
|
||||
|
||||
permissions, err := guardian.GetHiddenACL(cfg)
|
||||
require.NoError(t, err)
|
||||
var hiddenUserNames []string
|
||||
for name := range tt.hiddenUsers {
|
||||
hiddenUserNames = append(hiddenUserNames, name)
|
||||
}
|
||||
assert.Len(t, permissions, len(hiddenUserNames))
|
||||
for _, p := range permissions {
|
||||
assert.Contains(t, hiddenUserNames, fmt.Sprintf("user%d", p.UserID))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func setupAccessControlGuardianTest(t *testing.T, dashID int64, permissions []*accesscontrol.Permission) *AccessControlDashboardGuardian {
|
||||
t.Helper()
|
||||
store := sqlstore.InitTestDB(t)
|
||||
|
||||
Reference in New Issue
Block a user