summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/AppHeader/AppHeader.vue3
-rw-r--r--src/components/AppNavigation/AppNavigation.vue15
-rw-r--r--src/components/AppNavigation/AppNavigationMixin.js8
-rw-r--r--src/env/components/AppNavigation/intel.js9
-rw-r--r--src/env/router/intel.js9
-rw-r--r--src/router/index.js32
-rw-r--r--src/router/routes.js9
-rw-r--r--src/store/modules/Authentication/AuthenticanStore.js6
-rw-r--r--src/store/modules/GlobalStore.js5
-rw-r--r--src/views/Login/Login.vue12
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));