mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 11:38:02 +00:00
* initial upgrade running ember-cli-update --to 3.28 * bumps node-sass version * fragments bump * fixes overriding errors prop on policy model causing issues * bumps some addon versions related to Ember Global deprecation warning on build * bumps back ember-test-selectors version for now * removes ember-promise-helpers addon and creates await helper * upgrades ember-template-lint and adds prettier plugin * Ember 3.28 Upgrade Lint Fixes (#14890) * fixes js lint errors * fixes hbs lint errors * allow multiple node versions for now to get tests runinng * fixes tests * Upgrade ember-test-selectors (#14937) * updates ember-test-selectors, ember-cli-page-object and ember-cli-string-helpers * adds attributeBindings to classic components with data-test property * glimmerizes toolbar-link component and removes data-test args * glimmerizes toolbar-secret-link and secret-link components and removes data-test and class args * glimmerizes linked-block component * glimmerizes toggle-button component * updates toggle-button test * fixes remaining test selector issues * comments out test assertions related to cp-validations bug * adds todo to comment * Model Validations (#14991) * adds model-validations decorator and validators util * converts key-mixin to decorator * updates models to use validations decorator instead of ember-cp-validations * updates invocation of model validations * removes ember-cp-validations * reverts secret-v2 model updates * adds initials to TODO comment * flight-icons (#14993) * flight-icons * basic dropdown * UI/merge main (#14997) * Vault documentation: changing references from learn to tutorial (#14844) * changed learn to tutorial references * changed learn to tutorial * Update website/content/docs/plugins/plugin-portal.mdx Co-authored-by: Yoko Hyakuna <yoko@hashicorp.com> * Update website/content/docs/platform/aws/run.mdx Co-authored-by: Yoko Hyakuna <yoko@hashicorp.com> Co-authored-by: Yoko Hyakuna <yoko@hashicorp.com> * UI/Only show form values if have read access (#14794) * only show value in edit form if has read capabilities * revert messing with form * delete secret data from secret * add check for selected version * remove added line * add changelog * modified text (#14854) * fixed a link issue (#14850) * docs: add known issue to 1.10 release notes (#14859) * Vault 3999 Change permissions for directory/archive created by debug command (#14846) * adding debug changes from ent * adding changelog * Vault 3992 ToB Config and Plugins Permissions (#14817) * updating changes from ent PR * adding changelog * fixing err * fixing semgrep error * updated references from learn to tutorial (#14866) * updated references from learn to tutorial (#14867) * changed reference from learn to tutorial (#14868) * Fix handling of default zero SignatureBits value with Any key type in PKI Secrets Engine (#14875) * Correctly handle minimums, default SignatureBits When using KeyType = "any" on a role (whether explicitly or implicitly via a sign-verbatim like operation), we need to update the value of SignatureBits from its new value 0 to a per-key-type default value. This will allow sign operations on these paths to function correctly, having the correctly inferred default signature bit length. Additionally, this allows the computed default value for key type to be used for minimum size validation in the RSA/ECDSA paths. We additionally enforce the 2048-minimum in this case as well. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix defaults and validation of "any" KeyType When certutil is given the placeholder any keytype, it attempts to validate and update the default zero value. However, in lacking a default value for SignatureBits, it cannot update the value from the zero value, thus causing validation to fail. Add more awareness to the placeholder "any" value to certutil. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add role-based regression tests for key bits This adds regression tests for Key Type, Key Bits, and Signature Bits parameters on the role. We test several values, including the "any" value to ensure it correctly restricts key sizes. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add sign-verbatim test for key type This ensures that we test sign-verbatim against a variety of key types. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog entry Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> Co-authored-by: Steven Clark <steven.clark@hashicorp.com> * Subtle docs change for allow_store_key (#14889) * Subtle docs change for allow_store_key * errant space * Adds Vault version prerelease and metadata to logical.PluginEnvironment (#14851) * docs: fix formatting on plugin upgrade page (#14874) * docs: fix formatting on plugin upgrade page * fix more formatting issues * Update CC docs (#14714) * Update CC docs * Add sample response * Address review feedback * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Meggie <meggie@hashicorp.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Update website/content/api-docs/system/internal-counters.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * Minor edits * Update partial month API Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> Co-authored-by: Meggie <meggie@hashicorp.com> * Docs improvements for Managed Keys (#14756) * Add more color around managed keys in their concepts page, and create additional links between the various docs pages related to them. * Typos * sdk/useragent: plugin version string consistent with Vault version string (#14912) * clean up (#14911) * website: fix usages of img tag (#14910) * fix usages of img tag and integrate dev-portal workflows * Adjust Makefile * remove mount_accessor from the docs (#14927) * Add extra test coverage to PKI (#14767) * Add PKI test for delete role - Create a role, validate that defaults are what we expect and delete the role, verifying it is gone on subsequent read attempts. * Add PKI test for crl/rotate command - Missing a unit test that validates the crl/rotate command works. The test validates the rotate command was successful by checking if we have a different/new update time on the CRL. * Rework PKI TestBackend_PathFetchValidRaw test to not write directly to storage - Rework the existing test to not write directly to storage as we might change that in the future. - Add tests that validate the ca_chain behaviour of not returning the root authority cert * PR Feedback * Additional PR feedback * Use WriteWithContext in auth helpers (#14775) * Add ability to pass certificate PEM bytes to vault/api (#14753) * Respect increment value in grace period calculations (api/LifetimeWatcher) (#14836) * Mount flag syntax to mitigate confusion from KV-v2 path discrepancies (#14807) * Add explanation to help text and flag usage text * KV get with new mount flag * Clearer naming * KV Put, Patch, Metadata Get + corresponding tests * KV Delete, Destroy, Rollback, Undelete, MetadataDelete, MetadataPatch, MetadataPut * Update KV-v2 docs to use mount flag syntax * Add changelog * Run make fmt * Clarify deprecation message in help string * Address style comments * Update vault-plugin-auth-gcp to newest pseudo-version (#14923) * docs: added hello-vault-spring repo link to developer-qs.mdx. (#14928) * Update developer-qs.mdx docs: added link to Java / Spring Boot sample app repo in developer quick start. * removed space. * trigger ci Co-authored-by: taoism4504 <loann@hashicorp.com> * OIDC Login Bug (#14916) * fixes issue logging in with oidc from listed auth path tab * adds changelog entry * adds more tests for oidc auth workflow * updates oidc auth method test to use non-standard path * Fix handling of SignatureBits for ECDSA issuers (#14943) When adding SignatureBits control logic, we incorrectly allowed specification of SignatureBits in the case of an ECDSA issuer. As noted in the original request, NIST and Mozilla (and others) are fairly prescriptive in the choice of signatures (matching the size of the NIST P-curve), and we shouldn't usually use a smaller (or worse, larger and truncate!) hash. Ignore the configuration of signature bits and always use autodetection for ECDSA like ed25519. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Bug Fix and Glimmerize secret-edit component (#14941) * inital glimmerize * wip * wip * wip * fix maybeQueryRecord * fix * fix * fix test * cleanup * add changelog * clean up * Agent error log level is mismatched (#14424) * [VAULT-1618] Agent error log level is mismatched `logLevelToStringPtr` translates `go-hclog`'s `ERROR` to `"ERROR"` for Consul Template's runner, but that expects `ERR` and is quite strict about it. This will address https://github.com/hashicorp/vault-k8s/issues/223 after it is set as the default image in `vault-k8s`. I didn't find a simple way to test this other than starting up a full server and agent and letting them run, which is unfortunately fairly slow. I confirmed that this addresses the original issue by modifying the helm chart with the values in this commit and patching the log level to `err`. * VAULT-1618 Add changelog/14424.txt * VAULT-1618 Update changelog/14424.txt based on @kalafut suggestion Co-authored-by: Jim Kalafut <jkalafut@hashicorp.com> * VAULT-1618 Move cancel and server stop into defer in tests * VAULT-1618 Triggering CircleCI tests * VAULT-1618 Replace ioutil with os functions for agent template tests Co-authored-by: Jim Kalafut <jkalafut@hashicorp.com> * UI/Add months to activity serializer (#14942) * add mock monthly data to mirage handler * add months to serializer for activity response * change selectors Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com> * clean up serializer * please stop being flakey <3 Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com> * Revert the WithContext changes to vault tests (#14947) * adding env var (#14958) * Fix dead link for JWT supported algorithms (#14953) * Don't clone OutputCurlString value (#14968) * Don't clone OutputCurlString value, add flag to docs * Add changelog * Ensure initialMmapSize is 0 on Windows (#14977) * ensure initialMmapSize is 0 on windows * add changelog * Vault 3992 documentation changes (#14918) * doc changes * adding config changes * adding chnages to plugins * using include * making doc changes * adding newline * aws auth displayName (#14954) * set displayName to include RoleSessionName * Add Windows error (#14982) * Warnings indicating ignored and replaced parameters (#14962) * Warnings indicating ignored and replaced parameters * Avoid additional var creation * Add warnings only if the response is non-nil * Return the response even when error is non-nil * Fix tests * Rearrange comments * Print warning in the log * Fix another test * Add CL * Fix edit capabilities call in auth method (#14966) * Fix edit capabilities call in auth method - Capabilities call was not getting triggered correctly as apiPath method was missing the correct context. * Added changelog * make linting fix Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> Co-authored-by: Yoko Hyakuna <yoko@hashicorp.com> Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> Co-authored-by: Austin Gebauer <34121980+austingebauer@users.noreply.github.com> Co-authored-by: akshya96 <87045294+akshya96@users.noreply.github.com> Co-authored-by: Alexander Scheel <alex.scheel@hashicorp.com> Co-authored-by: Steven Clark <steven.clark@hashicorp.com> Co-authored-by: Scott Miller <smiller@hashicorp.com> Co-authored-by: John-Michael Faircloth <fairclothjm@users.noreply.github.com> Co-authored-by: Vishal Nayak <vishalnayak@users.noreply.github.com> Co-authored-by: Meggie <meggie@hashicorp.com> Co-authored-by: Bryce Kalow <bkalow@hashicorp.com> Co-authored-by: Josh Black <raskchanky@users.noreply.github.com> Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> Co-authored-by: VAL <val@hashicorp.com> Co-authored-by: Robert <17119716+robmonte@users.noreply.github.com> Co-authored-by: mryan-hashi <88851444+mryan-hashi@users.noreply.github.com> Co-authored-by: taoism4504 <loann@hashicorp.com> Co-authored-by: Jordan Reimer <zofskeez@gmail.com> Co-authored-by: Christopher Swenson <swenson@swenson.io> Co-authored-by: Jim Kalafut <jkalafut@hashicorp.com> Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com> Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com> Co-authored-by: Jose Estrada <jose.estrada@tradeshift.com> Co-authored-by: Arnav Palnitkar <arnav@hashicorp.com> * skips kmip tests with concurrency issues for now * changelog * skips another test * Remove ModelWrap Component (#15001) * removes ModelWrap component which was not working in Ember 3.28 * removes kmip test skips * updates role controller class name * adds annotations to model-validations file * pr feedback * lint fixes after main merge Co-authored-by: Jordan Reimer <zofskeez@gmail.com> Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> Co-authored-by: Yoko Hyakuna <yoko@hashicorp.com> Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> Co-authored-by: Austin Gebauer <34121980+austingebauer@users.noreply.github.com> Co-authored-by: akshya96 <87045294+akshya96@users.noreply.github.com> Co-authored-by: Alexander Scheel <alex.scheel@hashicorp.com> Co-authored-by: Steven Clark <steven.clark@hashicorp.com> Co-authored-by: Scott Miller <smiller@hashicorp.com> Co-authored-by: John-Michael Faircloth <fairclothjm@users.noreply.github.com> Co-authored-by: Vishal Nayak <vishalnayak@users.noreply.github.com> Co-authored-by: Meggie <meggie@hashicorp.com> Co-authored-by: Bryce Kalow <bkalow@hashicorp.com> Co-authored-by: Josh Black <raskchanky@users.noreply.github.com> Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> Co-authored-by: VAL <val@hashicorp.com> Co-authored-by: Robert <17119716+robmonte@users.noreply.github.com> Co-authored-by: mryan-hashi <88851444+mryan-hashi@users.noreply.github.com> Co-authored-by: taoism4504 <loann@hashicorp.com> Co-authored-by: Christopher Swenson <swenson@swenson.io> Co-authored-by: Jim Kalafut <jkalafut@hashicorp.com> Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com> Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com> Co-authored-by: Jose Estrada <jose.estrada@tradeshift.com> Co-authored-by: Arnav Palnitkar <arnav@hashicorp.com>
538 lines
24 KiB
JavaScript
538 lines
24 KiB
JavaScript
import { module, test } from 'qunit';
|
||
import { setupApplicationTest } from 'ember-qunit';
|
||
import { currentURL, settled, click, visit, fillIn, typeIn } from '@ember/test-helpers';
|
||
import { create } from 'ember-cli-page-object';
|
||
import { selectChoose, clickTrigger } from 'ember-power-select/test-support/helpers';
|
||
|
||
import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend';
|
||
import connectionPage from 'vault/tests/pages/secrets/backend/database/connection';
|
||
import rolePage from 'vault/tests/pages/secrets/backend/database/role';
|
||
import apiStub from 'vault/tests/helpers/noop-all-api-requests';
|
||
import authPage from 'vault/tests/pages/auth';
|
||
import logout from 'vault/tests/pages/logout';
|
||
import consoleClass from 'vault/tests/pages/components/console/ui-panel';
|
||
import searchSelect from 'vault/tests/pages/components/search-select';
|
||
|
||
const searchSelectComponent = create(searchSelect);
|
||
|
||
const consoleComponent = create(consoleClass);
|
||
|
||
const MODEL = {
|
||
engineType: 'database',
|
||
id: 'database-name',
|
||
};
|
||
|
||
const mount = async () => {
|
||
let path = `database-${Date.now()}`;
|
||
await mountSecrets.enable('database', path);
|
||
await settled();
|
||
return path;
|
||
};
|
||
|
||
const newConnection = async (backend, plugin = 'mongodb-database-plugin') => {
|
||
const name = `connection-${Date.now()}`;
|
||
await connectionPage.visitCreate({ backend });
|
||
await connectionPage.dbPlugin(plugin);
|
||
await connectionPage.name(name);
|
||
await connectionPage.connectionUrl(`mongodb://127.0.0.1:4321/${name}`);
|
||
await connectionPage.toggleVerify();
|
||
await connectionPage.save();
|
||
await connectionPage.enable();
|
||
return name;
|
||
};
|
||
|
||
const connectionTests = [
|
||
{
|
||
name: 'elasticsearch-connection',
|
||
plugin: 'elasticsearch-database-plugin',
|
||
elasticUser: 'username',
|
||
elasticPassword: 'password',
|
||
url: 'http://127.0.0.1:9200',
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert.dom('[data-test-input="ca_cert"]').exists(`CA certificate field exists for ${name}`);
|
||
assert.dom('[data-test-input="ca_path"]').exists(`CA path field exists for ${name}`);
|
||
assert.dom('[data-test-input="client_cert"]').exists(`Client certificate field exists for ${name}`);
|
||
assert.dom('[data-test-input="client_key"]').exists(`Client key field exists for ${name}`);
|
||
assert.dom('[data-test-input="tls_server_name"]').exists(`TLS server name field exists for ${name}`);
|
||
assert.dom('[data-test-input="insecure"]').exists(`Insecure checkbox exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-toggle-input="show-username_template"]')
|
||
.exists(`Username template toggle exists for ${name}`);
|
||
},
|
||
},
|
||
{
|
||
name: 'mongodb-connection',
|
||
plugin: 'mongodb-database-plugin',
|
||
url: `mongodb://127.0.0.1:4321/test`,
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert.dom('[data-test-input="write_concern"]').exists(`Write concern field exists for ${name}`);
|
||
assert.dom('[data-test-toggle-group="TLS options"]').exists('TLS options toggle exists');
|
||
assert
|
||
.dom('[data-test-input="root_rotation_statements"]')
|
||
.exists(`Root rotation statements exists for ${name}`);
|
||
},
|
||
},
|
||
{
|
||
name: 'mssql-connection',
|
||
plugin: 'mssql-database-plugin',
|
||
url: `mssql://127.0.0.1:4321/test`,
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_open_connections"]')
|
||
.exists(`Max open connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_idle_connections"]')
|
||
.exists(`Max idle connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_connection_lifetime"]')
|
||
.exists(`Max connection lifetime exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="root_rotation_statements"]')
|
||
.exists(`Root rotation statements exists for ${name}`);
|
||
},
|
||
},
|
||
{
|
||
name: 'mysql-connection',
|
||
plugin: 'mysql-database-plugin',
|
||
url: `{{username}}:{{password}}@tcp(127.0.0.1:3306)/test`,
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_open_connections"]')
|
||
.exists(`Max open connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_idle_connections"]')
|
||
.exists(`Max idle connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_connection_lifetime"]')
|
||
.exists(`Max connection lifetime exists for ${name}`);
|
||
assert.dom('[data-test-toggle-group="TLS options"]').exists('TLS options toggle exists');
|
||
assert
|
||
.dom('[data-test-input="root_rotation_statements"]')
|
||
.exists(`Root rotation statements exists for ${name}`);
|
||
},
|
||
},
|
||
{
|
||
name: 'mysql-aurora-connection',
|
||
plugin: 'mysql-aurora-database-plugin',
|
||
url: `{{username}}:{{password}}@tcp(127.0.0.1:3306)/test`,
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_open_connections"]')
|
||
.exists(`Max open connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_idle_connections"]')
|
||
.exists(`Max idle connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_connection_lifetime"]')
|
||
.exists(`Max connection lifetime exists for ${name}`);
|
||
assert.dom('[data-test-toggle-group="TLS options"]').exists('TLS options toggle exists');
|
||
assert
|
||
.dom('[data-test-input="root_rotation_statements"]')
|
||
.exists(`Root rotation statements exists for ${name}`);
|
||
},
|
||
},
|
||
{
|
||
name: 'mysql-rds-connection',
|
||
plugin: 'mysql-rds-database-plugin',
|
||
url: `{{username}}:{{password}}@tcp(127.0.0.1:3306)/test`,
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_open_connections"]')
|
||
.exists(`Max open connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_idle_connections"]')
|
||
.exists(`Max idle connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_connection_lifetime"]')
|
||
.exists(`Max connection lifetime exists for ${name}`);
|
||
assert.dom('[data-test-toggle-group="TLS options"]').exists('TLS options toggle exists');
|
||
assert
|
||
.dom('[data-test-input="root_rotation_statements"]')
|
||
.exists(`Root rotation statements exists for ${name}`);
|
||
},
|
||
},
|
||
{
|
||
name: 'mysql-legacy-connection',
|
||
plugin: 'mysql-legacy-database-plugin',
|
||
url: `{{username}}:{{password}}@tcp(127.0.0.1:3306)/test`,
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_open_connections"]')
|
||
.exists(`Max open connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_idle_connections"]')
|
||
.exists(`Max idle connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_connection_lifetime"]')
|
||
.exists(`Max connection lifetime exists for ${name}`);
|
||
assert.dom('[data-test-toggle-group="TLS options"]').exists('TLS options toggle exists');
|
||
assert
|
||
.dom('[data-test-input="root_rotation_statements"]')
|
||
.exists(`Root rotation statements exists for ${name}`);
|
||
},
|
||
},
|
||
{
|
||
name: 'postgresql-connection',
|
||
plugin: 'postgresql-database-plugin',
|
||
url: `postgresql://{{username}}:{{password}}@localhost:5432/postgres?sslmode=disable`,
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_open_connections"]')
|
||
.exists(`Max open connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_idle_connections"]')
|
||
.exists(`Max idle connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_connection_lifetime"]')
|
||
.exists(`Max connection lifetime exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="root_rotation_statements"]')
|
||
.exists(`Root rotation statements exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-toggle-input="show-username_template"]')
|
||
.exists(`Username template toggle exists for ${name}`);
|
||
},
|
||
},
|
||
// keep oracle as last DB because it is skipped in some tests (line 285) the UI doesn't return to empty state after
|
||
{
|
||
name: 'oracle-connection',
|
||
plugin: 'vault-plugin-database-oracle',
|
||
url: `{{username}}/{{password}}@localhost:1521/OraDoc.localhost`,
|
||
requiredFields: async (assert, name) => {
|
||
assert.dom('[data-test-input="username"]').exists(`Username field exists for ${name}`);
|
||
assert.dom('[data-test-input="password"]').exists(`Password field exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_open_connections"]')
|
||
.exists(`Max open connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_idle_connections"]')
|
||
.exists(`Max idle connections exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="max_connection_lifetime"]')
|
||
.exists(`Max connection lifetime exists for ${name}`);
|
||
assert
|
||
.dom('[data-test-input="root_rotation_statements"]')
|
||
.exists(`Root rotation statements exists for ${name}`);
|
||
},
|
||
},
|
||
];
|
||
|
||
module('Acceptance | secrets/database/*', function (hooks) {
|
||
setupApplicationTest(hooks);
|
||
|
||
hooks.beforeEach(async function () {
|
||
this.server = apiStub({ usePassthrough: true });
|
||
return authPage.login();
|
||
});
|
||
hooks.afterEach(function () {
|
||
this.server.shutdown();
|
||
});
|
||
|
||
test('can enable the database secrets engine', async function (assert) {
|
||
let backend = `database-${Date.now()}`;
|
||
await mountSecrets.enable('database', backend);
|
||
await settled();
|
||
assert.equal(
|
||
currentURL(),
|
||
`/vault/secrets/${backend}/list`,
|
||
'Mounts and redirects to connection list page'
|
||
);
|
||
assert.dom('[data-test-component="empty-state"]').exists('Empty state exists');
|
||
assert
|
||
.dom('.active[data-test-secret-list-tab="Connections"]')
|
||
.exists('Has Connections tab which is active');
|
||
await click('[data-test-tab="overview"]');
|
||
assert.equal(currentURL(), `/vault/secrets/${backend}/overview`, 'Tab links to overview page');
|
||
assert.dom('[data-test-component="empty-state"]').exists('Empty state also exists on overview page');
|
||
assert.dom('[data-test-secret-list-tab="Roles"]').exists('Has Roles tab');
|
||
});
|
||
|
||
test('Connection create and edit form for each plugin', async function (assert) {
|
||
assert.expect(160);
|
||
const backend = await mount();
|
||
for (let testCase of connectionTests) {
|
||
await connectionPage.visitCreate({ backend });
|
||
assert.equal(currentURL(), `/vault/secrets/${backend}/create`, 'Correct creation URL');
|
||
assert
|
||
.dom('[data-test-empty-state-title]')
|
||
.hasText('No plugin selected', 'No plugin is selected by default and empty state shows');
|
||
await connectionPage.dbPlugin(testCase.plugin);
|
||
assert.dom('[data-test-empty-state]').doesNotExist('Empty state goes away after plugin selected');
|
||
await connectionPage.name(testCase.name);
|
||
if (testCase.plugin === 'elasticsearch-database-plugin') {
|
||
await connectionPage.url(testCase.url);
|
||
await connectionPage.username(testCase.elasticUser);
|
||
await connectionPage.password(testCase.elasticPassword);
|
||
} else {
|
||
await connectionPage.connectionUrl(testCase.url);
|
||
}
|
||
// skip adding oracle db connection since plugin doesn't exist
|
||
if (testCase.plugin === 'vault-plugin-database-oracle') {
|
||
testCase.requiredFields(assert, testCase.name);
|
||
continue;
|
||
}
|
||
testCase.requiredFields(assert, testCase.name);
|
||
await connectionPage.toggleVerify();
|
||
await connectionPage.save();
|
||
await settled();
|
||
assert
|
||
.dom('.modal.is-active .title')
|
||
.hasText('Rotate your root credentials?', 'Modal appears asking to rotate root credentials');
|
||
await connectionPage.enable();
|
||
assert.ok(
|
||
currentURL().startsWith(`/vault/secrets/${backend}/show/${testCase.name}`),
|
||
`Saves connection and takes you to show page for ${testCase.name}`
|
||
);
|
||
assert
|
||
.dom(`[data-test-row-value="Password"]`)
|
||
.doesNotExist(`Does not show Password value on show page for ${testCase.name}`);
|
||
await connectionPage.edit();
|
||
assert.ok(
|
||
currentURL().startsWith(`/vault/secrets/${backend}/edit/${testCase.name}`),
|
||
`Edit connection button and takes you to edit page for ${testCase.name}`
|
||
);
|
||
assert.dom(`[data-test-input="name"]`).hasAttribute('readonly');
|
||
assert.dom(`[data-test-input="plugin_name"]`).hasAttribute('readonly');
|
||
assert.dom('[data-test-input="password"]').doesNotExist('Password is not displayed on edit form');
|
||
assert.dom('[data-test-toggle-input="show-password"]').exists('Update password toggle exists');
|
||
await connectionPage.toggleVerify();
|
||
await connectionPage.save();
|
||
// click "Add Role"
|
||
await connectionPage.addRole();
|
||
await settled();
|
||
assert.equal(
|
||
searchSelectComponent.selectedOptions[0].text,
|
||
testCase.name,
|
||
'Database connection is pre-selected on the form'
|
||
);
|
||
await click('[data-test-secret-breadcrumb]');
|
||
}
|
||
});
|
||
|
||
test('Can create and delete a connection', async function (assert) {
|
||
const backend = await mount();
|
||
const connectionDetails = {
|
||
plugin: 'mongodb-database-plugin',
|
||
id: 'horses-db',
|
||
fields: [
|
||
{ label: 'Connection name', name: 'name', value: 'horses-db' },
|
||
{ label: 'Connection URL', name: 'connection_url', value: 'mongodb://127.0.0.1:235/horses' },
|
||
{ label: 'Username', name: 'username', value: 'user', hideOnShow: true },
|
||
{ label: 'Password', name: 'password', password: 'so-secure', hideOnShow: true },
|
||
{ label: 'Write concern', name: 'write_concern' },
|
||
],
|
||
};
|
||
assert.equal(
|
||
currentURL(),
|
||
`/vault/secrets/${backend}/list`,
|
||
'Mounts and redirects to connection list page'
|
||
);
|
||
await connectionPage.createLink();
|
||
assert.equal(currentURL(), `/vault/secrets/${backend}/create`, 'Create link goes to create page');
|
||
assert
|
||
.dom('[data-test-empty-state-title]')
|
||
.hasText('No plugin selected', 'No plugin is selected by default and empty state shows');
|
||
await connectionPage.dbPlugin(connectionDetails.plugin);
|
||
assert.dom('[data-test-empty-state]').doesNotExist('Empty state goes away after plugin selected');
|
||
connectionDetails.fields.forEach(async ({ name, value }) => {
|
||
assert
|
||
.dom(`[data-test-input="${name}"]`)
|
||
.exists(`Field ${name} exists for ${connectionDetails.plugin}`);
|
||
if (value) {
|
||
await fillIn(`[data-test-input="${name}"]`, value);
|
||
}
|
||
});
|
||
// uncheck verify for the save step to work
|
||
await connectionPage.toggleVerify();
|
||
await connectionPage.save();
|
||
await settled();
|
||
assert
|
||
.dom('.modal.is-active .title')
|
||
.hasText('Rotate your root credentials?', 'Modal appears asking to ');
|
||
await connectionPage.enable();
|
||
assert.equal(
|
||
currentURL(),
|
||
`/vault/secrets/${backend}/show/${connectionDetails.id}`,
|
||
'Saves connection and takes you to show page'
|
||
);
|
||
connectionDetails.fields.forEach(({ label, name, value, hideOnShow }) => {
|
||
if (hideOnShow) {
|
||
assert
|
||
.dom(`[data-test-row-value="${label}"]`)
|
||
.doesNotExist(`Does not show ${name} value on show page for ${connectionDetails.plugin}`);
|
||
} else if (!value) {
|
||
assert.dom(`[data-test-row-value="${label}"]`).hasText('Default');
|
||
} else {
|
||
assert.dom(`[data-test-row-value="${label}"]`).hasText(value);
|
||
}
|
||
});
|
||
await connectionPage.delete();
|
||
assert
|
||
.dom('.modal.is-active .title')
|
||
.hasText('Delete connection?', 'Modal appears asking to confirm delete action');
|
||
await fillIn('[data-test-confirmation-modal-input="delete"]', connectionDetails.id);
|
||
await click('[data-test-confirm-button]');
|
||
|
||
assert.equal(currentURL(), `/vault/secrets/${backend}/list`, 'Redirects to connection list page');
|
||
assert
|
||
.dom('[data-test-empty-state-title]')
|
||
.hasText('No connections in this backend', 'No connections listed because it was deleted');
|
||
});
|
||
|
||
test('buttons show up for managing connection', async function (assert) {
|
||
const backend = await mount();
|
||
const connection = await newConnection(backend);
|
||
await connectionPage.visitShow({ backend, id: connection });
|
||
assert
|
||
.dom('[data-test-database-connection-delete]')
|
||
.hasText('Delete connection', 'Delete connection button exists with correct text');
|
||
assert
|
||
.dom('[data-test-database-connection-reset]')
|
||
.hasText('Reset connection', 'Reset button exists with correct text');
|
||
assert.dom('[data-test-secret-create]').hasText('Add role', 'Add role button exists with correct text');
|
||
assert.dom('[data-test-edit-link]').hasText('Edit configuration', 'Edit button exists with correct text');
|
||
const CONNECTION_VIEW_ONLY = `
|
||
path "${backend}/*" {
|
||
capabilities = ["deny"]
|
||
}
|
||
path "${backend}/config" {
|
||
capabilities = ["list"]
|
||
}
|
||
path "${backend}/config/*" {
|
||
capabilities = ["read"]
|
||
}
|
||
`;
|
||
await consoleComponent.runCommands([
|
||
`write sys/mounts/${backend} type=database`,
|
||
`write sys/policies/acl/test-policy policy=${btoa(CONNECTION_VIEW_ONLY)}`,
|
||
'write -field=client_token auth/token/create policies=test-policy ttl=1h',
|
||
]);
|
||
let token = consoleComponent.lastTextOutput;
|
||
await logout.visit();
|
||
await authPage.login(token);
|
||
await connectionPage.visitShow({ backend, id: connection });
|
||
assert.equal(currentURL(), `/vault/secrets/${backend}/show/${connection}`, 'Allows reading connection');
|
||
assert
|
||
.dom('[data-test-database-connection-delete]')
|
||
.doesNotExist('Delete button does not show due to permissions');
|
||
assert
|
||
.dom('[data-test-database-connection-reset]')
|
||
.doesNotExist('Reset button does not show due to permissions');
|
||
assert.dom('[data-test-secret-create]').doesNotExist('Add role button does not show due to permissions');
|
||
assert.dom('[data-test-edit-link]').doesNotExist('Edit button does not show due to permissions');
|
||
await visit(`/vault/secrets/${backend}/overview`);
|
||
assert.dom('[data-test-selectable-card="Connections"]').exists('Connections card exists on overview');
|
||
assert
|
||
.dom('[data-test-selectable-card="Roles"]')
|
||
.doesNotExist('Roles card does not exist on overview w/ policy');
|
||
assert.dom('.title-number').hasText('1', 'Lists the correct number of connections');
|
||
// confirm get credentials card is an option to select. Regression bug.
|
||
await typeIn('.ember-text-field', 'blah');
|
||
assert.dom('[data-test-get-credentials]').isEnabled();
|
||
});
|
||
|
||
test('Role create form', async function (assert) {
|
||
const backend = await mount();
|
||
// Connection needed for role fields
|
||
await newConnection(backend);
|
||
await rolePage.visitCreate({ backend });
|
||
await rolePage.name('bar');
|
||
assert
|
||
.dom('[data-test-component="empty-state"]')
|
||
.exists({ count: 2 }, 'Two empty states exist before selections made');
|
||
await clickTrigger('#database');
|
||
assert.equal(searchSelectComponent.options.length, 1, 'list shows existing connections so far');
|
||
await selectChoose('#database', '.ember-power-select-option', 0);
|
||
assert
|
||
.dom('[data-test-component="empty-state"]')
|
||
.exists({ count: 2 }, 'Two empty states exist before selections made');
|
||
await rolePage.roleType('static');
|
||
assert.dom('[data-test-component="empty-state"]').doesNotExist('Empty states go away');
|
||
assert.dom('[data-test-input="username"]').exists('Username field appears for static role');
|
||
assert
|
||
.dom('[data-test-toggle-input="Rotation period"]')
|
||
.exists('Rotation period field appears for static role');
|
||
await rolePage.roleType('dynamic');
|
||
assert
|
||
.dom('[data-test-toggle-input="Generated credentials’s Time-to-Live (TTL)"]')
|
||
.exists('TTL field exists for dynamic');
|
||
assert
|
||
.dom('[data-test-toggle-input="Generated credentials’s maximum Time-to-Live (Max TTL)"]')
|
||
.exists('Max TTL field exists for dynamic');
|
||
// Real connection (actual running db) required to save role, so we aren't testing that flow yet
|
||
});
|
||
|
||
test('root and limited access', async function (assert) {
|
||
this.set('model', MODEL);
|
||
let backend = 'database';
|
||
const NO_ROLES_POLICY = `
|
||
path "database/roles/*" {
|
||
capabilities = ["delete"]
|
||
}
|
||
path "database/static-roles/*" {
|
||
capabilities = ["delete"]
|
||
}
|
||
path "database/config/*" {
|
||
capabilities = ["list", "create", "read", "update"]
|
||
}
|
||
path "database/creds/*" {
|
||
capabilities = ["list", "create", "read", "update"]
|
||
}
|
||
`;
|
||
await consoleComponent.runCommands([
|
||
`write sys/mounts/${backend} type=database`,
|
||
`write sys/policies/acl/test-policy policy=${btoa(NO_ROLES_POLICY)}`,
|
||
'write -field=client_token auth/token/create policies=test-policy ttl=1h',
|
||
]);
|
||
let token = consoleComponent.lastTextOutput;
|
||
|
||
// test root user flow
|
||
await settled();
|
||
|
||
// await click('[data-test-secret-backend-row="database"]');
|
||
// skipping the click because occasionally is shows up on the second page and cannot be found
|
||
await visit(`/vault/secrets/database/overview`);
|
||
|
||
assert.dom('[data-test-component="empty-state"]').exists('renders empty state');
|
||
assert.dom('[data-test-secret-list-tab="Connections"]').exists('renders connections tab');
|
||
assert.dom('[data-test-secret-list-tab="Roles"]').exists('renders connections tab');
|
||
|
||
await click('[data-test-secret-create="connections"]');
|
||
assert.equal(currentURL(), '/vault/secrets/database/create');
|
||
|
||
// Login with restricted policy
|
||
await logout.visit();
|
||
await authPage.login(token);
|
||
await settled();
|
||
// skipping the click because occasionally is shows up on the second page and cannot be found
|
||
await visit(`/vault/secrets/database/overview`);
|
||
assert.dom('[data-test-tab="overview"]').exists('renders overview tab');
|
||
assert.dom('[data-test-secret-list-tab="Connections"]').exists('renders connections tab');
|
||
assert
|
||
.dom('[data-test-secret-list-tab="Roles"]')
|
||
.doesNotExist(`does not show the roles tab because it does not have permissions`);
|
||
assert
|
||
.dom('[data-test-selectable-card="Connections"]')
|
||
.exists({ count: 1 }, 'renders only the connection card');
|
||
|
||
await click('[data-test-action-text="Configure new"]');
|
||
assert.equal(currentURL(), '/vault/secrets/database/create?itemType=connection');
|
||
});
|
||
});
|