From def5c6735d3fd4501f453379322d28b719a5e1b3 Mon Sep 17 00:00:00 2001 From: Jose Antonio Carmona Date: Fri, 30 Sep 2022 16:27:32 +0200 Subject: [PATCH] [bitnami/ejbca] Add ejbca tests (#12725) * [bitnami/ejbca] Add tests Signed-off-by: Jose Antonio Carmona * Publish ejbca using VIB Signed-off-by: Jose Antonio Carmona * Add a fixture for cert specs Signed-off-by: Jose Antonio Carmona Signed-off-by: Jose Antonio Carmona --- .github/workflows/cd-pipeline.yml | 1 + .vib/ejbca/cypress/cypress.json | 8 ++++ .../ejbca/cypress/cypress/fixtures/certs.json | 6 +++ .../cypress/cypress/integration/ejbca_spec.js | 40 +++++++++++++++++++ .vib/ejbca/cypress/cypress/plugins/index.js | 27 +++++++++++++ .../ejbca/cypress/cypress/support/commands.js | 13 ++++++ .vib/ejbca/cypress/cypress/support/index.js | 20 ++++++++++ .vib/ejbca/goss/goss.yaml | 38 ++++++++++++++++++ .vib/ejbca/goss/vars.yaml | 18 +++++++++ .vib/ejbca/vib-publish.json | 26 +++++++++++- .vib/ejbca/vib-verify.json | 26 +++++++++++- 11 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 .vib/ejbca/cypress/cypress.json create mode 100644 .vib/ejbca/cypress/cypress/fixtures/certs.json create mode 100644 .vib/ejbca/cypress/cypress/integration/ejbca_spec.js create mode 100644 .vib/ejbca/cypress/cypress/plugins/index.js create mode 100644 .vib/ejbca/cypress/cypress/support/commands.js create mode 100644 .vib/ejbca/cypress/cypress/support/index.js create mode 100644 .vib/ejbca/goss/goss.yaml create mode 100644 .vib/ejbca/goss/vars.yaml diff --git a/.github/workflows/cd-pipeline.yml b/.github/workflows/cd-pipeline.yml index 8f58c936c5..87ce72e954 100644 --- a/.github/workflows/cd-pipeline.yml +++ b/.github/workflows/cd-pipeline.yml @@ -14,6 +14,7 @@ on: # rebuild any PRs and main branch changes - 'bitnami/discourse/**' - 'bitnami/dokuwiki/**' - 'bitnami/drupal/**' + - 'bitnami/ejbca/**' - 'bitnami/elasticsearch/**' - 'bitnami/etcd/**' - 'bitnami/external-dns/**' diff --git a/.vib/ejbca/cypress/cypress.json b/.vib/ejbca/cypress/cypress.json new file mode 100644 index 0000000000..093e969ee0 --- /dev/null +++ b/.vib/ejbca/cypress/cypress.json @@ -0,0 +1,8 @@ +{ + "baseUrl": "http://localhost", + "env": { + "username": "bitnamiTest", + "password": "ComplicatedPassword123!4", + "baseDN": "UID=c-1CCXmPAsNWmZuDtQQ8FHl7tcVdjCiNTH,O=ExampleCA,C=SE" + } +} \ No newline at end of file diff --git a/.vib/ejbca/cypress/cypress/fixtures/certs.json b/.vib/ejbca/cypress/cypress/fixtures/certs.json new file mode 100644 index 0000000000..de4df283e8 --- /dev/null +++ b/.vib/ejbca/cypress/cypress/fixtures/certs.json @@ -0,0 +1,6 @@ +{ + "newAdminCert": { + "cipherSpec": "RSA_2048", + "profile": "ENDUSER" + } +} diff --git a/.vib/ejbca/cypress/cypress/integration/ejbca_spec.js b/.vib/ejbca/cypress/cypress/integration/ejbca_spec.js new file mode 100644 index 0000000000..781584a452 --- /dev/null +++ b/.vib/ejbca/cypress/cypress/integration/ejbca_spec.js @@ -0,0 +1,40 @@ +/// + +it('allows to enrol and verify certificate', () => { + const certFile = `cypress/downloads/${Cypress.env('username')}.p12`; + cy.task('fileExists', certFile).then((exists) => { + // A user can only enrol once + if (!exists) { + cy.visit('/ejbca/enrol/keystore.jsp'); + cy.get('#textfieldusername').type(Cypress.env('username')); + cy.get('#textfieldpassword').type(Cypress.env('password')); + cy.get('#buttonsubmitusername').click(); + cy.fixture('certs').then((certs) => { + cy.get('#tokenKeySpec').select(certs.newAdminCert.cipherSpec); + cy.get('#certprofile').select(certs.newAdminCert.profile); + }); + // Clicking on the button will download the certificate, but Cypress + // expects the page to be reloaded and fails with a timeout. We manually + // force the reload to avoid it and then verify that the file was indeed + // downloaded. + cy.window() + .document() + .then(function (doc) { + doc.addEventListener('click', () => { + setTimeout(function () { + doc.location.reload(); + }, 2000); + }); + + cy.contains('input', 'Enroll').click(); + }); + } + cy.readFile(certFile).should('exist'); + }); + + cy.visit('/ejbca/retrieve/list_certs.jsp'); + cy.get('#subject').type(`${Cypress.env('baseDN')},CN=SuperAdmin`); + cy.get('#ok').click(); + cy.contains('Check if certificate is revoked').click(); + cy.contains('has NOT been revoked'); +}); diff --git a/.vib/ejbca/cypress/cypress/plugins/index.js b/.vib/ejbca/cypress/cypress/plugins/index.js new file mode 100644 index 0000000000..273aa37869 --- /dev/null +++ b/.vib/ejbca/cypress/cypress/plugins/index.js @@ -0,0 +1,27 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +// eslint-disable-next-line no-unused-vars +const fs = require('fs'); + +module.exports = (on, config) => { + on('task', { + fileExists(filename) { + return fs.existsSync(filename); + }, + }); +}; diff --git a/.vib/ejbca/cypress/cypress/support/commands.js b/.vib/ejbca/cypress/cypress/support/commands.js new file mode 100644 index 0000000000..db6590fd8c --- /dev/null +++ b/.vib/ejbca/cypress/cypress/support/commands.js @@ -0,0 +1,13 @@ +const COMMAND_DELAY = 2000; + +for (const command of ['click']) { + Cypress.Commands.overwrite(command, (originalFn, ...args) => { + const origVal = originalFn(...args); + + return new Promise((resolve) => { + setTimeout(() => { + resolve(origVal); + }, COMMAND_DELAY); + }); + }); +} \ No newline at end of file diff --git a/.vib/ejbca/cypress/cypress/support/index.js b/.vib/ejbca/cypress/cypress/support/index.js new file mode 100644 index 0000000000..37a498fb5b --- /dev/null +++ b/.vib/ejbca/cypress/cypress/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands'; + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/.vib/ejbca/goss/goss.yaml b/.vib/ejbca/goss/goss.yaml new file mode 100644 index 0000000000..ef53f8bf48 --- /dev/null +++ b/.vib/ejbca/goss/goss.yaml @@ -0,0 +1,38 @@ +http: + https://ejbca:{{ .Vars.service.ports.https }}: + status: 200 + allow-insecure: true +file: + /bitnami/ejbca: + exists: true + filetype: directory + mode: "0775" + owner: root + /opt/bitnami/wildfly/standalone/configuration/standalone.xml: + exists: true + filetype: file + mode: "0644" + contains: + - /http.*{{ .Vars.containerPorts.http }}/ + - /https.*{{ .Vars.containerPorts.https }}/ + - /connection-url.*{{ .Vars.mariadb.auth.database }}/ + - /user-name.*{{ .Vars.mariadb.auth.username }}/ + - /password.*{{ .Vars.mariadb.auth.password }}/ +command: + {{- $baseDN := .Vars.ejbcaCA.baseDN }} + {{- $caName := .Vars.ejbcaCA.name }} + {{- $user := printf "user_%s" (randAlpha 5) }} + {{- $pass := printf "%s" (randAlpha 5) }} + {{- $dn := printf "%s,CN=%s" $baseDN $user }} + # Identity type 1 corresponds to END-USER + {{- $identityType := "1" }} + add-identity-export-cert: + exec: ejbca.sh ra addendentity --username '{{ $user }}' --caname '{{ $caName}}' --dn '{{ $dn }}' --type {{ $identityType }} --token P12 --password '{{ $pass }}' && ejbca.sh ra setclearpwd '{{ $user }}' '{{ $pass }}' && ejbca.sh batch && ls ./p12/{{ $user }}.p12 + exit-status: 0 + timeout: 20000 + check-user-info: + exec: id + exit-status: 0 + stdout: + - uid={{ .Vars.containerSecurityContext.runAsUser }} + - /groups=.*{{ .Vars.podSecurityContext.fsGroup }}/ diff --git a/.vib/ejbca/goss/vars.yaml b/.vib/ejbca/goss/vars.yaml new file mode 100644 index 0000000000..09a7d2767a --- /dev/null +++ b/.vib/ejbca/goss/vars.yaml @@ -0,0 +1,18 @@ +ejbcaCA: + name: ManagementTestCA + baseDN: "UID=c-1CCXmPAsNWmZuDtQQ8FHl7tcVdjCiNTH,O=ExampleCA,C=SE" +podSecurityContext: + fsGroup: 1002 +containerSecurityContext: + runAsUser: 1002 +containerPorts: + http: 8081 + https: 8443 +service: + ports: + https: 8444 +mariadb: + auth: + database: bitnami_ejbca_test + username: bn_ejbca_test + password: bn_ejbca_pass_test \ No newline at end of file diff --git a/.vib/ejbca/vib-publish.json b/.vib/ejbca/vib-publish.json index b79de6cdca..5bb4724ea3 100644 --- a/.vib/ejbca/vib-publish.json +++ b/.vib/ejbca/vib-publish.json @@ -22,11 +22,11 @@ "url": "{SHA_ARCHIVE}", "path": "/bitnami/ejbca" }, - "runtime_parameters": "ImVqYmNhQWRtaW5QYXNzd29yZCI6ICJCaXRuYW1pMTIzNCIKImVqYmNhQWRtaW5Vc2VybmFtZSI6ICJzdXBlcmFkbWluIgoic2VydmljZSI6CiAgInBvcnRzIjoKICAgICJodHRwIjogODAKICAidHlwZSI6ICJMb2FkQmFsYW5jZXIi", + "runtime_parameters": "ZWpiY2FBZG1pblVzZXJuYW1lOiBiaXRuYW1pVGVzdAplamJjYUFkbWluUGFzc3dvcmQ6ICJDb21wbGljYXRlZFBhc3N3b3JkMTIzITQiCmVqYmNhQ0E6CiAgbmFtZTogTWFuYWdlbWVudFRlc3RDQQogIGJhc2VETjogIlVJRD1jLTFDQ1htUEFzTldtWnVEdFFROEZIbDd0Y1ZkakNpTlRILE89RXhhbXBsZUNBLEM9U0UiCnBvZFNlY3VyaXR5Q29udGV4dDoKICBlbmFibGVkOiB0cnVlCiAgZnNHcm91cDogMTAwMgpjb250YWluZXJTZWN1cml0eUNvbnRleHQ6CiAgZW5hYmxlZDogdHJ1ZQogIHJ1bkFzVXNlcjogMTAwMgpjb250YWluZXJQb3J0czoKICBodHRwOiA4MDgxCiAgaHR0cHM6IDg0NDMKc2VydmljZToKICB0eXBlOiBMb2FkQmFsYW5jZXIKICBwb3J0czoKICAgIGh0dHA6IDgwCiAgICBodHRwczogODQ0NAogIGFkdmVydGlzZWRIdHRwc1BvcnQ6IDg0NDQKbWFyaWFkYjoKICBlbmFibGVkOiB0cnVlCiAgYXV0aDoKICAgIGRhdGFiYXNlOiBiaXRuYW1pX2VqYmNhX3Rlc3QKICAgIHVzZXJuYW1lOiBibl9lamJjYV90ZXN0CiAgICBwYXNzd29yZDogYm5fZWpiY2FfcGFzc190ZXN0", "target_platform": { "target_platform_id": "{VIB_ENV_TARGET_PLATFORM}", "size": { - "name": "S4" + "name": "M4" } } }, @@ -37,6 +37,28 @@ "endpoint": "lb-ejbca-http", "app_protocol": "HTTP" } + }, + { + "action_id": "goss", + "params": { + "resources": { + "path": "/.vib/ejbca/goss" + }, + "remote": { + "workload": "deploy-ejbca" + }, + "vars_file": "vars.yaml" + } + }, + { + "action_id": "cypress", + "params": { + "resources": { + "path": "/.vib/ejbca/cypress" + }, + "endpoint": "lb-ejbca-http", + "app_protocol": "HTTP" + } } ] }, diff --git a/.vib/ejbca/vib-verify.json b/.vib/ejbca/vib-verify.json index aa8b947d78..d2aa8cff89 100644 --- a/.vib/ejbca/vib-verify.json +++ b/.vib/ejbca/vib-verify.json @@ -22,11 +22,11 @@ "url": "{SHA_ARCHIVE}", "path": "/bitnami/ejbca" }, - "runtime_parameters": "ImVqYmNhQWRtaW5QYXNzd29yZCI6ICJCaXRuYW1pMTIzNCIKImVqYmNhQWRtaW5Vc2VybmFtZSI6ICJzdXBlcmFkbWluIgoic2VydmljZSI6CiAgInBvcnRzIjoKICAgICJodHRwIjogODAKICAidHlwZSI6ICJMb2FkQmFsYW5jZXIi", + "runtime_parameters": "ZWpiY2FBZG1pblVzZXJuYW1lOiBiaXRuYW1pVGVzdAplamJjYUFkbWluUGFzc3dvcmQ6ICJDb21wbGljYXRlZFBhc3N3b3JkMTIzITQiCmVqYmNhQ0E6CiAgbmFtZTogTWFuYWdlbWVudFRlc3RDQQogIGJhc2VETjogIlVJRD1jLTFDQ1htUEFzTldtWnVEdFFROEZIbDd0Y1ZkakNpTlRILE89RXhhbXBsZUNBLEM9U0UiCnBvZFNlY3VyaXR5Q29udGV4dDoKICBlbmFibGVkOiB0cnVlCiAgZnNHcm91cDogMTAwMgpjb250YWluZXJTZWN1cml0eUNvbnRleHQ6CiAgZW5hYmxlZDogdHJ1ZQogIHJ1bkFzVXNlcjogMTAwMgpjb250YWluZXJQb3J0czoKICBodHRwOiA4MDgxCiAgaHR0cHM6IDg0NDMKc2VydmljZToKICB0eXBlOiBMb2FkQmFsYW5jZXIKICBwb3J0czoKICAgIGh0dHA6IDgwCiAgICBodHRwczogODQ0NAogIGFkdmVydGlzZWRIdHRwc1BvcnQ6IDg0NDQKbWFyaWFkYjoKICBlbmFibGVkOiB0cnVlCiAgYXV0aDoKICAgIGRhdGFiYXNlOiBiaXRuYW1pX2VqYmNhX3Rlc3QKICAgIHVzZXJuYW1lOiBibl9lamJjYV90ZXN0CiAgICBwYXNzd29yZDogYm5fZWpiY2FfcGFzc190ZXN0", "target_platform": { "target_platform_id": "{VIB_ENV_TARGET_PLATFORM}", "size": { - "name": "S4" + "name": "M4" } } }, @@ -37,6 +37,28 @@ "endpoint": "lb-ejbca-http", "app_protocol": "HTTP" } + }, + { + "action_id": "goss", + "params": { + "resources": { + "path": "/.vib/ejbca/goss" + }, + "remote": { + "workload": "deploy-ejbca" + }, + "vars_file": "vars.yaml" + } + }, + { + "action_id": "cypress", + "params": { + "resources": { + "path": "/.vib/ejbca/cypress" + }, + "endpoint": "lb-ejbca-http", + "app_protocol": "HTTP" + } } ] }