From 05887b50f1d1b08468b401b357faf13f505ee75f Mon Sep 17 00:00:00 2001 From: Sandeepa Singh Date: Mon, 10 Jan 2022 19:19:36 +0530 Subject: Add Key clear page under Operations section This page will allow privileged user to clear encrypted keys. - Only admin and CE login user will be able to see the page - The UI will be different for both, admin and CE login user(service) - This page is IBM only Signed-off-by: Sandeepa Singh Change-Id: Ic6fe3454de815629a6b2250daa99ab21f2b316c3 --- src/components/AppNavigation/AppNavigationMixin.js | 5 + src/env/components/AppNavigation/ibm.js | 69 ++++++++------ src/env/router/ibm.js | 9 ++ src/env/store/ibm.js | 3 + src/locales/en-US.json | 39 +++++++- src/router/routes.js | 9 ++ src/store/index.js | 2 + src/store/modules/Operations/KeyClearStore.js | 25 +++++ src/views/Operations/KeyClear/KeyClear.vue | 106 +++++++++++++++++++++ src/views/Operations/KeyClear/index.js | 2 + .../unit/__snapshots__/AppNavigation.spec.js.snap | 18 ++++ 11 files changed, 258 insertions(+), 29 deletions(-) create mode 100644 src/store/modules/Operations/KeyClearStore.js create mode 100644 src/views/Operations/KeyClear/KeyClear.vue create mode 100644 src/views/Operations/KeyClear/index.js diff --git a/src/components/AppNavigation/AppNavigationMixin.js b/src/components/AppNavigation/AppNavigationMixin.js index edeabc52..bbbbb1ee 100644 --- a/src/components/AppNavigation/AppNavigationMixin.js +++ b/src/components/AppNavigation/AppNavigationMixin.js @@ -76,6 +76,11 @@ const AppNavigationMixin = { label: this.$t('appNavigation.kvm'), route: '/operations/kvm', }, + { + id: 'key-clear', + label: this.$t('appNavigation.keyClear'), + route: '/operations/key-clear', + }, { id: 'firmware', label: this.$t('appNavigation.firmware'), diff --git a/src/env/components/AppNavigation/ibm.js b/src/env/components/AppNavigation/ibm.js index 32f5c9f4..ed84e17a 100644 --- a/src/env/components/AppNavigation/ibm.js +++ b/src/env/components/AppNavigation/ibm.js @@ -70,33 +70,7 @@ const AppNavigationMixin = { id: 'operations', label: this.$t('appNavigation.operations'), icon: 'iconControl', - children: [ - { - id: 'factory-reset', - label: this.$t('appNavigation.factoryReset'), - route: '/operations/factory-reset', - }, - { - id: 'firmware', - label: this.$t('appNavigation.firmware'), - route: '/operations/firmware', - }, - { - id: 'reboot-bmc', - label: this.$t('appNavigation.rebootBmc'), - route: '/operations/reboot-bmc', - }, - { - id: 'serial-over-lan', - label: this.$t('appNavigation.serialOverLan'), - route: '/operations/serial-over-lan', - }, - { - id: 'server-power-operations', - label: this.$t('appNavigation.serverPowerOperations'), - route: '/operations/server-power-operations', - }, - ], + children: this.operationsNavigationItems(), }, { id: 'settings', @@ -167,6 +141,47 @@ const AppNavigationMixin = { ], }; }, + methods: { + operationsNavigationItems() { + const username = this.$store.getters['global/username']; + let operationNavigationItems = [ + { + id: 'factory-reset', + label: this.$t('appNavigation.factoryReset'), + route: '/operations/factory-reset', + }, + { + id: 'firmware', + label: this.$t('appNavigation.firmware'), + route: '/operations/firmware', + }, + { + id: 'reboot-bmc', + label: this.$t('appNavigation.rebootBmc'), + route: '/operations/reboot-bmc', + }, + { + id: 'serial-over-lan', + label: this.$t('appNavigation.serialOverLan'), + route: '/operations/serial-over-lan', + }, + { + id: 'server-power-operations', + label: this.$t('appNavigation.serverPowerOperations'), + route: '/operations/server-power-operations', + }, + ]; + let pageKeyClear = { + id: 'key-clear', + label: this.$t('appNavigation.keyClear'), + route: '/operations/key-clear', + }; + if (username === 'service' || username === 'admin') { + operationNavigationItems.splice(2, 0, pageKeyClear); + } + return operationNavigationItems; + }, + }, }; export default AppNavigationMixin; diff --git a/src/env/router/ibm.js b/src/env/router/ibm.js index c6ac61f7..0ccf90ba 100644 --- a/src/env/router/ibm.js +++ b/src/env/router/ibm.js @@ -19,6 +19,7 @@ import PowerRestorePolicy from '@/views/Settings/PowerRestorePolicy'; import ProfileSettings from '@/views/ProfileSettings'; import RebootBmc from '@/views/Operations/RebootBmc'; import Policies from '@/views/SecurityAndAccess/Policies'; +import KeyClear from '@/views/Operations/KeyClear'; import Sensors from '@/views/HardwareStatus/Sensors'; import SerialOverLan from '@/views/Operations/SerialOverLan'; import SerialOverLanConsole from '@/views/Operations/SerialOverLan/SerialOverLanConsole'; @@ -222,6 +223,14 @@ const routes = [ title: i18n.t('appPageTitle.factoryReset'), }, }, + { + path: '/operations/key-clear', + name: 'key-clear', + component: KeyClear, + meta: { + title: i18n.t('appPageTitle.keyClear'), + }, + }, { path: '/operations/reboot-bmc', name: 'reboot-bmc', diff --git a/src/env/store/ibm.js b/src/env/store/ibm.js index 787f8975..86fc52d1 100644 --- a/src/env/store/ibm.js +++ b/src/env/store/ibm.js @@ -1,8 +1,11 @@ import store from '@/store'; import DumpsStore from '@/store/modules/Logs/DumpsStore'; +import KeyClearStore from '@/store/modules/Operations/KeyClearStore'; store.unregisterModule('virtualMedia'); store.registerModule('dumps', DumpsStore); +store.registerModule('key-clear', KeyClearStore); + export default store; diff --git a/src/locales/en-US.json b/src/locales/en-US.json index ddc556df..d8df61c0 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -126,7 +126,8 @@ "serverPowerOperations": "@:appPageTitle.serverPowerOperations", "certificates": "@:appPageTitle.certificates", "virtualMedia": "@:appPageTitle.virtualMedia", - "power": "@:appPageTitle.power" + "power": "@:appPageTitle.power", + "keyClear": "@:appPageTitle.keyClear" }, "appPageTitle": { "changePassword": "Change password", @@ -154,7 +155,8 @@ "serialOverLan": "Serial over LAN (SOL) console", "serverPowerOperations": "Server power operations", "certificates": "Certificates", - "virtualMedia": "Virtual media" + "virtualMedia": "Virtual media", + "keyClear": "Key clear" }, "pageChangePassword": { "changePassword": "Change password", @@ -444,6 +446,39 @@ "errorEnableIdentifyLed": "Error enabling Identify LED." } }, + "pageKeyClear": { + "description": "Securely clear sensitive data on the system", + "alert": { + "description": "Due to senstivity of the data that will be cleared, verification through physical presence is required to authorize this operation.", + "title": "This operation requires physical presence and system reboot" + }, + "form": { + "clearAllSetGenesisIPL": "Clear all and set genesis IPL", + "clear": "Clear", + "clearAllLabel": "Clear all", + "clearAllHeperText":"Clear all the sensitive data that is controlled by the platform firmware", + "clearHypervisorSystemKeyLabel":"Clear hypervisor system key", + "clearHypervisorSystemKeyHelperText":"This indicates the hypervisor to clear the system key.", + "clearOperatingSystemKeysLabel":"Clear operating system keys label", + "clearOperatingSystemKeysHelperText":"This indicates OPAL to clear the operating system Secure Boot keys.", + "clearSystemSecurityKeyLabel":"Clear system security officer key", + "clearSystemSecurityKeyHelperText":"This incicates OPAL/PEF to clear teh system security officer keys.", + "keyClearOptionsLabel": "Key clear options", + "keyClearNotRequested": "Key clear not requested", + "none": "None", + "setFactoryDefault": "Set factory default" + }, + "modal":{ + "clear": "Clear keys", + "clearAllMessage": "Any encryption keys contained in the selected data will be lost. System will not be able to decrypt any data that requires these keys.", + "clearAllTitle": "Warning: This operation is not reversible" + + }, + "toast":{ + "selectedKeyClearedError": "Error clearing keys", + "selectedKeyClearedSuccess": "Keys cleared successfully" + } + }, "pageKvm": { "openNewTab": "Open in new tab", "buttonCtrlAltDelete": "Send Ctrl+Alt+Delete", diff --git a/src/router/routes.js b/src/router/routes.js index b99aac51..3cbdabce 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -21,6 +21,7 @@ import PowerRestorePolicy from '@/views/Settings/PowerRestorePolicy'; import ProfileSettings from '@/views/ProfileSettings'; import RebootBmc from '@/views/Operations/RebootBmc'; import Policies from '@/views/SecurityAndAccess/Policies'; +import KeyClear from '@/views/Operations/KeyClear'; import Sensors from '@/views/HardwareStatus/Sensors'; import SerialOverLan from '@/views/Operations/SerialOverLan'; import SerialOverLanConsole from '@/views/Operations/SerialOverLan/SerialOverLanConsole'; @@ -190,6 +191,14 @@ const routes = [ title: i18n.t('appPageTitle.factoryReset'), }, }, + { + path: '/operations/key-clear', + name: 'key-clear', + component: KeyClear, + meta: { + title: i18n.t('appPageTitle.keyClear'), + }, + }, { path: '/operations/kvm', name: 'kvm', diff --git a/src/store/index.js b/src/store/index.js index d7c1b22d..ba248c58 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -27,6 +27,7 @@ import AssemblyStore from './modules/HardwareStatus/AssemblyStore'; import PostCodeLogsStore from './modules/Logs/PostCodeLogsStore'; import PoliciesStore from './modules/SecurityAndAccess/PoliciesStore'; import FactoryResetStore from './modules/Operations/FactoryResetStore'; +import KeyClearStore from './modules/Operations/KeyClearStore'; import WebSocketPlugin from './plugins/WebSocketPlugin'; import DateTimeStore from './modules/Settings/DateTimeStore'; @@ -67,6 +68,7 @@ export default new Vuex.Store({ virtualMedia: VirtualMediaStore, policies: PoliciesStore, factoryReset: FactoryResetStore, + keyClear: KeyClearStore, }, plugins: [WebSocketPlugin], }); diff --git a/src/store/modules/Operations/KeyClearStore.js b/src/store/modules/Operations/KeyClearStore.js new file mode 100644 index 00000000..1dc96e0f --- /dev/null +++ b/src/store/modules/Operations/KeyClearStore.js @@ -0,0 +1,25 @@ +import api from '@/store/api'; +import i18n from '@/i18n'; + +const KeyClearStore = { + namespaced: true, + actions: { + async clearEncryptionKeys(_, selectedKey) { + const selectedKeyForClearing = { + Attributes: { hb_key_clear_request: selectedKey }, + }; + return await api + .patch( + '/redfish/v1/Systems/system/Bios/Settings', + selectedKeyForClearing + ) + .then(() => i18n.t('pageKeyClear.toast.selectedKeyClearedSuccess')) + .catch((error) => { + console.log('Key clear', error); + throw new Error(i18n.t('pageKeyClear.toast.selectedKeyClearedError')); + }); + }, + }, +}; + +export default KeyClearStore; diff --git a/src/views/Operations/KeyClear/KeyClear.vue b/src/views/Operations/KeyClear/KeyClear.vue new file mode 100644 index 00000000..2524da10 --- /dev/null +++ b/src/views/Operations/KeyClear/KeyClear.vue @@ -0,0 +1,106 @@ + + + diff --git a/src/views/Operations/KeyClear/index.js b/src/views/Operations/KeyClear/index.js new file mode 100644 index 00000000..56de8c4e --- /dev/null +++ b/src/views/Operations/KeyClear/index.js @@ -0,0 +1,2 @@ +import KeyClear from './KeyClear.vue'; +export default KeyClear; diff --git a/tests/unit/__snapshots__/AppNavigation.spec.js.snap b/tests/unit/__snapshots__/AppNavigation.spec.js.snap index 37609d39..98628186 100644 --- a/tests/unit/__snapshots__/AppNavigation.spec.js.snap +++ b/tests/unit/__snapshots__/AppNavigation.spec.js.snap @@ -311,6 +311,15 @@ exports[`AppNavigation.vue should render correctly 1`] = ` appNavigation.kvm + + + + appNavigation.keyClear + + + + appNavigation.keyClear +