diff --git a/src/app/middleware/telemetryMiddleware.ts b/src/app/middleware/telemetryMiddleware.ts
index 423ae21d3..0b7141071 100644
--- a/src/app/middleware/telemetryMiddleware.ts
+++ b/src/app/middleware/telemetryMiddleware.ts
@@ -38,9 +38,7 @@ const telemetryMiddleware =
componentNames.FETCH_PERMISSIONS_ACTION,
state.sampleQuery,
action.response.error,
- {
- HasRequestUrl: action.response.hasUrl
- }
+ {}
);
break;
}
diff --git a/src/app/services/actions/autocomplete-action-creators.spec.ts b/src/app/services/actions/autocomplete-action-creators.spec.ts
index fb2f7f1de..1075eb1ec 100644
--- a/src/app/services/actions/autocomplete-action-creators.spec.ts
+++ b/src/app/services/actions/autocomplete-action-creators.spec.ts
@@ -56,8 +56,10 @@ const mockState: IRootState = {
},
scopes: {
pending: false,
- data: [],
- hasUrl: false,
+ data: {
+ fullPermissions: [],
+ specificPermissions: []
+ },
error: null
},
history: [],
diff --git a/src/app/services/actions/permissions-action-creator.spec.ts b/src/app/services/actions/permissions-action-creator.spec.ts
index e4af12e29..9099e1a34 100644
--- a/src/app/services/actions/permissions-action-creator.spec.ts
+++ b/src/app/services/actions/permissions-action-creator.spec.ts
@@ -1,12 +1,12 @@
import {
FETCH_SCOPES_ERROR,
FETCH_SCOPES_PENDING,
- FETCH_SCOPES_SUCCESS,
- QUERY_GRAPH_STATUS
-} from '../redux-constants';
+ QUERY_GRAPH_STATUS,
+ FETCH_FULL_SCOPES_SUCCESS
+} from '../../../app/services/redux-constants';
import {
- fetchScopesSuccess, fetchScopesPending, fetchScopesError, getPermissionsScopeType, fetchScopes,
+ fetchFullScopesSuccess, fetchScopesPending, fetchScopesError, getPermissionsScopeType, fetchScopes,
consentToScopes
} from
'./permissions-action-creator';
@@ -59,8 +59,10 @@ const mockState: IRootState = {
},
scopes: {
pending: false,
- data: [],
- hasUrl: false,
+ data: {
+ fullPermissions: [],
+ specificPermissions: []
+ },
error: null
},
history: [],
@@ -133,24 +135,19 @@ describe('tests permissions action creators', () => {
it('Tests if FETCH_SCOPES_SUCCESS is dispatched when fetchScopesSuccess is called', () => {
// Arrange
const response: IPermissionsResponse = {
- hasUrl: true,
- scopes: [
- {
- value: '',
- consentDescription: '',
- isAdmin: false,
- consented: true
- }
- ]
+ scopes: {
+ fullPermissions: [],
+ specificPermissions: []
+ }
}
const expectedAction = {
- type: FETCH_SCOPES_SUCCESS,
+ type: FETCH_FULL_SCOPES_SUCCESS,
response
}
// Act
- const action = fetchScopesSuccess(response);
+ const action = fetchFullScopesSuccess(response);
// Assert
expect(action).toEqual(expectedAction);
@@ -159,7 +156,6 @@ describe('tests permissions action creators', () => {
it('Tests if FETCH_SCOPES_ERROR is dispatched when fetchScopesError is called', () => {
// Arrange
const response = {
- hasUrl: true,
error: {}
}
diff --git a/src/app/services/actions/permissions-action-creator.ts b/src/app/services/actions/permissions-action-creator.ts
index 081cba7d2..756cbef4e 100644
--- a/src/app/services/actions/permissions-action-creator.ts
+++ b/src/app/services/actions/permissions-action-creator.ts
@@ -14,7 +14,8 @@ import { ACCOUNT_TYPE, PERMS_SCOPE } from '../graph-constants';
import {
FETCH_SCOPES_ERROR,
FETCH_SCOPES_PENDING,
- FETCH_SCOPES_SUCCESS
+ FETCH_FULL_SCOPES_SUCCESS,
+ FETCH_URL_SCOPES_SUCCESS
} from '../redux-constants';
import {
getAuthTokenSuccess,
@@ -23,13 +24,20 @@ import {
import { getProfileInfo } from './profile-action-creators';
import { setQueryResponseStatus } from './query-status-action-creator';
-export function fetchScopesSuccess(response: object): IAction {
+export function fetchFullScopesSuccess(response: object): IAction {
return {
- type: FETCH_SCOPES_SUCCESS,
+ type: FETCH_FULL_SCOPES_SUCCESS,
response
};
}
+export function fetchUrlScopesSuccess(response: Object): IAction {
+ return {
+ type: FETCH_URL_SCOPES_SUCCESS,
+ response
+ }
+}
+
export function fetchScopesPending(): any {
return {
type: FETCH_SCOPES_PENDING
@@ -45,7 +53,6 @@ export function fetchScopesError(response: object): IAction {
export function fetchScopes(): Function {
return async (dispatch: Function, getState: Function) => {
- let hasUrl = false; // whether permissions are for a specific url
try {
const { devxApi, permissionsPanelOpen, profile, sampleQuery: query }: IRootState = getState();
let permissionsUrl = `${devxApi.baseUrl}/permissions`;
@@ -62,7 +69,6 @@ export function fetchScopes(): Function {
// eslint-disable-next-line max-len
permissionsUrl = `${permissionsUrl}?requesturl=/${requestUrl}&method=${query.selectedVerb}&scopeType=${scopeType}`;
- hasUrl = true;
}
if (devxApi.parameters) {
@@ -81,18 +87,19 @@ export function fetchScopes(): Function {
const response = await fetch(permissionsUrl, options);
if (response.ok) {
const scopes = await response.json();
- return dispatch(
- fetchScopesSuccess({
- hasUrl,
- scopes
- })
- );
+
+ return permissionsPanelOpen ? dispatch(fetchFullScopesSuccess({
+ scopes: { fullPermissions: scopes }
+ })) :
+ dispatch(fetchUrlScopesSuccess({
+ scopes: { specificPermissions: scopes }
+ }));
}
+
throw response;
} catch (error) {
return dispatch(
fetchScopesError({
- hasUrl,
error
})
);
diff --git a/src/app/services/actions/resource-explorer-action-creators.spec.ts b/src/app/services/actions/resource-explorer-action-creators.spec.ts
index 3e7f546a6..11f503146 100644
--- a/src/app/services/actions/resource-explorer-action-creators.spec.ts
+++ b/src/app/services/actions/resource-explorer-action-creators.spec.ts
@@ -51,8 +51,10 @@ const mockState: IRootState = {
},
scopes: {
pending: false,
- data: [],
- hasUrl: false,
+ data: {
+ fullPermissions: [],
+ specificPermissions: []
+ },
error: null
},
history: [],
diff --git a/src/app/services/reducers/permissions-reducer.spec.ts b/src/app/services/reducers/permissions-reducer.spec.ts
index 724ea65b5..94703ae65 100644
--- a/src/app/services/reducers/permissions-reducer.spec.ts
+++ b/src/app/services/reducers/permissions-reducer.spec.ts
@@ -1,27 +1,37 @@
import { scopes } from '../../../app/services/reducers/permissions-reducer';
-import { FETCH_SCOPES_ERROR, FETCH_SCOPES_PENDING, FETCH_SCOPES_SUCCESS } from '../../../app/services/redux-constants';
+import {
+ FETCH_SCOPES_ERROR, FETCH_SCOPES_PENDING,
+ FETCH_FULL_SCOPES_SUCCESS,
+ FETCH_URL_SCOPES_SUCCESS
+} from '../../../app/services/redux-constants';
const initialState = {
pending: false,
- data: [],
- hasUrl: false,
+ data: {
+ fullPermissions: [],
+ specificPermissions: []
+ },
error: null
};
describe('Permissions reducer', () => {
- it('should handle FETCH_SCOPES_SUCCESS', () => {
+ it('should handle FETCH_FULL_SCOPES_SUCCESS', () => {
const action = {
- type: FETCH_SCOPES_SUCCESS,
+ type: FETCH_FULL_SCOPES_SUCCESS,
response: {
- hasUrl: false,
- scopes: ['profile.read', 'profile.write', 'email.read', 'email.write']
+ scopes: {
+ specificPermissions: [],
+ fullPermissions: ['profile.read', 'profile.write', 'email.read', 'email.write']
+ }
}
}
const expectedState = {
pending: false,
- data: ['profile.read', 'profile.write', 'email.read', 'email.write'],
- hasUrl: false,
+ data: {
+ fullPermissions: ['profile.read', 'profile.write', 'email.read', 'email.write'],
+ specificPermissions: []
+ },
error: null
}
@@ -29,6 +39,30 @@ describe('Permissions reducer', () => {
expect(newState).toEqual(expectedState);
});
+ it('should handle FETCH_URL_SCOPES_SUCCESS', () => {
+ const action = {
+ type: FETCH_URL_SCOPES_SUCCESS,
+ response: {
+ scopes: {
+ specificPermissions: ['profile.read', 'profile.write', 'email.read', 'email.write'],
+ fullPermissions: []
+ }
+ }
+ }
+
+ const expectedState = {
+ pending: false,
+ data: {
+ fullPermissions: [],
+ specificPermissions: ['profile.read', 'profile.write', 'email.read', 'email.write']
+ },
+ error: null
+ }
+
+ const newState = scopes(initialState, action);
+ expect(newState).toEqual(expectedState);
+ })
+
it('should handle FETCH_SCOPES_ERROR', () => {
const action = {
type: FETCH_SCOPES_ERROR,
@@ -36,8 +70,7 @@ describe('Permissions reducer', () => {
}
const expectedState = {
pending: false,
- data: [],
- hasUrl: false,
+ data: {},
error: 'error'
}
@@ -53,8 +86,10 @@ describe('Permissions reducer', () => {
const expectedState = {
pending: true,
- data: [],
- hasUrl: false,
+ data: {
+ fullPermissions: [],
+ specificPermissions: []
+ },
error: null
}
diff --git a/src/app/services/reducers/permissions-reducer.ts b/src/app/services/reducers/permissions-reducer.ts
index 08a771032..44b0a1013 100644
--- a/src/app/services/reducers/permissions-reducer.ts
+++ b/src/app/services/reducers/permissions-reducer.ts
@@ -1,37 +1,46 @@
import { IAction } from '../../../types/action';
import { IPermissionsResponse, IScopes } from '../../../types/permissions';
-import { FETCH_SCOPES_ERROR, FETCH_SCOPES_PENDING, FETCH_SCOPES_SUCCESS } from '../redux-constants';
+import {
+ FETCH_SCOPES_ERROR, FETCH_SCOPES_PENDING, FETCH_FULL_SCOPES_SUCCESS,
+ FETCH_URL_SCOPES_SUCCESS
+} from '../redux-constants';
const initialState: IScopes = {
pending: false,
- data: [],
- hasUrl: false,
+ data: {
+ specificPermissions: [],
+ fullPermissions: []
+ },
error: null
};
export function scopes(state: IScopes = initialState, action: IAction): any {
switch (action.type) {
- case FETCH_SCOPES_SUCCESS:
- const response: IPermissionsResponse = { ...action.response as IPermissionsResponse };
+ case FETCH_FULL_SCOPES_SUCCESS:
+ let response: IPermissionsResponse = { ...action.response as IPermissionsResponse };
return {
pending: false,
- data: response.scopes,
- hasUrl: response.hasUrl,
+ data: { ...state.data, fullPermissions: response.scopes.fullPermissions },
error: null
};
+ case FETCH_URL_SCOPES_SUCCESS:
+ response = { ...action.response as IPermissionsResponse };
+ return {
+ pending: false,
+ data: { ...state.data, specificPermissions: response.scopes.specificPermissions },
+ error: null
+ }
case FETCH_SCOPES_ERROR:
return {
pending: false,
error: action.response,
- hasUrl: false,
- data: []
+ data: {}
};
case FETCH_SCOPES_PENDING:
return {
pending: true,
- data: [],
- error: null,
- hasUrl: false
+ data: state.data,
+ error: null
};
default:
return state;
diff --git a/src/app/services/redux-constants.ts b/src/app/services/redux-constants.ts
index 27c5a5a72..81f066345 100644
--- a/src/app/services/redux-constants.ts
+++ b/src/app/services/redux-constants.ts
@@ -27,7 +27,8 @@ export const FETCH_ADAPTIVE_CARD_SUCCESS = 'FETCH_ADAPTIVE_CARD_SUCCESS';
export const FETCH_ADAPTIVE_CARD_PENDING = 'FETCH_ADAPTIVE_CARD_PENDING';
export const FETCH_ADAPTIVE_CARD_ERROR = 'FETCH_ADAPTIVE_CARD_ERROR';
export const CLEAR_TERMS_OF_USE = 'CLEAR_TERMS_OF_USE';
-export const FETCH_SCOPES_SUCCESS = 'SCOPES_FETCH_SUCCESS';
+export const FETCH_FULL_SCOPES_SUCCESS = 'FULL_SCOPES_FETCH_SUCCESS';
+export const FETCH_URL_SCOPES_SUCCESS = 'FETCH_URL_SCOPES_SUCCESS';
export const FETCH_SCOPES_ERROR = 'SCOPES_FETCH_ERROR';
export const FETCH_SCOPES_PENDING = 'FETCH_SCOPES_PENDING';
export const GET_CONSENT_ERROR = 'GET_CONSENT_ERROR';
diff --git a/src/app/views/query-runner/request/permissions/PanelList.tsx b/src/app/views/query-runner/request/permissions/PanelList.tsx
index d491fb913..76e5859e2 100644
--- a/src/app/views/query-runner/request/permissions/PanelList.tsx
+++ b/src/app/views/query-runner/request/permissions/PanelList.tsx
@@ -34,8 +34,13 @@ const PanelList = ({ messages,
columns, classes, selection,
renderItemColumn, renderDetailsHeader, renderCustomCheckbox }: IPanelList) => {
+ const sortedPermissions = (permissionsToSort: IPermission[]) : IPermission[] => {
+ return permissionsToSort.sort(dynamicSort('value', SortOrder.ASC));
+ }
+
const { consentedScopes, scopes, authToken } = useSelector((state: IRootState) => state);
- const [permissions, setPermissions] = useState(scopes.data.sort(dynamicSort('value', SortOrder.ASC)));
+ const { fullPermissions } = scopes.data;
+ const [permissions, setPermissions] = useState(sortedPermissions(fullPermissions));
const permissionsList: any[] = [];
const tokenPresent = !!authToken.token;
@@ -50,11 +55,11 @@ const PanelList = ({ messages,
});
const searchValueChanged = (event: any, value?: string): void => {
- let filteredPermissions = scopes.data;
+ let filteredPermissions = scopes.data.fullPermissions;
if (value) {
const keyword = value.toLowerCase();
- filteredPermissions = scopes.data.filter((permission: IPermission) => {
+ filteredPermissions = fullPermissions.filter((permission: IPermission) => {
const name = permission.value.toLowerCase();
return name.includes(keyword);
});
@@ -65,7 +70,7 @@ const PanelList = ({ messages,
const groups = generateGroupsFromList(permissionsList, 'groupName');
- const _onRenderGroupHeader = (props: any): any => {
+ const onRenderGroupHeader = (props: any): any => {
if (props) {
return (
@@ -101,7 +106,7 @@ const PanelList = ({ messages,
compact={true}
groupProps={{
showEmptyGroups: false,
- onRenderHeader: _onRenderGroupHeader
+ onRenderHeader: onRenderGroupHeader
}}
ariaLabelForSelectionColumn={messages['Toggle selection'] || 'Toggle selection'}
ariaLabelForSelectAllCheckbox={messages['Toggle selection for all items'] || 'Toggle selection for all items'}
diff --git a/src/app/views/query-runner/request/permissions/Permission.spec.tsx b/src/app/views/query-runner/request/permissions/Permission.spec.tsx
index 3aefdc573..cc4ef1ab8 100644
--- a/src/app/views/query-runner/request/permissions/Permission.spec.tsx
+++ b/src/app/views/query-runner/request/permissions/Permission.spec.tsx
@@ -42,7 +42,6 @@ const renderPermission = (args?: any) => {
consented: true
}
],
- hasUrl: true,
error: null
},
panel: args?.panel || false,
@@ -67,20 +66,36 @@ const renderPermission = (args?: any) => {
}
const permissionState: IPermissionState = {
- permissions: [
- {
- value: 'profile.read',
- isAdmin: false,
- consentDescription: 'Read your profile',
- consented: true
- },
- {
- value: 'profile.write',
- isAdmin: false,
- consentDescription: 'Write your profile',
- consented: true
- }
- ]
+ permissions: {
+ specificPermissions: [
+ {
+ value: 'profile.read',
+ isAdmin: false,
+ consentDescription: 'Read your profile',
+ consented: true
+ },
+ {
+ value: 'profile.write',
+ isAdmin: false,
+ consentDescription: 'Write your profile',
+ consented: true
+ }
+ ],
+ fullPermissions: [
+ {
+ value: 'profile.read',
+ isAdmin: false,
+ consentDescription: 'Read your profile',
+ consented: true
+ },
+ {
+ value: 'profile.write',
+ isAdmin: false,
+ consentDescription: 'Write your profile',
+ consented: true
+ }
+ ]
+ }
}
const allProps = { ...permissionProps, ...permissionState };
diff --git a/src/app/views/query-runner/request/permissions/Permission.tsx b/src/app/views/query-runner/request/permissions/Permission.tsx
index 848e4ff34..814fd80e4 100644
--- a/src/app/views/query-runner/request/permissions/Permission.tsx
+++ b/src/app/views/query-runner/request/permissions/Permission.tsx
@@ -31,7 +31,10 @@ export class Permission extends Component {
constructor(props: IPermissionProps) {
super(props);
this.state = {
- permissions: []
+ permissions: {
+ specificPermissions: [],
+ fullPermissions: []
+ }
};
}
diff --git a/src/app/views/query-runner/request/permissions/TabList.spec.tsx b/src/app/views/query-runner/request/permissions/TabList.spec.tsx
index bcb986586..5e1b330de 100644
--- a/src/app/views/query-runner/request/permissions/TabList.spec.tsx
+++ b/src/app/views/query-runner/request/permissions/TabList.spec.tsx
@@ -53,20 +53,36 @@ jest.mock('react-redux', () => {
consentedScopes: ['profile.read', 'profile.write', 'mail.read', 'mail.write'],
scopes: {
pending: false,
- data: [
- {
- value: 'profile.read',
- isAdmin: false,
- consentDescription: 'Read your profile',
- consented: true
- },
- {
- value: 'profile.write',
- isAdmin: false,
- consentDescription: 'Write your profile',
- consented: true
- }
- ]
+ data: {
+ specificPermissions: [
+ {
+ value: 'profile.read',
+ isAdmin: false,
+ consentDescription: 'Read your profile',
+ consented: true
+ },
+ {
+ value: 'profile.write',
+ isAdmin: false,
+ consentDescription: 'Write your profile',
+ consented: true
+ }
+ ],
+ fullPermissions: [
+ {
+ value: 'profile.read',
+ isAdmin: false,
+ consentDescription: 'Read your profile',
+ consented: true
+ },
+ {
+ value: 'profile.write',
+ isAdmin: false,
+ consentDescription: 'Write your profile',
+ consented: true
+ }
+ ]
+ }
},
authToken: {
pending: false,
@@ -84,6 +100,6 @@ console.warn = jest.fn()
describe('Renders permissions tab', () => {
it('Renders Modify Permissions Tab without crasing', () => {
const { getByText } = renderTabList();
- getByText(/Permissions for the query are missing on this tab/)
+ getByText(/One of the following permissions is required to run the query/)
})
})
\ No newline at end of file
diff --git a/src/app/views/query-runner/request/permissions/TabList.tsx b/src/app/views/query-runner/request/permissions/TabList.tsx
index 484ab68eb..a46e0017a 100644
--- a/src/app/views/query-runner/request/permissions/TabList.tsx
+++ b/src/app/views/query-runner/request/permissions/TabList.tsx
@@ -19,7 +19,7 @@ interface ITabList {
const TabList = ({ columns, classes, renderItemColumn, renderDetailsHeader, maxHeight }: ITabList) => {
const dispatch = useDispatch();
const { consentedScopes, scopes, authToken } = useSelector((state: IRootState) => state);
- const permissions: IPermission[] = scopes.hasUrl ? scopes.data : [];
+ const permissions: IPermission[] = scopes.data.specificPermissions;
const tokenPresent = !!authToken.token;
const [isHoverOverPermissionsList, setIsHoverOverPermissionsList] = useState(false);
@@ -45,11 +45,7 @@ const TabList = ({ columns, classes, renderItemColumn, renderDetailsHeader, maxH
)
}
- if (tokenPresent && !scopes.hasUrl) {
- return displayNoPermissionsFoundMessage();
- }
-
- if (!tokenPresent && !scopes.hasUrl) {
+ if (!tokenPresent) {
return displayNotSignedInMessage();
}
diff --git a/src/types/permissions.ts b/src/types/permissions.ts
index 66b563108..0cfc56276 100644
--- a/src/types/permissions.ts
+++ b/src/types/permissions.ts
@@ -23,21 +23,28 @@ export interface IPermissionProps {
actions?: {
fetchScopes: Function;
consentToScopes: Function;
- };
+ }
}
export interface IPermissionState {
- permissions: IPermission[];
+ permissions: {
+ specificPermissions: IPermission[];
+ fullPermissions: IPermission[];
+ };
}
export interface IPermissionsResponse {
- hasUrl: boolean;
- scopes: IPermission[];
+ scopes: {
+ specificPermissions: IPermission[];
+ fullPermissions: IPermission[];
+ }
}
export interface IScopes {
pending: boolean;
- data: IPermission[];
- hasUrl: boolean;
+ data: {
+ specificPermissions: IPermission[];
+ fullPermissions: IPermission[];
+ };
error: any | null;
}