diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/AppHeader/AppHeader.vue | 3 | ||||
-rw-r--r-- | src/components/AppNavigation/AppNavigation.vue | 15 | ||||
-rw-r--r-- | src/components/AppNavigation/AppNavigationMixin.js | 8 | ||||
-rw-r--r-- | src/env/components/AppNavigation/intel.js | 9 | ||||
-rw-r--r-- | src/env/router/intel.js | 9 | ||||
-rw-r--r-- | src/router/index.js | 32 | ||||
-rw-r--r-- | src/router/routes.js | 9 | ||||
-rw-r--r-- | src/store/modules/Authentication/AuthenticanStore.js | 6 | ||||
-rw-r--r-- | src/store/modules/GlobalStore.js | 5 | ||||
-rw-r--r-- | src/views/Login/Login.vue | 12 |
10 files changed, 96 insertions, 12 deletions
diff --git a/src/components/AppHeader/AppHeader.vue b/src/components/AppHeader/AppHeader.vue index 84e4588f..a1984953 100644 --- a/src/components/AppHeader/AppHeader.vue +++ b/src/components/AppHeader/AppHeader.vue @@ -155,6 +155,9 @@ export default { isAuthorized() { return this.$store.getters['global/isAuthorized']; }, + userPrivilege() { + return this.$store.getters['global/userPrivilege']; + }, serverStatus() { return this.$store.getters['global/serverStatus']; }, diff --git a/src/components/AppNavigation/AppNavigation.vue b/src/components/AppNavigation/AppNavigation.vue index acfabe76..a5f81051 100644 --- a/src/components/AppNavigation/AppNavigation.vue +++ b/src/components/AppNavigation/AppNavigation.vue @@ -29,7 +29,7 @@ <b-collapse :id="navItem.id" tag="ul" class="nav-item__nav"> <li class="nav-item"> <router-link - v-for="(subNavItem, i) of navItem.children" + v-for="(subNavItem, i) of filteredNavItem(navItem.children)" :key="i" :to="subNavItem.route" :data-test-id="`nav-item-${subNavItem.id}`" @@ -67,6 +67,7 @@ export default { data() { return { isNavigationOpen: false, + currentUserRole: null, }; }, watch: { @@ -78,12 +79,24 @@ export default { }, }, mounted() { + this.getPrivilege(); this.$root.$on('toggle-navigation', () => this.toggleIsOpen()); }, methods: { toggleIsOpen() { this.isNavigationOpen = !this.isNavigationOpen; }, + getPrivilege() { + this.currentUserRole = this.$store?.getters['global/userPrivilege']; + }, + filteredNavItem(navItem) { + if (this.currentUserRole) { + return navItem.filter(({ exclusiveToRoles }) => { + if (!exclusiveToRoles?.length) return true; + return exclusiveToRoles.includes(this.currentUserRole); + }); + } else return navItem; + }, }, }; </script> diff --git a/src/components/AppNavigation/AppNavigationMixin.js b/src/components/AppNavigation/AppNavigationMixin.js index bbbbb1ee..61230988 100644 --- a/src/components/AppNavigation/AppNavigationMixin.js +++ b/src/components/AppNavigation/AppNavigationMixin.js @@ -6,6 +6,12 @@ import IconSettings from '@carbon/icons-vue/es/settings/16'; import IconSecurity from '@carbon/icons-vue/es/security/16'; import IconChevronUp from '@carbon/icons-vue/es/chevron--up/16'; import IconDataBase from '@carbon/icons-vue/es/data--base--alt/16'; +const roles = { + administrator: 'Administrator', + operator: 'Operator', + readonly: 'ReadOnly', + noaccess: 'NoAccess', +}; const AppNavigationMixin = { components: { @@ -95,6 +101,7 @@ const AppNavigationMixin = { id: 'serial-over-lan', label: this.$t('appNavigation.serialOverLan'), route: '/operations/serial-over-lan', + exclusiveToRoles: [roles.administrator], }, { id: 'server-power-operations', @@ -105,6 +112,7 @@ const AppNavigationMixin = { id: 'virtual-media', label: this.$t('appNavigation.virtualMedia'), route: '/operations/virtual-media', + exclusiveToRoles: [roles.administrator], }, ], }, diff --git a/src/env/components/AppNavigation/intel.js b/src/env/components/AppNavigation/intel.js index 3fe0ad1c..0688a05e 100644 --- a/src/env/components/AppNavigation/intel.js +++ b/src/env/components/AppNavigation/intel.js @@ -7,6 +7,13 @@ import IconSecurity from '@carbon/icons-vue/es/security/16'; import IconChevronUp from '@carbon/icons-vue/es/chevron--up/16'; import IconDataBase from '@carbon/icons-vue/es/data--base--alt/16'; +const roles = { + administrator: 'Administrator', + operator: 'Operator', + readonly: 'ReadOnly', + noaccess: 'NoAccess', +}; + const AppNavigationMixin = { components: { iconOverview: IconDashboard, @@ -85,6 +92,7 @@ const AppNavigationMixin = { id: 'serial-over-lan', label: this.$t('appNavigation.serialOverLan'), route: '/operations/serial-over-lan', + exclusiveToRoles: [roles.administrator], }, { id: 'server-power-operations', @@ -95,6 +103,7 @@ const AppNavigationMixin = { id: 'virtual-media', label: this.$t('appNavigation.virtualMedia'), route: '/operations/virtual-media', + exclusiveToRoles: [roles.administrator], }, ], }, diff --git a/src/env/router/intel.js b/src/env/router/intel.js index fd8ed77c..5f3ee6eb 100644 --- a/src/env/router/intel.js +++ b/src/env/router/intel.js @@ -27,6 +27,13 @@ import VirtualMedia from '@/views/Operations/VirtualMedia'; import Power from '@/views/ResourceManagement/Power'; import i18n from '@/i18n'; +const roles = { + administrator: 'Administrator', + operator: 'Operator', + readonly: 'ReadOnly', + noaccess: 'NoAccess', +}; + const routes = [ { path: '/login', @@ -217,6 +224,7 @@ const routes = [ component: SerialOverLan, meta: { title: i18n.t('appPageTitle.serialOverLan'), + exclusiveToRoles: [roles.administrator], }, }, { @@ -233,6 +241,7 @@ const routes = [ component: VirtualMedia, meta: { title: i18n.t('appPageTitle.virtualMedia'), + exclusiveToRoles: [roles.administrator], }, }, { diff --git a/src/router/index.js b/src/router/index.js index 3cd52264..bcb2c7a2 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -8,16 +8,25 @@ import store from '../store'; import routes from './routes'; Vue.use(VueRouter); - const router = new VueRouter({ base: process.env.BASE_URL, routes, linkExactActiveClass: 'nav-link--current', }); -router.beforeEach((to, from, next) => { +function allowRouterToNavigate(to, next, currentUserRole) { if (to.matched.some((record) => record.meta.requiresAuth)) { if (store.getters['authentication/isLoggedIn']) { + if (to.meta.exclusiveToRoles) { + // The privilege for the specific router was verified using the + // exclusiveToRoles roles in the router. + if (to.meta.exclusiveToRoles.includes(currentUserRole)) { + next(); + } else { + next('*'); + } + return; + } next(); return; } @@ -25,6 +34,25 @@ router.beforeEach((to, from, next) => { } else { next(); } +} + +router.beforeEach((to, from, next) => { + let currentUserRole = store.getters['global/userPrivilege']; + // condition will get satisfied if user refreshed after login + if (!currentUserRole && store.getters['authentication/isLoggedIn']) { + // invoke API call to get the role ID + let username = localStorage.getItem('storedUsername'); + store.dispatch('authentication/getUserInfo', username).then((response) => { + if (response?.RoleId) { + // set role ID + store.commit('global/setPrivilege', response.RoleId); + // allow the route to continue + allowRouterToNavigate(to, next, response.RoleId); + } + }); + } else { + allowRouterToNavigate(to, next, currentUserRole); + } }); export default router; diff --git a/src/router/routes.js b/src/router/routes.js index 3cbdabce..1404da5e 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -31,6 +31,13 @@ import VirtualMedia from '@/views/Operations/VirtualMedia'; import Power from '@/views/ResourceManagement/Power'; import i18n from '@/i18n'; +const roles = { + administrator: 'Administrator', + operator: 'Operator', + readonly: 'ReadOnly', + noaccess: 'NoAccess', +}; + const routes = [ { path: '/login', @@ -253,6 +260,7 @@ const routes = [ component: SerialOverLan, meta: { title: i18n.t('appPageTitle.serialOverLan'), + exclusiveToRoles: [roles.administrator], }, }, { @@ -269,6 +277,7 @@ const routes = [ component: VirtualMedia, meta: { title: i18n.t('appPageTitle.virtualMedia'), + exclusiveToRoles: [roles.administrator], }, }, { diff --git a/src/store/modules/Authentication/AuthenticanStore.js b/src/store/modules/Authentication/AuthenticanStore.js index 88fb54b8..02d6e637 100644 --- a/src/store/modules/Authentication/AuthenticanStore.js +++ b/src/store/modules/Authentication/AuthenticanStore.js @@ -58,10 +58,10 @@ const AuthenticationStore = { .then(() => router.go('/login')) .catch((error) => console.log(error)); }, - checkPasswordChangeRequired(_, username) { - api + getUserInfo(_, username) { + return api .get(`/redfish/v1/AccountService/Accounts/${username}`) - .then(({ data: { PasswordChangeRequired } }) => PasswordChangeRequired) + .then(({ data }) => data) .catch((error) => console.log(error)); }, resetStoreState({ state }) { diff --git a/src/store/modules/GlobalStore.js b/src/store/modules/GlobalStore.js index 95d7a083..74eb1e80 100644 --- a/src/store/modules/GlobalStore.js +++ b/src/store/modules/GlobalStore.js @@ -40,6 +40,7 @@ const GlobalStore = { : true, username: localStorage.getItem('storedUsername'), isAuthorized: true, + userPrivilege: null, }, getters: { assetTag: (state) => state.assetTag, @@ -51,6 +52,7 @@ const GlobalStore = { isUtcDisplay: (state) => state.isUtcDisplay, username: (state) => state.username, isAuthorized: (state) => state.isAuthorized, + userPrivilege: (state) => state.userPrivilege, }, mutations: { setAssetTag: (state, assetTag) => (state.assetTag = assetTag), @@ -70,6 +72,9 @@ const GlobalStore = { state.isAuthorized = true; }, 100); }, + setPrivilege: (state, privilege) => { + state.userPrivilege = privilege; + }, }, actions: { async getBmcTime({ commit }) { diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue index 8d96573a..88d1c7db 100644 --- a/src/views/Login/Login.vue +++ b/src/views/Login/Login.vue @@ -126,17 +126,17 @@ export default { localStorage.setItem('storedUsername', username); this.$store.commit('global/setUsername', username); this.$store.commit('global/setLanguagePreference', i18n.locale); - return this.$store.dispatch( - 'authentication/checkPasswordChangeRequired', - username - ); + return this.$store.dispatch('authentication/getUserInfo', username); }) - .then((passwordChangeRequired) => { - if (passwordChangeRequired) { + .then(({ PasswordChangeRequired, RoleId }) => { + if (PasswordChangeRequired) { this.$router.push('/change-password'); } else { this.$router.push('/'); } + if (RoleId) { + this.$store.commit('global/setPrivilege', RoleId); + } }) .catch((error) => console.log(error)) .finally(() => (this.disableSubmitButton = false)); |