diff options
author | Sandeepa Singh <sandeepa.singh@ibm.com> | 2021-07-26 12:35:39 +0300 |
---|---|---|
committer | Derick Montague <derick.montague@ibm.com> | 2021-08-10 22:20:42 +0300 |
commit | b440616c23b61166ae6d87839a70eec31bdca235 (patch) | |
tree | d72769d4aa425e96e47419515b85a8631d8e99d7 /src/views/SecurityAndAccess/Certificates/Certificates.vue | |
parent | f67f769f2304bca64d2b9758e22c21203960eef9 (diff) | |
download | webui-vue-b440616c23b61166ae6d87839a70eec31bdca235.tar.xz |
IA update: Update access and control section
This is the fifth commit of the information architecture changes and
has the following changes:
- The icon for access and control has been updated
- Access and control section has been updated to security and
access section
- Security settings page has been updated to policies page and moved to
security and access section
- Client sessions page has been updated to sessions page
- Local user management page has been updated to user management page
- SSL certificates page has been updated to certificates page
Signed-off-by: Sandeepa Singh <sandeepa.singh@ibm.com>
Change-Id: Ie93cee9002742ecf7d33615636f4f159f4395fc4
Diffstat (limited to 'src/views/SecurityAndAccess/Certificates/Certificates.vue')
-rw-r--r-- | src/views/SecurityAndAccess/Certificates/Certificates.vue | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/src/views/SecurityAndAccess/Certificates/Certificates.vue b/src/views/SecurityAndAccess/Certificates/Certificates.vue new file mode 100644 index 00000000..9d208897 --- /dev/null +++ b/src/views/SecurityAndAccess/Certificates/Certificates.vue @@ -0,0 +1,319 @@ +<template> + <b-container fluid="xl"> + <page-title /> + <b-row> + <b-col xl="11"> + <!-- Expired certificates banner --> + <alert :show="expiredCertificateTypes.length > 0" variant="danger"> + <template v-if="expiredCertificateTypes.length > 1"> + {{ $t('pageCertificates.alert.certificatesExpiredMessage') }} + </template> + <template v-else> + {{ + $t('pageCertificates.alert.certificateExpiredMessage', { + certificate: expiredCertificateTypes[0], + }) + }} + </template> + </alert> + <!-- Expiring certificates banner --> + <alert :show="expiringCertificateTypes.length > 0" variant="warning"> + <template v-if="expiringCertificateTypes.length > 1"> + {{ $t('pageCertificates.alert.certificatesExpiringMessage') }} + </template> + <template v-else> + {{ + $t('pageCertificates.alert.certificateExpiringMessage', { + certificate: expiringCertificateTypes[0], + }) + }} + </template> + </alert> + </b-col> + </b-row> + <b-row> + <b-col xl="11" class="text-right"> + <b-button + v-b-modal.generate-csr + data-test-id="certificates-button-generateCsr" + variant="link" + > + <icon-add /> + {{ $t('pageCertificates.generateCsr') }} + </b-button> + <b-button + variant="primary" + :disabled="certificatesForUpload.length === 0" + @click="initModalUploadCertificate(null)" + > + <icon-add /> + {{ $t('pageCertificates.addNewCertificate') }} + </b-button> + </b-col> + </b-row> + <b-row> + <b-col xl="11"> + <b-table + responsive="md" + show-empty + hover + :fields="fields" + :items="tableItems" + :empty-text="$t('global.table.emptyMessage')" + > + <template #cell(validFrom)="{ value }"> + {{ value | formatDate }} + </template> + + <template #cell(validUntil)="{ value }"> + <status-icon + v-if="getDaysUntilExpired(value) < 31" + :status="getIconStatus(value)" + /> + {{ value | formatDate }} + </template> + + <template #cell(actions)="{ value, item }"> + <table-row-action + v-for="(action, index) in value" + :key="index" + :value="action.value" + :title="action.title" + :enabled="action.enabled" + @click-table-action="onTableRowAction($event, item)" + > + <template #icon> + <icon-replace v-if="action.value === 'replace'" /> + <icon-trashcan v-if="action.value === 'delete'" /> + </template> + </table-row-action> + </template> + </b-table> + </b-col> + </b-row> + + <!-- Modals --> + <modal-upload-certificate :certificate="modalCertificate" @ok="onModalOk" /> + <modal-generate-csr /> + </b-container> +</template> + +<script> +import IconAdd from '@carbon/icons-vue/es/add--alt/20'; +import IconReplace from '@carbon/icons-vue/es/renew/20'; +import IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; + +import ModalGenerateCsr from './ModalGenerateCsr'; +import ModalUploadCertificate from './ModalUploadCertificate'; +import PageTitle from '@/components/Global/PageTitle'; +import TableRowAction from '@/components/Global/TableRowAction'; +import StatusIcon from '@/components/Global/StatusIcon'; +import Alert from '@/components/Global/Alert'; + +import BVToastMixin from '@/components/Mixins/BVToastMixin'; +import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; + +export default { + name: 'Certificates', + components: { + Alert, + IconAdd, + IconReplace, + IconTrashcan, + ModalGenerateCsr, + ModalUploadCertificate, + PageTitle, + StatusIcon, + TableRowAction, + }, + mixins: [BVToastMixin, LoadingBarMixin], + beforeRouteLeave(to, from, next) { + this.hideLoader(); + next(); + }, + data() { + return { + modalCertificate: null, + fields: [ + { + key: 'certificate', + label: this.$t('pageCertificates.table.certificate'), + }, + { + key: 'issuedBy', + label: this.$t('pageCertificates.table.issuedBy'), + }, + { + key: 'issuedTo', + label: this.$t('pageCertificates.table.issuedTo'), + }, + { + key: 'validFrom', + label: this.$t('pageCertificates.table.validFrom'), + }, + { + key: 'validUntil', + label: this.$t('pageCertificates.table.validUntil'), + }, + { + key: 'actions', + label: '', + tdClass: 'text-right text-nowrap', + }, + ], + }; + }, + computed: { + certificates() { + return this.$store.getters['certificates/allCertificates']; + }, + tableItems() { + return this.certificates.map((certificate) => { + return { + ...certificate, + actions: [ + { + value: 'replace', + title: this.$t('pageCertificates.replaceCertificate'), + }, + { + value: 'delete', + title: this.$t('pageCertificates.deleteCertificate'), + enabled: + certificate.type === 'TrustStore Certificate' ? true : false, + }, + ], + }; + }); + }, + certificatesForUpload() { + return this.$store.getters['certificates/availableUploadTypes']; + }, + bmcTime() { + return this.$store.getters['global/bmcTime']; + }, + expiredCertificateTypes() { + return this.certificates.reduce((acc, val) => { + const daysUntilExpired = this.getDaysUntilExpired(val.validUntil); + if (daysUntilExpired < 1) { + acc.push(val.certificate); + } + return acc; + }, []); + }, + expiringCertificateTypes() { + return this.certificates.reduce((acc, val) => { + const daysUntilExpired = this.getDaysUntilExpired(val.validUntil); + if (daysUntilExpired < 31 && daysUntilExpired > 0) { + acc.push(val.certificate); + } + return acc; + }, []); + }, + }, + async created() { + this.startLoader(); + await this.$store.dispatch('global/getBmcTime'); + this.$store + .dispatch('certificates/getCertificates') + .finally(() => this.endLoader()); + }, + methods: { + onTableRowAction(event, rowItem) { + switch (event) { + case 'replace': + this.initModalUploadCertificate(rowItem); + break; + case 'delete': + this.initModalDeleteCertificate(rowItem); + break; + default: + break; + } + }, + initModalUploadCertificate(certificate = null) { + this.modalCertificate = certificate; + this.$bvModal.show('upload-certificate'); + }, + initModalDeleteCertificate(certificate) { + this.$bvModal + .msgBoxConfirm( + this.$t('pageCertificates.modal.deleteConfirmMessage', { + issuedBy: certificate.issuedBy, + certificate: certificate.certificate, + }), + { + title: this.$t('pageCertificates.deleteCertificate'), + okTitle: this.$t('global.action.delete'), + cancelTitle: this.$t('global.action.cancel'), + } + ) + .then((deleteConfirmed) => { + if (deleteConfirmed) this.deleteCertificate(certificate); + }); + }, + onModalOk({ addNew, file, type, location }) { + if (addNew) { + // Upload a new certificate + this.addNewCertificate(file, type); + } else { + // Replace an existing certificate + this.replaceCertificate(file, type, location); + } + }, + addNewCertificate(file, type) { + this.startLoader(); + this.$store + .dispatch('certificates/addNewCertificate', { file, type }) + .then((success) => this.successToast(success)) + .catch(({ message }) => this.errorToast(message)) + .finally(() => this.endLoader()); + }, + replaceCertificate(file, type, location) { + this.startLoader(); + const reader = new FileReader(); + reader.readAsBinaryString(file); + reader.onloadend = (event) => { + const certificateString = event.target.result; + this.$store + .dispatch('certificates/replaceCertificate', { + certificateString, + type, + location, + }) + .then((success) => this.successToast(success)) + .catch(({ message }) => this.errorToast(message)) + .finally(() => this.endLoader()); + }; + }, + deleteCertificate({ type, location }) { + this.startLoader(); + this.$store + .dispatch('certificates/deleteCertificate', { + type, + location, + }) + .then((success) => this.successToast(success)) + .catch(({ message }) => this.errorToast(message)) + .finally(() => this.endLoader()); + }, + getDaysUntilExpired(date) { + if (this.bmcTime) { + const validUntilMs = date.getTime(); + const currentBmcTimeMs = this.bmcTime.getTime(); + const oneDayInMs = 24 * 60 * 60 * 1000; + return Math.round((validUntilMs - currentBmcTimeMs) / oneDayInMs); + } + return new Date(); + }, + getIconStatus(date) { + const daysUntilExpired = this.getDaysUntilExpired(date); + if (daysUntilExpired < 1) { + return 'danger'; + } else if (daysUntilExpired < 31) { + return 'warning'; + } + }, + }, +}; +</script> |