add-isAdmin-to-store
authorPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Thu, 29 Nov 2018 10:52:54 +0000 (11:52 +0100)
committerPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Thu, 29 Nov 2018 10:52:54 +0000 (11:52 +0100)
Feature #14498

Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>

package.json
src/models/user.ts
src/services/auth-service/auth-service.ts
src/store/auth/auth-actions.test.ts
src/store/auth/auth-reducer.test.ts
src/store/virtual-machines/virtual-machines-actions.ts
src/views/virtual-machine-panel/virtual-machine-panel.tsx

index 89458046ae9707d97571397fdfb7e37a54f3d9d4..c99aa1ab640031b34a28201878fd48c1a9ab5d2d 100644 (file)
@@ -47,7 +47,7 @@
   "scripts": {
     "start": "react-scripts-ts start",
     "build": "REACT_APP_BUILD_NUMBER=$BUILD_NUMBER REACT_APP_GIT_COMMIT=$GIT_COMMIT react-scripts-ts build",
-    "test": "CI=true react-scripts-ts test --env=jsdom",
+    "test": "react-scripts-ts test --env=jsdom",
     "eject": "react-scripts-ts eject",
     "lint": "tslint src/** -t verbose",
     "build-css": "node-sass-chokidar src/ -o src/",
index c2f21e582798dacd5597872696ff7fc1685d62e7..9f9c534763ca86ee40190c2361c89b4e81da2f95 100644 (file)
@@ -10,6 +10,7 @@ export interface User {
     lastName: string;
     uuid: string;
     ownerUuid: string;
+    isAdmin: boolean;
 }
 
 export const getUserFullname = (user?: User) => {
index 50760bb4d8493b5384b1564ca6e936c00001b40e..247869e191316f2527ffb2f9b11aaa09109f2ebe 100644 (file)
@@ -13,6 +13,7 @@ export const USER_FIRST_NAME_KEY = 'userFirstName';
 export const USER_LAST_NAME_KEY = 'userLastName';
 export const USER_UUID_KEY = 'userUuid';
 export const USER_OWNER_UUID_KEY = 'userOwnerUuid';
+export const USER_IS_ADMIN = 'userIsAdmin';
 
 export interface UserDetailsResponse {
     email: string;
@@ -56,9 +57,10 @@ export class AuthService {
         const lastName = localStorage.getItem(USER_LAST_NAME_KEY);
         const uuid = localStorage.getItem(USER_UUID_KEY);
         const ownerUuid = localStorage.getItem(USER_OWNER_UUID_KEY);
+        const isAdmin = Boolean(localStorage.getItem(USER_IS_ADMIN));
 
-        return email && firstName && lastName && uuid && ownerUuid
-            ? { email, firstName, lastName, uuid, ownerUuid }
+        return email && firstName && lastName && uuid && ownerUuid && isAdmin
+            ? { email, firstName, lastName, uuid, ownerUuid, isAdmin }
             : undefined;
     }
 
@@ -68,6 +70,7 @@ export class AuthService {
         localStorage.setItem(USER_LAST_NAME_KEY, user.lastName);
         localStorage.setItem(USER_UUID_KEY, user.uuid);
         localStorage.setItem(USER_OWNER_UUID_KEY, user.ownerUuid);
+        localStorage.setItem(USER_IS_ADMIN, JSON.stringify(user.isAdmin));
     }
 
     public removeUser() {
@@ -100,7 +103,8 @@ export class AuthService {
                     firstName: resp.data.first_name,
                     lastName: resp.data.last_name,
                     uuid: resp.data.uuid,
-                    ownerUuid: resp.data.owner_uuid
+                    ownerUuid: resp.data.owner_uuid,
+                    isAdmin: resp.data.is_admin
                 };
             })
             .catch(e => {
index 231c37b4effc6c2587bd4c1289c434cd7b0d1e83..4f1b3cf35daf00b9d653f5912d2cac7370151e31 100644 (file)
@@ -10,7 +10,8 @@ import {
     USER_FIRST_NAME_KEY,
     USER_LAST_NAME_KEY,
     USER_OWNER_UUID_KEY,
-    USER_UUID_KEY
+    USER_UUID_KEY,
+    USER_IS_ADMIN
 } from "~/services/auth-service/auth-service";
 
 import 'jest-localstorage-mock';
@@ -42,6 +43,7 @@ describe('auth-actions', () => {
         localStorage.setItem(USER_LAST_NAME_KEY, "Doe");
         localStorage.setItem(USER_UUID_KEY, "uuid");
         localStorage.setItem(USER_OWNER_UUID_KEY, "ownerUuid");
+        localStorage.setItem(USER_IS_ADMIN, "isAdmin");
 
         store.dispatch(initAuth());
 
@@ -53,7 +55,8 @@ describe('auth-actions', () => {
                 firstName: "John",
                 lastName: "Doe",
                 uuid: "uuid",
-                ownerUuid: "ownerUuid"
+                ownerUuid: "ownerUuid",
+                isAdmin: true
             }
         });
     });
index 8cde324549008b4790ff4d4595e4bfa46d55a948..3dd486b31cba402bd1adc92be9a8574837729b9d 100644 (file)
@@ -29,7 +29,8 @@ describe('auth-reducer', () => {
             firstName: "John",
             lastName: "Doe",
             uuid: "uuid",
-            ownerUuid: "ownerUuid"
+            ownerUuid: "ownerUuid",
+            isAdmin: true
         };
         const state = reducer(initialState, authActions.INIT({ user, token: "token" }));
         expect(state).toEqual({
@@ -58,7 +59,8 @@ describe('auth-reducer', () => {
             firstName: "John",
             lastName: "Doe",
             uuid: "uuid",
-            ownerUuid: "ownerUuid"
+            ownerUuid: "ownerUuid",
+            isAdmin: true
         };
 
         const state = reducer(initialState, authActions.USER_DETAILS_SUCCESS(user));
@@ -71,6 +73,7 @@ describe('auth-reducer', () => {
                 lastName: "Doe",
                 uuid: "uuid",
                 ownerUuid: "ownerUuid",
+                isAdmin: true
             }
         });
     });
index 9bd79884ff470e86e4bb9d08c79d53c5867989c3..ae753562170099f7972d6a9cebf99f26493ff944 100644 (file)
@@ -35,7 +35,6 @@ const loadRequestedDate = () =>
         dispatch(virtualMachinesActions.SET_REQUESTED_DATE(date));
     };
 
-
 export const loadVirtualMachinesData = () =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         dispatch<any>(loadRequestedDate());
index c94c3a74bb956a2506be60cfb762f1ad6f354571..5eb9b191944ef362249167fc0296fafaf72fb5ed 100644 (file)
@@ -9,7 +9,7 @@ import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/st
 import { ArvadosTheme } from '~/common/custom-theme';
 import { DefaultCodeSnippet } from '~/components/default-code-snippet/default-code-snippet';
 import { Link } from 'react-router-dom';
-import { Dispatch, compose } from 'redux';
+import { compose } from 'redux';
 import { saveRequestedDate, loadVirtualMachinesData } from '~/store/virtual-machines/virtual-machines-actions';
 import { RootState } from '~/store/store';
 import { ListResults } from '~/services/common-service/common-resource-service';
@@ -58,9 +58,10 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     }
 });
 
-const mapStateToProps = ({ virtualMachines }: RootState) => {
+const mapStateToProps = ({ virtualMachines, auth }: RootState) => {
     return {
         requestedDate: virtualMachines.date,
+        isAdmin: auth.user!.isAdmin,
         ...virtualMachines
     };
 };
@@ -75,6 +76,7 @@ interface VirtualMachinesPanelDataProps {
     virtualMachines: ListResults<any>;
     logins: VirtualMachinesLoginsResource[];
     links: ListResults<any>;
+    isAdmin: string;
 }
 
 interface VirtualMachinesPanelActionProps {
@@ -91,12 +93,12 @@ export const VirtualMachinePanel = compose(
             componentDidMount() {
                 this.props.loadVirtualMachinesData();
             }
-
+            
             render() {
-                const { virtualMachines, links } = this.props;
+                const { virtualMachines, links, isAdmin } = this.props;
                 return (
                     <Grid container spacing={16}>
-                        {virtualMachines.itemsAvailable === 0 && <CardContentWithNoVirtualMachines {...this.props} />}
+                        {isAdmin && <CardContentWithNoVirtualMachines {...this.props} />}
                         {virtualMachines.itemsAvailable > 0 && links.itemsAvailable > 0 && <CardContentWithVirtualMachines {...this.props} />}
                         {<CardSSHSection {...this.props} />}
                     </Grid>