summaryrefslogtreecommitdiff
path: root/src/store
diff options
context:
space:
mode:
authorYoshie Muranaka <yoshiemuranaka@gmail.com>2020-03-25 01:25:24 +0300
committerDerick Montague <derick.montague@ibm.com>2020-04-08 21:58:55 +0300
commit37393810fa1ed2ae69ec05d0b19887e27760d48e (patch)
tree55381170946aed7c856de354d7ae8e0614fadc30 /src/store
parentb346406f3aa407869a3c868fb14322fc529673a3 (diff)
downloadwebui-vue-37393810fa1ed2ae69ec05d0b19887e27760d48e.tar.xz
Add SSL Certificates page
Adds ability to view, add, replace, and delete SSL certificates in GUI. Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com> Change-Id: I5cf9fa7bbd588dfb22f2431eed0b5976ff860703
Diffstat (limited to 'src/store')
-rw-r--r--src/store/api.js4
-rw-r--r--src/store/index.js4
-rw-r--r--src/store/modules/AccessControl/SslCertificatesStore.js158
3 files changed, 163 insertions, 3 deletions
diff --git a/src/store/api.js b/src/store/api.js
index 8fdbdd2f..24a38e4b 100644
--- a/src/store/api.js
+++ b/src/store/api.js
@@ -29,8 +29,8 @@ export default {
delete(path, payload) {
return api.delete(path, payload);
},
- post(path, payload) {
- return api.post(path, payload);
+ post(path, payload, config) {
+ return api.post(path, payload, config);
},
patch(path, payload) {
return api.patch(path, payload);
diff --git a/src/store/index.js b/src/store/index.js
index 08ada05e..0180213d 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -4,6 +4,7 @@ import Vuex from 'vuex';
import GlobalStore from './modules/GlobalStore';
import AuthenticationStore from './modules/Authentication/AuthenticanStore';
import LocalUserManagementStore from './modules/AccessControl/LocalUserMangementStore';
+import SslCertificatesStore from './modules/AccessControl/SslCertificatesStore';
import OverviewStore from './modules/Overview/OverviewStore';
import FirmwareStore from './modules/Configuration/FirmwareStore';
import BootSettingsStore from './modules/Control/BootSettingsStore';
@@ -32,7 +33,8 @@ export default new Vuex.Store({
powerControl: PowerControlStore,
networkSettings: NetworkSettingStore,
eventLog: EventLogStore,
- sensors: SensorsStore
+ sensors: SensorsStore,
+ sslCertificates: SslCertificatesStore
},
plugins: [WebSocketPlugin]
});
diff --git a/src/store/modules/AccessControl/SslCertificatesStore.js b/src/store/modules/AccessControl/SslCertificatesStore.js
new file mode 100644
index 00000000..e1758d3c
--- /dev/null
+++ b/src/store/modules/AccessControl/SslCertificatesStore.js
@@ -0,0 +1,158 @@
+import api from '../../api';
+import i18n from '../../../i18n';
+
+const CERTIFICATE_TYPES = [
+ {
+ type: 'HTTPS Certificate',
+ location: '/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/',
+ label: i18n.t('pageSslCertificates.httpsCertificate')
+ },
+ {
+ type: 'LDAP Certificate',
+ location: '/redfish/v1/AccountService/LDAP/Certificates/',
+ label: i18n.t('pageSslCertificates.ldapCertificate')
+ },
+ {
+ type: 'TrustStore Certificate',
+ location: '/redfish/v1/Managers/bmc/Truststore/Certificates/',
+ // Web UI will show 'CA Certificate' instead of
+ // 'TrustStore Certificate' after user testing revealed
+ // the term 'TrustStore Certificate' wasn't recognized/was unfamilar
+ label: i18n.t('pageSslCertificates.caCertificate')
+ }
+];
+
+const getCertificateProp = (type, prop) => {
+ const certificate = CERTIFICATE_TYPES.find(
+ certificate => certificate.type === type
+ );
+ return certificate ? certificate[prop] : null;
+};
+
+const SslCertificatesStore = {
+ namespaced: true,
+ state: {
+ allCertificates: [],
+ availableUploadTypes: []
+ },
+ getters: {
+ allCertificates: state => state.allCertificates,
+ availableUploadTypes: state => state.availableUploadTypes
+ },
+ mutations: {
+ setCertificates(state, certificates) {
+ state.allCertificates = certificates;
+ },
+ setAvailableUploadTypes(state, availableUploadTypes) {
+ state.availableUploadTypes = availableUploadTypes;
+ }
+ },
+ actions: {
+ getCertificates({ commit }) {
+ api
+ .get('/redfish/v1/CertificateService/CertificateLocations')
+ .then(({ data: { Links: { Certificates } } }) =>
+ Certificates.map(certificate => certificate['@odata.id'])
+ )
+ .then(certificateLocations => {
+ const promises = certificateLocations.map(location =>
+ api.get(location)
+ );
+ api.all(promises).then(
+ api.spread((...responses) => {
+ const certificates = responses.map(({ data }) => {
+ const {
+ Name,
+ ValidNotAfter,
+ ValidNotBefore,
+ Issuer = {},
+ Subject = {}
+ } = data;
+ return {
+ type: Name,
+ location: data['@odata.id'],
+ certificate: getCertificateProp(Name, 'label'),
+ issuedBy: Issuer.CommonName,
+ issuedTo: Subject.CommonName,
+ validFrom: new Date(ValidNotBefore),
+ validUntil: new Date(ValidNotAfter)
+ };
+ });
+ const availableUploadTypes = CERTIFICATE_TYPES.filter(
+ ({ type }) =>
+ !certificates
+ .map(certificate => certificate.type)
+ .includes(type)
+ );
+
+ commit('setCertificates', certificates);
+ commit('setAvailableUploadTypes', availableUploadTypes);
+ })
+ );
+ });
+ },
+ async addNewCertificate({ dispatch }, { file, type }) {
+ return await api
+ .post(getCertificateProp(type, 'location'), file, {
+ headers: { 'Content-Type': 'application/x-pem-file' }
+ })
+ .then(() => dispatch('getCertificates'))
+ .then(() =>
+ i18n.t('pageSslCertificates.toast.successAddCertificate', {
+ certificate: getCertificateProp(type, 'label')
+ })
+ )
+ .catch(error => {
+ console.log(error);
+ throw new Error(
+ i18n.t('pageSslCertificates.toast.errorAddCertificate')
+ );
+ });
+ },
+ async replaceCertificate(
+ { dispatch },
+ { certificateString, location, type }
+ ) {
+ const data = {};
+ data.CertificateString = certificateString;
+ data.CertificateType = 'PEM';
+ data.CertificateUri = { '@odata.id': location };
+
+ return await api
+ .post(
+ '/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate',
+ data
+ )
+ .then(() => dispatch('getCertificates'))
+ .then(() =>
+ i18n.t('pageSslCertificates.toast.successReplaceCertificate', {
+ certificate: getCertificateProp(type, 'label')
+ })
+ )
+ .catch(error => {
+ console.log(error);
+ throw new Error(
+ i18n.t('pageSslCertificates.toast.errorReplaceCertificate')
+ );
+ });
+ },
+ async deleteCertificate({ dispatch }, { type, location }) {
+ return await api
+ .delete(location)
+ .then(() => dispatch('getCertificates'))
+ .then(() =>
+ i18n.t('pageSslCertificates.toast.successDeleteCertificate', {
+ certificate: getCertificateProp(type, 'label')
+ })
+ )
+ .catch(error => {
+ console.log(error);
+ throw new Error(
+ i18n.t('pageSslCertificates.toast.errorDeleteCertificate')
+ );
+ });
+ }
+ }
+};
+
+export default SslCertificatesStore;