diff --git a/packages/grafana-data/src/types/config.ts b/packages/grafana-data/src/types/config.ts
index 04ebffbb4cf..a9d55ee2e07 100644
--- a/packages/grafana-data/src/types/config.ts
+++ b/packages/grafana-data/src/types/config.ts
@@ -181,6 +181,7 @@ export interface GrafanaConfig {
autoAssignOrg: boolean;
verifyEmailEnabled: boolean;
oauth: OAuthSettings;
+ /** @deprecated always set to true. */
rbacEnabled: boolean;
disableUserSignUp: boolean;
loginHint: string;
diff --git a/public/app/core/services/context_srv.ts b/public/app/core/services/context_srv.ts
index b1a63b0d381..f76ca6b5c00 100644
--- a/public/app/core/services/context_srv.ts
+++ b/public/app/core/services/context_srv.ts
@@ -97,11 +97,9 @@ export class ContextSrv {
async fetchUserPermissions() {
try {
- if (this.accessControlEnabled()) {
- this.user.permissions = await getBackendSrv().get('/api/access-control/user/actions', {
- reloadcache: true,
- });
- }
+ this.user.permissions = await getBackendSrv().get('/api/access-control/user/actions', {
+ reloadcache: true,
+ });
} catch (e) {
console.error(e);
}
@@ -125,31 +123,17 @@ export class ContextSrv {
}
}
- accessControlEnabled(): boolean {
- return config.rbacEnabled;
- }
-
licensedAccessControlEnabled(): boolean {
- return featureEnabled('accesscontrol') && config.rbacEnabled;
+ return featureEnabled('accesscontrol');
}
// Checks whether user has required permission
hasPermissionInMetadata(action: AccessControlAction | string, object: WithAccessControlMetadata): boolean {
- // Fallback if access control disabled
- if (!this.accessControlEnabled()) {
- return true;
- }
-
return !!object.accessControl?.[action];
}
// Checks whether user has required permission
hasPermission(action: AccessControlAction | string): boolean {
- // Fallback if access control disabled
- if (!this.accessControlEnabled()) {
- return true;
- }
-
return !!this.user.permissions?.[action];
}
@@ -180,23 +164,14 @@ export class ContextSrv {
}
hasAccessToExplore() {
- if (this.accessControlEnabled()) {
- return this.hasPermission(AccessControlAction.DataSourcesExplore) && config.exploreEnabled;
- }
- return (this.isEditor || config.viewersCanEdit) && config.exploreEnabled;
+ return this.hasPermission(AccessControlAction.DataSourcesExplore) && config.exploreEnabled;
}
hasAccess(action: string, fallBack: boolean): boolean {
- if (!this.accessControlEnabled()) {
- return fallBack;
- }
return this.hasPermission(action);
}
hasAccessInMetadata(action: string, object: WithAccessControlMetadata, fallBack: boolean): boolean {
- if (!this.accessControlEnabled()) {
- return fallBack;
- }
return this.hasPermissionInMetadata(action, object);
}
diff --git a/public/app/core/utils/accessControl.ts b/public/app/core/utils/accessControl.ts
index e31b4a75717..47bc51f9ccc 100644
--- a/public/app/core/utils/accessControl.ts
+++ b/public/app/core/utils/accessControl.ts
@@ -1,9 +1,4 @@
-import config from '../../core/config';
-
// accessControlQueryParam adds an additional accesscontrol=true param to params when accesscontrol is enabled
export function accessControlQueryParam(params = {}) {
- if (!config.rbacEnabled) {
- return params;
- }
return { ...params, accesscontrol: true };
}
diff --git a/public/app/features/admin/UserOrgs.tsx b/public/app/features/admin/UserOrgs.tsx
index 4e2865e764d..31379631d01 100644
--- a/public/app/features/admin/UserOrgs.tsx
+++ b/public/app/features/admin/UserOrgs.tsx
@@ -377,21 +377,17 @@ export class AddToOrgModal extends PureComponent
- {contextSrv.accessControlEnabled() ? (
-
- ) : (
-
- )}
+
diff --git a/public/app/features/alerting/unified/MuteTimings.test.tsx b/public/app/features/alerting/unified/MuteTimings.test.tsx
index 53d91ce4dc3..e87db13b33c 100644
--- a/public/app/features/alerting/unified/MuteTimings.test.tsx
+++ b/public/app/features/alerting/unified/MuteTimings.test.tsx
@@ -6,10 +6,11 @@ import { byRole, byTestId, byText } from 'testing-library-selector';
import { locationService, setDataSourceSrv } from '@grafana/runtime';
import { AlertManagerCortexConfig, MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types';
+import { AccessControlAction } from 'app/types';
import MuteTimings from './MuteTimings';
import { fetchAlertManagerConfig, updateAlertManagerConfig } from './api/alertmanager';
-import { disableRBAC, mockDataSource, MockDataSourceSrv } from './mocks';
+import { grantUserPermissions, mockDataSource, MockDataSourceSrv } from './mocks';
import { DataSourceType } from './utils/datasource';
jest.mock('./api/alertmanager');
@@ -105,10 +106,11 @@ describe('Mute timings', () => {
beforeEach(() => {
setDataSourceSrv(new MockDataSourceSrv(dataSources));
resetMocks();
+ // FIXME: scope down
+ grantUserPermissions(Object.values(AccessControlAction));
});
it('creates a new mute timing', async () => {
- disableRBAC();
renderMuteTimings();
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled());
diff --git a/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx b/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx
index 8d33c54e6a8..add93de4b69 100644
--- a/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx
+++ b/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx
@@ -13,13 +13,14 @@ import { toKeyedAction } from 'app/features/variables/state/keyedVariablesReduce
import { PrometheusDatasource } from 'app/plugins/datasource/prometheus/datasource';
import { PromOptions } from 'app/plugins/datasource/prometheus/types';
import { configureStore } from 'app/store/configureStore';
+import { AccessControlAction } from 'app/types';
import { AlertQuery } from 'app/types/unified-alerting-dto';
import { PanelAlertTabContent } from './PanelAlertTabContent';
import { fetchRules } from './api/prometheus';
import { fetchRulerRules } from './api/ruler';
import {
- disableRBAC,
+ grantUserPermissions,
mockDataSource,
MockDataSourceSrv,
mockPromAlertingRule,
@@ -180,6 +181,14 @@ const ui = {
describe('PanelAlertTabContent', () => {
beforeEach(() => {
jest.resetAllMocks();
+ grantUserPermissions([
+ AccessControlAction.AlertingRuleRead,
+ AccessControlAction.AlertingRuleUpdate,
+ AccessControlAction.AlertingRuleDelete,
+ AccessControlAction.AlertingRuleCreate,
+ AccessControlAction.AlertingRuleExternalRead,
+ AccessControlAction.AlertingRuleExternalWrite,
+ ]);
mocks.getAllDataSources.mockReturnValue(Object.values(dataSources));
const dsService = new MockDataSourceSrv(dataSources);
dsService.datasources[dataSources.prometheus.uid] = new PrometheusDatasource(
@@ -187,7 +196,6 @@ describe('PanelAlertTabContent', () => {
) as DataSourceApi;
dsService.datasources[dataSources.default.uid] = new PrometheusDatasource(dataSources.default) as DataSourceApi;
setDataSourceSrv(dsService);
- disableRBAC();
});
it('Will take into account panel maxDataPoints', async () => {
diff --git a/public/app/features/alerting/unified/RuleEditorCloudOnlyAllowed.test.tsx b/public/app/features/alerting/unified/RuleEditorCloudOnlyAllowed.test.tsx
index 61e2e3d576e..8c335a5a007 100644
--- a/public/app/features/alerting/unified/RuleEditorCloudOnlyAllowed.test.tsx
+++ b/public/app/features/alerting/unified/RuleEditorCloudOnlyAllowed.test.tsx
@@ -6,6 +6,7 @@ import { byRole, byText } from 'testing-library-selector';
import { setDataSourceSrv } from '@grafana/runtime';
import { contextSrv } from 'app/core/services/context_srv';
+import { AccessControlAction } from 'app/types';
import { PromApiFeatures, PromApplication } from 'app/types/unified-alerting-dto';
import { searchFolders } from '../../manage-dashboards/state/actions';
@@ -13,7 +14,7 @@ import { searchFolders } from '../../manage-dashboards/state/actions';
import { discoverFeatures } from './api/buildInfo';
import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler';
import { ExpressionEditorProps } from './components/rule-editor/ExpressionEditor';
-import { disableRBAC, mockDataSource, MockDataSourceSrv } from './mocks';
+import { grantUserPermissions, mockDataSource, MockDataSourceSrv } from './mocks';
import { fetchRulerRulesIfNotFetchedYet } from './state/actions';
import * as config from './utils/config';
import { DataSourceType } from './utils/datasource';
@@ -139,10 +140,10 @@ describe('RuleEditor cloud: checking editable data sources', () => {
jest.clearAllMocks();
contextSrv.isEditor = true;
contextSrv.hasEditPermissionInFolders = true;
+ // grant all permissions in AccessControlActionEnum
+ grantUserPermissions(Object.values(AccessControlAction));
});
- disableRBAC();
-
it('for cloud alerts, should only allow to select editable rules sources', async () => {
mocks.api.discoverFeatures.mockImplementation(async (dataSourceName) => {
if (dataSourceName === 'loki with ruler' || dataSourceName === 'cortex with ruler') {
diff --git a/public/app/features/alerting/unified/RuleEditorCloudRules.test.tsx b/public/app/features/alerting/unified/RuleEditorCloudRules.test.tsx
index 4925613526d..e89c9c033c1 100644
--- a/public/app/features/alerting/unified/RuleEditorCloudRules.test.tsx
+++ b/public/app/features/alerting/unified/RuleEditorCloudRules.test.tsx
@@ -6,13 +6,14 @@ import { clickSelectOption } from 'test/helpers/selectOptionInTest';
import { byRole } from 'testing-library-selector';
import { contextSrv } from 'app/core/services/context_srv';
+import { AccessControlAction } from 'app/types';
import { searchFolders } from '../../manage-dashboards/state/actions';
import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler';
import { ExpressionEditorProps } from './components/rule-editor/ExpressionEditor';
import { mockApi, mockFeatureDiscoveryApi, setupMswServer } from './mockApi';
-import { disableRBAC, mockDataSource } from './mocks';
+import { grantUserPermissions, mockDataSource } from './mocks';
import {
defaultAlertmanagerChoiceResponse,
emptyExternalAlertmanagersResponse,
@@ -82,10 +83,19 @@ describe('RuleEditor cloud', () => {
jest.clearAllMocks();
contextSrv.isEditor = true;
contextSrv.hasEditPermissionInFolders = true;
+ grantUserPermissions([
+ AccessControlAction.AlertingRuleRead,
+ AccessControlAction.AlertingRuleUpdate,
+ AccessControlAction.AlertingRuleDelete,
+ AccessControlAction.AlertingRuleCreate,
+ AccessControlAction.DataSourcesRead,
+ AccessControlAction.DataSourcesWrite,
+ AccessControlAction.DataSourcesCreate,
+ AccessControlAction.AlertingRuleExternalRead,
+ AccessControlAction.AlertingRuleExternalWrite,
+ ]);
});
- disableRBAC();
-
it('can create a new cloud alert', async () => {
mocks.api.setRulerRuleGroup.mockResolvedValue();
mocks.api.fetchRulerRulesNamespace.mockResolvedValue([]);
diff --git a/public/app/features/alerting/unified/RuleEditorExisting.test.tsx b/public/app/features/alerting/unified/RuleEditorExisting.test.tsx
index fa85b62d952..a3ecbbfcb6f 100644
--- a/public/app/features/alerting/unified/RuleEditorExisting.test.tsx
+++ b/public/app/features/alerting/unified/RuleEditorExisting.test.tsx
@@ -18,7 +18,7 @@ import RuleEditor from './RuleEditor';
import { discoverFeatures } from './api/buildInfo';
import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler';
import { ExpressionEditorProps } from './components/rule-editor/ExpressionEditor';
-import { disableRBAC, mockDataSource, MockDataSourceSrv, mockFolder } from './mocks';
+import { grantUserPermissions, mockDataSource, MockDataSourceSrv, mockFolder } from './mocks';
import { fetchRulerRulesIfNotFetchedYet } from './state/actions';
import * as config from './utils/config';
import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
@@ -79,9 +79,21 @@ describe('RuleEditor grafana managed rules', () => {
jest.clearAllMocks();
contextSrv.isEditor = true;
contextSrv.hasEditPermissionInFolders = true;
- });
- disableRBAC();
+ grantUserPermissions([
+ AccessControlAction.AlertingRuleRead,
+ AccessControlAction.AlertingRuleUpdate,
+ AccessControlAction.AlertingRuleDelete,
+ AccessControlAction.AlertingRuleCreate,
+ AccessControlAction.DataSourcesRead,
+ AccessControlAction.DataSourcesWrite,
+ AccessControlAction.DataSourcesCreate,
+ AccessControlAction.FoldersWrite,
+ AccessControlAction.FoldersRead,
+ AccessControlAction.AlertingRuleExternalRead,
+ AccessControlAction.AlertingRuleExternalWrite,
+ ]);
+ });
it('can edit grafana managed rule', async () => {
const uid = 'FOOBAR123';
diff --git a/public/app/features/alerting/unified/RuleEditorGrafanaRules.test.tsx b/public/app/features/alerting/unified/RuleEditorGrafanaRules.test.tsx
index f14e44b7bbd..cc15a0c61d1 100644
--- a/public/app/features/alerting/unified/RuleEditorGrafanaRules.test.tsx
+++ b/public/app/features/alerting/unified/RuleEditorGrafanaRules.test.tsx
@@ -8,6 +8,7 @@ import { byRole } from 'testing-library-selector';
import { setDataSourceSrv } from '@grafana/runtime';
import { contextSrv } from 'app/core/services/context_srv';
import { DashboardSearchHit } from 'app/features/search/types';
+import { AccessControlAction } from 'app/types';
import { GrafanaAlertStateDecision, PromApplication } from 'app/types/unified-alerting-dto';
import { searchFolders } from '../../../../app/features/manage-dashboards/state/actions';
@@ -15,7 +16,7 @@ import { searchFolders } from '../../../../app/features/manage-dashboards/state/
import { discoverFeatures } from './api/buildInfo';
import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler';
import { ExpressionEditorProps } from './components/rule-editor/ExpressionEditor';
-import { disableRBAC, mockDataSource, MockDataSourceSrv } from './mocks';
+import { grantUserPermissions, mockDataSource, MockDataSourceSrv } from './mocks';
import { fetchRulerRulesIfNotFetchedYet } from './state/actions';
import * as config from './utils/config';
import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
@@ -66,10 +67,21 @@ describe('RuleEditor grafana managed rules', () => {
jest.clearAllMocks();
contextSrv.isEditor = true;
contextSrv.hasEditPermissionInFolders = true;
+ grantUserPermissions([
+ AccessControlAction.AlertingRuleRead,
+ AccessControlAction.AlertingRuleUpdate,
+ AccessControlAction.AlertingRuleDelete,
+ AccessControlAction.AlertingRuleCreate,
+ AccessControlAction.DataSourcesRead,
+ AccessControlAction.DataSourcesWrite,
+ AccessControlAction.DataSourcesCreate,
+ AccessControlAction.FoldersWrite,
+ AccessControlAction.FoldersRead,
+ AccessControlAction.AlertingRuleExternalRead,
+ AccessControlAction.AlertingRuleExternalWrite,
+ ]);
});
- disableRBAC();
-
it('can create new grafana managed alert', async () => {
const dataSources = {
default: mockDataSource(
diff --git a/public/app/features/alerting/unified/RuleEditorRecordingRule.test.tsx b/public/app/features/alerting/unified/RuleEditorRecordingRule.test.tsx
index 8e189c291a5..681a84611b1 100644
--- a/public/app/features/alerting/unified/RuleEditorRecordingRule.test.tsx
+++ b/public/app/features/alerting/unified/RuleEditorRecordingRule.test.tsx
@@ -7,6 +7,7 @@ import { byRole, byText } from 'testing-library-selector';
import { setDataSourceSrv } from '@grafana/runtime';
import { contextSrv } from 'app/core/services/context_srv';
+import { AccessControlAction } from 'app/types';
import { PromApplication } from 'app/types/unified-alerting-dto';
import { searchFolders } from '../../manage-dashboards/state/actions';
@@ -14,7 +15,7 @@ import { searchFolders } from '../../manage-dashboards/state/actions';
import { discoverFeatures } from './api/buildInfo';
import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler';
import { RecordingRuleEditorProps } from './components/rule-editor/RecordingRuleEditor';
-import { disableRBAC, mockDataSource, MockDataSourceSrv } from './mocks';
+import { grantUserPermissions, mockDataSource, MockDataSourceSrv } from './mocks';
import { fetchRulerRulesIfNotFetchedYet } from './state/actions';
import * as config from './utils/config';
@@ -96,9 +97,21 @@ describe('RuleEditor recording rules', () => {
jest.clearAllMocks();
contextSrv.isEditor = true;
contextSrv.hasEditPermissionInFolders = true;
+ grantUserPermissions([
+ AccessControlAction.AlertingRuleRead,
+ AccessControlAction.AlertingRuleUpdate,
+ AccessControlAction.AlertingRuleDelete,
+ AccessControlAction.AlertingRuleCreate,
+ AccessControlAction.DataSourcesRead,
+ AccessControlAction.DataSourcesWrite,
+ AccessControlAction.DataSourcesCreate,
+ AccessControlAction.FoldersWrite,
+ AccessControlAction.FoldersRead,
+ AccessControlAction.AlertingRuleExternalRead,
+ AccessControlAction.AlertingRuleExternalWrite,
+ ]);
});
- disableRBAC();
it('can create a new cloud recording rule', async () => {
setDataSourceSrv(new MockDataSourceSrv(dataSources));
mocks.getAllDataSources.mockReturnValue(Object.values(dataSources));
diff --git a/public/app/features/alerting/unified/RuleList.test.tsx b/public/app/features/alerting/unified/RuleList.test.tsx
index 54a5f82af68..07de53cb27a 100644
--- a/public/app/features/alerting/unified/RuleList.test.tsx
+++ b/public/app/features/alerting/unified/RuleList.test.tsx
@@ -18,7 +18,6 @@ import { discoverFeatures } from './api/buildInfo';
import { fetchRules } from './api/prometheus';
import { deleteNamespace, deleteRulerRulesGroup, fetchRulerRules, setRulerRuleGroup } from './api/ruler';
import {
- enableRBAC,
grantUserPermissions,
mockDataSource,
MockDataSourceSrv,
@@ -686,8 +685,6 @@ describe('RuleList', () => {
describe('RBAC Enabled', () => {
describe('Export button', () => {
it('Export button should be visible when the user has alert provisioning read permissions', async () => {
- enableRBAC();
-
grantUserPermissions([AccessControlAction.AlertingProvisioningRead]);
mocks.getAllDataSourcesMock.mockReturnValue([]);
@@ -701,8 +698,6 @@ describe('RuleList', () => {
expect(ui.exportButton.get()).toBeInTheDocument();
});
it('Export button should be visible when the user has alert provisioning read secrets permissions', async () => {
- enableRBAC();
-
grantUserPermissions([AccessControlAction.AlertingProvisioningReadSecrets]);
mocks.getAllDataSourcesMock.mockReturnValue([]);
@@ -716,8 +711,6 @@ describe('RuleList', () => {
expect(ui.exportButton.get()).toBeInTheDocument();
});
it('Export button should not be visible when the user has no alert provisioning read permissions', async () => {
- enableRBAC();
-
grantUserPermissions([AccessControlAction.AlertingRuleCreate, AccessControlAction.FoldersRead]);
mocks.getAllDataSourcesMock.mockReturnValue([]);
@@ -733,8 +726,6 @@ describe('RuleList', () => {
});
describe('Grafana Managed Alerts', () => {
it('New alert button should be visible when the user has alert rule create and folder read permissions and no rules exists', async () => {
- enableRBAC();
-
grantUserPermissions([
AccessControlAction.FoldersRead,
AccessControlAction.AlertingRuleCreate,
@@ -753,8 +744,6 @@ describe('RuleList', () => {
});
it('New alert button should be visible when the user has alert rule create and folder read permissions and rules already exists', async () => {
- enableRBAC();
-
grantUserPermissions([
AccessControlAction.FoldersRead,
AccessControlAction.AlertingRuleCreate,
@@ -775,8 +764,6 @@ describe('RuleList', () => {
describe('Cloud Alerts', () => {
it('New alert button should be visible when the user has the alert rule external write and datasource read permissions and no rules exists', async () => {
- enableRBAC();
-
grantUserPermissions([
// AccessControlAction.AlertingRuleRead,
AccessControlAction.DataSourcesRead,
@@ -803,8 +790,6 @@ describe('RuleList', () => {
});
it('New alert button should be visible when the user has the alert rule external write and data source read permissions and rules already exists', async () => {
- enableRBAC();
-
grantUserPermissions([
AccessControlAction.DataSourcesRead,
AccessControlAction.AlertingRuleExternalRead,
@@ -833,8 +818,6 @@ describe('RuleList', () => {
describe('Analytics', () => {
it('Sends log info when creating an alert rule from a scratch', async () => {
- enableRBAC();
-
grantUserPermissions([
AccessControlAction.FoldersRead,
AccessControlAction.AlertingRuleCreate,
diff --git a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx
index e8e02d2d341..61860be1322 100644
--- a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx
+++ b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx
@@ -12,6 +12,7 @@ import {
AlertManagerDataSourceJsonData,
AlertManagerImplementation,
} from 'app/plugins/datasource/alertmanager/types';
+import { AccessControlAction } from 'app/types';
import {
fetchAlertManagerConfig,
@@ -20,7 +21,7 @@ import {
fetchStatus,
} from '../../api/alertmanager';
import {
- disableRBAC,
+ grantUserPermissions,
mockDataSource,
MockDataSourceSrv,
someCloudAlertManagerConfig,
@@ -88,11 +89,12 @@ const ui = {
describe('Admin config', () => {
beforeEach(() => {
jest.resetAllMocks();
+ // FIXME: scope down
+ grantUserPermissions(Object.values(AccessControlAction));
mocks.getAllDataSources.mockReturnValue(Object.values(dataSources));
setDataSourceSrv(new MockDataSourceSrv(dataSources));
contextSrv.isGrafanaAdmin = true;
store.delete(ALERTMANAGER_NAME_LOCAL_STORAGE_KEY);
- disableRBAC();
});
it('Reset alertmanager config', async () => {
diff --git a/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx b/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx
index fd999810e01..7195e2b70fb 100644
--- a/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx
+++ b/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx
@@ -17,7 +17,7 @@ import { AccessControlAction, ContactPointsState, NotifierDTO, NotifierType } fr
import { backendSrv } from '../../../../../core/services/backend_srv';
import * as receiversApi from '../../api/receiversApi';
import { mockProvisioningApi, setupMswServer } from '../../mockApi';
-import { enableRBAC, grantUserPermissions } from '../../mocks';
+import { grantUserPermissions } from '../../mocks';
import { AlertmanagerProvider } from '../../state/AlertmanagerContext';
import { fetchGrafanaNotifiersAction } from '../../state/actions';
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
@@ -184,7 +184,6 @@ describe('ReceiversTable', () => {
const notifiers: NotifierDTO[] = [mockNotifier('googlechat', 'Google Chat'), mockNotifier('sensugo', 'Sensu Go')];
it('should be visible when user has permissions to read provisioning', async () => {
- enableRBAC();
grantUserPermissions([AccessControlAction.AlertingProvisioningRead]);
await renderReceieversTable(receivers, notifiers, GRAFANA_RULES_SOURCE_NAME);
@@ -193,7 +192,6 @@ describe('ReceiversTable', () => {
expect(buttons).toHaveLength(2);
});
it('should be visible when user has permissions to read provisioning with secrets', async () => {
- enableRBAC();
grantUserPermissions([AccessControlAction.AlertingProvisioningReadSecrets]);
await renderReceieversTable(receivers, notifiers, GRAFANA_RULES_SOURCE_NAME);
@@ -202,7 +200,6 @@ describe('ReceiversTable', () => {
expect(buttons).toHaveLength(2);
});
it('should not be visible when user has no provisioning permissions', async () => {
- enableRBAC();
grantUserPermissions([AccessControlAction.AlertingNotificationsRead]);
await renderReceieversTable(receivers, [], GRAFANA_RULES_SOURCE_NAME);
@@ -235,7 +232,6 @@ describe('ReceiversTable', () => {
const notifiers: NotifierDTO[] = [mockNotifier('googlechat', 'Google Chat'), mockNotifier('sensugo', 'Sensu Go')];
- enableRBAC();
grantUserPermissions([AccessControlAction.AlertingProvisioningRead]);
// Act
diff --git a/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx b/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx
index bed1ad3b75a..d8b07efe7dc 100644
--- a/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx
@@ -34,8 +34,6 @@ const ui = {
},
};
-jest.spyOn(contextSrv, 'accessControlEnabled').mockReturnValue(true);
-
const server = setupServer();
const alertmanagerChoiceMockedResponse: AlertmanagersChoiceResponse = {
diff --git a/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx b/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx
index 38c0a829e3f..7649000f67c 100644
--- a/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx
@@ -31,8 +31,6 @@ const ui = {
describe('RuleListGroupView', () => {
describe('RBAC', () => {
- jest.spyOn(contextSrv, 'accessControlEnabled').mockReturnValue(true);
-
it('Should display Grafana rules when the user has the alert rule read permission', async () => {
const grafanaNamespace = getGrafanaNamespace();
const namespaces: CombinedRuleNamespace[] = [grafanaNamespace];
diff --git a/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx b/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
index cd299760040..044e358d278 100644
--- a/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
@@ -8,12 +8,13 @@ import { byRole, byTestId, byText } from 'testing-library-selector';
import { logInfo } from '@grafana/runtime';
import { contextSrv } from 'app/core/services/context_srv';
import { configureStore } from 'app/store/configureStore';
+import { AccessControlAction } from 'app/types';
import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting';
import { LogMessages } from '../../Analytics';
import { useHasRuler } from '../../hooks/useHasRuler';
import { mockFolderApi, mockProvisioningApi, setupMswServer } from '../../mockApi';
-import { disableRBAC, mockCombinedRule, mockDataSource, mockFolder, mockGrafanaRulerRule } from '../../mocks';
+import { grantUserPermissions, mockCombinedRule, mockDataSource, mockFolder, mockGrafanaRulerRule } from '../../mocks';
import { RulesGroup } from './RulesGroup';
@@ -46,6 +47,8 @@ function mockUseHasRuler(hasRuler: boolean, rulerRulesLoaded: boolean) {
beforeEach(() => {
mocks.useHasRuler.mockReset();
+ // FIXME: scope down
+ grantUserPermissions(Object.values(AccessControlAction));
});
const ui = {
@@ -164,8 +167,6 @@ describe('Rules group tests', () => {
groups: [group],
};
- disableRBAC();
-
it('When ruler enabled should display delete and edit group buttons', () => {
// Arrange
mockUseHasRuler(true, true);
@@ -223,8 +224,6 @@ describe('Rules group tests', () => {
groups: [group],
};
- disableRBAC();
-
it('Should log info when closing the edit group rule modal without saving', async () => {
mockUseHasRuler(true, true);
renderRulesGroup(namespace, group);
diff --git a/public/app/features/alerting/unified/components/rules/RulesTable.test.tsx b/public/app/features/alerting/unified/components/rules/RulesTable.test.tsx
index f5283c8fd6e..da7cccf7a55 100644
--- a/public/app/features/alerting/unified/components/rules/RulesTable.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/RulesTable.test.tsx
@@ -5,7 +5,6 @@ import { Provider } from 'react-redux';
import { MemoryRouter } from 'react-router-dom';
import { byRole } from 'testing-library-selector';
-import { contextSrv } from 'app/core/services/context_srv';
import { configureStore } from 'app/store/configureStore';
import { CombinedRule } from 'app/types/unified-alerting';
@@ -31,8 +30,6 @@ const ui = {
},
};
-jest.spyOn(contextSrv, 'accessControlEnabled').mockReturnValue(true);
-
function renderRulesTable(rule: CombinedRule) {
const store = configureStore();
diff --git a/public/app/features/alerting/unified/hooks/useIsRuleEditable.test.tsx b/public/app/features/alerting/unified/hooks/useIsRuleEditable.test.tsx
index c94d79a21f5..f58f2c24f58 100644
--- a/public/app/features/alerting/unified/hooks/useIsRuleEditable.test.tsx
+++ b/public/app/features/alerting/unified/hooks/useIsRuleEditable.test.tsx
@@ -5,14 +5,7 @@ import { Provider } from 'react-redux';
import { contextSrv } from 'app/core/services/context_srv';
import { AccessControlAction, FolderDTO, StoreState } from 'app/types';
-import {
- disableRBAC,
- enableRBAC,
- mockFolder,
- mockRulerAlertingRule,
- mockRulerGrafanaRule,
- mockUnifiedAlertingStore,
-} from '../mocks';
+import { mockFolder, mockRulerAlertingRule, mockRulerGrafanaRule, mockUnifiedAlertingStore } from '../mocks';
import { useFolder } from './useFolder';
import { useIsRuleEditable } from './useIsRuleEditable';
@@ -27,7 +20,6 @@ const mocks = {
describe('useIsRuleEditable', () => {
describe('RBAC enabled', () => {
- beforeEach(enableRBAC);
describe('Grafana rules', () => {
// When RBAC is enabled we require appropriate alerting permissions in the folder scope
it('Should allow editing when the user has the alert rule update permission in the folder', async () => {
@@ -130,35 +122,6 @@ describe('useIsRuleEditable', () => {
});
});
});
-
- describe('RBAC disabled', () => {
- beforeEach(disableRBAC);
- describe('Grafana rules', () => {
- it('Should allow editing and deleting when the user has folder canSave permission', async () => {
- mockUseFolder({ canSave: true });
-
- const wrapper = getProviderWrapper();
-
- const { result } = renderHook(() => useIsRuleEditable('grafana', mockRulerGrafanaRule()), { wrapper });
-
- await waitFor(() => expect(result.current.loading).toBe(false));
- expect(result.current.isEditable).toBe(true);
- expect(result.current.isRemovable).toBe(true);
- });
-
- it('Should forbid editing and deleting when the user has no folder canSave permission', async () => {
- mockUseFolder({ canSave: false });
-
- const wrapper = getProviderWrapper();
-
- const { result } = renderHook(() => useIsRuleEditable('grafana', mockRulerGrafanaRule()), { wrapper });
-
- await waitFor(() => expect(result.current.loading).toBe(false));
- expect(result.current.isEditable).toBe(false);
- expect(result.current.isRemovable).toBe(false);
- });
- });
- });
});
function mockUseFolder(partial?: Partial) {
diff --git a/public/app/features/alerting/unified/mocks.ts b/public/app/features/alerting/unified/mocks.ts
index b7c78a7c1e2..132aba7d0a7 100644
--- a/public/app/features/alerting/unified/mocks.ts
+++ b/public/app/features/alerting/unified/mocks.ts
@@ -595,14 +595,6 @@ export const mockFolder = (partial?: Partial): FolderDTO => {
};
};
-export const enableRBAC = () => {
- jest.spyOn(contextSrv, 'accessControlEnabled').mockReturnValue(true);
-};
-
-export const disableRBAC = () => {
- jest.spyOn(contextSrv, 'accessControlEnabled').mockReturnValue(false);
-};
-
export const grantUserPermissions = (permissions: AccessControlAction[]) => {
jest
.spyOn(contextSrv, 'hasPermission')
diff --git a/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx
index 4cbf1393b14..1f42955fe5b 100644
--- a/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx
+++ b/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx
@@ -17,7 +17,6 @@ import { DashboardMetaChangedEvent } from 'app/types/events';
import { VariableEditorContainer } from '../../../variables/editor/VariableEditorContainer';
import { DashboardModel } from '../../state/DashboardModel';
import { AccessControlDashboardPermissions } from '../DashboardPermissions/AccessControlDashboardPermissions';
-import { DashboardPermissions } from '../DashboardPermissions/DashboardPermissions';
import { SaveDashboardAsButton, SaveDashboardButton } from '../SaveDashboard/SaveDashboardButton';
import { AnnotationsSettings } from './AnnotationsSettings';
@@ -148,14 +147,7 @@ function getSettingsPages(dashboard: DashboardModel) {
const permissionsTitle = t('dashboard-settings.permissions.title', 'Permissions');
if (dashboard.id && dashboard.meta.canAdmin) {
- if (!config.rbacEnabled) {
- pages.push({
- title: permissionsTitle,
- id: 'permissions',
- icon: 'lock',
- component: DashboardPermissions,
- });
- } else if (contextSrv.hasPermission(AccessControlAction.DashboardsPermissionsRead)) {
+ if (contextSrv.hasPermission(AccessControlAction.DashboardsPermissionsRead)) {
pages.push({
title: permissionsTitle,
id: 'permissions',
diff --git a/public/app/features/dashboard/state/DashboardModel.test.ts b/public/app/features/dashboard/state/DashboardModel.test.ts
index 8d764aa671b..58e14ca32bd 100644
--- a/public/app/features/dashboard/state/DashboardModel.test.ts
+++ b/public/app/features/dashboard/state/DashboardModel.test.ts
@@ -2,7 +2,6 @@ import { keys as _keys } from 'lodash';
import { dateTime, TimeRange, VariableHide } from '@grafana/data';
import { Dashboard, defaultVariableModel } from '@grafana/schema';
-import { contextSrv } from 'app/core/services/context_srv';
import { getDashboardModel } from '../../../../test/helpers/getDashboardModel';
import { variableAdapters } from '../../variables/adapters';
@@ -22,8 +21,6 @@ import {
jest.mock('app/core/services/context_srv');
-const mockContextSrv = jest.mocked(contextSrv);
-
variableAdapters.setInit(() => [
createQueryVariableAdapter(),
createAdHocVariableAdapter(),
@@ -950,7 +947,6 @@ describe('DashboardModel', () => {
dashboard.meta.canEdit = canEdit;
dashboard.meta.canMakeEditable = canMakeEditable;
- mockContextSrv.accessControlEnabled.mockReturnValue(true);
const result = dashboard.canAddAnnotations();
expect(result).toBe(expected);
}
@@ -983,7 +979,6 @@ describe('DashboardModel', () => {
dashboard.meta.canEdit = canEdit;
dashboard.meta.canMakeEditable = canMakeEditable;
- mockContextSrv.accessControlEnabled.mockReturnValue(true);
const result = dashboard.canEditAnnotations();
expect(result).toBe(expected);
}
@@ -1014,7 +1009,6 @@ describe('DashboardModel', () => {
dashboard.meta.canEdit = canEdit;
dashboard.meta.canMakeEditable = canMakeEditable;
- mockContextSrv.accessControlEnabled.mockReturnValue(true);
const result = dashboard.canEditAnnotations('testDashboardUID');
expect(result).toBe(expected);
}
@@ -1047,7 +1041,6 @@ describe('DashboardModel', () => {
dashboard.meta.canEdit = canEdit;
dashboard.meta.canMakeEditable = canMakeEditable;
- mockContextSrv.accessControlEnabled.mockReturnValue(true);
const result = dashboard.canDeleteAnnotations();
expect(result).toBe(expected);
}
@@ -1078,7 +1071,6 @@ describe('DashboardModel', () => {
dashboard.meta.canEdit = canEdit;
dashboard.meta.canMakeEditable = canMakeEditable;
- mockContextSrv.accessControlEnabled.mockReturnValue(true);
const result = dashboard.canDeleteAnnotations('testDashboardUID');
expect(result).toBe(expected);
}
diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts
index f10718649dd..d99b0f89628 100644
--- a/public/app/features/dashboard/state/DashboardModel.ts
+++ b/public/app/features/dashboard/state/DashboardModel.ts
@@ -1186,14 +1186,11 @@ export class DashboardModel implements TimeModel {
canEditAnnotations(dashboardUID?: string) {
let canEdit = true;
- // if RBAC is enabled there are additional conditions to check
- if (contextSrv.accessControlEnabled()) {
- // dashboardUID is falsy when it is an organizational annotation
- if (!dashboardUID) {
- canEdit = !!this.meta.annotationsPermissions?.organization.canEdit;
- } else {
- canEdit = !!this.meta.annotationsPermissions?.dashboard.canEdit;
- }
+ // dashboardUID is falsy when it is an organizational annotation
+ if (!dashboardUID) {
+ canEdit = !!this.meta.annotationsPermissions?.organization.canEdit;
+ } else {
+ canEdit = !!this.meta.annotationsPermissions?.dashboard.canEdit;
}
return this.canEditDashboard() && canEdit;
}
@@ -1201,13 +1198,11 @@ export class DashboardModel implements TimeModel {
canDeleteAnnotations(dashboardUID?: string) {
let canDelete = true;
- if (contextSrv.accessControlEnabled()) {
- // dashboardUID is falsy when it is an organizational annotation
- if (!dashboardUID) {
- canDelete = !!this.meta.annotationsPermissions?.organization.canDelete;
- } else {
- canDelete = !!this.meta.annotationsPermissions?.dashboard.canDelete;
- }
+ // dashboardUID is falsy when it is an organizational annotation
+ if (!dashboardUID) {
+ canDelete = !!this.meta.annotationsPermissions?.organization.canDelete;
+ } else {
+ canDelete = !!this.meta.annotationsPermissions?.dashboard.canDelete;
}
return canDelete && this.canEditDashboard();
}
@@ -1220,7 +1215,7 @@ export class DashboardModel implements TimeModel {
}
// If RBAC is enabled there are additional conditions to check.
- return !contextSrv.accessControlEnabled() || Boolean(this.meta.annotationsPermissions?.dashboard.canAdd);
+ return Boolean(this.meta.annotationsPermissions?.dashboard.canAdd);
}
canEditDashboard() {
diff --git a/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.test.ts b/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.test.ts
index 2b7ab9064ab..9d401a130b2 100644
--- a/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.test.ts
+++ b/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.test.ts
@@ -3,7 +3,7 @@ import { lastValueFrom } from 'rxjs';
import { AlertState, getDefaultTimeRange, TimeRange } from '@grafana/data';
import { config } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
-import { disableRBAC, enableRBAC, grantUserPermissions } from 'app/features/alerting/unified/mocks';
+import { grantUserPermissions } from 'app/features/alerting/unified/mocks';
import { Annotation } from 'app/features/alerting/unified/utils/constants';
import { createDashboardModelFixture } from 'app/features/dashboard/state/__fixtures__/dashboardFixtures';
import { AccessControlAction } from 'app/types/accessControl';
@@ -47,10 +47,7 @@ describe('UnifiedAlertStatesWorker', () => {
beforeEach(() => {
config.publicDashboardAccessToken = '';
- });
-
- beforeAll(() => {
- disableRBAC();
+ grantUserPermissions(Object.values(AccessControlAction));
});
describe('when canWork is called with correct props', () => {
@@ -231,7 +228,6 @@ describe('UnifiedAlertStatesWorker', () => {
describe('UnifiedAlertStateWorker with RBAC', () => {
beforeAll(() => {
- enableRBAC();
grantUserPermissions([]);
});
diff --git a/public/app/features/teams/TeamPages.tsx b/public/app/features/teams/TeamPages.tsx
index e8f0f56e53c..240a113dda5 100644
--- a/public/app/features/teams/TeamPages.tsx
+++ b/public/app/features/teams/TeamPages.tsx
@@ -41,11 +41,9 @@ function mapStateToProps(state: StoreState, props: OwnProps) {
const teamId = parseInt(props.match.params.id, 10);
const team = getTeam(state.team, teamId);
let defaultPage = 'members';
- if (contextSrv.accessControlEnabled()) {
- // With RBAC the settings page will always be available
- if (!team || !contextSrv.hasPermissionInMetadata(AccessControlAction.ActionTeamsPermissionsRead, team)) {
- defaultPage = 'settings';
- }
+ // With RBAC the settings page will always be available
+ if (!team || !contextSrv.hasPermissionInMetadata(AccessControlAction.ActionTeamsPermissionsRead, team)) {
+ defaultPage = 'settings';
}
const pageName = props.match.params.page ?? defaultPage;
const teamLoadingNav = getTeamLoadingNav(pageName);
diff --git a/public/app/plugins/panel/graph/event_editor.ts b/public/app/plugins/panel/graph/event_editor.ts
index c64b2c9e2b1..886d7d698c7 100644
--- a/public/app/plugins/panel/graph/event_editor.ts
+++ b/public/app/plugins/panel/graph/event_editor.ts
@@ -4,7 +4,6 @@ import { AnnotationEvent, dateTime } from '@grafana/data';
import { coreModule } from 'app/angular/core_module';
import { MetricsPanelCtrl } from 'app/angular/panel/metrics_panel_ctrl';
-import { contextSrv } from '../../../core/services/context_srv';
import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../../features/annotations/api';
import { getDashboardQueryRunner } from '../../../features/query/state/DashboardQueryRunner/DashboardQueryRunner';
@@ -34,13 +33,10 @@ export class EventEditorCtrl {
}
canDelete(): boolean {
- if (contextSrv.accessControlEnabled()) {
- if (this.event.source?.type === 'dashboard') {
- return !!this.panelCtrl.dashboard.meta.annotationsPermissions?.dashboard.canDelete;
- }
- return !!this.panelCtrl.dashboard.meta.annotationsPermissions?.organization.canDelete;
+ if (this.event.source?.type === 'dashboard') {
+ return !!this.panelCtrl.dashboard.meta.annotationsPermissions?.dashboard.canDelete;
}
- return true;
+ return !!this.panelCtrl.dashboard.meta.annotationsPermissions?.organization.canDelete;
}
async save(): Promise {