enable permissions for data source

This commit is contained in:
Peter Holmberg
2018-10-10 10:39:48 +02:00
parent 363592a97b
commit 8ed5594dbc
5 changed files with 76 additions and 25 deletions

View File

@@ -4,14 +4,20 @@ import SlideDown from '../../core/components/Animations/SlideDown';
import AddDataSourcePermissions from './AddDataSourcePermissions'; import AddDataSourcePermissions from './AddDataSourcePermissions';
import DataSourcePermissionsList from './DataSourcePermissionsList'; import DataSourcePermissionsList from './DataSourcePermissionsList';
import { AclTarget } from 'app/types/acl'; 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 { DashboardAcl, DataSourcePermission } from 'app/types';
import { getRouteParamsId } from '../../core/selectors/location'; import { getRouteParamsId } from '../../core/selectors/location';
export interface Props { export interface Props {
dataSourcePermissions: DataSourcePermission[]; dataSourcePermission: { enabled: boolean; datasouceId: number; permissions: DataSourcePermission[] };
pageId: number; pageId: number;
addDataSourcePermission: typeof addDataSourcePermission; addDataSourcePermission: typeof addDataSourcePermission;
enableDataSourcePermissions: typeof enableDataSourcePermissions;
loadDataSourcePermissions: typeof loadDataSourcePermissions; loadDataSourcePermissions: typeof loadDataSourcePermissions;
removeDataSourcePermission: typeof removeDataSourcePermission; removeDataSourcePermission: typeof removeDataSourcePermission;
} }
@@ -41,6 +47,11 @@ export class DataSourcePermissions extends PureComponent<Props, State> {
}); });
}; };
onEnablePermissions = () => {
const { pageId, enableDataSourcePermissions } = this.props;
enableDataSourcePermissions(pageId);
};
onAddPermission = state => { onAddPermission = state => {
const { pageId, addDataSourcePermission } = this.props; const { pageId, addDataSourcePermission } = this.props;
const data = { const data = {
@@ -69,25 +80,51 @@ export class DataSourcePermissions extends PureComponent<Props, State> {
}; };
render() { render() {
const { dataSourcePermissions } = this.props; const { dataSourcePermission } = this.props;
const { isAdding } = this.state; const { isAdding } = this.state;
const isPermissionsEnabled = dataSourcePermission.enabled;
return ( return (
<div> <div>
<div className="page-action-bar"> <div className="page-action-bar">
<h3 className="page-sub-heading">Permissions</h3> <h3 className="page-sub-heading">Permissions</h3>
<div className="page-action-bar__spacer" /> <div className="page-action-bar__spacer" />
<button className="btn btn-success pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}> {!isPermissionsEnabled && (
<i className="fa fa-plus" /> Add Permission <button className="btn btn-success pull-right" onClick={this.onEnablePermissions} disabled={isAdding}>
</button> Enable Permissions
</button>
)}
{isPermissionsEnabled && (
<button className="btn btn-success pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
<i className="fa fa-plus" /> Add Permission
</button>
)}
</div> </div>
<SlideDown in={isAdding}> {!isPermissionsEnabled ? (
<AddDataSourcePermissions <div className="empty-list-cta">
onAddPermission={state => this.onAddPermission(state)} <div className="empty-list-cta__title">{'Permissions not enabled for this data source.'}</div>
onCancel={this.onCancelAddPermission} <button onClick={this.onEnablePermissions} className="empty-list-cta__button btn btn-xlarge btn-success">
/> {'Enable'}
</SlideDown> </button>
<DataSourcePermissionsList items={dataSourcePermissions} onRemoveItem={item => this.onRemovePermission(item)} /> <div className="empty-list-cta__pro-tip">
<i className="fa fa-rocket" /> ProTip:{' '}
{'Only admins will be able to query the data source after you enable permissions.'}
</div>
</div>
) : (
<div>
<SlideDown in={isAdding}>
<AddDataSourcePermissions
onAddPermission={state => this.onAddPermission(state)}
onCancel={this.onCancelAddPermission}
/>
</SlideDown>
<DataSourcePermissionsList
items={dataSourcePermission.permissions}
onRemoveItem={item => this.onRemovePermission(item)}
/>
</div>
)}
</div> </div>
); );
} }
@@ -96,12 +133,13 @@ export class DataSourcePermissions extends PureComponent<Props, State> {
function mapStateToProps(state) { function mapStateToProps(state) {
return { return {
pageId: getRouteParamsId(state.location), pageId: getRouteParamsId(state.location),
dataSourcePermissions: state.dataSources.dataSourcePermissions, dataSourcePermission: state.dataSources.dataSourcePermission,
}; };
} }
const mapDispatchToProps = { const mapDispatchToProps = {
addDataSourcePermission, addDataSourcePermission,
enableDataSourcePermissions,
loadDataSourcePermissions, loadDataSourcePermissions,
removeDataSourcePermission, removeDataSourcePermission,
}; };

View File

@@ -1,11 +1,10 @@
import { ThunkAction } from 'redux-thunk'; 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 { getBackendSrv } from '../../../core/services/backend_srv';
import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector'; import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector';
import { updateLocation, updateNavIndex, UpdateNavIndexAction } from '../../../core/actions'; import { updateLocation, updateNavIndex, UpdateNavIndexAction } from '../../../core/actions';
import { UpdateLocationAction } from '../../../core/actions/location'; import { UpdateLocationAction } from '../../../core/actions/location';
import { buildNavModel } from './navModel'; import { buildNavModel } from './navModel';
import { DataSourcePermission } from '../../../types/datasources';
export enum ActionTypes { export enum ActionTypes {
LoadDataSources = 'LOAD_DATA_SOURCES', LoadDataSources = 'LOAD_DATA_SOURCES',
@@ -55,7 +54,7 @@ export interface LoadDataSourceMetaAction {
export interface LoadDataSourcePermissionsAction { export interface LoadDataSourcePermissionsAction {
type: ActionTypes.LoadDataSourcePermissions; type: ActionTypes.LoadDataSourcePermissions;
payload: DataSourcePermission[]; payload: DataSourcePermissionDTO;
} }
const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({ const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({
@@ -79,10 +78,10 @@ const dataSourceTypesLoaded = (dataSourceTypes: Plugin[]): LoadDataSourceTypesAc
}); });
const dataSourcePermissionsLoaded = ( const dataSourcePermissionsLoaded = (
dataSourcePermissions: DataSourcePermission[] dataSourcePermission: DataSourcePermissionDTO
): LoadDataSourcePermissionsAction => ({ ): LoadDataSourcePermissionsAction => ({
type: ActionTypes.LoadDataSourcePermissions, type: ActionTypes.LoadDataSourcePermissions,
payload: dataSourcePermissions, payload: dataSourcePermission,
}); });
export const setDataSourcesSearchQuery = (searchQuery: string): SetDataSourcesSearchQueryAction => ({ export const setDataSourcesSearchQuery = (searchQuery: string): SetDataSourcesSearchQueryAction => ({
@@ -163,7 +162,14 @@ export function loadDataSourceTypes(): ThunkResult<void> {
export function loadDataSourcePermissions(id: number): ThunkResult<void> { export function loadDataSourcePermissions(id: number): ThunkResult<void> {
return async dispatch => { return async dispatch => {
const response = await getBackendSrv().get(`/api/datasources/${id}/permissions`); const response = await getBackendSrv().get(`/api/datasources/${id}/permissions`);
dispatch(dataSourcePermissionsLoaded(response.permissions)); dispatch(dataSourcePermissionsLoaded(response));
};
}
export function enableDataSourcePermissions(id: number): ThunkResult<void> {
return async dispatch => {
await getBackendSrv().post(`/api/datasources/${id}/enable-permissions`, {});
dispatch(loadDataSourcePermissions(id));
}; };
} }

View File

@@ -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 { Action, ActionTypes } from './actions';
import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector'; import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector';
@@ -11,7 +11,7 @@ const initialState: DataSourcesState = {
dataSourceTypes: [] as Plugin[], dataSourceTypes: [] as Plugin[],
dataSourceTypeSearchQuery: '', dataSourceTypeSearchQuery: '',
dataSourceMeta: {} as Plugin, dataSourceMeta: {} as Plugin,
dataSourcePermissions: [] as DataSourcePermission[], dataSourcePermission: {} as DataSourcePermissionDTO,
}; };
export const dataSourcesReducer = (state = initialState, action: Action): DataSourcesState => { 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 }; return { ...state, dataSourceMeta: action.payload };
case ActionTypes.LoadDataSourcePermissions: case ActionTypes.LoadDataSourcePermissions:
return { ...state, dataSourcePermissions: action.payload }; return { ...state, dataSourcePermission: action.payload };
} }
return state; return state;

View File

@@ -14,6 +14,12 @@ export interface DataSourcePermission {
updated: string; updated: string;
} }
export interface DataSourcePermissionDTO {
datasourceId: number;
enabled: boolean;
permissions: DataSourcePermission[];
}
export interface DataSource { export interface DataSource {
id: number; id: number;
orgId: number; orgId: number;
@@ -40,5 +46,5 @@ export interface DataSourcesState {
dataSourceTypes: Plugin[]; dataSourceTypes: Plugin[];
dataSource: DataSource; dataSource: DataSource;
dataSourceMeta: Plugin; dataSourceMeta: Plugin;
dataSourcePermissions: DataSourcePermission[]; dataSourcePermission: DataSourcePermissionDTO;
} }

View File

@@ -7,7 +7,7 @@ import { DashboardState } from './dashboard';
import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { DashboardAcl, OrgRole, PermissionLevel } from './acl';
import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys'; import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys';
import { Invitee, OrgUser, User, UsersState } from './user'; 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'; import { PluginMeta, Plugin, PluginsState } from './plugins';
export { export {
@@ -41,6 +41,7 @@ export {
Plugin, Plugin,
PluginsState, PluginsState,
DataSourcesState, DataSourcesState,
DataSourcePermissionDTO,
DataSourcePermission, DataSourcePermission,
Invitee, Invitee,
OrgUser, OrgUser,