Revert "Authz: Removes setting viewers_can_edit" (#101528)
Revert "Authz: Removes setting `viewers_can_edit` (#101265)"
This reverts commit 4ce41acade.
This commit is contained in:
@@ -71,6 +71,10 @@ func (hs *HTTPServer) declareFixedRoles() error {
|
|||||||
Grants: []string{string(org.RoleEditor)},
|
Grants: []string{string(org.RoleEditor)},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if hs.Cfg.ViewersCanEdit {
|
||||||
|
datasourcesExplorerRole.Grants = append(datasourcesExplorerRole.Grants, string(org.RoleViewer))
|
||||||
|
}
|
||||||
|
|
||||||
datasourcesReaderRole := ac.RoleRegistration{
|
datasourcesReaderRole := ac.RoleRegistration{
|
||||||
Role: ac.RoleDTO{
|
Role: ac.RoleDTO{
|
||||||
Name: "fixed:datasources:reader",
|
Name: "fixed:datasources:reader",
|
||||||
|
|||||||
@@ -221,6 +221,10 @@ func (a *accessControlDashboardGuardian) CanEdit() (bool, error) {
|
|||||||
return false, ErrGuardianDashboardNotFound.Errorf("failed to check edit permissions for dashboard")
|
return false, ErrGuardianDashboardNotFound.Errorf("failed to check edit permissions for dashboard")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if a.cfg.ViewersCanEdit {
|
||||||
|
return a.CanView()
|
||||||
|
}
|
||||||
|
|
||||||
return a.evaluate(
|
return a.evaluate(
|
||||||
accesscontrol.EvalPermission(dashboards.ActionDashboardsWrite, dashboards.ScopeDashboardsProvider.GetResourceScopeUID(a.dashboard.UID)),
|
accesscontrol.EvalPermission(dashboards.ActionDashboardsWrite, dashboards.ScopeDashboardsProvider.GetResourceScopeUID(a.dashboard.UID)),
|
||||||
)
|
)
|
||||||
@@ -231,6 +235,10 @@ func (a *accessControlFolderGuardian) CanEdit() (bool, error) {
|
|||||||
return false, ErrGuardianFolderNotFound.Errorf("failed to check edit permissions for folder")
|
return false, ErrGuardianFolderNotFound.Errorf("failed to check edit permissions for folder")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if a.cfg.ViewersCanEdit {
|
||||||
|
return a.CanView()
|
||||||
|
}
|
||||||
|
|
||||||
return a.evaluate(accesscontrol.EvalPermission(dashboards.ActionFoldersWrite, dashboards.ScopeFoldersProvider.GetResourceScopeUID(a.folder.UID)))
|
return a.evaluate(accesscontrol.EvalPermission(dashboards.ActionFoldersWrite, dashboards.ScopeFoldersProvider.GetResourceScopeUID(a.folder.UID)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,10 +36,11 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type accessControlGuardianTestCase struct {
|
type accessControlGuardianTestCase struct {
|
||||||
desc string
|
desc string
|
||||||
dashboard *dashboards.Dashboard
|
dashboard *dashboards.Dashboard
|
||||||
permissions []accesscontrol.Permission
|
permissions []accesscontrol.Permission
|
||||||
expected bool
|
viewersCanEdit bool
|
||||||
|
expected bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessControlDashboardGuardian_CanSave(t *testing.T) {
|
func TestAccessControlDashboardGuardian_CanSave(t *testing.T) {
|
||||||
@@ -256,6 +257,18 @@ func TestAccessControlDashboardGuardian_CanEdit(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "should be able to edit dashboard with read action when viewer_can_edit is true",
|
||||||
|
dashboard: dashboard,
|
||||||
|
permissions: []accesscontrol.Permission{
|
||||||
|
{
|
||||||
|
Action: dashboards.ActionDashboardsRead,
|
||||||
|
Scope: "dashboards:uid:1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
viewersCanEdit: true,
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
desc: "should not be able to edit folder with folder write and dashboard wildcard scope",
|
desc: "should not be able to edit folder with folder write and dashboard wildcard scope",
|
||||||
dashboard: fldr,
|
dashboard: fldr,
|
||||||
@@ -311,11 +324,24 @@ func TestAccessControlDashboardGuardian_CanEdit(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "should be able to edit folder with folder read action when viewer_can_edit is true",
|
||||||
|
dashboard: fldr,
|
||||||
|
permissions: []accesscontrol.Permission{
|
||||||
|
{
|
||||||
|
Action: dashboards.ActionFoldersRead,
|
||||||
|
Scope: folderUIDScope,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
viewersCanEdit: true,
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
|
cfg.ViewersCanEdit = tt.viewersCanEdit
|
||||||
guardian := setupAccessControlGuardianTest(t, tt.dashboard, tt.permissions, cfg)
|
guardian := setupAccessControlGuardianTest(t, tt.dashboard, tt.permissions, cfg)
|
||||||
|
|
||||||
can, err := guardian.CanEdit()
|
can, err := guardian.CanEdit()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type CallbackHandler func(c *contextmodel.ReqContext) response.Response
|
|||||||
func (s *QueryHistoryService) permissionsMiddleware(handler CallbackHandler, errorMessage string) CallbackHandler {
|
func (s *QueryHistoryService) permissionsMiddleware(handler CallbackHandler, errorMessage string) CallbackHandler {
|
||||||
return func(c *contextmodel.ReqContext) response.Response {
|
return func(c *contextmodel.ReqContext) response.Response {
|
||||||
hasAccess := ac.HasAccess(s.accessControl, c)
|
hasAccess := ac.HasAccess(s.accessControl, c)
|
||||||
if c.GetOrgRole() == org.RoleViewer && !hasAccess(ac.EvalPermission(ac.ActionDatasourcesExplore)) {
|
if c.GetOrgRole() == org.RoleViewer && !s.Cfg.ViewersCanEdit && !hasAccess(ac.EvalPermission(ac.ActionDatasourcesExplore)) {
|
||||||
return response.Error(http.StatusUnauthorized, errorMessage, nil)
|
return response.Error(http.StatusUnauthorized, errorMessage, nil)
|
||||||
}
|
}
|
||||||
return handler(c)
|
return handler(c)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import {
|
|||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
|
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
|
||||||
import { NavToolbarSeparator } from 'app/core/components/AppChrome/NavToolbar/NavToolbarSeparator';
|
import { NavToolbarSeparator } from 'app/core/components/AppChrome/NavToolbar/NavToolbarSeparator';
|
||||||
import grafanaConfig from 'app/core/config';
|
|
||||||
import { LS_PANEL_COPY_KEY } from 'app/core/constants';
|
import { LS_PANEL_COPY_KEY } from 'app/core/constants';
|
||||||
import { contextSrv } from 'app/core/core';
|
import { contextSrv } from 'app/core/core';
|
||||||
import { Trans, t } from 'app/core/internationalization';
|
import { Trans, t } from 'app/core/internationalization';
|
||||||
@@ -79,11 +78,6 @@ export function ToolbarActions({ dashboard }: Props) {
|
|||||||
const showScopesSelector = config.featureToggles.scopeFilters && !isEditing;
|
const showScopesSelector = config.featureToggles.scopeFilters && !isEditing;
|
||||||
const dashboardNewLayouts = config.featureToggles.dashboardNewLayouts;
|
const dashboardNewLayouts = config.featureToggles.dashboardNewLayouts;
|
||||||
|
|
||||||
// Internal only;
|
|
||||||
// allows viewer editing without ability to save
|
|
||||||
// used for grafana play
|
|
||||||
const canEdit = grafanaConfig.viewersCanEdit;
|
|
||||||
|
|
||||||
if (!isEditingPanel) {
|
if (!isEditingPanel) {
|
||||||
// This adds the presence indicators in enterprise
|
// This adds the presence indicators in enterprise
|
||||||
addDynamicActions(toolbarActions, dynamicDashNavActions.left, 'left-actions');
|
addDynamicActions(toolbarActions, dynamicDashNavActions.left, 'left-actions');
|
||||||
@@ -360,7 +354,7 @@ export function ToolbarActions({ dashboard }: Props) {
|
|||||||
|
|
||||||
toolbarActions.push({
|
toolbarActions.push({
|
||||||
group: 'main-buttons',
|
group: 'main-buttons',
|
||||||
condition: !isEditing && (dashboard.canEditDashboard() || canEdit) && !isViewingPanel && !isPlaying && editable,
|
condition: !isEditing && dashboard.canEditDashboard() && !isViewingPanel && !isPlaying && editable,
|
||||||
render: () => (
|
render: () => (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user