UI/Hide empty masked PKI row values (#14400)
* fix empty masked inputs displaying * Revert "fix empty masked inputs displaying" This reverts commit 8b297df7cf971bce32d73c07fea2b1b8112c2f4b. * fix empty masked inputs displaying * fix info banner conditional * add test coverage * adds changelog * fixes tests * change other canParse conditional
This commit is contained in:
parent
8844895745
commit
ce0c872478
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
ui: Fixes displaying empty masked values in PKI engine
|
||||||
|
```
|
|
@ -8,7 +8,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</h2>
|
</h2>
|
||||||
{{#if (or this.model.certificate this.model.csr)}}
|
{{#if (or this.model.certificate this.model.csr)}}
|
||||||
{{#if (not (eq this.model.canParse true))}}
|
{{#if (eq this.model.canParse false)}}
|
||||||
<AlertBanner
|
<AlertBanner
|
||||||
@type="info"
|
@type="info"
|
||||||
@message="There was an error parsing the certificate's metadata. As a result, Vault cannot display the issue and expiration dates. This will not interfere with the certificate's functionality."
|
@message="There was an error parsing the certificate's metadata. As a result, Vault cannot display the issue and expiration dates. This will not interfere with the certificate's functionality."
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#each this.model.attrs as |attr|}}
|
{{#each this.model.attrs as |attr|}}
|
||||||
{{#if attr.options.masked}}
|
{{#if (and attr.options.masked (get this.model attr.name))}}
|
||||||
<InfoTableRow
|
<InfoTableRow
|
||||||
data-test-table-row
|
data-test-table-row
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
data-test-warning
|
data-test-warning
|
||||||
/>
|
/>
|
||||||
{{#each this.model.attrs as |attr|}}
|
{{#each this.model.attrs as |attr|}}
|
||||||
{{#if attr.options.masked}}
|
{{#if (and attr.options.masked (get this.model attr.name))}}
|
||||||
<InfoTableRow
|
<InfoTableRow
|
||||||
data-test-table-row={{this.value}}
|
data-test-table-row={{this.value}}
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||||
|
|
|
@ -75,12 +75,6 @@
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||||
@value={{date-format (get this.model attr.name) "MMM dd, yyyy hh:mm:ss a" isFormatted=true}}
|
@value={{date-format (get this.model attr.name) "MMM dd, yyyy hh:mm:ss a" isFormatted=true}}
|
||||||
/>
|
/>
|
||||||
{{else if (and (get this.model attr.name) (eq attr.name "revocationTime"))}}
|
|
||||||
<InfoTableRow
|
|
||||||
data-test-table-row
|
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
|
||||||
@value={{date-format (get this.model attr.name) "MMM dd, yyyy hh:mm:ss a"}}
|
|
||||||
/>
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<InfoTableRow
|
<InfoTableRow
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</h1>
|
</h1>
|
||||||
</p.levelLeft>
|
</p.levelLeft>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
{{#if (not (eq this.model.canParse true))}}
|
{{#if (eq this.model.canParse false)}}
|
||||||
<AlertBanner
|
<AlertBanner
|
||||||
@type="info"
|
@type="info"
|
||||||
@message="There was an error parsing the certificate's metadata. As a result, Vault cannot display the common name or the issue and expiration dates. This will not interfere with the certificate's functionality."
|
@message="There was an error parsing the certificate's metadata. As a result, Vault cannot display the common name or the issue and expiration dates. This will not interfere with the certificate's functionality."
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
@value={{stringify (get this.model attr.name)}}
|
@value={{stringify (get this.model attr.name)}}
|
||||||
/>
|
/>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if attr.options.masked}}
|
{{#if (and attr.options.masked (get this.model attr.name))}}
|
||||||
<InfoTableRow
|
<InfoTableRow
|
||||||
data-test-table-row
|
data-test-table-row
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||||
@value={{date-format (get this.model attr.name) "MMM dd, yyyy hh:mm:ss a" isFormatted=true}}
|
@value={{date-format (get this.model attr.name) "MMM dd, yyyy hh:mm:ss a" isFormatted=true}}
|
||||||
/>
|
/>
|
||||||
{{else if (and (get this.model attr.name) (eq attr.name "revocationTime"))}}
|
{{else if (eq attr.name "revocationTime")}}
|
||||||
<InfoTableRow
|
<InfoTableRow
|
||||||
data-test-table-row
|
data-test-table-row
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||||
|
|
|
@ -90,7 +90,9 @@ module('Acceptance | clients current', function (hooks) {
|
||||||
// Filter by namespace
|
// Filter by namespace
|
||||||
await clickTrigger();
|
await clickTrigger();
|
||||||
await searchSelect.options.objectAt(0).click();
|
await searchSelect.options.objectAt(0).click();
|
||||||
await settled();
|
await waitUntil(() => {
|
||||||
|
return find('[data-test-horizontal-bar-chart]');
|
||||||
|
});
|
||||||
assert.dom('[data-test-stat-text="total-clients"] .stat-value').hasText('15');
|
assert.dom('[data-test-stat-text="total-clients"] .stat-value').hasText('15');
|
||||||
assert.dom('[data-test-stat-text="entity-clients"] .stat-value').hasText('5');
|
assert.dom('[data-test-stat-text="entity-clients"] .stat-value').hasText('5');
|
||||||
assert.dom('[data-test-stat-text="non-entity-clients"] .stat-value').hasText('10');
|
assert.dom('[data-test-stat-text="non-entity-clients"] .stat-value').hasText('10');
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { currentRouteName, settled, click } from '@ember/test-helpers';
|
import { currentRouteName, settled } from '@ember/test-helpers';
|
||||||
import { module, test } from 'qunit';
|
import { module, test } from 'qunit';
|
||||||
import { setupApplicationTest } from 'ember-qunit';
|
import { setupApplicationTest } from 'ember-qunit';
|
||||||
import editPage from 'vault/tests/pages/secrets/backend/pki/edit-role';
|
import editPage from 'vault/tests/pages/secrets/backend/pki/edit-role';
|
||||||
|
@ -7,6 +7,7 @@ import generatePage from 'vault/tests/pages/secrets/backend/pki/generate-cert';
|
||||||
import configPage from 'vault/tests/pages/settings/configure-secret-backends/pki/section-cert';
|
import configPage from 'vault/tests/pages/settings/configure-secret-backends/pki/section-cert';
|
||||||
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
|
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
|
||||||
import authPage from 'vault/tests/pages/auth';
|
import authPage from 'vault/tests/pages/auth';
|
||||||
|
import { SELECTORS } from 'vault/tests/helpers/pki';
|
||||||
|
|
||||||
module('Acceptance | secrets/pki/list?tab=certs', function (hooks) {
|
module('Acceptance | secrets/pki/list?tab=certs', function (hooks) {
|
||||||
setupApplicationTest(hooks);
|
setupApplicationTest(hooks);
|
||||||
|
@ -55,11 +56,15 @@ elRplAzrMF4=
|
||||||
await settled();
|
await settled();
|
||||||
await generatePage.issueCert('foo');
|
await generatePage.issueCert('foo');
|
||||||
await settled();
|
await settled();
|
||||||
assert.dom('.masked-font').exists({ count: 3 }, 'renders 3 masked rows');
|
assert.dom(SELECTORS.certificate).exists('displays masked certificate');
|
||||||
let firstUnMaskButton = document.querySelectorAll('.masked-input-toggle')[0];
|
assert.dom(SELECTORS.commonName).exists('displays common name');
|
||||||
await click(firstUnMaskButton);
|
assert.dom(SELECTORS.issueDate).exists('displays issue date');
|
||||||
assert.dom('.masked-value').hasTextContaining('-----BEGIN CERTIFICATE-----');
|
assert.dom(SELECTORS.expiryDate).exists('displays expiration date');
|
||||||
await settled();
|
assert.dom(SELECTORS.issuingCa).exists('displays masked issuing CA');
|
||||||
|
assert.dom(SELECTORS.privateKey).exists('displays masked private key');
|
||||||
|
assert.dom(SELECTORS.serialNumber).exists('displays serial number');
|
||||||
|
assert.dom(SELECTORS.caChain).doesNotExist('does not display empty masked CA chain');
|
||||||
|
|
||||||
await generatePage.back();
|
await generatePage.back();
|
||||||
await settled();
|
await settled();
|
||||||
assert.notOk(generatePage.commonNameValue, 'the form is cleared');
|
assert.notOk(generatePage.commonNameValue, 'the form is cleared');
|
||||||
|
@ -70,9 +75,10 @@ elRplAzrMF4=
|
||||||
await settled();
|
await settled();
|
||||||
await generatePage.sign('common', CSR);
|
await generatePage.sign('common', CSR);
|
||||||
await settled();
|
await settled();
|
||||||
let firstUnMaskButton = document.querySelectorAll('.masked-input-toggle')[0];
|
assert.ok(SELECTORS.certificate, 'displays masked certificate');
|
||||||
await click(firstUnMaskButton);
|
assert.ok(SELECTORS.commonName, 'displays common name');
|
||||||
assert.dom('.masked-value').hasTextContaining('-----BEGIN CERTIFICATE-----');
|
assert.ok(SELECTORS.issuingCa, 'displays masked issuing CA');
|
||||||
|
assert.ok(SELECTORS.serialNumber, 'displays serial number');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it views a cert', async function (assert) {
|
test('it views a cert', async function (assert) {
|
||||||
|
@ -82,12 +88,17 @@ elRplAzrMF4=
|
||||||
await listPage.visitRoot({ backend: path, tab: 'certs' });
|
await listPage.visitRoot({ backend: path, tab: 'certs' });
|
||||||
await settled();
|
await settled();
|
||||||
assert.ok(listPage.secrets.length > 0, 'lists certs');
|
assert.ok(listPage.secrets.length > 0, 'lists certs');
|
||||||
|
|
||||||
await listPage.secrets.objectAt(0).click();
|
await listPage.secrets.objectAt(0).click();
|
||||||
await settled();
|
await settled();
|
||||||
assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'navigates to the show page');
|
assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'navigates to the show page');
|
||||||
let firstUnMaskButton = document.querySelectorAll('.masked-input-toggle')[0];
|
assert.dom(SELECTORS.certificate).exists('displays masked certificate');
|
||||||
await click(firstUnMaskButton);
|
assert.dom(SELECTORS.commonName).exists('displays common name');
|
||||||
assert.dom('.masked-value').hasTextContaining('-----BEGIN CERTIFICATE-----');
|
assert.dom(SELECTORS.issueDate).exists('displays issue date');
|
||||||
|
assert.dom(SELECTORS.expiryDate).exists('displays expiration date');
|
||||||
|
assert.dom(SELECTORS.serialNumber).exists('displays serial number');
|
||||||
|
assert.dom(SELECTORS.revocationTime).doesNotExist('does not display revocation time of 0');
|
||||||
|
assert.dom(SELECTORS.issuingCa).doesNotExist('does not display empty issuing CA');
|
||||||
|
assert.dom(SELECTORS.caChain).doesNotExist('does not display empty CA chain');
|
||||||
|
assert.dom(SELECTORS.privateKey).doesNotExist('does not display empty private key');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { currentRouteName, settled, click } from '@ember/test-helpers';
|
||||||
import { module, test } from 'qunit';
|
import { module, test } from 'qunit';
|
||||||
import { setupApplicationTest } from 'ember-qunit';
|
import { setupApplicationTest } from 'ember-qunit';
|
||||||
import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section-cert';
|
import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section-cert';
|
||||||
|
import { SELECTORS } from 'vault/tests/helpers/pki';
|
||||||
import authPage from 'vault/tests/pages/auth';
|
import authPage from 'vault/tests/pages/auth';
|
||||||
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
|
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
|
||||||
|
|
||||||
|
@ -77,13 +78,15 @@ BXUV2Uwtxf+QCphnlht9muX2fsLIzDJea0JipWj1uf2H8OZsjE8=
|
||||||
await page.form.generateCA();
|
await page.form.generateCA();
|
||||||
await settled();
|
await settled();
|
||||||
|
|
||||||
assert.ok(page.form.commonNameIsPresent, 'the common name displays');
|
assert.dom(SELECTORS.certificate).exists('certificate is present and masked');
|
||||||
assert.ok(page.form.issueDateIsPresent, 'the issue date displays');
|
assert.dom(SELECTORS.commonName).exists('displays common name');
|
||||||
assert.ok(page.form.expiryDateIsPresent, 'the expiration date displays');
|
assert.dom(SELECTORS.issueDate).exists('displays issue date');
|
||||||
assert
|
assert.dom(SELECTORS.expiryDate).exists('displays expiration date');
|
||||||
.dom('[data-test-value-div="Certificate"] [data-test-masked-input]')
|
assert.dom(SELECTORS.issuingCa).exists('displays masked issuing CA');
|
||||||
.exists('certificate is present');
|
assert.dom(SELECTORS.serialNumber).exists('displays serial number');
|
||||||
|
assert.dom(SELECTORS.csr).doesNotExist('does not display empty CSR');
|
||||||
|
assert.dom(SELECTORS.caChain).doesNotExist('does not display empty CA chain');
|
||||||
|
assert.dom(SELECTORS.privateKey).doesNotExist('does not display empty private key');
|
||||||
await page.form.back();
|
await page.form.back();
|
||||||
await page.form.generateCA();
|
await page.form.generateCA();
|
||||||
await settled();
|
await settled();
|
||||||
|
@ -126,6 +129,8 @@ BXUV2Uwtxf+QCphnlht9muX2fsLIzDJea0JipWj1uf2H8OZsjE8=
|
||||||
await settled();
|
await settled();
|
||||||
await page.form.csrField(csrVal).submit();
|
await page.form.csrField(csrVal).submit();
|
||||||
await settled();
|
await settled();
|
||||||
|
assert.dom(SELECTORS.caChain).doesNotExist('does not display empty CA chain');
|
||||||
|
assert.dom(SELECTORS.privateKey).doesNotExist('does not display empty private key');
|
||||||
await click('.masked-input-toggle');
|
await click('.masked-input-toggle');
|
||||||
intermediateCert = document.querySelector('[data-test-masked-input]').innerText;
|
intermediateCert = document.querySelector('[data-test-masked-input]').innerText;
|
||||||
await page.form.back();
|
await page.form.back();
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
export const SELECTORS = {
|
||||||
|
caChain: '[data-test-value-div="CA chain"] [data-test-masked-input]',
|
||||||
|
certificate: '[data-test-value-div="Certificate"] [data-test-masked-input]',
|
||||||
|
commonName: '[data-test-row-value="Common name"]',
|
||||||
|
csr: '[data-test-value-div="CSR"] [data-test-masked-input]',
|
||||||
|
expiryDate: '[data-test-row-value="Expiration date"]',
|
||||||
|
issueDate: '[data-test-row-value="Issue date"]',
|
||||||
|
issuingCa: '[data-test-value-div="Issuing CA"] [data-test-masked-input]',
|
||||||
|
privateKey: '[data-test-value-div="Private key"] [data-test-masked-input]',
|
||||||
|
revocationTime: '[data-test-row-value="Revocation time"]',
|
||||||
|
serialNumber: '[data-test-row-value="Serial number"]',
|
||||||
|
};
|
|
@ -27,15 +27,11 @@ export default {
|
||||||
csr: text('[data-test-row-value="CSR"]', { normalize: false }),
|
csr: text('[data-test-row-value="CSR"]', { normalize: false }),
|
||||||
csrField: fillable('[data-test-input="csr"]'),
|
csrField: fillable('[data-test-input="csr"]'),
|
||||||
certificate: text('[data-test-row-value="Certificate"]', { normalize: false }),
|
certificate: text('[data-test-row-value="Certificate"]', { normalize: false }),
|
||||||
commonNameIsPresent: isPresent('[data-test-row-value="Common name"]'),
|
|
||||||
uploadCert: clickable('[data-test-input="uploadPemBundle"]'),
|
uploadCert: clickable('[data-test-input="uploadPemBundle"]'),
|
||||||
enterCertAsText: clickable('[data-test-text-toggle]'),
|
enterCertAsText: clickable('[data-test-text-toggle]'),
|
||||||
pemBundle: fillable('[data-test-text-file-textarea]'),
|
pemBundle: fillable('[data-test-text-file-textarea]'),
|
||||||
commonName: fillable('[data-test-input="commonName"]'),
|
commonName: fillable('[data-test-input="commonName"]'),
|
||||||
|
|
||||||
issueDateIsPresent: text('[data-test-row-value="Issue date"]'),
|
|
||||||
expiryDateIsPresent: text('[data-test-row-value="Expiration date"]'),
|
|
||||||
|
|
||||||
async generateCA(commonName = 'PKI CA', type = 'root') {
|
async generateCA(commonName = 'PKI CA', type = 'root') {
|
||||||
if (type === 'intermediate') {
|
if (type === 'intermediate') {
|
||||||
return await this.replaceCA().commonName(commonName).caType('intermediate').submit();
|
return await this.replaceCA().commonName(commonName).caType('intermediate').submit();
|
||||||
|
|
Loading…
Reference in New Issue