UI: pki cross-sign component tests (#18847)
* make all alert banners type=danger * finish tests and adding selectors
This commit is contained in:
parent
f3df55ad58
commit
d8e36a3916
|
@ -5,7 +5,7 @@
|
|||
have when it is imported to Vault.
|
||||
</p>
|
||||
{{#if this.signedIssuers}}
|
||||
<h2 class="title is-5">Cross-signing complete ({{this.statusCount}})</h2>
|
||||
<h2 data-test-cross-sign-status-count class="title is-5">Cross-signing complete ({{this.statusCount}})</h2>
|
||||
<p class="has-bottom-margin-xl">
|
||||
The next step is to
|
||||
<DocLink class="has-font-weight-normal" @path="/vault/docs/secrets/pki/rotation-primitives#notes-on-manual_chain">
|
||||
|
@ -26,16 +26,16 @@
|
|||
{{/each}}
|
||||
</div>
|
||||
<div class="box is-fullwidth is-sideless">
|
||||
{{#each this.signedIssuers as |crossSignRow|}}
|
||||
{{#each this.signedIssuers as |crossSignRow idx|}}
|
||||
<div class="box is-marginless no-top-shadow has-slim-padding">
|
||||
<div class="is-flex-start">
|
||||
<div data-test-info-table-row={{idx}} class="is-flex-start">
|
||||
<Icon
|
||||
@name={{if crossSignRow.hasError "alert-circle-fill" "check-circle"}}
|
||||
class={{if crossSignRow.hasError "has-text-danger" "has-text-success"}}
|
||||
/>
|
||||
{{#each (map-by "key" this.inputFields) as |columnAttr|}}
|
||||
{{#let (get crossSignRow columnAttr) as |data|}}
|
||||
<div class="is-flex-1 basis-0 has-bottom-margin-xs">
|
||||
<div data-test-info-table-column={{columnAttr}} class="is-flex-1 basis-0 has-bottom-margin-xs">
|
||||
{{#if (eq columnAttr "intermediateMount")}}
|
||||
<LinkTo class="has-text-black has-text-weight-semibold" @route="overview" @model={{data}}>
|
||||
{{data}}
|
||||
|
@ -59,7 +59,7 @@
|
|||
</div>
|
||||
{{#if crossSignRow.hasError}}
|
||||
<AlertBanner
|
||||
@type={{if crossSignRow.hasUnsupportedParams "warning" "danger"}}
|
||||
@type="danger"
|
||||
@title={{if crossSignRow.hasUnsupportedParams crossSignRow.hasError "Cross-sign failed"}}
|
||||
@message={{if crossSignRow.hasUnsupportedParams crossSignRow.hasUnsupportedParams crossSignRow.hasError}}
|
||||
@marginless={{true}}
|
||||
|
|
|
@ -26,7 +26,7 @@ import { parseCertificate } from 'vault/utils/parse-pki-cert';
|
|||
* -> POST /:intermediateMount/issuers/import/bundle
|
||||
* 5. Read the imported issuer
|
||||
* -> GET /:intermediateMount/issuer/:issuer_id
|
||||
* 5. Update this issuer with the newCrossSignedIssuer
|
||||
* 6. Update this issuer with the newCrossSignedIssuer
|
||||
* -> POST /:intermediateMount/issuer/:issuer_id
|
||||
*
|
||||
* @example
|
||||
|
|
|
@ -135,3 +135,14 @@ export const skeletonCert = `-----BEGIN CERTIFICATE-----\nMIIDQTCCAimgAwIBAgIUVQ
|
|||
// contains unsupported subject and extension OIDs
|
||||
export const unsupportedOids = `-----BEGIN CERTIFICATE-----\nMIIEjDCCA3SgAwIBAgIUD4EeORgh/i+ZZFOk8KsGKQPWsoIwDQYJKoZIhvcNAQEL\nBQAwgZIxMTAvBgNVBAMMKGZhbmN5LWNlcnQtdW5zdXBwb3J0ZWQtc3Viai1hbmQt\nZXh0LW9pZHMxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIDAZLYW5zYXMxDzANBgNVBAcM\nBlRvcGVrYTESMBAGA1UECgwJQWNtZSwgSW5jMRowGAYJKoZIhvcNAQkBFgtmb29A\nYmFyLmNvbTAeFw0yMzAxMjMxODQ3MjNaFw0zMzAxMjAxODQ3MjNaMIGSMTEwLwYD\nVQQDDChmYW5jeS1jZXJ0LXVuc3VwcG9ydGVkLXN1YmotYW5kLWV4dC1vaWRzMQsw\nCQYDVQQGEwJVUzEPMA0GA1UECAwGS2Fuc2FzMQ8wDQYDVQQHDAZUb3Bla2ExEjAQ\nBgNVBAoMCUFjbWUsIEluYzEaMBgGCSqGSIb3DQEJARYLZm9vQGJhci5jb20wggEi\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDyYH5qS7krfZ2tA5uZsY2qXbTb\ntGNG1BsyDhZ/qqVlQybjDsHJZwNUbpfhBcCLaKyAwH1R9n54NOOOn6bYgfKWTgy3\nL7224YDAqYe7Y/GPjgI2MRvRfn6t2xzQxtJ0l0k8LeyNcwhiqYLQyOOfDdc127fm\nW40r2nmhLpH0i9e2I/YP1HQ+ldVgVBqeUTntgVSBfrQF56v9mAcvvHEa5sdHqmX4\nJ2lhWTnx9jqb7NZxCem76BlX1Gt5TpP3Ym2ZFVQI9fuPK4O8JVhk1KBCmIgR3Ft+\nPpFUs/c41EMunKJNzveYrInSDScaC6voIJpK23nMAiM1HckLfUUc/4UojD+VAgMB\nAAGjgdcwgdQwHQYDVR0OBBYEFH7tt4enejKTZtYjUKUUx6PXyzlgMB8GA1UdIwQY\nMBaAFH7tt4enejKTZtYjUKUUx6PXyzlgMA4GA1UdDwEB/wQEAwIFoDAgBgNVHSUB\nAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBCjBM\nBgNVHREERTBDhwTAngEmhgx1cmlTdXBwb3J0ZWSCEWRucy1OYW1lU3VwcG9ydGVk\noBoGAyoDBKATDBFleGFtcGxlIG90aGVybmFtZTANBgkqhkiG9w0BAQsFAAOCAQEA\nP6ckVJgbcJue+MK3RVDuG+Mh7dl89ynC7NwpQFRjLVZQuoMHZT/dcLlVeFejVXu5\nR+IPLmQU6NV7JAmy4zGap8awf12QTy3g410ecrSF94WWlu8bPoekfUnnP+kfzLPH\nCUAkRKxWDSRKX5C8cMMxacVBBaBIayuusLcHkHmxLLDw34PFzyz61gtZOJq7JYnD\nhU9YsNh6bCDmnBDBsDMOI7h8lBRQwTiWVoSD9YNVvFiY29YvFbJQGdh+pmBtf7E+\n1B/0t5NbvqlQSbhMM0QgYFhuCxr3BGNob7kRjgW4i+oh+Nc5ptA5q70QMaYudqRS\nd8SYWhRdxmH3qcHNPcR1iw==\n-----END CERTIFICATE-----`;
|
||||
export const certWithoutCN = `-----BEGIN CERTIFICATE-----\nMIIDUDCCAjigAwIBAgIUEUpM5i7XMd/imZkR9XvonMaqPyYwDQYJKoZIhvcNAQEL\nBQAwHDEaMBgGCSqGSIb3DQEJARYLZm9vQGJhci5jb20wHhcNMjMwMTIzMjMyODEw\nWhcNMzMwMTIwMjMyODEwWjAcMRowGAYJKoZIhvcNAQkBFgtmb29AYmFyLmNvbTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPGSdeqLICZcoUzxk88F8Tp+\nVNI+mS74L8pHyb9ZNZfeXPo0E9L5pi+KKI7rkxAtBGUecG1ENSxDDK9p6XZhWHSU\nZ6bdjOsjcIlfiM+1hhtDclIVxIDnz2Jt1/Vmnm8DXwdwVATWiFLTnfm288deNwsT\npl0ehAR3BadkZvteC6t+giEw/4qm1/FP53GEBOQeUWJDZRvtL37rdx4joFv3cR4w\nV0dukOjc5AGXtIOorO145OSZj8s7RsW3pfGcFUcOg7/flDxfK1UqFflQa7veLvKa\nWE/fOMyB/711QjSkTuQ5Rw3Rf9Fr2pqVJQgElTIW1SKaX5EJTB9mtGB34UqUXtsC\nAwEAAaOBiTCBhjAdBgNVHQ4EFgQUyhFP/fm+798mErPD5VQvEaAZQrswHwYDVR0j\nBBgwFoAUyhFP/fm+798mErPD5VQvEaAZQrswDgYDVR0PAQH/BAQDAgWgMCAGA1Ud\nJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEK\nMA0GCSqGSIb3DQEBCwUAA4IBAQCishzVkhuSAtqxgsZdYzBs3GpakGIio5zReW27\n6dk96hYCbbe4K3DtcFbRD1B8t6aTJlHxkFRaOWErSXu9WP3fUhIDNRE64Qsrg1zk\n3Km430qBlorXmTp6xhYHQfY5bn5rT2YY7AmaYIlIFxRhod43i5GDbBP+e+d/vTqR\nv1AJflYofeR4LeATP64B6a4R+QQVoxI43+pyH3ka+nRHwJBR9h8SMtJoqBy7x9pl\nYlBDa8lSn05doA3+e03VIzitvBBWI4oX1XB0tShSLk6YJXayIwe0ZNVvfYLIRKCp\nb4DUwChYzG/FwFSssUAqzVFhu3i+uU3Z47bsLVm0R5m7hLiZ\n-----END CERTIFICATE-----`;
|
||||
|
||||
// CROSS-SIGNING:
|
||||
export const newCSR = {
|
||||
common_name: 'Short-Lived Int R1',
|
||||
csr: `-----BEGIN CERTIFICATE REQUEST-----\nMIICYjCCAUoCAQAwHTEbMBkGA1UEAxMSU2hvcnQtTGl2ZWQgSW50IFIxMIIBIjAN\nBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqsvFU7lzt06n1w6BL+Waf9zd+Z3G\n90Kv0HAksoLaWYinhkxNIUTU8ar9HLa2WV4EoJbNq91Hn+jFc2SYEXtRV+jm0kEh\nz4C4AoQ4D0s83JcYNssiNbVA04wa5ovD0iA/pzwVz8TnJSfAAuZ3vXFlyIbQ3ESo\nzt9hGjo/JOpoBh67E7xkuzw4lnC2rXGHdh9pk1Di+wqREnKU4nuhDLnTC/LL+Mkm\n07F1aMAW3Z/PWFmmsDJHMhZnaYo2LGCwU4A0U1ED0XpwflobVbkzZDmCXOPEI8UX\nG6VcL36zWnzEQnlZKN91MAa+s0E4z40KHKVSblSkjYD1K6n0y787ic2mDwIDAQAB\noAAwDQYJKoZIhvcNAQELBQADggEBAFQtiJaRfaQS3jHr7aFeszB/JmDRQiOoML3g\nhA3EcVd2rvDjiqikwD9EFdLTJyYJfb+9yiKDJqB7Fw2GPSrFxrd+jC9qZRI3VEWK\n8VdflLbruc1FcqJcE/0z2hWa11eud1bMLq8U6AfxNHL4r4ukrp2D5elrdsrDnhZj\nwMi3FtEFd4RZVaWZYVmWcQTeH7Zz/LYwkVDgBuvC+SOCaNNo/dCurkAAoxw8obBj\n1FS2F/3oHQxMui8vS8j6sMWMPZ5D3Q0xSC3HBUNoI2ZC77Mxn9yfj6ianUXKOOlf\nQMRaPBVajxZm9ovV64QKr+7HK7W7U/fNEqvoKBUDCqEuWmSsxMk=\n-----END CERTIFICATE REQUEST-----`,
|
||||
};
|
||||
|
||||
export const oldParentIssuerCert = `-----BEGIN CERTIFICATE-----\nMIIDKzCCAhOgAwIBAgIUMCEF+bzBC4NQIWjE1sv/RbnYfUgwDQYJKoZIhvcNAQEL\nBQAwHTEbMBkGA1UEAxMSTG9uZy1MaXZlZCBSb290IFgxMB4XDTIzMDEyNTAwMjQz\nM1oXDTIzMDIyNjAwMjUwM1owHTEbMBkGA1UEAxMSTG9uZy1MaXZlZCBSb290IFgx\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0zrpJvjWcBV49Eor+zfh\nGW40xH6PcPSpzWGCCFiMPFwKrBSjuGRwwkLsXU7u2P15jIV/IU2kPS+WOW+EIe0x\ns5X2SoujZGOmM6du/6HIo9lz9yjb5G1SHdv/e65Q45QWb6wQcuO4axffvPzmAU9L\nQcunEF4g3rCz4cHYumi0osybbwR45z+8owNhykdbu7AwV0Cyz3C/lT1wxDxbFr0Y\n1NEjQ8AF4oRzqkmGoLp6ixDxp8zMpOlKWWYem1mx0RbqlwLP7khiS5YKi8+j8aog\nOhHA/W4i+ihrBzkv4GtOSdkhJz5qacifydUXtJ7SmvYs9Fi+hFgw61sw23ywbr3+\nywIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\nHQ4EFgQUQsdYFMtsNMYNDIhZHMd77kcLLi8wHwYDVR0jBBgwFoAUQsdYFMtsNMYN\nDIhZHMd77kcLLi8wDQYJKoZIhvcNAQELBQADggEBAFNKTnNUzjZGHpXVK9Go8k/i\nVMNBktjGp58z+EN32TJnq/tOW1eVswUmq71S3R16Iho4XZDZVchuK+zhqSwlAmgM\no1vs6L5IJ0rVZcLZpysxFtawlbA362zBOX0F7tqStdEeBWaXw6J+MQ26xAPgHjXo\nc3fqqNWGbrOPt1uFoXWD+0Bg8M90a7OT0ijubh/PcuCe1yF9G2BqRQruB05gZiHl\n0NGbUka1ntD/lxYfLeSnp+FHJVDrcAHwPhKQS8HHr/ZBjKEGY8In+JIi/KBV/M8b\nGeW2k5odl6r2UIR6PWSei1WKKHe09WzO7rGJaN6uKLP14c0nSF3/q+AQY3m+tPY=\n-----END CERTIFICATE-----\n`;
|
||||
export const parentIssuerCert = `-----BEGIN CERTIFICATE-----\nMIIDKzCCAhOgAwIBAgIUBxLeuD3K0hF5dGpaEgZqytTN3lswDQYJKoZIhvcNAQEL\nBQAwHTEbMBkGA1UEAxMSTG9uZy1MaXZlZCBSb290IFgyMB4XDTIzMDEyNTAwMjQz\nM1oXDTIzMDIyNjAwMjUwM1owHTEbMBkGA1UEAxMSTG9uZy1MaXZlZCBSb290IFgy\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuqkwN4m5dFLwFi0iYs4r\nTO4HWzloF4yCOaNfVksh1cOafVu9vjFwOWgHZFe6h8BOn6biKdFtvGTyIzlMHe5t\nyFmec9pfjX243bH9Ev4n2RTMKs818g9LdoZT6SI7DxHEu3yuHBg9TM87+GB+dA1V\nkRsK5hgtNCSMdgFSljM169sYbNilpk8M7O2hr+AmgRi0c1nUEPCe4JAr0Zv8iweJ\ntFRVHiQJXD9WIVxaWVxqWFsHoXseZS7H76RSdf4jNfENmBguHZMAPhtqlc/pMan8\nu0IJETWjWENn+WYC7DnnfQtNqyebU2LdT3oKO8tELqITygjT2tCS1Zavmsy69VY0\nYwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\nHQ4EFgQUxgchIBo+1F++IFW0F586I5QDFGYwHwYDVR0jBBgwFoAUxgchIBo+1F++\nIFW0F586I5QDFGYwDQYJKoZIhvcNAQELBQADggEBAI6DdnW8q/FqGqk/Y0k7iUrZ\nYkfMRlss6uBTzLev53eXqFIJ3+EFVfV+ohDEedlYYm2QCELzQcJSR7Q2I22PQj8X\nTO0yqk6LOCMv/4yiDhF4D+haiDU4joq5GX1dpFdlNSQ5fJmnLKu8HYbOhbwUo4ns\n4yGzIMulZR1Zqf/HGEOCYPDQ0ZHucmHn7uGhmV+kgYGoKVEZ8XxfmyNPKuwTAUHL\nfInPJZtbxXTVmiWWy3iraeI4XcUvaD0JtVnsVphYrqrSZ60DjgFsjiyenxePGHXf\nYXV9HIS6OXlvWhJKlSINOTv9fAa+e+JtK7frdvxJNHoTG34PiGXfOV2swTvLJQo=\n-----END CERTIFICATE-----\n`;
|
||||
export const intIssuerCert = `-----BEGIN CERTIFICATE-----\nMIIDKzCCAhOgAwIBAgIUPt5VyO6gyA4hVaMkdpNyBlP+I64wDQYJKoZIhvcNAQEL\nBQAwHTEbMBkGA1UEAxMSTG9uZy1MaXZlZCBSb290IFgxMB4XDTIzMDEyNTAwMjQz\nM1oXDTIzMDIyNjAwMjUwM1owHTEbMBkGA1UEAxMSU2hvcnQtTGl2ZWQgSW50IFIx\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqsvFU7lzt06n1w6BL+Wa\nf9zd+Z3G90Kv0HAksoLaWYinhkxNIUTU8ar9HLa2WV4EoJbNq91Hn+jFc2SYEXtR\nV+jm0kEhz4C4AoQ4D0s83JcYNssiNbVA04wa5ovD0iA/pzwVz8TnJSfAAuZ3vXFl\nyIbQ3ESozt9hGjo/JOpoBh67E7xkuzw4lnC2rXGHdh9pk1Di+wqREnKU4nuhDLnT\nC/LL+Mkm07F1aMAW3Z/PWFmmsDJHMhZnaYo2LGCwU4A0U1ED0XpwflobVbkzZDmC\nXOPEI8UXG6VcL36zWnzEQnlZKN91MAa+s0E4z40KHKVSblSkjYD1K6n0y787ic2m\nDwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\nHQ4EFgQUkBK+oGpo5DNj2pCKoUE08WFOxQUwHwYDVR0jBBgwFoAUQsdYFMtsNMYN\nDIhZHMd77kcLLi8wDQYJKoZIhvcNAQELBQADggEBAIf4Bp/NYftiN8LmQrVzPWAe\nc4Bxm/NFFtkwQEvFhndMN68MUyXa5yxAdnYAHN+fRpYPxbjoZNXjW/jx3Kjft44r\ntyNGrrkjR80TI9FbL53nN7hLtZQdizsQD0Wype4Q1JOIxYw2Wd5Hr/PVPrJZ3PGg\nwNeI5IRu/cVbVT/vkRaHqYSwpa+V2cZTaEk6h62KPaKu3ui+omoeitU6qXHOysXQ\nrdGkJl/x831sIKmN0dMiGeoJdHGAr/E2f3ijKbVPsjIxZbm2SSumldOFYWn9cNYD\nI6sizFH976Wpde/GRIvBIzJnlK3xgfy0D9AUvwKyt75PVEnshc9tlhxoSVlKaUE=\n-----END CERTIFICATE-----\n`;
|
||||
export const newlySignedCert = `-----BEGIN CERTIFICATE-----\nMIIDKzCCAhOgAwIBAgIUKapKK5Coau2sfIJgqA9jcC6BkWIwDQYJKoZIhvcNAQEL\nBQAwHTEbMBkGA1UEAxMSTG9uZy1MaXZlZCBSb290IFgyMB4XDTIzMDEyNTIyMjky\nNVoXDTIzMDIyNjIyMjk1NVowHTEbMBkGA1UEAxMSU2hvcnQtTGl2ZWQgSW50IFIx\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqsvFU7lzt06n1w6BL+Wa\nf9zd+Z3G90Kv0HAksoLaWYinhkxNIUTU8ar9HLa2WV4EoJbNq91Hn+jFc2SYEXtR\nV+jm0kEhz4C4AoQ4D0s83JcYNssiNbVA04wa5ovD0iA/pzwVz8TnJSfAAuZ3vXFl\nyIbQ3ESozt9hGjo/JOpoBh67E7xkuzw4lnC2rXGHdh9pk1Di+wqREnKU4nuhDLnT\nC/LL+Mkm07F1aMAW3Z/PWFmmsDJHMhZnaYo2LGCwU4A0U1ED0XpwflobVbkzZDmC\nXOPEI8UXG6VcL36zWnzEQnlZKN91MAa+s0E4z40KHKVSblSkjYD1K6n0y787ic2m\nDwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\nHQ4EFgQUkBK+oGpo5DNj2pCKoUE08WFOxQUwHwYDVR0jBBgwFoAUxgchIBo+1F++\nIFW0F586I5QDFGYwDQYJKoZIhvcNAQELBQADggEBAJaems1vgEjxgb3d1y9PYxzN\nLZbuf/+0+BCVa9k4bEsbuhXhEecFdIi2OKS6fabeoEOF97Gvqrgc+LEpNsU6lIRA\nkJ/nHe0CD2hf0aBQsGsOllYy/4QnrPlbowb4KizPknEMWdGcvfnlzzOJzo4/UuMk\nMZ9vn2GrINzfml/sLocOzP/MsPd8bBhXI2Emh2O9tJ4+zeHLhEzcM1gdNk8pp+wP\nEOks0EcN4UBkpEnDZcDTJVgp9XpWy19EEGqsxjBq6rlpIvPW8XHoH1jZSGY1KWBJ\nRGtDcGugwTxO9jYHz/a1qu4BVt5FFcb0L3IOvcr+3QCCeiJQHcVY8QRbO9M4AQk=\n-----END CERTIFICATE-----\n`;
|
||||
|
|
|
@ -1,29 +1,349 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { click, fillIn, render } from '@ember/test-helpers';
|
||||
import { setupEngine } from 'ember-engines/test-support';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { Response } from 'miragejs';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import {
|
||||
intIssuerCert,
|
||||
newCSR,
|
||||
newlySignedCert,
|
||||
oldParentIssuerCert,
|
||||
parentIssuerCert,
|
||||
unsupportedOids,
|
||||
} from 'vault/tests/helpers/pki/values';
|
||||
|
||||
module('Integration | Component | pki-issuer-cross-sign', function (hooks) {
|
||||
const SELECTORS = {
|
||||
input: (key, row = 0) => `[data-test-object-list-input="${key}-${row}"]`,
|
||||
addRow: '[data-test-object-list-add-button',
|
||||
submitButton: '[data-test-cross-sign-submit]',
|
||||
cancelButton: '[data-test-cross-sign-cancel]',
|
||||
statusCount: '[data-test-cross-sign-status-count]',
|
||||
signedIssuerRow: (row = 0) => `[data-test-info-table-row="${row}"]`,
|
||||
signedIssuerCol: (attr) => `[data-test-info-table-column="${attr}"]`,
|
||||
};
|
||||
const FIELDS = [
|
||||
{
|
||||
label: 'Mount path',
|
||||
key: 'intermediateMount',
|
||||
placeholder: 'Mount path',
|
||||
helpText: 'The mount in which your new certificate can be found.',
|
||||
},
|
||||
{
|
||||
label: "Issuer's current name",
|
||||
key: 'intermediateIssuer',
|
||||
placeholder: 'Current issuer name',
|
||||
helpText: 'The API name of the previous intermediate which was cross-signed.',
|
||||
},
|
||||
{
|
||||
label: 'New issuer name',
|
||||
key: 'newCrossSignedIssuer',
|
||||
placeholder: 'Enter a new issuer name',
|
||||
helpText: `This is your new issuer’s name in the API.`,
|
||||
},
|
||||
];
|
||||
module('Integration | Component | pki issuer cross sign', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupEngine(hooks, 'pki'); // https://github.com/ember-engines/ember-engines/pull/653
|
||||
setupEngine(hooks, 'pki');
|
||||
setupMirage(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
this.model = this.store.createRecord('pki/issuer', {
|
||||
issuerId: 'dcc69709-0056-b008-2ad1-a939cfae0c2a',
|
||||
issuerName: 'my-parent-issuer-name',
|
||||
});
|
||||
hooks.beforeEach(async function () {
|
||||
const store = this.owner.lookup('service:store');
|
||||
this.backend = 'my-parent-issuer-mount';
|
||||
this.intMountPath = 'int-mount';
|
||||
this.owner.lookup('service:secret-mount-path').update(this.backend);
|
||||
|
||||
// parent issuer
|
||||
this.parentIssuerData = {
|
||||
ca_chain: [parentIssuerCert],
|
||||
certificate: parentIssuerCert,
|
||||
crl_distribution_points: [],
|
||||
issuer_id: '0c983955-6426-22b2-1b3f-c0bdca40fd15',
|
||||
issuer_name: 'my-parent-issuer-name',
|
||||
issuing_certificates: [],
|
||||
key_id: '8b8d0017-a067-ac50-c5cf-475876f9aac5',
|
||||
leaf_not_after_behavior: 'err',
|
||||
manual_chain: null,
|
||||
ocsp_servers: [],
|
||||
revocation_signature_algorithm: 'SHA256WithRSA',
|
||||
revoked: false,
|
||||
usage: 'crl-signing,issuing-certificates,ocsp-signing,read-only',
|
||||
};
|
||||
// intermediate issuer
|
||||
this.intIssuerData = {
|
||||
ca_chain: [intIssuerCert, oldParentIssuerCert],
|
||||
certificate: intIssuerCert,
|
||||
crl_distribution_points: [],
|
||||
issuer_id: '6c286455-7904-5698-bf86-8aba81e680e6',
|
||||
issuer_name: 'source-int-name',
|
||||
issuing_certificates: [],
|
||||
key_id: '2e2b8baf-4dac-c46f-cee4-8afbc7f2d8b2',
|
||||
leaf_not_after_behavior: 'err',
|
||||
manual_chain: null,
|
||||
ocsp_servers: [],
|
||||
revocation_signature_algorithm: '',
|
||||
revoked: false,
|
||||
usage: 'crl-signing,issuing-certificates,ocsp-signing,read-only',
|
||||
};
|
||||
// newly cross signed issuer
|
||||
this.newIssuerData = {
|
||||
ca_chain: [newlySignedCert, parentIssuerCert],
|
||||
certificate: newlySignedCert,
|
||||
crl_distribution_points: [],
|
||||
issuer_id: 'bc159ba8-930c-c894-e871-2f3e889e8e02',
|
||||
issuer_name: 'newly-cross-signed-cert',
|
||||
issuing_certificates: [],
|
||||
key_id: '2e2b8baf-4dac-c46f-cee4-8afbc7f2d8b2',
|
||||
leaf_not_after_behavior: 'err',
|
||||
manual_chain: null,
|
||||
ocsp_servers: [],
|
||||
revocation_signature_algorithm: '',
|
||||
revoked: false,
|
||||
usage: 'crl-signing,issuing-certificates,ocsp-signing,read-only',
|
||||
};
|
||||
|
||||
this.testInputs = {
|
||||
intermediateMount: this.intMountPath,
|
||||
intermediateIssuer: this.intIssuerData.issuer_name,
|
||||
newCrossSignedIssuer: this.newIssuerData.issuer_name,
|
||||
};
|
||||
|
||||
store.pushPayload('pki/issuer', { modelName: 'pki/issuer', data: this.parentIssuerData });
|
||||
this.parentIssuerModel = store.peekRecord('pki/issuer', this.parentIssuerData.issuer_id);
|
||||
});
|
||||
|
||||
// TODO finish
|
||||
test('it renders', async function (assert) {
|
||||
await render(
|
||||
hbs`
|
||||
<PkiIssuerCrossSign @parentIssuer={{this.model}} />
|
||||
`,
|
||||
{ owner: this.engine }
|
||||
test('it makes requests to the correct endpoints', async function (assert) {
|
||||
assert.expect(18);
|
||||
this.server.get(`/${this.intMountPath}/issuer/${this.intIssuerData.issuer_name}`, () => {
|
||||
assert.ok(true, 'Step 1. GET request is made to fetch existing issuer data');
|
||||
return { data: this.intIssuerData };
|
||||
});
|
||||
this.server.post(`/${this.intMountPath}/intermediate/generate/existing`, (schema, req) => {
|
||||
assert.ok(true, 'Step 2. POST request is made to generate new CSR');
|
||||
assert.propEqual(
|
||||
JSON.parse(req.requestBody),
|
||||
{
|
||||
common_name: newCSR.common_name,
|
||||
country: null,
|
||||
exclude_cn_from_sans: false,
|
||||
format: 'pem',
|
||||
locality: null,
|
||||
organization: null,
|
||||
ou: null,
|
||||
province: null,
|
||||
key_ref: this.intIssuerData.key_id,
|
||||
},
|
||||
'payload contains correct key ref'
|
||||
);
|
||||
return { data: { csr: newCSR.csr, key_id: this.intIssuerData.key_id } };
|
||||
});
|
||||
this.server.post(
|
||||
`/${this.backend}/issuer/${this.parentIssuerData.issuer_name}/sign-intermediate`,
|
||||
(schema, req) => {
|
||||
assert.ok(true, 'Step 3. POST request is made to sign CSR with new parent issuer');
|
||||
assert.propEqual(JSON.parse(req.requestBody), newCSR, 'payload has common name and csr');
|
||||
return { data: { ca_chain: [newlySignedCert, parentIssuerCert] } };
|
||||
}
|
||||
);
|
||||
assert.dom(this.element).exists();
|
||||
this.server.post(`/${this.intMountPath}/issuers/import/bundle`, (schema, req) => {
|
||||
assert.ok(true, 'Step 4. POST request made to import issuer');
|
||||
assert.propEqual(
|
||||
JSON.parse(req.requestBody),
|
||||
{ pem_bundle: [newlySignedCert, parentIssuerCert].join('\n') },
|
||||
'payload contains pem bundle'
|
||||
);
|
||||
return {
|
||||
data: {
|
||||
imported_issuers: null,
|
||||
imported_keys: null,
|
||||
mapping: { [this.newIssuerData.issuer_id]: this.intIssuerData.key_id },
|
||||
},
|
||||
};
|
||||
});
|
||||
this.server.get(`/${this.intMountPath}/issuer/${this.newIssuerData.issuer_id}`, () => {
|
||||
assert.ok(true, 'Step 5. GET request is made to newly imported issuer');
|
||||
return { data: this.newIssuerData };
|
||||
});
|
||||
|
||||
this.server.post(`/${this.intMountPath}/issuer/${this.newIssuerData.issuer_id}`, (schema, req) => {
|
||||
assert.ok(true, 'Step 6. POST request is made to update issuer name');
|
||||
assert.propEqual(
|
||||
JSON.parse(req.requestBody),
|
||||
{
|
||||
issuer_name: 'newly-cross-signed-cert',
|
||||
leaf_not_after_behavior: 'err',
|
||||
usage: 'crl-signing,issuing-certificates,ocsp-signing,read-only',
|
||||
},
|
||||
'payload has correct data '
|
||||
);
|
||||
return { data: this.newIssuerData };
|
||||
});
|
||||
|
||||
await render(hbs`<PkiIssuerCrossSign @parentIssuer={{this.parentIssuerModel}} /> `, {
|
||||
owner: this.engine,
|
||||
});
|
||||
// fill out form and submit
|
||||
for (const field of FIELDS) {
|
||||
await fillIn(SELECTORS.input(field.key), this.testInputs[field.key]);
|
||||
}
|
||||
await click(SELECTORS.submitButton);
|
||||
|
||||
assert.dom(SELECTORS.statusCount).hasText('Cross-signing complete (1 successful, 0 errors)');
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerRow()} [data-test-icon="check-circle"]`)
|
||||
.exists('row has success icon');
|
||||
for (const field of FIELDS) {
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerCol(field.key)}`)
|
||||
.hasText(this.testInputs[field.key], `${field.key} displays correct value`);
|
||||
assert.dom(`${SELECTORS.signedIssuerCol(field.key)} a`).hasTagName('a');
|
||||
}
|
||||
});
|
||||
|
||||
test('it cross-signs multiple certs', async function (assert) {
|
||||
assert.expect(13);
|
||||
const nonexistentIssuer = {
|
||||
intermediateMount: this.intMountPath,
|
||||
intermediateIssuer: 'some-fake-issuer',
|
||||
newCrossSignedIssuer: 'failed-cert-1',
|
||||
};
|
||||
const unsupportedCert = {
|
||||
intermediateMount: this.intMountPath,
|
||||
intermediateIssuer: 'some-fancy-issuer',
|
||||
newCrossSignedIssuer: 'failed-cert-2',
|
||||
};
|
||||
|
||||
this.server.get(`/${this.intMountPath}/issuer/${this.intIssuerData.issuer_name}`, () => {
|
||||
assert.ok(true, 'request is made to sign first cert');
|
||||
return { data: this.intIssuerData };
|
||||
});
|
||||
|
||||
this.server.get(`/${this.intMountPath}/issuer/${nonexistentIssuer.intermediateIssuer}`, () => {
|
||||
assert.ok(true, 'request is made to second cert');
|
||||
return new Response(
|
||||
500,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify({
|
||||
errors: [
|
||||
`1 error occurred:\n\t* unable to find PKI issuer for reference: ${nonexistentIssuer.intermediateIssuer}\n\n`,
|
||||
],
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
this.server.get(`/${this.intMountPath}/issuer/${unsupportedCert.intermediateIssuer}`, () => {
|
||||
assert.ok(true, 'request is made to third cert');
|
||||
return { data: { isser_name: unsupportedCert.intermediateIssuer, certificate: unsupportedOids } };
|
||||
});
|
||||
|
||||
await render(hbs`<PkiIssuerCrossSign @parentIssuer={{this.parentIssuerModel}} /> `, {
|
||||
owner: this.engine,
|
||||
});
|
||||
|
||||
// fill out form and submit
|
||||
for (const field of FIELDS) {
|
||||
await fillIn(SELECTORS.input(field.key), this.testInputs[field.key]);
|
||||
}
|
||||
await click(SELECTORS.addRow);
|
||||
for (const field of FIELDS) {
|
||||
await fillIn(SELECTORS.input(field.key, 1), nonexistentIssuer[field.key]);
|
||||
}
|
||||
await click(SELECTORS.addRow);
|
||||
for (const field of FIELDS) {
|
||||
await fillIn(SELECTORS.input(field.key, 2), unsupportedCert[field.key]);
|
||||
}
|
||||
await click(SELECTORS.submitButton);
|
||||
|
||||
assert.dom(SELECTORS.statusCount).hasText('Cross-signing complete (0 successful, 3 errors)');
|
||||
for (const field of FIELDS) {
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerRow()} ${SELECTORS.signedIssuerCol(field.key)}`)
|
||||
.hasText(this.testInputs[field.key], `first row has correct values`);
|
||||
}
|
||||
for (const field of FIELDS) {
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerRow(1)} ${SELECTORS.signedIssuerCol(field.key)}`)
|
||||
.hasText(nonexistentIssuer[field.key], `second row has correct values`);
|
||||
}
|
||||
for (const field of FIELDS) {
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerRow(2)} ${SELECTORS.signedIssuerCol(field.key)}`)
|
||||
.hasText(unsupportedCert[field.key], `third row has correct values`);
|
||||
}
|
||||
});
|
||||
|
||||
test('it returns API errors when a request fails', async function (assert) {
|
||||
assert.expect(7);
|
||||
this.server.get(`/${this.intMountPath}/issuer/${this.intIssuerData.issuer_name}`, () => {
|
||||
return new Response(
|
||||
500,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify({
|
||||
errors: ['1 error occurred:\n\t* unable to find PKI issuer for reference: nonexistent-mount\n\n'],
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
await render(hbs`<PkiIssuerCrossSign @parentIssuer={{this.parentIssuerModel}} /> `, {
|
||||
owner: this.engine,
|
||||
});
|
||||
|
||||
// fill out form and submit
|
||||
for (const field of FIELDS) {
|
||||
await fillIn(SELECTORS.input(field.key), this.testInputs[field.key]);
|
||||
}
|
||||
await click(SELECTORS.submitButton);
|
||||
|
||||
assert.dom(SELECTORS.statusCount).hasText('Cross-signing complete (0 successful, 1 error)');
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerRow()} [data-test-icon="alert-circle-fill"]`)
|
||||
.exists('row has failure icon');
|
||||
|
||||
assert.dom('[data-test-alert-banner="alert"] .message-title').hasText('Cross-sign failed');
|
||||
assert
|
||||
.dom('[data-test-alert-banner="alert"] .alert-banner-message-body')
|
||||
.hasText('1 error occurred: * unable to find PKI issuer for reference: nonexistent-mount');
|
||||
|
||||
for (const field of FIELDS) {
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerCol(field.key)}`)
|
||||
.hasText(this.testInputs[field.key], `${field.key} displays correct value`);
|
||||
}
|
||||
});
|
||||
|
||||
test('it returns an error when a certificate contains unsupported values', async function (assert) {
|
||||
assert.expect(7);
|
||||
const unsupportedIssuerCert = { ...this.intIssuerData, certificate: unsupportedOids };
|
||||
this.server.get(`/${this.intMountPath}/issuer/${this.intIssuerData.issuer_name}`, () => {
|
||||
return { data: unsupportedIssuerCert };
|
||||
});
|
||||
|
||||
await render(hbs`<PkiIssuerCrossSign @parentIssuer={{this.parentIssuerModel}} /> `, {
|
||||
owner: this.engine,
|
||||
});
|
||||
// fill out form and submit
|
||||
for (const field of FIELDS) {
|
||||
await fillIn(SELECTORS.input(field.key), this.testInputs[field.key]);
|
||||
}
|
||||
await click(SELECTORS.submitButton);
|
||||
assert.dom(SELECTORS.statusCount).hasText('Cross-signing complete (0 successful, 1 error)');
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerRow()} [data-test-icon="alert-circle-fill"]`)
|
||||
.exists('row has failure icon');
|
||||
assert
|
||||
.dom('[data-test-alert-banner="alert"] .message-title')
|
||||
.hasText('Certificate must be manually cross-signed using the CLI.');
|
||||
assert
|
||||
.dom('[data-test-alert-banner="alert"] .alert-banner-message-body')
|
||||
.hasText(
|
||||
'certificate contains unsupported subject OIDs, certificate contains unsupported extension OIDs, subjectAltName contains unsupported types '
|
||||
);
|
||||
|
||||
for (const field of FIELDS) {
|
||||
assert
|
||||
.dom(`${SELECTORS.signedIssuerCol(field.key)}`)
|
||||
.hasText(this.testInputs[field.key], `${field.key} displays correct value`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue