diff --git a/public/app/features/datasources/DataSourcePermissions.tsx b/public/app/features/datasources/DataSourcePermissions.tsx index dbee2d41634..ff02a9a6516 100644 --- a/public/app/features/datasources/DataSourcePermissions.tsx +++ b/public/app/features/datasources/DataSourcePermissions.tsx @@ -4,14 +4,20 @@ import SlideDown from '../../core/components/Animations/SlideDown'; import AddDataSourcePermissions from './AddDataSourcePermissions'; import DataSourcePermissionsList from './DataSourcePermissionsList'; import { AclTarget } from 'app/types/acl'; -import { addDataSourcePermission, loadDataSourcePermissions, removeDataSourcePermission } from './state/actions'; +import { + addDataSourcePermission, + enableDataSourcePermissions, + loadDataSourcePermissions, + removeDataSourcePermission, +} from './state/actions'; import { DashboardAcl, DataSourcePermission } from 'app/types'; import { getRouteParamsId } from '../../core/selectors/location'; export interface Props { - dataSourcePermissions: DataSourcePermission[]; + dataSourcePermission: { enabled: boolean; datasouceId: number; permissions: DataSourcePermission[] }; pageId: number; addDataSourcePermission: typeof addDataSourcePermission; + enableDataSourcePermissions: typeof enableDataSourcePermissions; loadDataSourcePermissions: typeof loadDataSourcePermissions; removeDataSourcePermission: typeof removeDataSourcePermission; } @@ -41,6 +47,11 @@ export class DataSourcePermissions extends PureComponent { }); }; + onEnablePermissions = () => { + const { pageId, enableDataSourcePermissions } = this.props; + enableDataSourcePermissions(pageId); + }; + onAddPermission = state => { const { pageId, addDataSourcePermission } = this.props; const data = { @@ -69,25 +80,51 @@ export class DataSourcePermissions extends PureComponent { }; render() { - const { dataSourcePermissions } = this.props; + const { dataSourcePermission } = this.props; const { isAdding } = this.state; + const isPermissionsEnabled = dataSourcePermission.enabled; return (

Permissions

- + {!isPermissionsEnabled && ( + + )} + {isPermissionsEnabled && ( + + )}
- - this.onAddPermission(state)} - onCancel={this.onCancelAddPermission} - /> - - this.onRemovePermission(item)} /> + {!isPermissionsEnabled ? ( +
+
{'Permissions not enabled for this data source.'}
+ +
+ ProTip:{' '} + {'Only admins will be able to query the data source after you enable permissions.'} +
+
+ ) : ( +
+ + this.onAddPermission(state)} + onCancel={this.onCancelAddPermission} + /> + + this.onRemovePermission(item)} + /> +
+ )}
); } @@ -96,12 +133,13 @@ export class DataSourcePermissions extends PureComponent { function mapStateToProps(state) { return { pageId: getRouteParamsId(state.location), - dataSourcePermissions: state.dataSources.dataSourcePermissions, + dataSourcePermission: state.dataSources.dataSourcePermission, }; } const mapDispatchToProps = { addDataSourcePermission, + enableDataSourcePermissions, loadDataSourcePermissions, removeDataSourcePermission, }; diff --git a/public/app/features/datasources/state/actions.ts b/public/app/features/datasources/state/actions.ts index ebd7c860c32..379b16b9e06 100644 --- a/public/app/features/datasources/state/actions.ts +++ b/public/app/features/datasources/state/actions.ts @@ -1,11 +1,10 @@ import { ThunkAction } from 'redux-thunk'; -import { DataSource, Plugin, StoreState } from 'app/types'; +import { DataSource, DataSourcePermissionDTO, Plugin, StoreState } from 'app/types'; import { getBackendSrv } from '../../../core/services/backend_srv'; import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector'; import { updateLocation, updateNavIndex, UpdateNavIndexAction } from '../../../core/actions'; import { UpdateLocationAction } from '../../../core/actions/location'; import { buildNavModel } from './navModel'; -import { DataSourcePermission } from '../../../types/datasources'; export enum ActionTypes { LoadDataSources = 'LOAD_DATA_SOURCES', @@ -55,7 +54,7 @@ export interface LoadDataSourceMetaAction { export interface LoadDataSourcePermissionsAction { type: ActionTypes.LoadDataSourcePermissions; - payload: DataSourcePermission[]; + payload: DataSourcePermissionDTO; } const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({ @@ -79,10 +78,10 @@ const dataSourceTypesLoaded = (dataSourceTypes: Plugin[]): LoadDataSourceTypesAc }); const dataSourcePermissionsLoaded = ( - dataSourcePermissions: DataSourcePermission[] + dataSourcePermission: DataSourcePermissionDTO ): LoadDataSourcePermissionsAction => ({ type: ActionTypes.LoadDataSourcePermissions, - payload: dataSourcePermissions, + payload: dataSourcePermission, }); export const setDataSourcesSearchQuery = (searchQuery: string): SetDataSourcesSearchQueryAction => ({ @@ -163,7 +162,14 @@ export function loadDataSourceTypes(): ThunkResult { export function loadDataSourcePermissions(id: number): ThunkResult { return async dispatch => { const response = await getBackendSrv().get(`/api/datasources/${id}/permissions`); - dispatch(dataSourcePermissionsLoaded(response.permissions)); + dispatch(dataSourcePermissionsLoaded(response)); + }; +} + +export function enableDataSourcePermissions(id: number): ThunkResult { + return async dispatch => { + await getBackendSrv().post(`/api/datasources/${id}/enable-permissions`, {}); + dispatch(loadDataSourcePermissions(id)); }; } diff --git a/public/app/features/datasources/state/reducers.ts b/public/app/features/datasources/state/reducers.ts index 0793e03b4d8..2fd8a21b9a7 100644 --- a/public/app/features/datasources/state/reducers.ts +++ b/public/app/features/datasources/state/reducers.ts @@ -1,4 +1,4 @@ -import { DataSource, DataSourcePermission, DataSourcesState, Plugin } from 'app/types'; +import { DataSource, DataSourcePermissionDTO, DataSourcesState, Plugin } from 'app/types'; import { Action, ActionTypes } from './actions'; import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector'; @@ -11,7 +11,7 @@ const initialState: DataSourcesState = { dataSourceTypes: [] as Plugin[], dataSourceTypeSearchQuery: '', dataSourceMeta: {} as Plugin, - dataSourcePermissions: [] as DataSourcePermission[], + dataSourcePermission: {} as DataSourcePermissionDTO, }; export const dataSourcesReducer = (state = initialState, action: Action): DataSourcesState => { @@ -38,7 +38,7 @@ export const dataSourcesReducer = (state = initialState, action: Action): DataSo return { ...state, dataSourceMeta: action.payload }; case ActionTypes.LoadDataSourcePermissions: - return { ...state, dataSourcePermissions: action.payload }; + return { ...state, dataSourcePermission: action.payload }; } return state; diff --git a/public/app/types/datasources.ts b/public/app/types/datasources.ts index 7abd96ce27f..7e62978e642 100644 --- a/public/app/types/datasources.ts +++ b/public/app/types/datasources.ts @@ -14,6 +14,12 @@ export interface DataSourcePermission { updated: string; } +export interface DataSourcePermissionDTO { + datasourceId: number; + enabled: boolean; + permissions: DataSourcePermission[]; +} + export interface DataSource { id: number; orgId: number; @@ -40,5 +46,5 @@ export interface DataSourcesState { dataSourceTypes: Plugin[]; dataSource: DataSource; dataSourceMeta: Plugin; - dataSourcePermissions: DataSourcePermission[]; + dataSourcePermission: DataSourcePermissionDTO; } diff --git a/public/app/types/index.ts b/public/app/types/index.ts index f7a52ec8b6d..eee34c291af 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -7,7 +7,7 @@ import { DashboardState } from './dashboard'; import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys'; import { Invitee, OrgUser, User, UsersState } from './user'; -import { DataSource, DataSourcePermission, DataSourcesState } from './datasources'; +import { DataSource, DataSourcePermissionDTO, DataSourcePermission, DataSourcesState } from './datasources'; import { PluginMeta, Plugin, PluginsState } from './plugins'; export { @@ -41,6 +41,7 @@ export { Plugin, PluginsState, DataSourcesState, + DataSourcePermissionDTO, DataSourcePermission, Invitee, OrgUser,