Access Control: Filter out hidden permissions in access control dashboard guardian (#46177)

* Implement GetHiddenACL to handle legacy api correctly
This commit is contained in:
Karl Persson
2022-03-03 18:29:39 +01:00
committed by GitHub
parent 19266ad3de
commit 8cea8fdaea
3 changed files with 93 additions and 14 deletions

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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)