From aec52d4a3029542cb764a79b9654e85e3c26bdd8 Mon Sep 17 00:00:00 2001 From: Chris Capurso <1036769+ccapurso@users.noreply.github.com> Date: Tue, 15 Mar 2022 16:06:58 +0000 Subject: [PATCH] backport of commit 38f51cc51b6616995c4be8d0925def3a02a47749 --- .circleci/config.yml | 2 +- .../exit-if-branch-does-not-need-test-ui.yml | 2 +- .github/workflows/build.yml | 6 +- .github/workflows/changelog-checker.yml | 11 +- .gitignore | 3 +- .release/ci.hcl | 8 +- .release/release-metadata.hcl | 6 + CHANGELOG.md | 185 ++--------- CODEOWNERS | 6 +- Dockerfile | 8 +- Makefile | 24 +- api/client.go | 154 +-------- api/renewer_test.go | 11 +- api/sys_raft.go | 106 ++++-- builtin/credential/ldap/backend_test.go | 1 + builtin/credential/ldap/path_login.go | 4 + builtin/logical/database/backend_test.go | 27 -- builtin/logical/database/mockv5.go | 7 - .../logical/database/versioning_large_test.go | 9 - builtin/logical/pki/ca_util.go | 9 +- builtin/logical/pki/fields.go | 20 +- builtin/logical/pki/path_fetch.go | 4 +- builtin/logical/pki/path_roles.go | 9 +- builtin/logical/transit/path_encrypt.go | 11 +- builtin/logical/transit/path_encrypt_test.go | 6 +- builtin/logical/transit/path_hash.go | 11 +- builtin/logical/transit/path_hash_test.go | 2 +- builtin/logical/transit/path_trim.go | 10 +- changelog/14074.txt | 2 +- changelog/14217.txt | 3 - changelog/14269.txt | 3 - changelog/14292.txt | 3 - changelog/14324.txt | 3 + changelog/14389.txt | 3 - changelog/14489.txt | 3 + changelog/14493.txt | 3 + changelog/14543.txt | 3 + changelog/14545.txt | 3 + changelog/14551.txt | 3 + changelog/14622.txt | 3 + changelog/14670.txt | 3 + changelog/14704.txt | 3 + changelog/mount-migration.txt | 3 + command/auth_enable.go | 16 +- command/auth_tune.go | 16 +- command/debug.go | 2 +- command/debug_test.go | 2 +- command/policy_write.go | 11 +- command/secrets_enable.go | 16 +- command/secrets_tune.go | 16 +- go.mod | 8 +- go.sum | 18 +- helper/constants/fips.go | 2 +- helper/constants/fips_build_check.go | 38 +++ helper/constants/fips_cgo_check.go | 18 ++ http/help.go | 6 + http/help_test.go | 6 +- .../dbplugin/v5/plugin_client_test.go | 146 --------- .../dbplugin/v5/testing/test_helpers.go | 6 +- sdk/framework/backend.go | 15 +- sdk/framework/openapi.go | 51 +-- sdk/framework/openapi_test.go | 10 +- sdk/framework/path.go | 10 +- sdk/framework/testdata/legacy.json | 21 +- sdk/framework/testdata/operations.json | 73 ++--- sdk/framework/testdata/operations_list.json | 4 - sdk/framework/testdata/responses.json | 4 - sdk/helper/ldaputil/config.go | 12 + sdk/helper/ldaputil/config_test.go | 1 + sdk/plugin/grpc_storage.go | 6 + sdk/version/version_base.go | 4 +- ui/app/adapters/secret-engine.js | 11 +- ui/app/adapters/secret-v2-version.js | 1 + ui/app/components/auth-form.js | 38 ++- ui/app/components/auth-jwt.js | 1 - .../clients/horizontal-bar-chart.js | 42 ++- ui/app/components/mount-backend-form.js | 45 ++- .../cluster/secrets/backend/secret-edit.js | 15 +- ui/app/services/auth.js | 11 +- ui/app/styles/components/tabs.scss | 11 - ui/app/templates/components/auth-form.hbs | 1 - .../components/configure-aws-secret.hbs | 25 +- .../components/configure-pki-secret.hbs | 29 +- .../components/identity/entity-nav.hbs | 14 +- .../components/identity/item-metadata.hbs | 4 +- .../components/mount-backend-form.hbs | 2 +- .../components/secret-create-or-update.hbs | 4 +- .../components/secret-edit-toolbar.hbs | 9 +- ui/app/templates/components/secret-edit.hbs | 12 +- .../components/secret-list-header-tab.hbs | 6 +- .../components/secret-list-header.hbs | 41 ++- .../components/transformation-edit.hbs | 3 + .../cluster/access/identity/aliases/index.hbs | 9 +- .../cluster/access/identity/aliases/show.hbs | 8 +- .../vault/cluster/access/identity/index.hbs | 9 +- .../vault/cluster/access/identity/show.hbs | 10 +- .../cluster/secrets/backend/edit-metadata.hbs | 4 +- .../cluster/secrets/backend/metadata.hbs | 14 +- .../vault/cluster/secrets/backend/roles.hbs | 143 ++++++++ ui/app/templates/vault/cluster/tools/tool.hbs | 3 + ui/lib/core/addon/components/toggle.js | 53 ++- .../components/replication-header.hbs | 29 +- .../{ => templates}/components/toggle.hbs | 4 +- .../components/header-credentials.hbs | 14 +- .../templates/components/header-scope.hbs | 14 +- ui/mirage/handlers/clients.js | 8 +- ui/package.json | 1 - ui/scripts/enos-test-ember.js | 60 ---- ui/scripts/start-vault.js | 40 ++- ui/scripts/test-helper.js | 54 ---- ui/testem.enos.js | 40 --- .../access/identity/_shared-alias-tests.js | 3 +- ui/tests/acceptance/auth-list-test.js | 13 +- ui/tests/acceptance/client-current-test.js | 57 +++- ui/tests/acceptance/client-history-test.js | 55 +++- .../acceptance/logout-auth-method-test.js | 43 +++ .../secrets/backend/kv/secret-test.js | 26 +- .../settings/mount-secret-backend-test.js | 2 +- ui/tests/acceptance/unseal-test.js | 15 +- ui/tests/helpers/clients.js | 11 +- ui/tests/helpers/oidc-window-stub.js | 33 ++ .../integration/components/auth-jwt-test.js | 66 +--- ui/tests/pages/auth.js | 5 +- .../pages/components/identity/edit-form.js | 7 + vault/activity_log.go | 12 +- vault/custom_response_headers_test.go | 7 - .../identity/login_mfa_duo_test.go | 11 +- vault/external_tests/raft/raft_test.go | 33 +- vault/identity_store.go | 16 +- vault/identity_store_oidc.go | 31 +- vault/identity_store_oidc_test.go | 48 +++ vault/logical_system.go | 29 +- vault/logical_system_test.go | 35 +- vault/login_mfa.go | 11 +- vault/plugin_catalog_test.go | 98 ------ vault/seal_autoseal_test.go | 2 + vault/ui.go | 41 +-- website/content/api-docs/auth/ldap.mdx | 4 + website/content/api-docs/index.mdx | 2 +- .../api-docs/secret/identity/index.mdx | 2 - .../api-docs/secret/identity/mfa/duo.mdx | 157 --------- .../api-docs/secret/identity/mfa/index.mdx | 27 -- .../secret/identity/mfa/login-enforcement.mdx | 153 --------- .../api-docs/secret/identity/mfa/okta.mdx | 152 --------- .../api-docs/secret/identity/mfa/pingid.mdx | 147 --------- .../api-docs/secret/identity/mfa/totp.mdx | 283 ---------------- .../secret/identity/oidc-provider.mdx | 76 ++++- website/content/api-docs/secret/pki.mdx | 54 ++-- website/content/api-docs/secret/totp.mdx | 2 +- .../system/generate-recovery-token.mdx | 8 +- .../content/api-docs/system/generate-root.mdx | 6 +- website/content/api-docs/system/init.mdx | 6 +- website/content/api-docs/system/license.mdx | 4 +- .../content/api-docs/system/managed-keys.mdx | 60 ++-- .../content/api-docs/system/mfa/validate.mdx | 83 ----- website/content/api-docs/system/mounts.mdx | 4 +- website/content/api-docs/system/rekey.mdx | 12 +- website/content/api-docs/system/remount.mdx | 35 +- .../system/replication/replication-dr.mdx | 8 +- .../replication/replication-performance.mdx | 2 +- website/content/api-docs/system/unseal.mdx | 6 +- .../api-docs/system/version-history.mdx | 2 +- website/content/docs/auth/azure.mdx | 2 +- website/content/docs/auth/cf.mdx | 2 +- website/content/docs/auth/ldap.mdx | 5 + website/content/docs/auth/login-mfa.mdx | 179 ----------- website/content/docs/commands/auth/move.mdx | 12 +- website/content/docs/commands/login.mdx | 23 +- .../content/docs/commands/operator/init.mdx | 8 +- .../content/docs/commands/operator/rekey.mdx | 6 +- .../content/docs/commands/operator/seal.mdx | 6 +- .../content/docs/commands/operator/unseal.mdx | 4 +- .../content/docs/commands/secrets/move.mdx | 10 +- .../docs/concepts/client-count/faq.mdx | 75 ++++- website/content/docs/concepts/identity.mdx | 8 +- .../content/docs/concepts/mount-migration.mdx | 86 +++++ .../content/docs/concepts/oidc-provider.mdx | 104 ++++-- website/content/docs/concepts/seal.mdx | 20 +- website/content/docs/configuration/index.mdx | 4 +- .../docs/configuration/seal/awskms.mdx | 2 +- .../content/docs/configuration/seal/index.mdx | 4 +- .../docs/enterprise/entropy-augmentation.mdx | 2 +- .../content/docs/enterprise/hsm/behavior.mdx | 8 +- website/content/docs/enterprise/hsm/index.mdx | 6 +- .../content/docs/enterprise/hsm/security.mdx | 2 +- .../content/docs/enterprise/managed-keys.mdx | 4 +- website/content/docs/enterprise/sealwrap.mdx | 4 +- website/content/docs/glossary.mdx | 2 +- .../content/docs/internals/architecture.mdx | 6 +- website/content/docs/internals/limits.mdx | 2 +- website/content/docs/internals/plugins.mdx | 256 --------------- website/content/docs/internals/rotation.mdx | 14 +- website/content/docs/internals/security.mdx | 14 +- website/content/docs/partnerships.mdx | 2 +- .../docs/platform/{aws-mp => aws}/index.mdx | 0 .../platform/aws/lambda-extension-cache.mdx | 304 ++++++++++++++++++ .../docs/platform/{aws-mp => aws}/run.mdx | 0 .../docs/platform/k8s/injector-csi.mdx | 128 ++++++++ website/content/docs/plugin.mdx | 54 ---- website/content/docs/plugins/index.mdx | 39 +++ .../docs/plugins/plugin-architecture.mdx | 190 +++++++++++ .../docs/plugins/plugin-development.mdx | 91 ++++++ .../docs/plugins/plugin-management.mdx | 69 ++++ .../docs/{ => plugins}/plugin-portal.mdx | 6 +- website/content/docs/release-notes/1.10.mdx | 151 +++++++++ .../content/docs/secrets/databases/custom.mdx | 95 +++++- .../content/docs/secrets/databases/db2.mdx | 26 ++ .../docs/secrets/identity/oidc-provider.mdx | 224 +++++++------ .../docs/secrets/key-management/index.mdx | 2 +- website/content/docs/secrets/pki.mdx | 9 - website/content/docs/secrets/venafi.mdx | 6 +- website/content/docs/upgrading/plugins.mdx | 192 ++++++++++- .../docs/upgrading/upgrade-to-1.10.x.mdx | 78 ++++- .../content/intro/getting-started/deploy.mdx | 6 +- website/data/api-docs-nav-data.json | 33 -- website/data/docs-nav-data.json | 65 ++-- website/data/version.js | 4 +- website/public/img/comparison-table.png | Bin 0 -> 1126543 bytes website/public/img/k8s-auth-workflow.png | Bin 0 -> 69702 bytes website/public/img/vault-csi-workflow.png | Bin 0 -> 925817 bytes .../img/vault-sidecar-inject-workflow.png | Bin 0 -> 544363 bytes .../public/img/vault-usage-metrics-1-10.png | Bin 0 -> 284084 bytes website/redirects.next.js | 10 + 223 files changed, 3394 insertions(+), 3361 deletions(-) create mode 100644 .release/release-metadata.hcl delete mode 100644 changelog/14217.txt delete mode 100644 changelog/14269.txt delete mode 100644 changelog/14292.txt create mode 100644 changelog/14324.txt delete mode 100644 changelog/14389.txt create mode 100644 changelog/14489.txt create mode 100644 changelog/14493.txt create mode 100644 changelog/14543.txt create mode 100644 changelog/14545.txt create mode 100644 changelog/14551.txt create mode 100644 changelog/14622.txt create mode 100644 changelog/14670.txt create mode 100644 changelog/14704.txt create mode 100644 changelog/mount-migration.txt create mode 100644 helper/constants/fips_build_check.go create mode 100644 helper/constants/fips_cgo_check.go delete mode 100644 sdk/database/dbplugin/v5/plugin_client_test.go create mode 100644 ui/app/templates/vault/cluster/secrets/backend/roles.hbs rename ui/lib/core/addon/{ => templates}/components/toggle.hbs (60%) delete mode 100755 ui/scripts/enos-test-ember.js delete mode 100644 ui/scripts/test-helper.js delete mode 100644 ui/testem.enos.js create mode 100644 ui/tests/acceptance/logout-auth-method-test.js create mode 100644 ui/tests/helpers/oidc-window-stub.js delete mode 100644 website/content/api-docs/secret/identity/mfa/duo.mdx delete mode 100644 website/content/api-docs/secret/identity/mfa/index.mdx delete mode 100644 website/content/api-docs/secret/identity/mfa/login-enforcement.mdx delete mode 100644 website/content/api-docs/secret/identity/mfa/okta.mdx delete mode 100644 website/content/api-docs/secret/identity/mfa/pingid.mdx delete mode 100644 website/content/api-docs/secret/identity/mfa/totp.mdx delete mode 100644 website/content/api-docs/system/mfa/validate.mdx delete mode 100644 website/content/docs/auth/login-mfa.mdx create mode 100644 website/content/docs/concepts/mount-migration.mdx delete mode 100644 website/content/docs/internals/plugins.mdx rename website/content/docs/platform/{aws-mp => aws}/index.mdx (100%) create mode 100644 website/content/docs/platform/aws/lambda-extension-cache.mdx rename website/content/docs/platform/{aws-mp => aws}/run.mdx (100%) create mode 100644 website/content/docs/platform/k8s/injector-csi.mdx delete mode 100644 website/content/docs/plugin.mdx create mode 100644 website/content/docs/plugins/index.mdx create mode 100644 website/content/docs/plugins/plugin-architecture.mdx create mode 100644 website/content/docs/plugins/plugin-development.mdx create mode 100644 website/content/docs/plugins/plugin-management.mdx rename website/content/docs/{ => plugins}/plugin-portal.mdx (97%) create mode 100644 website/content/docs/release-notes/1.10.mdx create mode 100644 website/content/docs/secrets/databases/db2.mdx create mode 100644 website/public/img/comparison-table.png create mode 100644 website/public/img/k8s-auth-workflow.png create mode 100644 website/public/img/vault-csi-workflow.png create mode 100644 website/public/img/vault-sidecar-inject-workflow.png create mode 100644 website/public/img/vault-usage-metrics-1-10.png diff --git a/.circleci/config.yml b/.circleci/config.yml index 1dcde32e61e59..0fb251f8fead7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,7 +36,7 @@ jobs: - run: command: | case "$CIRCLE_BRANCH" in - main|ui/*|release/*|merge*) ;; + main|ui/*|backport/ui/*|release/*|merge*) ;; *) # If the branch being tested doesn't match one of the above patterns, # we don't need to run test-ui and can abort the job. circleci-agent step halt diff --git a/.circleci/config/commands/exit-if-branch-does-not-need-test-ui.yml b/.circleci/config/commands/exit-if-branch-does-not-need-test-ui.yml index c11ba6ecea972..771ef4d925f81 100644 --- a/.circleci/config/commands/exit-if-branch-does-not-need-test-ui.yml +++ b/.circleci/config/commands/exit-if-branch-does-not-need-test-ui.yml @@ -6,7 +6,7 @@ steps: name: Check branch name command: | case "$CIRCLE_BRANCH" in - main|ui/*|release/*|merge*) ;; + main|ui/*|backport/ui/*|release/*|merge*) ;; *) # If the branch being tested doesn't match one of the above patterns, # we don't need to run test-ui and can abort the job. circleci-agent step halt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 000ab92e4c94d..fc3887648c830 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,8 +4,8 @@ on: push: # Sequence of patterns matched against refs/heads branches: - # Push events on main branch - - main + # Push events on release/1.10.x branch + - release/1.10.x env: PKG_NAME: "vault" @@ -146,7 +146,7 @@ jobs: path: out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip - name: Package - uses: hashicorp/actions-packaging-linux@v1.2 + uses: hashicorp/actions-packaging-linux@v1 with: name: ${{ github.event.repository.name }} description: "Vault is a tool for secrets management, encryption as a service, and privileged access management." diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml index a30b5e3817bc2..44378dc117361 100644 --- a/.github/workflows/changelog-checker.yml +++ b/.github/workflows/changelog-checker.yml @@ -25,18 +25,11 @@ jobs: - name: Check for changelog entry in diff run: | # check if there is a diff in the changelog directory - if [ ${{ github.event.repository.name }} == "vault-enterprise" ]; then - expected_changelog_file=changelog/_${{ github.event.pull_request.number }}.txt - else - expected_changelog_file=changelog/${{ github.event.pull_request.number }}.txt - fi - - echo "looking for changelog file ${expected_changelog_file}" - changelog_files=$(git --no-pager diff --name-only HEAD "$(git merge-base HEAD "origin/${{ github.event.pull_request.base.ref }}")" -- ${expected_changelog_file}) + changelog_files=$(git --no-pager diff --name-only HEAD "$(git merge-base HEAD "origin/${{ github.event.pull_request.base.ref }}")" -- changelog/${{ github.event.pull_request.number }}.txt) # If we do not find a file matching the PR # in changelog/, we fail the check if [ -z "$changelog_files" ]; then - echo "Did not find a changelog entry named ${expected_changelog_file}" + echo "Did not find a changelog entry named ${{ github.event.pull_request.number }}.txt" echo "If your changelog file is correct, skip this check with the 'pr/no-changelog' label" echo "Reference - https://github.com/hashicorp/vault/pull/10363 and https://github.com/hashicorp/vault/pull/11894" exit 1 diff --git a/.gitignore b/.gitignore index 68bf1067f6dac..75b7fec103349 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,8 @@ _testmain.go /pkg/ # Generated Web UI goes here -/http/web_ui/** +/http/web_ui/*.* +/http/web_ui/**/*.* # Vault-specific example.hcl diff --git a/.release/ci.hcl b/.release/ci.hcl index 54c899dacb164..52bb54232f229 100644 --- a/.release/ci.hcl +++ b/.release/ci.hcl @@ -8,13 +8,7 @@ project "vault" { github { organization = "hashicorp" repository = "vault" - release_branches = [ - "main", - "release/1.7.x", - "release/1.8.x", - "release/1.9.x", - "release/1.10.x", - ] + release_branches = ["release/1.10.x"] } } diff --git a/.release/release-metadata.hcl b/.release/release-metadata.hcl new file mode 100644 index 0000000000000..19aadfc71ae1a --- /dev/null +++ b/.release/release-metadata.hcl @@ -0,0 +1,6 @@ +url_docker_registry_dockerhub = "https://hub.docker.com/r/hashicorp/vault" +url_docker_registry_ecr = "https://gallery.ecr.aws/hashicorp/vault" +url_license = "https://github.com/hashicorp/vault/blob/main/LICENSE" +url_project_website = "https://www.vaultproject.io/" +url_source_repository = "https://github.com/hashicorp/vault" +url_release_notes = "https://www.vaultproject.io/docs/release-notes" diff --git a/CHANGELOG.md b/CHANGELOG.md index b12ddf3d700f6..253af41c869f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,233 +1,117 @@ -## 1.10.0-rc1 -### March 3, 2022 +## 1.10.0 +### Unreleased CHANGES: -* core: Changes the unit of `default_lease_ttl` and `max_lease_ttl` values returned by -the `/sys/config/state/sanitized` endpoint from nanoseconds to seconds. [[GH-14206](https://github.com/hashicorp/vault/pull/14206)] -* core: Bump Go version to 1.17.7. [[GH-14232](https://github.com/hashicorp/vault/pull/14232)] -* plugin/database: The return value from `POST /database/config/:name` has been updated to "204 No Content" [[GH-14033](https://github.com/hashicorp/vault/pull/14033)] -* secrets/azure: Changes the configuration parameter `use_microsoft_graph_api` to use the Microsoft -Graph API by default. [[GH-14130](https://github.com/hashicorp/vault/pull/14130)] -* storage/etcd: Remove support for v2. [[GH-14193](https://github.com/hashicorp/vault/pull/14193)] +* go: Update go version to 1.17.5 [[GH-13408](https://github.com/hashicorp/vault/pull/13408)] * ui: Upgrade Ember to version 3.24 [[GH-13443](https://github.com/hashicorp/vault/pull/13443)] FEATURES: -* **Database plugin multiplexing**: manage multiple database connections with a single plugin process [[GH-14033](https://github.com/hashicorp/vault/pull/14033)] -* **Login MFA**: Single and two phase MFA is now available when authenticating to Vault. [[GH-14025](https://github.com/hashicorp/vault/pull/14025)] -* **Postgres in the UI**: Postgres DB is now supported by the UI [[GH-12945](https://github.com/hashicorp/vault/pull/12945)] -* **Remount across Namespaces (Enterprise)**: Secret engines and auth methods mounted at a namespace path are now able to be moved to a different namespace path * **Report in-flight requests**: Adding a trace capability to show in-flight requests, and a new gauge metric to show the total number of in-flight requests [[GH-13024](https://github.com/hashicorp/vault/pull/13024)] -* **Server Side Consistent Tokens**: Service tokens now use SSC token format and token prefixes are updated. [[GH-14109](https://github.com/hashicorp/vault/pull/14109)] * **Transit SHA-3 Support**: Add support for SHA-3 in the Transit backend. [[GH-13367](https://github.com/hashicorp/vault/pull/13367)] -* **Transit Time-Based Key Autorotation**: Add support for automatic, time-based key rotation to transit secrets engine, including in the UI. [[GH-13691](https://github.com/hashicorp/vault/pull/13691)] -* **UI Client Count Improvements**: Restructures client count dashboard, making use of billing start date to improve accuracy. Adds mount-level distribution and filtering. [[GH-client-counts](https://github.com/hashicorp/vault/pull/client-counts)] -* **Agent Telemetry**: The Vault Agent can now collect and return telemetry information at the `/agent/v1/metrics` endpoint. - +* **Transit Time-Based Key Autorotation**: Add support for automatic, time-based key rotation to transit secrets engine. [[GH-13691](https://github.com/hashicorp/vault/pull/13691)] IMPROVEMENTS: -* agent: Adds ability to configure specific user-assigned managed identities for Azure auto-auth. [[GH-14214](https://github.com/hashicorp/vault/pull/14214)] -* agent: The `agent/v1/quit` endpoint can now be used to stop the Vault Agent remotely [[GH-14223](https://github.com/hashicorp/vault/pull/14223)] * api: Allow cloning `api.Client` tokens via `api.Config.CloneToken` or `api.Client.SetCloneToken()`. [[GH-13515](https://github.com/hashicorp/vault/pull/13515)] -* api: Define constants for X-Vault-Forward and X-Vault-Inconsistent headers [[GH-14067](https://github.com/hashicorp/vault/pull/14067)] * api: Implements Login method in Go client libraries for GCP and Azure auth methods [[GH-13022](https://github.com/hashicorp/vault/pull/13022)] -* api: Implements Login method in Go client libraries for LDAP auth methods [[GH-13841](https://github.com/hashicorp/vault/pull/13841)] * api: Trim newline character from wrapping token in logical.Unwrap from the api package [[GH-13044](https://github.com/hashicorp/vault/pull/13044)] * api: add api method for modifying raft autopilot configuration [[GH-12428](https://github.com/hashicorp/vault/pull/12428)] * api: respect WithWrappingToken() option during AppRole login authentication when used with secret ID specified from environment or from string [[GH-13241](https://github.com/hashicorp/vault/pull/13241)] * audit: The audit logs now contain the port used by the client [[GH-12790](https://github.com/hashicorp/vault/pull/12790)] -* auth/aws: Enable region detection in the CLI by specifying the region as `auto` [[GH-14051](https://github.com/hashicorp/vault/pull/14051)] +* auth: reading `sys/auth/:path` now returns the configuration for the auth engine mounted at the given path [[GH-12793](https://github.com/hashicorp/vault/pull/12793)] * auth/cert: Add certificate extensions as metadata [[GH-13348](https://github.com/hashicorp/vault/pull/13348)] * auth/jwt: The Authorization Code flow makes use of the Proof Key for Code Exchange (PKCE) extension. [[GH-13365](https://github.com/hashicorp/vault/pull/13365)] * auth/kubernetes: Added support for dynamically reloading short-lived tokens for better Kubernetes 1.21+ compatibility [[GH-13595](https://github.com/hashicorp/vault/pull/13595)] -* auth/ldap: Add a response warning and server log whenever the config is accessed -if `userfilter` doesn't consider `userattr` [[GH-14095](https://github.com/hashicorp/vault/pull/14095)] * auth/ldap: Add username to alias metadata [[GH-13669](https://github.com/hashicorp/vault/pull/13669)] * auth/okta: Update [okta-sdk-golang](https://github.com/okta/okta-sdk-golang) dependency to version v2.9.1 for improved request backoff handling [[GH-13439](https://github.com/hashicorp/vault/pull/13439)] * auth/token: The `auth/token/revoke-accessor` endpoint is now idempotent and will not error out if the token has already been revoked. [[GH-13661](https://github.com/hashicorp/vault/pull/13661)] -* auth: reading `sys/auth/:path` now returns the configuration for the auth engine mounted at the given path [[GH-12793](https://github.com/hashicorp/vault/pull/12793)] -* cli: interactive CLI for login mfa [[GH-14131](https://github.com/hashicorp/vault/pull/14131)] * command (enterprise): "vault license get" now uses non-deprecated endpoint /sys/license/status * core/ha: Add new mechanism for keeping track of peers talking to active node, and new 'operator members' command to view them. [[GH-13292](https://github.com/hashicorp/vault/pull/13292)] * core/identity: Support updating an alias' `custom_metadata` to be empty. [[GH-13395](https://github.com/hashicorp/vault/pull/13395)] * core/pki: Support Y10K value in notAfter field to be compliant with IEEE 802.1AR-2018 standard [[GH-12795](https://github.com/hashicorp/vault/pull/12795)] -* core/pki: Support Y10K value in notAfter field when signing non-CA certificates [[GH-13736](https://github.com/hashicorp/vault/pull/13736)] * core: Add duration and start_time to completed requests log entries [[GH-13682](https://github.com/hashicorp/vault/pull/13682)] * core: Add support to list password policies at `sys/policies/password` [[GH-12787](https://github.com/hashicorp/vault/pull/12787)] -* core: Add support to list version history via API at `sys/version-history` and via CLI with `vault version-history` [[GH-13766](https://github.com/hashicorp/vault/pull/13766)] * core: Fixes code scanning alerts [[GH-13667](https://github.com/hashicorp/vault/pull/13667)] * core: Periodically test the health of connectivity to auto-seal backends [[GH-13078](https://github.com/hashicorp/vault/pull/13078)] * core: Reading `sys/mounts/:path` now returns the configuration for the secret engine at the given path [[GH-12792](https://github.com/hashicorp/vault/pull/12792)] * core: Replace "master key" terminology with "root key" [[GH-13324](https://github.com/hashicorp/vault/pull/13324)] -* core: Small changes to ensure goroutines terminate in tests [[GH-14197](https://github.com/hashicorp/vault/pull/14197)] -* core: Update github.com/prometheus/client_golang to fix security vulnerability CVE-2022-21698. [[GH-14190](https://github.com/hashicorp/vault/pull/14190)] * http (enterprise): Serve /sys/license/status endpoint within namespaces -* identity/oidc: Adds a default OIDC provider [[GH-14119](https://github.com/hashicorp/vault/pull/14119)] -* identity/oidc: Adds a default key for OIDC clients [[GH-14119](https://github.com/hashicorp/vault/pull/14119)] -* identity/oidc: Adds an `allow_all` assignment that permits all entities to authenticate via an OIDC client [[GH-14119](https://github.com/hashicorp/vault/pull/14119)] -* identity/oidc: Adds proof key for code exchange (PKCE) support to OIDC providers. [[GH-13917](https://github.com/hashicorp/vault/pull/13917)] * sdk: Add helper for decoding root tokens [[GH-10505](https://github.com/hashicorp/vault/pull/10505)] -* secrets/azure: Adds support for rotate-root. [#70](https://github.com/hashicorp/vault-plugin-secrets-azure/pull/70) [[GH-13034](https://github.com/hashicorp/vault/pull/13034)] -* secrets/consul: Add support for consul enterprise namespaces and admin partitions. [[GH-13850](https://github.com/hashicorp/vault/pull/13850)] -* secrets/consul: Add support for consul roles. [[GH-14014](https://github.com/hashicorp/vault/pull/14014)] * secrets/database/influxdb: Switch/upgrade to the `influxdb1-client` module [[GH-12262](https://github.com/hashicorp/vault/pull/12262)] -* secrets/database: Add database configuration parameter 'disable_escaping' for username and password when connecting to a database. +* secrets/database: Add database configuration parameter 'disable_escaping' for username and password when connecting to a database. [[GH-13414](https://github.com/hashicorp/vault/pull/13414)] * secrets/kv: add patch support for KVv2 key metadata [[GH-13215](https://github.com/hashicorp/vault/pull/13215)] -* secrets/kv: add subkeys endpoint to retrieve a secret's stucture without its values [[GH-13893](https://github.com/hashicorp/vault/pull/13893)] -* secrets/pki: Add ability to fetch individual certificate as DER or PEM [[GH-10948](https://github.com/hashicorp/vault/pull/10948)] -* secrets/pki: Add count and duration metrics to PKI issue and revoke calls. [[GH-13889](https://github.com/hashicorp/vault/pull/13889)] -* secrets/pki: Add error handling for error types other than UserError or InternalError [[GH-14195](https://github.com/hashicorp/vault/pull/14195)] * secrets/pki: Allow URI SAN templates in allowed_uri_sans when allowed_uri_sans_template is set to true. [[GH-10249](https://github.com/hashicorp/vault/pull/10249)] -* secrets/pki: Allow other_sans in sign-intermediate and sign-verbatim [[GH-13958](https://github.com/hashicorp/vault/pull/13958)] -* secrets/pki: Calculate the Subject Key Identifier as suggested in [RFC 5280, Section 4.2.1.2](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.2). [[GH-11218](https://github.com/hashicorp/vault/pull/11218)] -* secrets/pki: Restrict issuance of wildcard certificates via role parameter (`allow_wildcard_certificates`) [[GH-14238](https://github.com/hashicorp/vault/pull/14238)] -* secrets/pki: Return complete chain (in `ca_chain` field) on calls to `pki/cert/ca_chain` [[GH-13935](https://github.com/hashicorp/vault/pull/13935)] -* secrets/pki: Use application/pem-certificate-chain for PEM certificates, application/x-pem-file for PEM CRLs [[GH-13927](https://github.com/hashicorp/vault/pull/13927)] -* secrets/pki: select appropriate signature algorithm for ECDSA signature on certificates. [[GH-11216](https://github.com/hashicorp/vault/pull/11216)] -* secrets/ssh: Add support for generating non-RSA SSH CAs [[GH-14008](https://github.com/hashicorp/vault/pull/14008)] -* secrets/ssh: Allow specifying multiple approved key lengths for a single algorithm [[GH-13991](https://github.com/hashicorp/vault/pull/13991)] -* secrets/ssh: Use secure default for algorithm signer (rsa-sha2-256) with RSA SSH CA keys on new roles [[GH-14006](https://github.com/hashicorp/vault/pull/14006)] * secrets/transit: Don't abort transit encrypt or decrypt batches on single item failure. [[GH-13111](https://github.com/hashicorp/vault/pull/13111)] * storage/aerospike: Upgrade `aerospike-client-go` to v5.6.0. [[GH-12165](https://github.com/hashicorp/vault/pull/12165)] * storage/raft: Set InitialMmapSize to 100GB on 64bit architectures [[GH-13178](https://github.com/hashicorp/vault/pull/13178)] * storage/raft: When using retry_join stanzas, join against all of them in parallel. [[GH-13606](https://github.com/hashicorp/vault/pull/13606)] * sys/raw: Enhance sys/raw to read and write values that cannot be encoded in json. [[GH-13537](https://github.com/hashicorp/vault/pull/13537)] -* ui: Add support for ECDSA and Ed25519 certificate views [[GH-13894](https://github.com/hashicorp/vault/pull/13894)] * ui: Add version diff view for KV V2 [[GH-13000](https://github.com/hashicorp/vault/pull/13000)] -* ui: Add client side pagination for namespace list view [[GH-13195](https://github.com/hashicorp/vault/pull/13195)] -* ui: Add two-phase multi-factor authentication support to login flow [[GH-14049](https://github.com/hashicorp/vault/pull/14049)] -* ui: Allow static role credential rotation in Database secrets engines [[GH-14268](https://github.com/hashicorp/vault/pull/14268)] +* ui: Added client side paging for namespace list view [[GH-13195](https://github.com/hashicorp/vault/pull/13195)] +* ui: Adds flight icons to UI [[GH-12976](https://github.com/hashicorp/vault/pull/12976)] * ui: Display badge for all versions in secrets engine header [[GH-13015](https://github.com/hashicorp/vault/pull/13015)] -* ui: Swap browser localStorage in favor of sessionStorage [[GH-14054](https://github.com/hashicorp/vault/pull/14054)] * ui: The integrated web terminal now accepts both `-f` and `--force` as aliases -for `-force` for the `write` command. [[GH-13683](https://github.com/hashicorp/vault/pull/13683)] -* ui: Transform advanced templating with encode/decode format support [[GH-13908](https://github.com/hashicorp/vault/pull/13908)] +for `-force` for the `write` commmand. [[GH-13683](https://github.com/hashicorp/vault/pull/13683)] +* ui: Updates ember blueprints to glimmer components [[GH-13149](https://github.com/hashicorp/vault/pull/13149)] +* ui: customizes empty state messages for transit and transform [[GH-13090](https://github.com/hashicorp/vault/pull/13090)] BUG FIXES: -* Fixed bug where auth method only considers system-identity when multiple identities are available. [#50](https://github.com/hashicorp/vault-plugin-auth-azure/pull/50) [[GH-14138](https://github.com/hashicorp/vault/pull/14138)] -* activity log (enterprise): allow partial monthly client count to be accessed from namespaces [[GH-13086](https://github.com/hashicorp/vault/pull/13086)] * agent: Fixes bug where vault agent is unaware of the namespace in the config when wrapping token * api/client: Fixes an issue where the `replicateStateStore` was being set to `nil` upon consecutive calls to `client.SetReadYourWrites(true)`. [[GH-13486](https://github.com/hashicorp/vault/pull/13486)] * auth/approle: Fix regression where unset cidrlist is returned as nil instead of zero-length array. [[GH-13235](https://github.com/hashicorp/vault/pull/13235)] -* auth/approle: Fix wrapping of nil errors in `login` endpoint [[GH-14107](https://github.com/hashicorp/vault/pull/14107)] * auth/github: Use the Organization ID instead of the Organization name to verify the org membership. [[GH-13332](https://github.com/hashicorp/vault/pull/13332)] -* auth/kubernetes: Properly handle the migration of role storage entries containing an empty `alias_name_source` [[GH-13925](https://github.com/hashicorp/vault/pull/13925)] -* auth/kubernetes: ensure valid entity alias names created for projected volume tokens [[GH-14144](https://github.com/hashicorp/vault/pull/14144)] * auth/oidc: Fixes OIDC auth from the Vault UI when using the implicit flow and `form_post` response mode. [[GH-13492](https://github.com/hashicorp/vault/pull/13492)] * cli: Fix using kv patch with older server versions that don't support HTTP PATCH. [[GH-13615](https://github.com/hashicorp/vault/pull/13615)] -* core (enterprise): Fix a data race in logshipper. * core (enterprise): Workaround AWS CloudHSM v5 SDK issue not allowing read-only sessions -* core/api: Fix overwriting of request headers when using JSONMergePatch. [[GH-14222](https://github.com/hashicorp/vault/pull/14222)] -* core/identity: Address a data race condition between local updates to aliases and invalidations [[GH-13093](https://github.com/hashicorp/vault/pull/13093)] * core/identity: Address a data race condition between local updates to aliases and invalidations [[GH-13476](https://github.com/hashicorp/vault/pull/13476)] * core/token: Fix null token panic from 'v1/auth/token/' endpoints and return proper error response. [[GH-13233](https://github.com/hashicorp/vault/pull/13233)] * core/token: Fix null token_type panic resulting from 'v1/auth/token/roles/{role_name}' endpoint [[GH-13236](https://github.com/hashicorp/vault/pull/13236)] -* core: Fix warnings logged on perf standbys re stored versions [[GH-13042](https://github.com/hashicorp/vault/pull/13042)] * core: `-output-curl-string` now properly sets cURL options for client and CA certificates. [[GH-13660](https://github.com/hashicorp/vault/pull/13660)] * core: add support for go-sockaddr templates in the top-level cluster_addr field [[GH-13678](https://github.com/hashicorp/vault/pull/13678)] * core: authentication to "login" endpoint for non-existent mount path returns permission denied with status code 403 [[GH-13162](https://github.com/hashicorp/vault/pull/13162)] -* core: revert some unintentionally downgraded dependencies from 1.9.0-rc1 [[GH-13168](https://github.com/hashicorp/vault/pull/13168)] * ha (enterprise): Prevents performance standby nodes from serving and caching stale data immediately after performance standby election completes -* http (enterprise): Always forward internal/counters endpoints from perf standbys to active node * http:Fix /sys/monitor endpoint returning streaming not supported [[GH-13200](https://github.com/hashicorp/vault/pull/13200)] -* identity/oidc: Adds support for port-agnostic validation of loopback IP redirect URIs. [[GH-13871](https://github.com/hashicorp/vault/pull/13871)] * identity/oidc: Check for a nil signing key on rotation to prevent panics. [[GH-13716](https://github.com/hashicorp/vault/pull/13716)] -* identity/oidc: Fixes inherited group membership when evaluating client assignments [[GH-14013](https://github.com/hashicorp/vault/pull/14013)] * identity/oidc: Make the `nonce` parameter optional for the Authorization Endpoint of OIDC providers. [[GH-13231](https://github.com/hashicorp/vault/pull/13231)] * identity: Fix possible nil pointer dereference. [[GH-13318](https://github.com/hashicorp/vault/pull/13318)] -* identity: Fix regression preventing startup when aliases were created pre-1.9. [[GH-13169](https://github.com/hashicorp/vault/pull/13169)] * identity: Fixes a panic in the OIDC key rotation due to a missing nil check. [[GH-13298](https://github.com/hashicorp/vault/pull/13298)] * kmip (enterprise): Fix locate by name operations fail to find key after a rekey operation. -* licensing (enterprise): Revert accidental inclusion of the TDE feature from the `prem` build. -* physical/mysql: Create table with wider `vault_key` column when initializing database tables. [[GH-14231](https://github.com/hashicorp/vault/pull/14231)] -* plugin/couchbase: Fix an issue in which the locking patterns did not allow parallel requests. [[GH-13033](https://github.com/hashicorp/vault/pull/13033)] -* replication (enterprise): When using encrypted secondary tokens, only clear the -private key after a successful connection to the primary cluster * sdk/framework: Generate proper OpenAPI specs for path patterns that use an alternation as the root. [[GH-13487](https://github.com/hashicorp/vault/pull/13487)] * sdk/helper/ldaputil: properly escape a trailing escape character to prevent panics. [[GH-13452](https://github.com/hashicorp/vault/pull/13452)] * sdk/queue: move lock before length check to prevent panics. [[GH-13146](https://github.com/hashicorp/vault/pull/13146)] * sdk: Fixes OpenAPI to distinguish between paths that can do only List, or both List and Read. [[GH-13643](https://github.com/hashicorp/vault/pull/13643)] -* secrets/azure: Fixed bug where Azure environment did not change Graph URL [[GH-13973](https://github.com/hashicorp/vault/pull/13973)] * secrets/azure: Fixes service principal generation when assigning roles that have [DataActions](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-definitions#dataactions). [[GH-13277](https://github.com/hashicorp/vault/pull/13277)] -* secrets/azure: Fixes the [rotate root](https://www.vaultproject.io/api-docs/secret/azure#rotate-root) -operation for upgraded configurations with a `root_password_ttl` of zero. [[GH-14130](https://github.com/hashicorp/vault/pull/14130)] -* secrets/database/cassandra: change connect_timeout to 5s as documentation says [[GH-12443](https://github.com/hashicorp/vault/pull/12443)] * secrets/database/mssql: Accept a boolean for `contained_db`, rather than just a string. [[GH-13469](https://github.com/hashicorp/vault/pull/13469)] -* secrets/gcp: Fixed bug where error was not reported for invalid bindings [[GH-13974](https://github.com/hashicorp/vault/pull/13974)] * secrets/gcp: Fixes role bindings for BigQuery dataset resources. [[GH-13548](https://github.com/hashicorp/vault/pull/13548)] -* secrets/openldap: Fix panic from nil logger in backend [[GH-14171](https://github.com/hashicorp/vault/pull/14171)] * secrets/pki: Default value for key_bits changed to 0, enabling key_type=ec key generation with default value [[GH-13080](https://github.com/hashicorp/vault/pull/13080)] -* secrets/pki: Fix issuance of wildcard certificates matching glob patterns [[GH-14235](https://github.com/hashicorp/vault/pull/14235)] * secrets/pki: Fix regression causing performance secondaries to forward certificate generation to the primary. [[GH-13759](https://github.com/hashicorp/vault/pull/13759)] * secrets/pki: Fix regression causing performance secondaries to forward certificate generation to the primary. [[GH-2456](https://github.com/hashicorp/vault/pull/2456)] * secrets/pki: Fixes around NIST P-curve signature hash length, default value for signature_bits changed to 0. [[GH-12872](https://github.com/hashicorp/vault/pull/12872)] * secrets/pki: Recognize ed25519 when requesting a response in PKCS8 format [[GH-13257](https://github.com/hashicorp/vault/pull/13257)] * secrets/pki: Skip signature bits validation for ed25519 curve key type [[GH-13254](https://github.com/hashicorp/vault/pull/13254)] * secrets/transit: Ensure that Vault does not panic for invalid nonce size when we aren't in convergent encryption mode. [[GH-13690](https://github.com/hashicorp/vault/pull/13690)] -* secrets/transit: Return an error if any required parameter is missing or nil. Do not encrypt nil plaintext as if it was an empty string. [[GH-14074](https://github.com/hashicorp/vault/pull/14074)] * storage/raft: Fix a panic when trying to store a key > 32KB in a transaction. [[GH-13286](https://github.com/hashicorp/vault/pull/13286)] * storage/raft: Fix a panic when trying to write a key > 32KB [[GH-13282](https://github.com/hashicorp/vault/pull/13282)] * storage/raft: Fix issues allowing invalid nodes to become leadership candidates. [[GH-13703](https://github.com/hashicorp/vault/pull/13703)] -* storage/raft: Fix regression in 1.9.0-rc1 that changed how time is represented in Raft logs; this prevented using a raft db created pre-1.9. [[GH-13165](https://github.com/hashicorp/vault/pull/13165)] * storage/raft: On linux, use map_populate for bolt files to improve startup time. [[GH-13573](https://github.com/hashicorp/vault/pull/13573)] * storage/raft: Units for bolt metrics now given in milliseconds instead of nanoseconds [[GH-13749](https://github.com/hashicorp/vault/pull/13749)] -* ui: Adds pagination to auth methods list view [[GH-13054](https://github.com/hashicorp/vault/pull/13054)] -* ui: Remove “verify connection” value on database connection config show page [[GH-13152](https://github.com/hashicorp/vault/pull/13152)] +* ui: Do not show verify connection value on database connection config page [[GH-13152](https://github.com/hashicorp/vault/pull/13152)] * ui: Fix client count current month data not showing unless monthly history data exists [[GH-13396](https://github.com/hashicorp/vault/pull/13396)] -* ui: Fix default TTL display and set on database role [[GH-14224](https://github.com/hashicorp/vault/pull/14224)] -* ui: Fix incorrect validity message on transit secrets engine [[GH-14233](https://github.com/hashicorp/vault/pull/14233)] -* ui: Fix kv engine access bug [[GH-13872](https://github.com/hashicorp/vault/pull/13872)] -* ui: Fix breadcrumb bug for secrets navigation [[GH-13604](https://github.com/hashicorp/vault/pull/13604)] -* ui: Fix issue removing raft storage peer via cli not reflected in UI until refresh [[GH-13098](https://github.com/hashicorp/vault/pull/13098)] -* ui: Fix issue restoring raft storage snapshot [[GH-13107](https://github.com/hashicorp/vault/pull/13107)] -* ui: Fix issue saving KMIP role correctly [[GH-13585](https://github.com/hashicorp/vault/pull/13585)] -* ui: Fix issue with OIDC auth workflow when using MetaMask Chrome extension [[GH-13133](https://github.com/hashicorp/vault/pull/13133)] -* ui: Fix issue with SearchSelect component not holding focus [[GH-13590](https://github.com/hashicorp/vault/pull/13590)] -* ui: Fix issue with automate secret deletion value not displaying initially if set in secret metadata edit view [[GH-13177](https://github.com/hashicorp/vault/pull/13177)] -* ui: Fix issue with placeholder not displaying for automatically deleted secrets when deletion time has passed [[GH-13166](https://github.com/hashicorp/vault/pull/13166)] -* ui: Fix issue with the number of PGP Key inputs not matching the key shares number in the initialization form on change [[GH-13038](https://github.com/hashicorp/vault/pull/13038)] -* ui: Fix long secret key names overlapping masked values [[GH-13032](https://github.com/hashicorp/vault/pull/13032)] -* ui: Fix node-forge error when parsing EC (elliptical curve) certs [[GH-13238](https://github.com/hashicorp/vault/pull/13238)] -* ui: Removes ability to tune token_type for token auth methods [[GH-12904](https://github.com/hashicorp/vault/pull/12904)] -* ui: Trigger background token self-renewal if inactive and half of TTL has passed [[GH-13950](https://github.com/hashicorp/vault/pull/13950)] - -## 1.9.4 -### March 3, 2022 - -CHANGES: - -* secrets/azure: Changes the configuration parameter `use_microsoft_graph_api` to use the Microsoft -Graph API by default. [[GH-14130](https://github.com/hashicorp/vault/pull/14130)] - -IMPROVEMENTS: - -* core: Bump Go version to 1.17.7. [[GH-14232](https://github.com/hashicorp/vault/pull/14232)] -* secrets/pki: Restrict issuance of wildcard certificates via role parameter (`allow_wildcard_certificates`) [[GH-14238](https://github.com/hashicorp/vault/pull/14238)] - -BUG FIXES: - -* Fixed bug where auth method only considers system-identity when multiple identities are available. [#50](https://github.com/hashicorp/vault-plugin-auth-azure/pull/50) [[GH-14138](https://github.com/hashicorp/vault/pull/14138)] -* auth/kubernetes: Properly handle the migration of role storage entries containing an empty `alias_name_source` [[GH-13925](https://github.com/hashicorp/vault/pull/13925)] -* auth/kubernetes: ensure valid entity alias names created for projected volume tokens [[GH-14144](https://github.com/hashicorp/vault/pull/14144)] -* identity/oidc: Adds support for port-agnostic validation of loopback IP redirect URIs. [[GH-13871](https://github.com/hashicorp/vault/pull/13871)] -* identity/oidc: Fixes inherited group membership when evaluating client assignments [[GH-14013](https://github.com/hashicorp/vault/pull/14013)] -* secrets/azure: Fixed bug where Azure environment did not change Graph URL [[GH-13973](https://github.com/hashicorp/vault/pull/13973)] -* secrets/azure: Fixes the [rotate root](https://www.vaultproject.io/api-docs/secret/azure#rotate-root) -operation for upgraded configurations with a `root_password_ttl` of zero. [[GH-14130](https://github.com/hashicorp/vault/pull/14130)] -* secrets/gcp: Fixed bug where error was not reported for invalid bindings [[GH-13974](https://github.com/hashicorp/vault/pull/13974)] -* secrets/openldap: Fix panic from nil logger in backend [[GH-14171](https://github.com/hashicorp/vault/pull/14171)] -* secrets/pki: Fix issuance of wildcard certificates matching glob patterns [[GH-14235](https://github.com/hashicorp/vault/pull/14235)] -* storage/raft: Fix issues allowing invalid nodes to become leadership candidates. [[GH-13703](https://github.com/hashicorp/vault/pull/13703)] -* ui: Fix default TTL display and set on database role [[GH-14224](https://github.com/hashicorp/vault/pull/14224)] -* ui: Fix incorrect validity message on transit secrets engine [[GH-14233](https://github.com/hashicorp/vault/pull/14233)] -* ui: Fix kv engine access bug [[GH-13872](https://github.com/hashicorp/vault/pull/13872)] -* ui: Fix issue removing raft storage peer via cli not reflected in UI until refresh [[GH-13098](https://github.com/hashicorp/vault/pull/13098)] -* ui: Trigger background token self-renewal if inactive and half of TTL has passed [[GH-13950](https://github.com/hashicorp/vault/pull/13950)] +* ui: Fixes breadcrumb bug for secrets navigation [[GH-13604](https://github.com/hashicorp/vault/pull/13604)] +* ui: Fixes issue removing raft storage peer via cli not reflected in UI until refresh [[GH-13098](https://github.com/hashicorp/vault/pull/13098)] +* ui: Fixes issue restoring raft storage snapshot [[GH-13107](https://github.com/hashicorp/vault/pull/13107)] +* ui: Fixes issue saving KMIP role correctly [[GH-13585](https://github.com/hashicorp/vault/pull/13585)] +* ui: Fixes issue with OIDC auth workflow when using MetaMask Chrome extension [[GH-13133](https://github.com/hashicorp/vault/pull/13133)] +* ui: Fixes issue with SearchSelect component not holding focus [[GH-13590](https://github.com/hashicorp/vault/pull/13590)] +* ui: Fixes issue with automate secret deletion value not displaying initially if set in secret metadata edit view [[GH-13177](https://github.com/hashicorp/vault/pull/13177)] +* ui: Fixes issue with placeholder not displaying for automatically deleted secrets when deletion time has passed [[GH-13166](https://github.com/hashicorp/vault/pull/13166)] +* ui: Fixes long secret key names overlapping masked values [[GH-13032](https://github.com/hashicorp/vault/pull/13032)] +* ui: Fixes node-forge error when parsing EC (elliptical curve) certs [[GH-13238](https://github.com/hashicorp/vault/pull/13238)] ## 1.9.3 ### January 27, 2022 @@ -507,22 +391,6 @@ of dirty pages in the merkle tree at time of checkpoint creation. [[GH-2093](htt * ui: update bar chart when model changes [[GH-12622](https://github.com/hashicorp/vault/pull/12622)] * ui: updating database TTL picker help text. [[GH-12212](https://github.com/hashicorp/vault/pull/12212)] -## 1.8.9 -### March 3, 2022 - -IMPROVEMENTS: - -* secrets/pki: Restrict issuance of wildcard certificates via role parameter (`allow_wildcard_certificates`) [[GH-14238](https://github.com/hashicorp/vault/pull/14238)] - -BUG FIXES: - -* auth/aws: Fix ec2 auth on instances that have a cert in their PKCS7 signature [[GH-12519](https://github.com/hashicorp/vault/pull/12519)] -* database/mssql: Removed string interpolation on internal queries and replaced them with inline queries using named parameters. [[GH-13799](https://github.com/hashicorp/vault/pull/13799)] -* secrets/openldap: Fix panic from nil logger in backend [[GH-14170](https://github.com/hashicorp/vault/pull/14170)] -* secrets/pki: Fix issuance of wildcard certificates matching glob patterns [[GH-14235](https://github.com/hashicorp/vault/pull/14235)] -* ui: Fix issue removing raft storage peer via cli not reflected in UI until refresh [[GH-13098](https://github.com/hashicorp/vault/pull/13098)] -* ui: Trigger background token self-renewal if inactive and half of TTL has passed [[GH-13950](https://github.com/hashicorp/vault/pull/13950)] - ## 1.8.8 ### January 27, 2022 @@ -842,15 +710,6 @@ BUG FIXES: * ui: fix issue where select-one option was not showing in secrets database role creation [[GH-11294](https://github.com/hashicorp/vault/pull/11294)] * ui: fix oidc login with Safari [[GH-11884](https://github.com/hashicorp/vault/pull/11884)] -## 1.7.10 -### March 3, 2022 - -BUG FIXES: - -* database/mssql: Removed string interpolation on internal queries and replaced them with inline queries using named parameters. [[GH-13799](https://github.com/hashicorp/vault/pull/13799)] -* ui: Fix issue removing raft storage peer via cli not reflected in UI until refresh [[GH-13098](https://github.com/hashicorp/vault/pull/13098)] -* ui: Trigger background token self-renewal if inactive and half of TTL has passed [[GH-13950](https://github.com/hashicorp/vault/pull/13950)] - ## 1.7.9 ### January 27, 2022 diff --git a/CODEOWNERS b/CODEOWNERS index 1c73c5679cc2c..4396a5873974f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -25,7 +25,11 @@ /command/agent/ @hashicorp/vault-ecosystem /plugins/ @hashicorp/vault-ecosystem -/website/content/ @taoism4504 +# Disabling for now to see if manually adding the reviewer when a PR +# is ready will be more useful and accurate. There have been cases where +# docs are being reviewed against PRs that haven't been vetted for acceptance. +# /website/content/ @taoism4504 + /website/content/docs/plugin-portal.mdx @taoism4504 @acahn # UI code related to Vault's JWT/OIDC auth method and OIDC provider. diff --git a/Dockerfile b/Dockerfile index 7748bb3f2b4c5..e4009b34599fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,15 @@ FROM alpine:3.15 as default ARG BIN_NAME -# NAME and PRODUCT_VERSION are the name of the software in releases.hashicorp.com -# and the version to download. Example: NAME=vault PRODUCT_VERSION=1.2.3. +# NAME and VERSION are the name of the software in releases.hashicorp.com +# and the version to download. Example: NAME=vault VERSION=1.2.3. ARG NAME=vault -ARG PRODUCT_VERSION +ARG VERSION # TARGETARCH and TARGETOS are set automatically when --platform is provided. ARG TARGETOS TARGETARCH LABEL maintainer="Vault Team " -LABEL version=${PRODUCT_VERSION} +LABEL version=$VERSION # Set ARGs as ENV so that they can be used in ENTRYPOINT/CMD ENV NAME=$NAME diff --git a/Makefile b/Makefile index 2afd3f5c8d174..fde793465581b 100644 --- a/Makefile +++ b/Makefile @@ -139,18 +139,12 @@ update-plugins: static-assets-dir: @mkdir -p ./http/web_ui -install-ui-dependencies: +test-ember: @echo "--> Installing JavaScript assets" @cd ui && yarn --ignore-optional - -test-ember: install-ui-dependencies @echo "--> Running ember tests" @cd ui && yarn run test:oss -test-ember-enos: install-ui-dependencies - @echo "--> Running ember tests with a real backend" - @cd ui && yarn run test:enos - ember-ci-test: # Deprecated, to be removed soon. @echo "ember-ci-test is deprecated in favour of test-ui-browserstack" @exit 1 @@ -164,23 +158,29 @@ check-browserstack-creds: @[ -n "$$BROWSERSTACK_ACCESS_KEY" ] || { echo "BROWSERSTACK_ACCESS_KEY not set"; exit 1; } @[ -n "$$BROWSERSTACK_USERNAME" ] || { echo "BROWSERSTACK_USERNAME not set"; exit 1; } -test-ui-browserstack: check-vault-in-path check-browserstack-creds install-ui-dependencies +test-ui-browserstack: check-vault-in-path check-browserstack-creds + @echo "--> Installing JavaScript assets" + @cd ui && yarn --ignore-optional @echo "--> Running ember tests in Browserstack" @cd ui && yarn run test:browserstack -ember-dist: install-ui-dependencies +ember-dist: + @echo "--> Installing JavaScript assets" + @cd ui && yarn --ignore-optional @cd ui && npm rebuild node-sass @echo "--> Building Ember application" @cd ui && yarn run build @rm -rf ui/if-you-need-to-delete-this-open-an-issue-async-disk-cache -ember-dist-dev: install-ui-dependencies +ember-dist-dev: + @echo "--> Installing JavaScript assets" + @cd ui && yarn --ignore-optional @cd ui && npm rebuild node-sass @echo "--> Building Ember application" @cd ui && yarn run build:dev -static-dist: ember-dist -static-dist-dev: ember-dist-dev +static-dist: ember-dist +static-dist-dev: ember-dist-dev proto: bootstrap protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative vault/*.proto diff --git a/api/client.go b/api/client.go index 3ce57a1de2e56..6a804091a2194 100644 --- a/api/client.go +++ b/api/client.go @@ -53,14 +53,6 @@ const ( HeaderIndex = "X-Vault-Index" HeaderForward = "X-Vault-Forward" HeaderInconsistent = "X-Vault-Inconsistent" - TLSErrorString = "This error usually means that the server is running with TLS disabled\n" + - "but the client is configured to use TLS. Please either enable TLS\n" + - "on the server or run the client with -address set to an address\n" + - "that uses the http protocol:\n\n" + - " vault -address http://
\n\n" + - "You can also set the VAULT_ADDR environment variable:\n\n\n" + - " VAULT_ADDR=http://
vault \n\n" + - "where
is replaced by the actual address to the server." ) // Deprecated values @@ -1135,9 +1127,12 @@ func (c *Client) RawRequestWithContext(ctx context.Context, r *Request) (*Respon limiter.Wait(ctx) } - // check the token before potentially erroring from the API - if err := validateToken(token); err != nil { - return nil, err + // Sanity check the token before potentially erroring from the API + idx := strings.IndexFunc(token, func(c rune) bool { + return !unicode.IsPrint(c) + }) + if idx != -1 { + return nil, fmt.Errorf("configured Vault token contains non-printable characters and cannot be used") } redirectCount := 0 @@ -1197,7 +1192,17 @@ START: } if err != nil { if strings.Contains(err.Error(), "tls: oversized") { - err = errwrap.Wrapf("{{err}}\n\n"+TLSErrorString, err) + err = errwrap.Wrapf( + "{{err}}\n\n"+ + "This error usually means that the server is running with TLS disabled\n"+ + "but the client is configured to use TLS. Please either enable TLS\n"+ + "on the server or run the client with -address set to an address\n"+ + "that uses the http protocol:\n\n"+ + " vault -address http://
\n\n"+ + "You can also set the VAULT_ADDR environment variable:\n\n\n"+ + " VAULT_ADDR=http://
vault \n\n"+ + "where
is replaced by the actual address to the server.", + err) } return result, err } @@ -1244,120 +1249,6 @@ START: return result, nil } -// httpRequestWithContext avoids the use of the go-retryable library found in RawRequestWithContext and is -// useful when making calls where a net/http client is desirable. A single redirect (status code 301, 302, -// or 307) will be followed but all retry and timeout logic is the responsibility of the caller as is -// closing the Response body. -func (c *Client) httpRequestWithContext(ctx context.Context, r *Request) (*Response, error) { - req, err := http.NewRequestWithContext(ctx, r.Method, r.URL.RequestURI(), r.Body) - if err != nil { - return nil, err - } - - c.modifyLock.RLock() - token := c.token - - c.config.modifyLock.RLock() - limiter := c.config.Limiter - httpClient := c.config.HttpClient - outputCurlString := c.config.OutputCurlString - if c.headers != nil { - for header, vals := range c.headers { - for _, val := range vals { - req.Header.Add(header, val) - } - } - } - c.config.modifyLock.RUnlock() - c.modifyLock.RUnlock() - - // OutputCurlString logic relies on the request type to be retryable.Request as - if outputCurlString { - return nil, fmt.Errorf("output-curl-string is not implemented for this request") - } - - req.URL.User = r.URL.User - req.URL.Scheme = r.URL.Scheme - req.URL.Host = r.URL.Host - req.Host = r.URL.Host - - if len(r.ClientToken) != 0 { - req.Header.Set(consts.AuthHeaderName, r.ClientToken) - } - - if len(r.WrapTTL) != 0 { - req.Header.Set("X-Vault-Wrap-TTL", r.WrapTTL) - } - - if len(r.MFAHeaderVals) != 0 { - for _, mfaHeaderVal := range r.MFAHeaderVals { - req.Header.Add("X-Vault-MFA", mfaHeaderVal) - } - } - - if r.PolicyOverride { - req.Header.Set("X-Vault-Policy-Override", "true") - } - - if limiter != nil { - limiter.Wait(ctx) - } - - // check the token before potentially erroring from the API - if err := validateToken(token); err != nil { - return nil, err - } - - var result *Response - - resp, err := httpClient.Do(req) - - if resp != nil { - result = &Response{Response: resp} - } - - if err != nil { - if strings.Contains(err.Error(), "tls: oversized") { - err = errwrap.Wrapf("{{err}}\n\n"+TLSErrorString, err) - } - return result, err - } - - // Check for a redirect, only allowing for a single redirect - if resp.StatusCode == 301 || resp.StatusCode == 302 || resp.StatusCode == 307 { - // Parse the updated location - respLoc, err := resp.Location() - if err != nil { - return result, fmt.Errorf("redirect failed: %s", err) - } - - // Ensure a protocol downgrade doesn't happen - if req.URL.Scheme == "https" && respLoc.Scheme != "https" { - return result, fmt.Errorf("redirect would cause protocol downgrade") - } - - // Update the request - req.URL = respLoc - - // Reset the request body if any - if err := r.ResetJSONBody(); err != nil { - return result, fmt.Errorf("redirect failed: %s", err) - } - - // Retry the request - resp, err = httpClient.Do(req) - if err != nil { - return result, fmt.Errorf("redirect failed: %s", err) - } - } - - if err := result.Error(); err != nil { - return nil, err - } - - return result, nil -} - type ( RequestCallback func(*Request) ResponseCallback func(*Response) @@ -1575,14 +1466,3 @@ func (w *replicationStateStore) states() []string { copy(c, w.store) return c } - -// validateToken will check for non-printable characters to prevent a call that will fail at the api -func validateToken(t string) error { - idx := strings.IndexFunc(t, func(c rune) bool { - return !unicode.IsPrint(c) - }) - if idx != -1 { - return fmt.Errorf("configured Vault token contains non-printable characters and cannot be used") - } - return nil -} diff --git a/api/renewer_test.go b/api/renewer_test.go index 3fa9ed8e2bcf2..6289b2fd56ac7 100644 --- a/api/renewer_test.go +++ b/api/renewer_test.go @@ -174,10 +174,8 @@ func TestLifetimeWatcher(t *testing.T) { t.Fatal(err) } - doneCh := make(chan error, 1) go func() { - doneCh <- v.doRenewWithOptions(false, false, - tc.leaseDurationSeconds, "myleaseID", tc.renew, time.Second) + v.doneCh <- v.doRenewWithOptions(false, false, tc.leaseDurationSeconds, "myleaseID", tc.renew, time.Second) }() defer v.Stop() @@ -191,15 +189,12 @@ func TestLifetimeWatcher(t *testing.T) { if r.Secret != renewedSecret { t.Fatalf("expected secret %v, got %v", renewedSecret, r.Secret) } - case err := <-doneCh: + case err := <-v.DoneCh(): if tc.expectError != nil && !errors.Is(err, tc.expectError) { t.Fatalf("expected error %q, got: %v", tc.expectError, err) } - if tc.expectError == nil && err != nil { - t.Fatalf("expected no error, got: %v", err) - } if tc.expectRenewal { - t.Fatalf("expected at least one renewal, got donech result: %v", err) + t.Fatal("expected at least one renewal") } } }) diff --git a/api/sys_raft.go b/api/sys_raft.go index 7dc10959ac32e..cbf3a2020038d 100644 --- a/api/sys_raft.go +++ b/api/sys_raft.go @@ -6,6 +6,7 @@ import ( "context" "encoding/json" "errors" + "fmt" "io" "io/ioutil" "net/http" @@ -13,6 +14,7 @@ import ( "time" "github.com/hashicorp/go-secure-stdlib/parseutil" + "github.com/hashicorp/vault/sdk/helper/consts" "github.com/mitchellh/mapstructure" ) @@ -130,25 +132,87 @@ func (c *Sys) RaftJoin(opts *RaftJoinRequest) (*RaftJoinResponse, error) { return &result, err } -// RaftSnapshot is a thin wrapper around RaftSnapshotWithContext -func (c *Sys) RaftSnapshot(snapWriter io.Writer) error { - ctx, cancelFunc := context.WithCancel(context.Background()) - defer cancelFunc() - - return c.RaftSnapshotWithContext(ctx, snapWriter) -} - -// RaftSnapshotWithContext invokes the API that takes the snapshot of the raft cluster and +// RaftSnapshot invokes the API that takes the snapshot of the raft cluster and // writes it to the supplied io.Writer. -func (c *Sys) RaftSnapshotWithContext(ctx context.Context, snapWriter io.Writer) error { +func (c *Sys) RaftSnapshot(snapWriter io.Writer) error { r := c.c.NewRequest("GET", "/v1/sys/storage/raft/snapshot") r.URL.RawQuery = r.Params.Encode() - resp, err := c.c.httpRequestWithContext(ctx, r) + req, err := http.NewRequest(http.MethodGet, r.URL.RequestURI(), nil) if err != nil { return err } - defer resp.Body.Close() + + req.URL.User = r.URL.User + req.URL.Scheme = r.URL.Scheme + req.URL.Host = r.URL.Host + req.Host = r.URL.Host + + if r.Headers != nil { + for header, vals := range r.Headers { + for _, val := range vals { + req.Header.Add(header, val) + } + } + } + + if len(r.ClientToken) != 0 { + req.Header.Set(consts.AuthHeaderName, r.ClientToken) + } + + if len(r.WrapTTL) != 0 { + req.Header.Set("X-Vault-Wrap-TTL", r.WrapTTL) + } + + if len(r.MFAHeaderVals) != 0 { + for _, mfaHeaderVal := range r.MFAHeaderVals { + req.Header.Add("X-Vault-MFA", mfaHeaderVal) + } + } + + if r.PolicyOverride { + req.Header.Set("X-Vault-Policy-Override", "true") + } + + // Avoiding the use of RawRequestWithContext which reads the response body + // to determine if the body contains error message. + var result *Response + resp, err := c.c.config.HttpClient.Do(req) + if err != nil { + return err + } + + if resp == nil { + return nil + } + + // Check for a redirect, only allowing for a single redirect + if resp.StatusCode == 301 || resp.StatusCode == 302 || resp.StatusCode == 307 { + // Parse the updated location + respLoc, err := resp.Location() + if err != nil { + return err + } + + // Ensure a protocol downgrade doesn't happen + if req.URL.Scheme == "https" && respLoc.Scheme != "https" { + return fmt.Errorf("redirect would cause protocol downgrade") + } + + // Update the request + req.URL = respLoc + + // Retry the request + resp, err = c.c.config.HttpClient.Do(req) + if err != nil { + return err + } + } + + result = &Response{Response: resp} + if err := result.Error(); err != nil { + return err + } // Make sure that the last file in the archive, SHA256SUMS.sealed, is present // and non-empty. This is to catch cases where the snapshot failed midstream, @@ -207,26 +271,20 @@ func (c *Sys) RaftSnapshotWithContext(ctx context.Context, snapWriter io.Writer) return nil } -// RaftSnapshotRestore is a thin wrapper around RaftSnapshotRestoreWithContext -func (c *Sys) RaftSnapshotRestore(snapReader io.Reader, force bool) error { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - return c.RaftSnapshotRestoreWithContext(ctx, snapReader, force) -} - -// RaftSnapshotRestoreWithContext reads the snapshot from the io.Reader and installs that +// RaftSnapshotRestore reads the snapshot from the io.Reader and installs that // snapshot, returning the cluster to the state defined by it. -func (c *Sys) RaftSnapshotRestoreWithContext(ctx context.Context, snapReader io.Reader, force bool) error { +func (c *Sys) RaftSnapshotRestore(snapReader io.Reader, force bool) error { path := "/v1/sys/storage/raft/snapshot" if force { path = "/v1/sys/storage/raft/snapshot-force" } + r := c.c.NewRequest("POST", path) - r := c.c.NewRequest(http.MethodPost, path) r.Body = snapReader - resp, err := c.c.httpRequestWithContext(ctx, r) + ctx, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() + resp, err := c.c.RawRequestWithContext(ctx, r) if err != nil { return err } diff --git a/builtin/credential/ldap/backend_test.go b/builtin/credential/ldap/backend_test.go index c53fc7819711e..c58fa2f2d10a7 100644 --- a/builtin/credential/ldap/backend_test.go +++ b/builtin/credential/ldap/backend_test.go @@ -1205,6 +1205,7 @@ func TestLdapAuthBackend_ConfigUpgrade(t *testing.T) { CaseSensitiveNames: falseBool, UsePre111GroupCNBehavior: new(bool), RequestTimeout: cfg.RequestTimeout, + UsernameAsAlias: false, }, } diff --git a/builtin/credential/ldap/path_login.go b/builtin/credential/ldap/path_login.go index eea2006e7f428..49c0cfe9d8fb1 100644 --- a/builtin/credential/ldap/path_login.go +++ b/builtin/credential/ldap/path_login.go @@ -103,6 +103,10 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew }, } + if cfg.UsernameAsAlias { + auth.Alias.Name = username + } + cfg.PopulateTokenAuth(auth) // Add in configured policies from mappings diff --git a/builtin/logical/database/backend_test.go b/builtin/logical/database/backend_test.go index 447ab7d66a5b5..6d42fcbfd6e35 100644 --- a/builtin/logical/database/backend_test.go +++ b/builtin/logical/database/backend_test.go @@ -47,11 +47,8 @@ func getCluster(t *testing.T) (*vault.TestCluster, logical.SystemView) { sys := vault.TestDynamicSystemView(cores[0].Core, nil) vault.TestAddTestPlugin(t, cores[0].Core, "postgresql-database-plugin", consts.PluginTypeDatabase, "TestBackend_PluginMain_Postgres", []string{}, "") - vault.TestAddTestPlugin(t, cores[0].Core, "postgresql-database-plugin-muxed", consts.PluginTypeDatabase, "TestBackend_PluginMain_PostgresMultiplexed", []string{}, "") vault.TestAddTestPlugin(t, cores[0].Core, "mongodb-database-plugin", consts.PluginTypeDatabase, "TestBackend_PluginMain_Mongo", []string{}, "") - vault.TestAddTestPlugin(t, cores[0].Core, "mongodb-database-plugin-muxed", consts.PluginTypeDatabase, "TestBackend_PluginMain_MongoMultiplexed", []string{}, "") vault.TestAddTestPlugin(t, cores[0].Core, "mongodbatlas-database-plugin", consts.PluginTypeDatabase, "TestBackend_PluginMain_MongoAtlas", []string{}, "") - vault.TestAddTestPlugin(t, cores[0].Core, "mongodbatlas-database-plugin-muxed", consts.PluginTypeDatabase, "TestBackend_PluginMain_MongoAtlasMultiplexed", []string{}, "") return cluster, sys } @@ -69,14 +66,6 @@ func TestBackend_PluginMain_Postgres(t *testing.T) { v5.Serve(dbType.(v5.Database)) } -func TestBackend_PluginMain_PostgresMultiplexed(t *testing.T) { - if os.Getenv(pluginutil.PluginVaultVersionEnv) == "" { - return - } - - v5.ServeMultiplex(postgresql.New) -} - func TestBackend_PluginMain_Mongo(t *testing.T) { if os.Getenv(pluginutil.PluginVaultVersionEnv) == "" { return @@ -90,14 +79,6 @@ func TestBackend_PluginMain_Mongo(t *testing.T) { v5.Serve(dbType.(v5.Database)) } -func TestBackend_PluginMain_MongoMultiplexed(t *testing.T) { - if os.Getenv(pluginutil.PluginVaultVersionEnv) == "" { - return - } - - v5.ServeMultiplex(mongodb.New) -} - func TestBackend_PluginMain_MongoAtlas(t *testing.T) { if os.Getenv(pluginutil.PluginUnwrapTokenEnv) == "" { return @@ -111,14 +92,6 @@ func TestBackend_PluginMain_MongoAtlas(t *testing.T) { v5.Serve(dbType.(v5.Database)) } -func TestBackend_PluginMain_MongoAtlasMultiplexed(t *testing.T) { - if os.Getenv(pluginutil.PluginUnwrapTokenEnv) == "" { - return - } - - v5.ServeMultiplex(mongodbatlas.New) -} - func TestBackend_RoleUpgrade(t *testing.T) { storage := &logical.InmemStorage{} backend := &databaseBackend{} diff --git a/builtin/logical/database/mockv5.go b/builtin/logical/database/mockv5.go index 632cfb38e037f..84db3eb19694a 100644 --- a/builtin/logical/database/mockv5.go +++ b/builtin/logical/database/mockv5.go @@ -36,13 +36,6 @@ func RunV5() error { return nil } -// Run instantiates a MongoDB object, and runs the RPC server for the plugin -func RunV6Multiplexed() error { - v5.ServeMultiplex(New) - - return nil -} - func (m MockDatabaseV5) Initialize(ctx context.Context, req v5.InitializeRequest) (v5.InitializeResponse, error) { log.Default().Info("Initialize called", "req", req) diff --git a/builtin/logical/database/versioning_large_test.go b/builtin/logical/database/versioning_large_test.go index 723f9dd808def..db2941308507e 100644 --- a/builtin/logical/database/versioning_large_test.go +++ b/builtin/logical/database/versioning_large_test.go @@ -24,7 +24,6 @@ func TestPlugin_lifecycle(t *testing.T) { vault.TestAddTestPlugin(t, cluster.Cores[0].Core, "mock-v4-database-plugin", consts.PluginTypeDatabase, "TestBackend_PluginMain_MockV4", []string{}, "") vault.TestAddTestPlugin(t, cluster.Cores[0].Core, "mock-v5-database-plugin", consts.PluginTypeDatabase, "TestBackend_PluginMain_MockV5", []string{}, "") - vault.TestAddTestPlugin(t, cluster.Cores[0].Core, "mock-v6-database-plugin-muxed", consts.PluginTypeDatabase, "TestBackend_PluginMain_MockV6Multiplexed", []string{}, "") config := logical.TestBackendConfig() config.StorageView = &logical.InmemStorage{} @@ -262,14 +261,6 @@ func TestBackend_PluginMain_MockV5(t *testing.T) { RunV5() } -func TestBackend_PluginMain_MockV6Multiplexed(t *testing.T) { - if os.Getenv(pluginutil.PluginVaultVersionEnv) == "" { - return - } - - RunV6Multiplexed() -} - func assertNoRespData(t *testing.T, resp *logical.Response) { t.Helper() if resp != nil && len(resp.Data) > 0 { diff --git a/builtin/logical/pki/ca_util.go b/builtin/logical/pki/ca_util.go index be1890984a393..93aa48f1e4c92 100644 --- a/builtin/logical/pki/ca_util.go +++ b/builtin/logical/pki/ca_util.go @@ -4,6 +4,7 @@ import ( "context" "crypto/ecdsa" "crypto/rsa" + "fmt" "time" "golang.org/x/crypto/ed25519" @@ -53,7 +54,7 @@ func (b *backend) getGenerationParams(ctx context.Context, return } // Determine key type and key bits from the managed public key - withManagedPKIKey(ctx, b, keyId, mountPoint, func(ctx context.Context, key logical.ManagedSigningKey) error { + err = withManagedPKIKey(ctx, b, keyId, mountPoint, func(ctx context.Context, key logical.ManagedSigningKey) error { pubKey, err := key.GetPublicKey(ctx) if err != nil { return err @@ -66,9 +67,15 @@ func (b *backend) getGenerationParams(ctx context.Context, keyType = "ec" case *ed25519.PublicKey: keyType = "ed25519" + default: + return fmt.Errorf("unsupported public key: %#v", pubKey) } return nil }) + if err != nil { + errorResp = logical.ErrorResponse("failed to lookup public key from managed key: %s", err.Error()) + return + } } role = &roleEntry{ diff --git a/builtin/logical/pki/fields.go b/builtin/logical/pki/fields.go index 8618cf89b0196..aafae04dd498b 100644 --- a/builtin/logical/pki/fields.go +++ b/builtin/logical/pki/fields.go @@ -107,9 +107,11 @@ email addresses.`, fields["serial_number"] = &framework.FieldSchema{ Type: framework.TypeString, - Description: `The requested serial number, if any. If you want -more than one, specify alternative names in -the alt_names map using OID 2.5.4.5.`, + Description: `The Subject's requested serial number, if any. +See RFC 4519 Section 2.31 'serialNumber' for a description of this field. +If you want more than one, specify alternative names in the alt_names +map using OID 2.5.4.5. This has no impact on the final certificate's +Serial Number field.`, } fields["ttl"] = &framework.FieldSchema{ @@ -127,7 +129,7 @@ be larger than the role max TTL.`, fields["not_after"] = &framework.FieldSchema{ Type: framework.TypeString, Description: `Set the not after field of the certificate with specified date value. - The value format should be given in UTC format YYYY-MM-ddTHH:MM:SSZ`, +The value format should be given in UTC format YYYY-MM-ddTHH:MM:SSZ`, } return fields @@ -231,14 +233,16 @@ this value.`, fields["serial_number"] = &framework.FieldSchema{ Type: framework.TypeString, - Description: `The requested serial number, if any. If you want -more than one, specify alternative names in -the alt_names map using OID 2.5.4.5.`, + Description: `The Subject's requested serial number, if any. +See RFC 4519 Section 2.31 'serialNumber' for a description of this field. +If you want more than one, specify alternative names in the alt_names +map using OID 2.5.4.5. This has no impact on the final certificate's +Serial Number field.`, } fields["not_after"] = &framework.FieldSchema{ Type: framework.TypeString, Description: `Set the not after field of the certificate with specified date value. - The value format should be given in UTC format YYYY-MM-ddTHH:MM:SSZ`, +The value format should be given in UTC format YYYY-MM-ddTHH:MM:SSZ`, } return fields diff --git a/builtin/logical/pki/path_fetch.go b/builtin/logical/pki/path_fetch.go index 6bacd4adf58f7..634964e9dcb69 100644 --- a/builtin/logical/pki/path_fetch.go +++ b/builtin/logical/pki/path_fetch.go @@ -320,9 +320,11 @@ Fetch a CA, CRL, CA Chain, or non-revoked certificate. ` const pathFetchHelpDesc = ` -This allows certificates to be fetched. If using the fetch/ prefix any non-revoked certificate can be fetched. +This allows certificates to be fetched. Use /cert/:serial for JSON responses. Using "ca" or "crl" as the value fetches the appropriate information in DER encoding. Add "/pem" to either to get PEM encoding. Using "ca_chain" as the value fetches the certificate authority trust chain in PEM encoding. + +Otherwise, specify a serial number to fetch the specified certificate. Add "/raw" to get just the certificate in DER form, "/raw/pem" to get the PEM encoded certificate. ` diff --git a/builtin/logical/pki/path_roles.go b/builtin/logical/pki/path_roles.go index e788c944bc6f1..497ed74d0737b 100644 --- a/builtin/logical/pki/path_roles.go +++ b/builtin/logical/pki/path_roles.go @@ -65,7 +65,7 @@ set, defaults to the system maximum lease TTL.`, "allow_localhost": { Type: framework.TypeBool, Default: true, - Description: `Whether to allow "localhost" and "localdoamin" + Description: `Whether to allow "localhost" and "localdomain" as a valid common name in a request, independent of allowed_domains value.`, DisplayAttrs: &framework.DisplayAttributes{ Value: true, @@ -583,7 +583,6 @@ func (b *backend) pathRoleList(ctx context.Context, req *logical.Request, d *fra func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { var err error - var resp *logical.Response name := data.Get("name").(string) entry := &roleEntry{ @@ -645,10 +644,6 @@ func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data // no_store implies generate_lease := false if entry.NoStore { *entry.GenerateLease = false - if data.Get("generate_lease").(bool) { - resp = &logical.Response{} - resp.AddWarning("mutually exclusive values no_store=true and generate_lease=true were both specified; no_store=true takes priority") - } } else { *entry.GenerateLease = data.Get("generate_lease").(bool) } @@ -699,7 +694,7 @@ func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data return nil, err } - return resp, nil + return nil, nil } func parseKeyUsages(input []string) int { diff --git a/builtin/logical/transit/path_encrypt.go b/builtin/logical/transit/path_encrypt.go index 5e27b549d0097..7b162f895ac4f 100644 --- a/builtin/logical/transit/path_encrypt.go +++ b/builtin/logical/transit/path_encrypt.go @@ -261,18 +261,17 @@ func (b *backend) pathEncryptWrite(ctx context.Context, req *logical.Request, d return logical.ErrorResponse("missing batch input to process"), logical.ErrInvalidRequest } } else { - valueRaw, ok := d.Raw["plaintext"] - if !ok { - return logical.ErrorResponse("missing plaintext to encrypt"), logical.ErrInvalidRequest + valueRaw, ok, err := d.GetOkErr("plaintext") + if err != nil { + return nil, err } - plaintext, ok := valueRaw.(string) if !ok { - return logical.ErrorResponse("expected plaintext of type 'string', got unconvertible type '%T'", valueRaw), logical.ErrInvalidRequest + return logical.ErrorResponse("missing plaintext to encrypt"), logical.ErrInvalidRequest } batchInputItems = make([]BatchRequestItem, 1) batchInputItems[0] = BatchRequestItem{ - Plaintext: plaintext, + Plaintext: valueRaw.(string), Context: d.Get("context").(string), Nonce: d.Get("nonce").(string), KeyVersion: d.Get("key_version").(int), diff --git a/builtin/logical/transit/path_encrypt_test.go b/builtin/logical/transit/path_encrypt_test.go index d9a7081ae4203..734a92524b558 100644 --- a/builtin/logical/transit/path_encrypt_test.go +++ b/builtin/logical/transit/path_encrypt_test.go @@ -30,15 +30,11 @@ func TestTransit_MissingPlaintext(t *testing.T) { t.Fatalf("err:%v resp:%#v", err, resp) } - encData := map[string]interface{}{ - "plaintext": nil, - } - encReq := &logical.Request{ Operation: logical.UpdateOperation, Path: "encrypt/existing_key", Storage: s, - Data: encData, + Data: map[string]interface{}{}, } resp, err = b.HandleRequest(context.Background(), encReq) if resp == nil || !resp.IsError() { diff --git a/builtin/logical/transit/path_hash.go b/builtin/logical/transit/path_hash.go index 2b894f00ef238..51ca37daa2317 100644 --- a/builtin/logical/transit/path_hash.go +++ b/builtin/logical/transit/path_hash.go @@ -63,16 +63,15 @@ Defaults to "sha2-256".`, } func (b *backend) pathHashWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { - rawInput, ok := d.Raw["input"] - if !ok { - return logical.ErrorResponse("input missing"), logical.ErrInvalidRequest + rawInput, ok, err := d.GetOkErr("input") + if err != nil { + return nil, err } - - inputB64, ok := rawInput.(string) if !ok { - return logical.ErrorResponse("expected input of type 'string', got unconvertible type '%T'", rawInput), logical.ErrInvalidRequest + return logical.ErrorResponse("input missing"), logical.ErrInvalidRequest } + inputB64 := rawInput.(string) format := d.Get("format").(string) algorithm := d.Get("urlalgorithm").(string) if algorithm == "" { diff --git a/builtin/logical/transit/path_hash_test.go b/builtin/logical/transit/path_hash_test.go index 0492cf03a42dc..3e5dce95c2999 100644 --- a/builtin/logical/transit/path_hash_test.go +++ b/builtin/logical/transit/path_hash_test.go @@ -86,7 +86,7 @@ func TestTransit_Hash(t *testing.T) { doRequest(req, false, "98rFrYMEIqVAizamCmBiBoe+GAdlo+KJW8O9vYV8nggkbIMGTU42EvDLkn8+rSCEE6uYYkv3sGF68PA/YggJdg==") // Test bad input/format/algorithm - req.Data["input"] = nil + delete(req.Data, "input") doRequest(req, true, "") req.Data["input"] = "dGhlIHF1aWNrIGJyb3duIGZveA==" diff --git a/builtin/logical/transit/path_trim.go b/builtin/logical/transit/path_trim.go index fd01b60a2cec3..60d6ef9dda6d8 100644 --- a/builtin/logical/transit/path_trim.go +++ b/builtin/logical/transit/path_trim.go @@ -55,14 +55,14 @@ func (b *backend) pathTrimUpdate() framework.OperationFunc { } defer p.Unlock() - minAvailableVersionRaw, ok := d.Raw["min_available_version"] - if !ok { - return logical.ErrorResponse("missing min_available_version"), nil + minAvailableVersionRaw, ok, err := d.GetOkErr("min_available_version") + if err != nil { + return nil, err } - minAvailableVersion, ok := minAvailableVersionRaw.(int) if !ok { - return logical.ErrorResponse("expected min_available_version of type 'int', got unconvertible type '%T'", minAvailableVersionRaw), logical.ErrInvalidRequest + return logical.ErrorResponse("missing min_available_version"), nil } + minAvailableVersion := minAvailableVersionRaw.(int) originalMinAvailableVersion := p.MinAvailableVersion diff --git a/changelog/14074.txt b/changelog/14074.txt index 9d126424828f9..2e553c8956107 100644 --- a/changelog/14074.txt +++ b/changelog/14074.txt @@ -1,3 +1,3 @@ ```release-note:bug -secrets/transit: Return an error if any required parameter is missing or nil. Do not encrypt nil plaintext as if it was an empty string. +secrets/transit: Return an error if any required parameter is missing. ``` diff --git a/changelog/14217.txt b/changelog/14217.txt deleted file mode 100644 index de42fca36b058..0000000000000 --- a/changelog/14217.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -sdk: Change OpenAPI code generator to extract request objects into /components/schemas and reference them by name. -``` diff --git a/changelog/14269.txt b/changelog/14269.txt deleted file mode 100644 index 529b7c6264299..0000000000000 --- a/changelog/14269.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug - api/sys/raft: Update RaftSnapshotRestore to use net/http client allowing bodies larger than allocated memory to be streamed -``` diff --git a/changelog/14292.txt b/changelog/14292.txt deleted file mode 100644 index 98d48f9d4fcd5..0000000000000 --- a/changelog/14292.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secrets/pki: Warn when `generate_lease` and `no_store` are both set to `true` on requests. -``` diff --git a/changelog/14324.txt b/changelog/14324.txt new file mode 100644 index 0000000000000..2932b2323cd10 --- /dev/null +++ b/changelog/14324.txt @@ -0,0 +1,3 @@ +```release-note:improvement +auth/ldap: Add username_as_alias configurable to change how aliases are named +``` diff --git a/changelog/14389.txt b/changelog/14389.txt deleted file mode 100644 index 56ee8c47aacfe..0000000000000 --- a/changelog/14389.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -website/docs: added a link to an Enigma secret plugin. -``` diff --git a/changelog/14489.txt b/changelog/14489.txt new file mode 100644 index 0000000000000..014d0a50f99d0 --- /dev/null +++ b/changelog/14489.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: Fixes caching issue on kv new version create +``` diff --git a/changelog/14493.txt b/changelog/14493.txt new file mode 100644 index 0000000000000..cb98314f514d8 --- /dev/null +++ b/changelog/14493.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: Fixes horizontal bar chart hover issue when filtering namespaces and mounts +``` \ No newline at end of file diff --git a/changelog/14543.txt b/changelog/14543.txt new file mode 100644 index 0000000000000..649d1e72cc860 --- /dev/null +++ b/changelog/14543.txt @@ -0,0 +1,3 @@ +```release-note:bug +identity/token: Fixes a bug where duplicate public keys could appear in the .well-known JWKS +``` diff --git a/changelog/14545.txt b/changelog/14545.txt new file mode 100644 index 0000000000000..6b3422132b0df --- /dev/null +++ b/changelog/14545.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: Fixes issue with correct auth method not selected when logging out from OIDC or JWT methods +``` \ No newline at end of file diff --git a/changelog/14551.txt b/changelog/14551.txt new file mode 100644 index 0000000000000..47ef9add25b3b --- /dev/null +++ b/changelog/14551.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: Fix issue where UI incorrectly handled API errors when mounting backends +``` \ No newline at end of file diff --git a/changelog/14622.txt b/changelog/14622.txt new file mode 100644 index 0000000000000..289756a539027 --- /dev/null +++ b/changelog/14622.txt @@ -0,0 +1,3 @@ +```release-note:bug +replication (enterprise): fix panic due to missing entity during invalidation of local aliases. +``` \ No newline at end of file diff --git a/changelog/14670.txt b/changelog/14670.txt new file mode 100644 index 0000000000000..3af761ad83a00 --- /dev/null +++ b/changelog/14670.txt @@ -0,0 +1,3 @@ +```release-note:improvement +cli/vault: warn when policy name contains upper-case letter +``` \ No newline at end of file diff --git a/changelog/14704.txt b/changelog/14704.txt new file mode 100644 index 0000000000000..e5663e1c9d8d6 --- /dev/null +++ b/changelog/14704.txt @@ -0,0 +1,3 @@ +```release-note:bug +core: Fix panic for help request URL paths without /v1/ prefix +``` \ No newline at end of file diff --git a/changelog/mount-migration.txt b/changelog/mount-migration.txt new file mode 100644 index 0000000000000..1e0eec36bd63e --- /dev/null +++ b/changelog/mount-migration.txt @@ -0,0 +1,3 @@ +```release-note:feature +**Mount Migration**: Vault supports moving secrets and auth mounts both within and across namespaces. +``` \ No newline at end of file diff --git a/command/auth_enable.go b/command/auth_enable.go index a23c7989f7a13..eb12589c44179 100644 --- a/command/auth_enable.go +++ b/command/auth_enable.go @@ -117,15 +117,15 @@ func (c *AuthEnableCommand) Flags() *FlagSets { f.StringSliceVar(&StringSliceVar{ Name: flagNameAuditNonHMACRequestKeys, Target: &c.flagAuditNonHMACRequestKeys, - Usage: "Key that will not be HMAC'd by audit devices in the request data object. " + - "To specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit " + + "devices in the request data object.", }) f.StringSliceVar(&StringSliceVar{ Name: flagNameAuditNonHMACResponseKeys, Target: &c.flagAuditNonHMACResponseKeys, - Usage: "Key that will not be HMAC'd by audit devices in the response data object. " + - "To specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit " + + "devices in the response data object.", }) f.StringVar(&StringVar{ @@ -137,15 +137,15 @@ func (c *AuthEnableCommand) Flags() *FlagSets { f.StringSliceVar(&StringSliceVar{ Name: flagNamePassthroughRequestHeaders, Target: &c.flagPassthroughRequestHeaders, - Usage: "Request header value that will be sent to the plugin. To specify multiple " + - "values, specify this flag multiple times.", + Usage: "Comma-separated string or list of request header values that " + + "will be sent to the plugin", }) f.StringSliceVar(&StringSliceVar{ Name: flagNameAllowedResponseHeaders, Target: &c.flagAllowedResponseHeaders, - Usage: "Response header value that plugins will be allowed to set. To specify multiple " + - "values, specify this flag multiple times.", + Usage: "Comma-separated string or list of response header values that " + + "plugins will be allowed to set", }) f.StringVar(&StringVar{ diff --git a/command/auth_tune.go b/command/auth_tune.go index 9c3a963efc378..a3ad65579cdcf 100644 --- a/command/auth_tune.go +++ b/command/auth_tune.go @@ -62,15 +62,15 @@ func (c *AuthTuneCommand) Flags() *FlagSets { f.StringSliceVar(&StringSliceVar{ Name: flagNameAuditNonHMACRequestKeys, Target: &c.flagAuditNonHMACRequestKeys, - Usage: "Key that will not be HMAC'd by audit devices in the request data " + - "object. To specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit " + + "devices in the request data object.", }) f.StringSliceVar(&StringSliceVar{ Name: flagNameAuditNonHMACResponseKeys, Target: &c.flagAuditNonHMACResponseKeys, - Usage: "Key that will not be HMAC'd by audit devices in the response data " + - "object. To specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit " + + "devices in the response data object.", }) f.DurationVar(&DurationVar{ @@ -112,15 +112,15 @@ func (c *AuthTuneCommand) Flags() *FlagSets { f.StringSliceVar(&StringSliceVar{ Name: flagNamePassthroughRequestHeaders, Target: &c.flagPassthroughRequestHeaders, - Usage: "Request header value that will be sent to the plugin. To specify " + - "multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of request header values that " + + "will be sent to the plugin", }) f.StringSliceVar(&StringSliceVar{ Name: flagNameAllowedResponseHeaders, Target: &c.flagAllowedResponseHeaders, - Usage: "Response header value that plugins will be allowed to set. To specify " + - "multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of response header values that " + + "plugins will be allowed to set", }) f.StringMapVar(&StringMapVar{ diff --git a/command/debug.go b/command/debug.go index ef39001be9952..f981b18478f64 100644 --- a/command/debug.go +++ b/command/debug.go @@ -20,7 +20,7 @@ import ( "github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/logging" "github.com/hashicorp/vault/sdk/version" - "github.com/mholt/archiver" + "github.com/mholt/archiver/v3" "github.com/mitchellh/cli" "github.com/oklog/run" "github.com/posener/complete" diff --git a/command/debug_test.go b/command/debug_test.go index 7c46eb5bd6717..a1489cec4bef9 100644 --- a/command/debug_test.go +++ b/command/debug_test.go @@ -12,7 +12,7 @@ import ( "time" "github.com/hashicorp/vault/api" - "github.com/mholt/archiver" + "github.com/mholt/archiver/v3" "github.com/mitchellh/cli" ) diff --git a/command/policy_write.go b/command/policy_write.go index 50a1ccf4ccce7..538414bc50fa8 100644 --- a/command/policy_write.go +++ b/command/policy_write.go @@ -91,7 +91,8 @@ func (c *PolicyWriteCommand) Run(args []string) int { } // Policies are normalized to lowercase - name := strings.TrimSpace(strings.ToLower(args[0])) + policyName := args[0] + formattedName := strings.TrimSpace(strings.ToLower(policyName)) path := strings.TrimSpace(args[1]) // Get the policy contents, either from stdin of a file @@ -119,11 +120,15 @@ func (c *PolicyWriteCommand) Run(args []string) int { } rules := buf.String() - if err := client.Sys().PutPolicy(name, rules); err != nil { + if err := client.Sys().PutPolicy(formattedName, rules); err != nil { c.UI.Error(fmt.Sprintf("Error uploading policy: %s", err)) return 2 } - c.UI.Output(fmt.Sprintf("Success! Uploaded policy: %s", name)) + if policyName != formattedName { + c.UI.Warn(fmt.Sprintf("Policy name was converted from \"%s\" to \"%s\"", policyName, formattedName)) + } + + c.UI.Output(fmt.Sprintf("Success! Uploaded policy: %s", formattedName)) return 0 } diff --git a/command/secrets_enable.go b/command/secrets_enable.go index 91144c156639f..5b9c49ebe5810 100644 --- a/command/secrets_enable.go +++ b/command/secrets_enable.go @@ -125,15 +125,15 @@ func (c *SecretsEnableCommand) Flags() *FlagSets { f.StringSliceVar(&StringSliceVar{ Name: flagNameAuditNonHMACRequestKeys, Target: &c.flagAuditNonHMACRequestKeys, - Usage: "Key that will not be HMAC'd by audit devices in the request data object. " + - "To specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit " + + "devices in the request data object.", }) f.StringSliceVar(&StringSliceVar{ Name: flagNameAuditNonHMACResponseKeys, Target: &c.flagAuditNonHMACResponseKeys, - Usage: "Key that will not be HMAC'd by audit devices in the response data object. " + - "To specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit " + + "devices in the response data object.", }) f.StringVar(&StringVar{ @@ -145,15 +145,15 @@ func (c *SecretsEnableCommand) Flags() *FlagSets { f.StringSliceVar(&StringSliceVar{ Name: flagNamePassthroughRequestHeaders, Target: &c.flagPassthroughRequestHeaders, - Usage: "Request header value that will be sent to the plugins. To specify multiple " + - "values, specify this flag multiple times.", + Usage: "Comma-separated string or list of request header values that " + + "will be sent to the plugins", }) f.StringSliceVar(&StringSliceVar{ Name: flagNameAllowedResponseHeaders, Target: &c.flagAllowedResponseHeaders, - Usage: "Response header value that plugins will be allowed to set. To specify multiple " + - "values, specify this flag multiple times.", + Usage: "Comma-separated string or list of response header values that " + + "plugins will be allowed to set", }) f.BoolVar(&BoolVar{ diff --git a/command/secrets_tune.go b/command/secrets_tune.go index 002bdd9ea096c..93d656a7c71ee 100644 --- a/command/secrets_tune.go +++ b/command/secrets_tune.go @@ -62,15 +62,15 @@ func (c *SecretsTuneCommand) Flags() *FlagSets { f.StringSliceVar(&StringSliceVar{ Name: flagNameAuditNonHMACRequestKeys, Target: &c.flagAuditNonHMACRequestKeys, - Usage: "Key that will not be HMAC'd by audit devices in the request data " + - "object. To specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit " + + "devices in the request data object.", }) f.StringSliceVar(&StringSliceVar{ Name: flagNameAuditNonHMACResponseKeys, Target: &c.flagAuditNonHMACResponseKeys, - Usage: "Key that will not be HMAC'd by audit devices in the response data " + - "object. To specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit " + + "devices in the response data object.", }) f.DurationVar(&DurationVar{ @@ -112,15 +112,15 @@ func (c *SecretsTuneCommand) Flags() *FlagSets { f.StringSliceVar(&StringSliceVar{ Name: flagNamePassthroughRequestHeaders, Target: &c.flagPassthroughRequestHeaders, - Usage: "Request header value that will be sent to the plugin. To specify " + - "multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of request header values that " + + "will be sent to the plugin", }) f.StringSliceVar(&StringSliceVar{ Name: flagNameAllowedResponseHeaders, Target: &c.flagAllowedResponseHeaders, - Usage: "Response header value that plugins will be allowed to set. To " + - "specify multiple values, specify this flag multiple times.", + Usage: "Comma-separated string or list of response header values that " + + "plugins will be allowed to set", }) f.StringMapVar(&StringMapVar{ diff --git a/go.mod b/go.mod index 9b7549a7580e6..46dacf14fa1b8 100644 --- a/go.mod +++ b/go.mod @@ -118,7 +118,7 @@ require ( github.com/hashicorp/vault/api v1.4.1 github.com/hashicorp/vault/api/auth/approle v0.1.0 github.com/hashicorp/vault/api/auth/userpass v0.1.0 - github.com/hashicorp/vault/sdk v0.4.1 + github.com/hashicorp/vault/sdk v0.4.2-0.20220324144656-cdb85cfca8f5 github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab github.com/jcmturner/gokrb5/v8 v8.4.2 github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f @@ -130,7 +130,7 @@ require ( github.com/lib/pq v1.10.3 github.com/mattn/go-colorable v0.1.12 github.com/mattn/go-isatty v0.0.14 - github.com/mholt/archiver v3.1.1+incompatible + github.com/mholt/archiver/v3 v3.5.1 github.com/michaelklishin/rabbit-hole/v2 v2.11.0 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/mitchellh/cli v1.1.2 @@ -216,6 +216,7 @@ require ( github.com/Microsoft/hcsshim v0.9.0 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/StackExchange/wmi v1.2.1 // indirect + github.com/andybalholm/brotli v1.0.1 // indirect github.com/apache/arrow/go/arrow v0.0.0-20210818145353-234c94e4ce64 // indirect github.com/aws/aws-sdk-go-v2 v1.8.0 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.3.2 // indirect @@ -252,7 +253,7 @@ require ( github.com/docker/cli v20.10.9+incompatible // indirect github.com/docker/distribution v2.7.1+incompatible // indirect github.com/docker/go-units v0.4.0 // indirect - github.com/dsnet/compress v0.0.1 // indirect + github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect github.com/gabriel-vasile/mimetype v1.3.1 // indirect @@ -304,6 +305,7 @@ require ( github.com/jstemmer/go-junit-report v0.9.1 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.13.6 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect github.com/linode/linodego v0.7.1 // indirect github.com/mattn/go-ieproxy v0.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect diff --git a/go.sum b/go.sum index f02a646f80a92..480c75e0812ba 100644 --- a/go.sum +++ b/go.sum @@ -190,6 +190,8 @@ github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f h1:oRD github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 h1:nWDRPCyCltiTsANwC/n3QZH7Vww33Npq9MKqlwRzI/c= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= +github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/arrow v0.0.0-20210818145353-234c94e4ce64 h1:ZsPrlYPY/v1PR7pGrmYD/rq5BFiSPalH8i9eEkSfnnI= github.com/apache/arrow/go/arrow v0.0.0-20210818145353-234c94e4ce64/go.mod h1:2qMFB56yOP3KzkB3PbYZ4AlUFg3a88F67TIx5lB/WwY= @@ -496,8 +498,8 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= -github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M= github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= @@ -1095,12 +1097,15 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -1160,8 +1165,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= -github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU= -github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= +github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= +github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/michaelklishin/rabbit-hole/v2 v2.11.0 h1:v/Jtrr0FY82pITY3VFhIDaXCllPCTGpGCIM2U505Row= github.com/michaelklishin/rabbit-hole/v2 v2.11.0/go.mod h1:tVpCFikY4BB40a436H81PRVybvtNwFwWI3oCflUTec8= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -1249,6 +1254,7 @@ github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nwaples/rardecode v1.1.2 h1:Cj0yZY6T1Zx1R7AhTbyGSALm44/Mmq+BAPc4B/p/d3M= github.com/nwaples/rardecode v1.1.2/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -1346,6 +1352,7 @@ github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.8 h1:ieHkV+i2BRzngO4Wd/3HGowuZStgq6QkPsD1eolNAO4= github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= @@ -1529,7 +1536,8 @@ github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDH github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= diff --git a/helper/constants/fips.go b/helper/constants/fips.go index d384e83e8433c..2a9f7ee7aae6b 100644 --- a/helper/constants/fips.go +++ b/helper/constants/fips.go @@ -1,4 +1,4 @@ -//go:build !fips_140_3 +//go:build !fips package constants diff --git a/helper/constants/fips_build_check.go b/helper/constants/fips_build_check.go new file mode 100644 index 0000000000000..aee3d0edba690 --- /dev/null +++ b/helper/constants/fips_build_check.go @@ -0,0 +1,38 @@ +//go:build (!fips && (fips_140_2 || fips_140_3)) || (fips && !fips_140_2 && !fips_140_3) || (fips_140_2 && fips_140_3) + +package constants + +import "C" + +// This function is the equivalent of an external (CGo) function definition, +// without implementation in any imported or built library. This results in +// a linker err if the above build constraints are satisfied: +// +// /home/cipherboy/GitHub/cipherboy/vault-enterprise/helper/constants/fips_build_check.go:10: undefined reference to `github.com/hashicorp/vault/helper/constants.VaultFIPSBuildRequiresVersionAgnosticTagAndOneVersionTag' +// +// This indicates that a build error has occurred due to mismatched tags. +// +// In particular, we use this to enforce the following restrictions on build +// tags: +// +// - If a versioned fips_140_* tag is specified, the unversioned tag must +// also be. +// - If the unversioned tag is specified, a versioned tag must be. +// - Both versioned flags cannot be specified at the same time. +// +// In the unlikely event that a FFI implementation for this function exists +// in the future, it should be renamed to a new function which does not +// exist. +// +// This approach was chosen above the other implementation in fips_cgo_check.go +// because this version does not break static analysis tools: most tools do not +// cross the CGo boundary and thus do not know that the below function is +// missing an implementation. However, in the other file, the function call is +// not marked as CGo (in part large because the lack of a cgo build tag +// prohibits us from using the same technique) and thus it must be a Go +// declaration, that is missing. +func VaultFIPSBuildRequiresVersionAgnosticTagAndOneVersionTag() + +func init() { + VaultFIPSBuildRequiresVersionAgnosticTagAndOneVersionTag() +} diff --git a/helper/constants/fips_cgo_check.go b/helper/constants/fips_cgo_check.go new file mode 100644 index 0000000000000..56eabb6c81e5f --- /dev/null +++ b/helper/constants/fips_cgo_check.go @@ -0,0 +1,18 @@ +//go:build (fips || fips_140_2 || fips_140_3) && !cgo + +package constants + +func init() { + // See note in fips_build_check.go. + // + // This function call is missing a declaration, causing the build to + // fail on improper tags (fips specified but cgo not specified). This + // ensures Vault fails to build if a FIPS build is requested but CGo + // support is not enabled. + // + // Note that this could confuse static analysis tools as this function + // should not ever be defined. If this function is defined in the future, + // the below reference should be renamed to a new name that is not + // defined to ensure we get a build failure. + VaultFIPSBuildTagMustEnableCGo() +} diff --git a/http/help.go b/http/help.go index 45099bd7b67f5..7ec6fb6131aae 100644 --- a/http/help.go +++ b/http/help.go @@ -1,7 +1,9 @@ package http import ( + "errors" "net/http" + "strings" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/logical" @@ -31,6 +33,10 @@ func handleHelp(core *vault.Core, w http.ResponseWriter, r *http.Request) { respondError(w, http.StatusBadRequest, nil) return } + if !strings.HasPrefix(r.URL.Path, "/v1/") { + respondError(w, http.StatusNotFound, errors.New("Missing /v1/ prefix in path. Use vault path-help command to retrieve API help for paths")) + return + } path := ns.TrimmedPath(r.URL.Path[len("/v1/"):]) req := &logical.Request{ diff --git a/http/help_test.go b/http/help_test.go index c3abfc86fa134..ec9a67dd1c58c 100644 --- a/http/help_test.go +++ b/http/help_test.go @@ -13,7 +13,11 @@ func TestHelp(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpGet(t, "", addr+"/v1/sys/mounts?help=1") + // request without /v1/ prefix + resp := testHttpGet(t, token, addr+"/?help=1") + testResponseStatus(t, resp, 404) + + resp = testHttpGet(t, "", addr+"/v1/sys/mounts?help=1") if resp.StatusCode != http.StatusForbidden { t.Fatal("expected permission denied with no token") } diff --git a/sdk/database/dbplugin/v5/plugin_client_test.go b/sdk/database/dbplugin/v5/plugin_client_test.go deleted file mode 100644 index 0ff8309f1092e..0000000000000 --- a/sdk/database/dbplugin/v5/plugin_client_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package dbplugin - -import ( - "context" - "errors" - "reflect" - "testing" - "time" - - log "github.com/hashicorp/go-hclog" - "github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" - "github.com/hashicorp/vault/sdk/helper/consts" - "github.com/hashicorp/vault/sdk/helper/pluginutil" - "github.com/hashicorp/vault/sdk/helper/wrapping" - "github.com/stretchr/testify/mock" - "google.golang.org/grpc" -) - -func TestNewPluginClient(t *testing.T) { - type testCase struct { - config pluginutil.PluginClientConfig - pluginClient pluginutil.PluginClient - expectedResp *DatabasePluginClient - expectedErr error - } - - tests := map[string]testCase{ - "happy path": { - config: testPluginClientConfig(), - pluginClient: &fakePluginClient{ - connResp: nil, - dispenseResp: gRPCClient{client: fakeClient{}}, - dispenseErr: nil, - }, - expectedResp: &DatabasePluginClient{ - client: &fakePluginClient{ - connResp: nil, - dispenseResp: gRPCClient{client: fakeClient{}}, - dispenseErr: nil, - }, - Database: gRPCClient{proto.NewDatabaseClient(nil), context.Context(nil)}, - }, - expectedErr: nil, - }, - "dispense error": { - config: testPluginClientConfig(), - pluginClient: &fakePluginClient{ - connResp: nil, - dispenseResp: gRPCClient{}, - dispenseErr: errors.New("dispense error"), - }, - expectedResp: nil, - expectedErr: errors.New("dispense error"), - }, - "error unsupported client type": { - config: testPluginClientConfig(), - pluginClient: &fakePluginClient{ - connResp: nil, - dispenseResp: nil, - dispenseErr: nil, - }, - expectedResp: nil, - expectedErr: errors.New("unsupported client type"), - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - ctx := context.Background() - - mockWrapper := new(mockRunnerUtil) - mockWrapper.On("NewPluginClient", ctx, mock.Anything). - Return(test.pluginClient, nil) - defer mockWrapper.AssertNumberOfCalls(t, "NewPluginClient", 1) - - resp, err := NewPluginClient(ctx, mockWrapper, test.config) - if test.expectedErr != nil && err == nil { - t.Fatalf("err expected, got nil") - } - if test.expectedErr == nil && err != nil { - t.Fatalf("no error expected, got: %s", err) - } - if test.expectedErr == nil && !reflect.DeepEqual(resp, test.expectedResp) { - t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) - } - }) - } -} - -func testPluginClientConfig() pluginutil.PluginClientConfig { - return pluginutil.PluginClientConfig{ - Name: "test-plugin", - PluginSets: PluginSets, - PluginType: consts.PluginTypeDatabase, - HandshakeConfig: HandshakeConfig, - Logger: log.NewNullLogger(), - IsMetadataMode: true, - AutoMTLS: true, - } -} - -var _ pluginutil.PluginClient = &fakePluginClient{} - -type fakePluginClient struct { - connResp grpc.ClientConnInterface - - dispenseResp interface{} - dispenseErr error -} - -func (f *fakePluginClient) Conn() grpc.ClientConnInterface { - return nil -} - -func (f *fakePluginClient) Dispense(name string) (interface{}, error) { - return f.dispenseResp, f.dispenseErr -} - -func (f *fakePluginClient) Ping() error { - return nil -} - -func (f *fakePluginClient) Close() error { - return nil -} - -var _ pluginutil.RunnerUtil = &mockRunnerUtil{} - -type mockRunnerUtil struct { - mock.Mock -} - -func (m *mockRunnerUtil) NewPluginClient(ctx context.Context, config pluginutil.PluginClientConfig) (pluginutil.PluginClient, error) { - args := m.Called(ctx, config) - return args.Get(0).(pluginutil.PluginClient), args.Error(1) -} - -func (m *mockRunnerUtil) ResponseWrapData(ctx context.Context, data map[string]interface{}, ttl time.Duration, jwt bool) (*wrapping.ResponseWrapInfo, error) { - args := m.Called(ctx, data, ttl, jwt) - return args.Get(0).(*wrapping.ResponseWrapInfo), args.Error(1) -} - -func (m *mockRunnerUtil) MlockEnabled() bool { - args := m.Called() - return args.Bool(0) -} diff --git a/sdk/database/dbplugin/v5/testing/test_helpers.go b/sdk/database/dbplugin/v5/testing/test_helpers.go index e3bee3b07e4b0..55a402c7fe3c8 100644 --- a/sdk/database/dbplugin/v5/testing/test_helpers.go +++ b/sdk/database/dbplugin/v5/testing/test_helpers.go @@ -12,7 +12,11 @@ import ( func getRequestTimeout(t *testing.T) time.Duration { rawDur := os.Getenv("VAULT_TEST_DATABASE_REQUEST_TIMEOUT") if rawDur == "" { - return 5 * time.Second + // Note: we incremented the default timeout from 5 to 10 seconds in a bid + // to fix sporadic failures of mssql_test.go tests TestInitialize() and + // TestUpdateUser_password(). + + return 10 * time.Second } dur, err := time.ParseDuration(rawDur) diff --git a/sdk/framework/backend.go b/sdk/framework/backend.go index ecb88f5c4667f..cdee46f486119 100644 --- a/sdk/framework/backend.go +++ b/sdk/framework/backend.go @@ -198,7 +198,7 @@ func (b *Backend) HandleRequest(ctx context.Context, req *logical.Request) (*log // If the path is empty and it is a help operation, handle that. if req.Path == "" && req.Operation == logical.HelpOperation { - return b.handleRootHelp(req) + return b.handleRootHelp() } // Find the matching route @@ -457,7 +457,7 @@ func (b *Backend) route(path string) (*Path, map[string]string) { return nil, nil } -func (b *Backend) handleRootHelp(req *logical.Request) (*logical.Response, error) { +func (b *Backend) handleRootHelp() (*logical.Response, error) { // Build a mapping of the paths and get the paths alphabetized to // make the output prettier. pathsMap := make(map[string]*Path) @@ -486,18 +486,9 @@ func (b *Backend) handleRootHelp(req *logical.Request) (*logical.Response, error return nil, err } - // Plugins currently don't have a direct knowledge of their own "type" - // (e.g. "kv", "cubbyhole"). It defaults to the name of the executable but - // can be overridden when the plugin is mounted. Since we need this type to - // form the request & response full names, we are passing it as an optional - // request parameter to the plugin's root help endpoint. If specified in - // the request, the type will be used as part of the request/response body - // names in the OAS document. - requestResponsePrefix := req.GetString("requestResponsePrefix") - // Build OpenAPI response for the entire backend doc := NewOASDocument() - if err := documentPaths(b, requestResponsePrefix, doc); err != nil { + if err := documentPaths(b, doc); err != nil { b.Logger().Warn("error generating OpenAPI", "error", err) } diff --git a/sdk/framework/openapi.go b/sdk/framework/openapi.go index 87240ecc85868..fb760774ba680 100644 --- a/sdk/framework/openapi.go +++ b/sdk/framework/openapi.go @@ -32,9 +32,6 @@ func NewOASDocument() *OASDocument { }, }, Paths: make(map[string]*OASPathItem), - Components: OASComponents{ - Schemas: make(map[string]*OASSchema), - }, } } @@ -81,14 +78,9 @@ func NewOASDocumentFromMap(input map[string]interface{}) (*OASDocument, error) { } type OASDocument struct { - Version string `json:"openapi" mapstructure:"openapi"` - Info OASInfo `json:"info"` - Paths map[string]*OASPathItem `json:"paths"` - Components OASComponents `json:"components"` -} - -type OASComponents struct { - Schemas map[string]*OASSchema `json:"schemas"` + Version string `json:"openapi" mapstructure:"openapi"` + Info OASInfo `json:"info"` + Paths map[string]*OASPathItem `json:"paths"` } type OASInfo struct { @@ -156,7 +148,6 @@ type OASMediaTypeObject struct { } type OASSchema struct { - Ref string `json:"$ref,omitempty"` Type string `json:"type,omitempty"` Description string `json:"description,omitempty"` Properties map[string]*OASSchema `json:"properties,omitempty"` @@ -213,9 +204,9 @@ var ( ) // documentPaths parses all paths in a framework.Backend into OpenAPI paths. -func documentPaths(backend *Backend, requestResponsePrefix string, doc *OASDocument) error { +func documentPaths(backend *Backend, doc *OASDocument) error { for _, p := range backend.Paths { - if err := documentPath(p, backend.SpecialPaths(), requestResponsePrefix, backend.BackendType, doc); err != nil { + if err := documentPath(p, backend.SpecialPaths(), backend.BackendType, doc); err != nil { return err } } @@ -224,7 +215,7 @@ func documentPaths(backend *Backend, requestResponsePrefix string, doc *OASDocum } // documentPath parses a framework.Path into one or more OpenAPI paths. -func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix string, backendType logical.BackendType, doc *OASDocument) error { +func documentPath(p *Path, specialPaths *logical.Paths, backendType logical.BackendType, doc *OASDocument) error { var sudoPaths []string var unauthPaths []string @@ -233,7 +224,7 @@ func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix st unauthPaths = specialPaths.Unauthenticated } - // Convert optional parameters into distinct patterns to be processed independently. + // Convert optional parameters into distinct patterns to be process independently. paths := expandPattern(p.Pattern) for _, path := range paths { @@ -367,12 +358,10 @@ func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix st // Set the final request body. Only JSON request data is supported. if len(s.Properties) > 0 || s.Example != nil { - requestName := constructRequestName(requestResponsePrefix, path) - doc.Components.Schemas[requestName] = s op.RequestBody = &OASRequestBody{ Content: OASContent{ "application/json": &OASMediaTypeObject{ - Schema: &OASSchema{Ref: fmt.Sprintf("#/components/schemas/%s", requestName)}, + Schema: s, }, }, } @@ -470,30 +459,6 @@ func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix st return nil } -// constructRequestName joins the given prefix with the path elements into a -// CamelCaseRequest string. -// -// For example, prefix="kv" & path=/config/lease/{name} => KvConfigLeaseRequest -func constructRequestName(requestResponsePrefix string, path string) string { - var b strings.Builder - - b.WriteString(strings.Title(requestResponsePrefix)) - - // split the path by / _ - separators - for _, token := range strings.FieldsFunc(path, func(r rune) bool { - return r == '/' || r == '_' || r == '-' - }) { - // exclude request fields - if !strings.ContainsAny(token, "{}") { - b.WriteString(strings.Title(token)) - } - } - - b.WriteString("Request") - - return b.String() -} - func specialPathMatch(path string, specialPaths []string) bool { // Test for exact or prefix match of special paths. for _, sp := range specialPaths { diff --git a/sdk/framework/openapi_test.go b/sdk/framework/openapi_test.go index fa14d2eb88c8a..7e514481de088 100644 --- a/sdk/framework/openapi_test.go +++ b/sdk/framework/openapi_test.go @@ -271,7 +271,7 @@ func TestOpenAPI_SpecialPaths(t *testing.T) { Root: test.rootPaths, Unauthenticated: test.unauthPaths, } - err := documentPath(&path, sp, "kv", logical.TypeLogical, doc) + err := documentPath(&path, sp, logical.TypeLogical, doc) if err != nil { t.Fatal(err) } @@ -515,11 +515,11 @@ func TestOpenAPI_OperationID(t *testing.T) { for _, context := range []string{"", "bar"} { doc := NewOASDocument() - err := documentPath(path1, nil, "kv", logical.TypeLogical, doc) + err := documentPath(path1, nil, logical.TypeLogical, doc) if err != nil { t.Fatal(err) } - err = documentPath(path2, nil, "kv", logical.TypeLogical, doc) + err = documentPath(path2, nil, logical.TypeLogical, doc) if err != nil { t.Fatal(err) } @@ -579,7 +579,7 @@ func TestOpenAPI_CustomDecoder(t *testing.T) { } docOrig := NewOASDocument() - err := documentPath(p, nil, "kv", logical.TypeLogical, docOrig) + err := documentPath(p, nil, logical.TypeLogical, docOrig) if err != nil { t.Fatal(err) } @@ -642,7 +642,7 @@ func testPath(t *testing.T, path *Path, sp *logical.Paths, expectedJSON string) t.Helper() doc := NewOASDocument() - if err := documentPath(path, sp, "kv", logical.TypeLogical, doc); err != nil { + if err := documentPath(path, sp, logical.TypeLogical, doc); err != nil { t.Fatal(err) } doc.CreateOperationIDs("") diff --git a/sdk/framework/path.go b/sdk/framework/path.go index b316d2cc1577b..4dc8ca3033618 100644 --- a/sdk/framework/path.go +++ b/sdk/framework/path.go @@ -301,17 +301,9 @@ func (p *Path) helpCallback(b *Backend) OperationFunc { return nil, errwrap.Wrapf("error executing template: {{err}}", err) } - // The plugin type (e.g. "kv", "cubbyhole") is only assigned at the time - // the plugin is enabled (mounted). If specified in the request, the type - // will be used as part of the request/response names in the OAS document - var requestResponsePrefix string - if v, ok := req.Data["requestResponsePrefix"]; ok { - requestResponsePrefix = v.(string) - } - // Build OpenAPI response for this path doc := NewOASDocument() - if err := documentPath(p, b.SpecialPaths(), requestResponsePrefix, b.BackendType, doc); err != nil { + if err := documentPath(p, b.SpecialPaths(), b.BackendType, doc); err != nil { b.Logger().Warn("error generating OpenAPI", "error", err) } diff --git a/sdk/framework/testdata/legacy.json b/sdk/framework/testdata/legacy.json index cb1f7ebd3f2d6..2fcb26882f529 100644 --- a/sdk/framework/testdata/legacy.json +++ b/sdk/framework/testdata/legacy.json @@ -41,7 +41,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/KvLookupRequest" + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "My token" + } + } } } } @@ -53,19 +59,6 @@ } } } - }, - "components": { - "schemas": { - "KvLookupRequest": { - "type": "object", - "properties": { - "token": { - "type": "string", - "description": "My token" - } - } - } - } } } diff --git a/sdk/framework/testdata/operations.json b/sdk/framework/testdata/operations.json index 94d54087b62f2..4c140f92b7326 100644 --- a/sdk/framework/testdata/operations.json +++ b/sdk/framework/testdata/operations.json @@ -66,7 +66,39 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/KvFooRequest" + "type": "object", + "required": ["age"], + "properties": { + "flavors": { + "type": "array", + "description": "the flavors", + "items": { + "type": "string" + } + }, + "age": { + "type": "integer", + "description": "the age", + "enum": [1, 2, 3], + "x-vault-displayAttrs": { + "name": "Age", + "sensitive": true, + "group": "Some Group", + "value": 7 + } + }, + "name": { + "type": "string", + "description": "the name", + "default": "Larry", + "pattern": "\\w([\\w-.]*\\w)?" + }, + "x-abc-token": { + "type": "string", + "description": "a header value", + "enum": ["a", "b", "c"] + } + } } } } @@ -78,44 +110,5 @@ } } } - }, - "components": { - "schemas": { - "KvFooRequest": { - "type": "object", - "required": ["age"], - "properties": { - "flavors": { - "type": "array", - "description": "the flavors", - "items": { - "type": "string" - } - }, - "age": { - "type": "integer", - "description": "the age", - "enum": [1, 2, 3], - "x-vault-displayAttrs": { - "name": "Age", - "sensitive": true, - "group": "Some Group", - "value": 7 - } - }, - "name": { - "type": "string", - "description": "the name", - "default": "Larry", - "pattern": "\\w([\\w-.]*\\w)?" - }, - "x-abc-token": { - "type": "string", - "description": "a header value", - "enum": ["a", "b", "c"] - } - } - } - } } } diff --git a/sdk/framework/testdata/operations_list.json b/sdk/framework/testdata/operations_list.json index e89622a3c40a1..bea40f61a37e8 100644 --- a/sdk/framework/testdata/operations_list.json +++ b/sdk/framework/testdata/operations_list.json @@ -59,9 +59,5 @@ ] } } - }, - "components": { - "schemas": { - } } } diff --git a/sdk/framework/testdata/responses.json b/sdk/framework/testdata/responses.json index b0e197babed5f..bd332054c379e 100644 --- a/sdk/framework/testdata/responses.json +++ b/sdk/framework/testdata/responses.json @@ -46,10 +46,6 @@ } } } - }, - "components": { - "schemas": { - } } } diff --git a/sdk/helper/ldaputil/config.go b/sdk/helper/ldaputil/config.go index d9118d1b2caee..43844da22b13f 100644 --- a/sdk/helper/ldaputil/config.go +++ b/sdk/helper/ldaputil/config.go @@ -112,6 +112,12 @@ Default: ({{.UserAttr}}={{.Username}})`, }, }, + "username_as_alias": { + Type: framework.TypeBool, + Default: false, + Description: "If true, sets the alias name to the username", + }, + "userattr": { Type: framework.TypeString, Default: "cn", @@ -242,6 +248,10 @@ func NewConfigEntry(existing *ConfigEntry, d *framework.FieldData) (*ConfigEntry cfg.AnonymousGroupSearch = d.Get("anonymous_group_search").(bool) } + if _, ok := d.Raw["username_as_alias"]; ok || !hadExisting { + cfg.UsernameAsAlias = d.Get("username_as_alias").(bool) + } + if _, ok := d.Raw["url"]; ok || !hadExisting { cfg.Url = strings.ToLower(d.Get("url").(string)) } @@ -393,6 +403,7 @@ type ConfigEntry struct { GroupFilter string `json:"groupfilter"` GroupAttr string `json:"groupattr"` UPNDomain string `json:"upndomain"` + UsernameAsAlias bool `json:"username_as_alias"` UserFilter string `json:"userfilter"` UserAttr string `json:"userattr"` Certificate string `json:"certificate"` @@ -444,6 +455,7 @@ func (c *ConfigEntry) PasswordlessMap() map[string]interface{} { "use_token_groups": c.UseTokenGroups, "anonymous_group_search": c.AnonymousGroupSearch, "request_timeout": c.RequestTimeout, + "username_as_alias": c.UsernameAsAlias, } if c.CaseSensitiveNames != nil { m["case_sensitive_names"] = *c.CaseSensitiveNames diff --git a/sdk/helper/ldaputil/config_test.go b/sdk/helper/ldaputil/config_test.go index 7463be363e01e..32edb5dffaad7 100644 --- a/sdk/helper/ldaputil/config_test.go +++ b/sdk/helper/ldaputil/config_test.go @@ -166,6 +166,7 @@ var jsonConfigDefault = []byte(` "tls_max_version": "tls12", "use_token_groups": false, "use_pre111_group_cn_behavior": null, + "username_as_alias": false, "request_timeout": 90, "CaseSensitiveNames": false, "ClientTLSCert": "", diff --git a/sdk/plugin/grpc_storage.go b/sdk/plugin/grpc_storage.go index 3da2ce31216f8..b7fd0caf8266a 100644 --- a/sdk/plugin/grpc_storage.go +++ b/sdk/plugin/grpc_storage.go @@ -90,6 +90,12 @@ func (s *GRPCStorageServer) List(ctx context.Context, args *pb.StorageListArgs) func (s *GRPCStorageServer) Get(ctx context.Context, args *pb.StorageGetArgs) (*pb.StorageGetReply, error) { storageEntry, err := s.impl.Get(ctx, args.Key) + if storageEntry == nil { + return &pb.StorageGetReply{ + Entry: nil, + Err: pb.ErrToString(err), + }, nil + } return &pb.StorageGetReply{ Entry: pb.LogicalStorageEntryToProtoStorageEntry(storageEntry), Err: pb.ErrToString(err), diff --git a/sdk/version/version_base.go b/sdk/version/version_base.go index e10edfeaf5708..8205d12459806 100644 --- a/sdk/version/version_base.go +++ b/sdk/version/version_base.go @@ -8,7 +8,7 @@ var ( // Whether cgo is enabled or not; set at build time CgoEnabled bool - Version = "1.11.0" - VersionPrerelease = "dev1" + Version = "1.10.1" + VersionPrerelease = "" VersionMetadata = "" ) diff --git a/ui/app/adapters/secret-engine.js b/ui/app/adapters/secret-engine.js index 1d75aae4273d9..40edfc3004f3f 100644 --- a/ui/app/adapters/secret-engine.js +++ b/ui/app/adapters/secret-engine.js @@ -61,15 +61,8 @@ export default ApplicationAdapter.extend({ data.id = path; } // first create the engine - try { - await this.ajax(this.url(path), 'POST', { data }); - } catch (e) { - // if error determine if path duplicate or permissions - if (e.httpStatus === 400) { - throw new Error('samePath'); - } - throw new Error('mountIssue'); - } + await this.ajax(this.url(path), 'POST', { data }); + // second post to config try { await this.ajax(this.urlForConfig(path), 'POST', { data: configData }); diff --git a/ui/app/adapters/secret-v2-version.js b/ui/app/adapters/secret-v2-version.js index 1d51a41bc696e..3195014001d49 100644 --- a/ui/app/adapters/secret-v2-version.js +++ b/ui/app/adapters/secret-v2-version.js @@ -149,6 +149,7 @@ export default ApplicationAdapter.extend({ } else if (deleteType === 'soft-delete') { return this.softDelete(backend, path, version); } else { + version = version || currentVersionForNoReadMetadata; return this.deleteByDeleteType(backend, path, deleteType, version); } }, diff --git a/ui/app/components/auth-form.js b/ui/app/components/auth-form.js index 8b1ed8aa837ac..6851737d2cc73 100644 --- a/ui/app/components/auth-form.js +++ b/ui/app/components/auth-form.js @@ -110,6 +110,18 @@ export default Component.extend(DEFAULTS, { this.setProperties(DEFAULTS); }, + getAuthBackend(type) { + const { wrappedToken, methods, selectedAuth, selectedAuthIsPath: keyIsPath } = this; + const selected = type || selectedAuth; + if (!methods && !wrappedToken) { + return {}; + } + if (keyIsPath) { + return methods.findBy('path', selected); + } + return BACKENDS.findBy('type', selected); + }, + selectedAuthIsPath: match('selectedAuth', /\/$/), selectedAuthBackend: computed( 'wrappedToken', @@ -118,14 +130,7 @@ export default Component.extend(DEFAULTS, { 'selectedAuth', 'selectedAuthIsPath', function () { - let { wrappedToken, methods, selectedAuth, selectedAuthIsPath: keyIsPath } = this; - if (!methods && !wrappedToken) { - return {}; - } - if (keyIsPath) { - return methods.findBy('path', selectedAuth); - } - return BACKENDS.findBy('type', selectedAuth); + return this.getAuthBackend(); } ), @@ -207,10 +212,18 @@ export default Component.extend(DEFAULTS, { authenticate: task( waitFor(function* (backendType, data) { - let clusterId = this.cluster.id; + const { + selectedAuth, + cluster: { id: clusterId }, + } = this; try { this.delayAuthMessageReminder.perform(); - const authResponse = yield this.auth.authenticate({ clusterId, backend: backendType, data }); + const authResponse = yield this.auth.authenticate({ + clusterId, + backend: backendType, + data, + selectedAuth, + }); this.onSuccess(authResponse, backendType, data); } catch (e) { this.set('loading', false); @@ -245,7 +258,10 @@ export default Component.extend(DEFAULTS, { this.setProperties({ error: null, }); - let backend = this.selectedAuthBackend || {}; + // if callback from oidc or jwt we have a token at this point + let backend = ['oidc', 'jwt'].includes(this.selectedAuth) + ? this.getAuthBackend('token') + : this.selectedAuthBackend || {}; let backendMeta = BACKENDS.find( (b) => (b.type || '').toLowerCase() === (backend.type || '').toLowerCase() ); diff --git a/ui/app/components/auth-jwt.js b/ui/app/components/auth-jwt.js index cb288b01110aa..6d200fd747447 100644 --- a/ui/app/components/auth-jwt.js +++ b/ui/app/components/auth-jwt.js @@ -165,7 +165,6 @@ export default Component.extend({ return this.handleOIDCError(e); } let token = resp.auth.client_token; - this.onSelectedAuth('token'); this.onToken(token); yield this.onSubmit(); }), diff --git a/ui/app/components/clients/horizontal-bar-chart.js b/ui/app/components/clients/horizontal-bar-chart.js index 429465357a05e..ddd6539f407aa 100644 --- a/ui/app/components/clients/horizontal-bar-chart.js +++ b/ui/app/components/clients/horizontal-bar-chart.js @@ -69,21 +69,26 @@ export default class HorizontalBarChart extends Component { let chartSvg = select(element); chartSvg.attr('width', '100%').attr('viewBox', `0 0 564 ${(dataset.length + 1) * LINE_HEIGHT}`); - // chartSvg.attr('viewBox', `0 0 700 300`); - let groups = chartSvg + let dataBarGroup = chartSvg .selectAll('g') .remove() .exit() .data(stackedData) .enter() .append('g') + .attr('data-test-group', (d) => `${d.key}`) // shifts chart to accommodate y-axis legend .attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`) .style('fill', (d, i) => LIGHT_AND_DARK_BLUE[i]); let yAxis = axisLeft(yScale).tickSize(0); - yAxis(chartSvg.append('g').attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`)); + + let yLabelsGroup = chartSvg + .append('g') + .attr('data-test-group', 'y-labels') + .attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`); + yAxis(yLabelsGroup); chartSvg.select('.domain').remove(); @@ -94,8 +99,10 @@ export default class HorizontalBarChart extends Component { chartSvg.selectAll('.tick text').call(truncate); - groups + dataBarGroup .selectAll('rect') + .remove() + .exit() // iterate through the stacked data and chart respectively .data((stackedData) => stackedData) .enter() @@ -109,8 +116,12 @@ export default class HorizontalBarChart extends Component { .attr('rx', 3) .attr('ry', 3); - let actionBars = chartSvg + let actionBarGroup = chartSvg.append('g').attr('data-test-group', 'action-bars'); + + let actionBars = actionBarGroup .selectAll('.action-bar') + .remove() + .exit() .data(dataset) .enter() .append('rect') @@ -124,8 +135,12 @@ export default class HorizontalBarChart extends Component { .style('opacity', '0') .style('mix-blend-mode', 'multiply'); - let yLegendBars = chartSvg - .selectAll('.label-bar') + let labelActionBarGroup = chartSvg.append('g').attr('data-test-group', 'label-action-bars'); + + let labelActionBar = labelActionBarGroup + .selectAll('.label-action-bar') + .remove() + .exit() .data(dataset) .enter() .append('rect') @@ -173,10 +188,10 @@ export default class HorizontalBarChart extends Component { }); // MOUSE EVENTS FOR Y-AXIS LABELS - yLegendBars + labelActionBar .on('mouseover', (data) => { if (data.label.length >= CHAR_LIMIT) { - let hoveredElement = yLegendBars.filter((bar) => bar.label === data.label).node(); + let hoveredElement = labelActionBar.filter((bar) => bar.label === data.label).node(); this.tooltipTarget = hoveredElement; this.isLabel = true; this.tooltipText = data.label; @@ -208,10 +223,13 @@ export default class HorizontalBarChart extends Component { .style('opacity', '0'); }); - // add client count total values to the right - chartSvg + // client count total values to the right + let totalValueGroup = chartSvg .append('g') - .attr('transform', `translate(${TRANSLATE.left}, ${TRANSLATE.down})`) + .attr('data-test-group', 'total-values') + .attr('transform', `translate(${TRANSLATE.left}, ${TRANSLATE.down})`); + + totalValueGroup .selectAll('text') .data(dataset) .enter() diff --git a/ui/app/components/mount-backend-form.js b/ui/app/components/mount-backend-form.js index 2433af9bcebb0..0493003d97aa4 100644 --- a/ui/app/components/mount-backend-form.js +++ b/ui/app/components/mount-backend-form.js @@ -113,22 +113,17 @@ export default Component.extend({ } } - if (!capabilities.get('canUpdate')) { - // if there is no sys/mount issue then error is config endpoint. - this.flashMessages.warning( - 'You do not have access to the config endpoint. The secret engine was mounted, but the configuration settings were not saved.' - ); - // remove the config data from the model otherwise it will save it even if the network request failed. - [this.mountModel.maxVersions, this.mountModel.casRequired, this.mountModel.deleteVersionAfter] = [ - 0, - false, - 0, - ]; - } + let changedAttrKeys = Object.keys(mountModel.changedAttributes()); + const updatesConfig = + mountModel.isV2KV && + (changedAttrKeys.includes('casRequired') || + changedAttrKeys.includes('deleteVersionAfter') || + changedAttrKeys.includes('maxVersions')); + try { yield mountModel.save(); } catch (err) { - if (err.message === 'mountIssue') { + if (err.httpStatus === 403) { this.mountIssue = true; this.set('isFormInvalid', this.mountIssue); this.flashMessages.danger( @@ -136,9 +131,31 @@ export default Component.extend({ ); return; } - this.set('errorMessage', 'This mount path already exist.'); + if (err.errors) { + let errors = err.errors.map((e) => { + if (typeof e === 'object') return e.title || e.message || JSON.stringify(e); + return e; + }); + this.set('errors', errors); + } else if (err.message) { + this.set('errorMessage', err.message); + } else { + this.set('errorMessage', 'An error occurred, check the vault logs.'); + } return; } + if (updatesConfig && !capabilities.get('canUpdate')) { + // config error is not thrown from secret-engine adapter, so handling here + this.flashMessages.warning( + 'You do not have access to the config endpoint. The secret engine was mounted, but the configuration settings were not saved.' + ); + // remove the config data from the model otherwise it will save it even if the network request failed. + [this.mountModel.maxVersions, this.mountModel.casRequired, this.mountModel.deleteVersionAfter] = [ + 0, + false, + 0, + ]; + } let mountType = this.mountType; mountType = mountType === 'secret' ? `${mountType}s engine` : `${mountType} method`; this.flashMessages.success(`Successfully mounted the ${type} ${mountType} at ${path}.`); diff --git a/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js b/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js index fb697b9449841..98d015b23f53e 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js +++ b/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js @@ -248,20 +248,7 @@ export default Route.extend(UnloadModelRoute, { if (modelType === 'secret-v2') { // after the the base model fetch, kv-v2 has a second associated // version model that contains the secret data - - // if no read access to metadata, return current Version from secret data. - if (!secretModel.currentVersion) { - let adapter = this.store.adapterFor('secret-v2-version'); - try { - secretModel.currentVersion = await adapter.getSecretDataVersion(backend, secret); - } catch { - // will get error if you have deleted the secret - // if this is the case do nothing - } - secretModel = await this.fetchV2Models(capabilities, secretModel, params); - } else { - secretModel = await this.fetchV2Models(capabilities, secretModel, params); - } + secretModel = await this.fetchV2Models(capabilities, secretModel, params); } return { secret: secretModel, diff --git a/ui/app/services/auth.js b/ui/app/services/auth.js index ec1db73f06fd6..598f754f03352 100644 --- a/ui/app/services/auth.js +++ b/ui/app/services/auth.js @@ -358,7 +358,7 @@ export default Service.extend({ return {}; }, - async authenticate(/*{clusterId, backend, data}*/) { + async authenticate(/*{clusterId, backend, data, selectedAuth}*/) { const [options] = arguments; const adapter = this.clusterAdapter(); @@ -389,6 +389,8 @@ export default Service.extend({ }, async authSuccess(options, response) { + // persist selectedAuth to sessionStorage to rehydrate auth form on logout + sessionStorage.setItem('selectedAuth', options.selectedAuth); const authData = await this.persistAuthData(options, response, this.namespaceService.path); await this.permissions.getPaths.perform(); return authData; @@ -407,8 +409,11 @@ export default Service.extend({ }, getAuthType() { - if (!this.authData) return; - return this.authData.backend.type; + // check sessionStorage first + const selectedAuth = sessionStorage.getItem('selectedAuth'); + if (selectedAuth) return selectedAuth; + // fallback to authData which discerns backend type from token + return this.authData ? this.authData.backend.type : null; }, deleteCurrentToken() { diff --git a/ui/app/styles/components/tabs.scss b/ui/app/styles/components/tabs.scss index 6b505313a77bb..d0cbf795285b8 100644 --- a/ui/app/styles/components/tabs.scss +++ b/ui/app/styles/components/tabs.scss @@ -8,17 +8,6 @@ ul { border-color: transparent; min-height: 3rem; - - > a { - &:focus { - box-shadow: none; - } - &.is-active, - &.is-active .tab { - border-color: $blue; - color: $blue; - } - } } li { diff --git a/ui/app/templates/components/auth-form.hbs b/ui/app/templates/components/auth-form.hbs index 9bc02fa8289e9..934d7f7ce9c1f 100644 --- a/ui/app/templates/components/auth-form.hbs +++ b/ui/app/templates/components/auth-form.hbs @@ -68,7 +68,6 @@ @onToken={{action (mut this.token)}} @namespace={{this.namespace}} @onNamespace={{action (mut this.namespace)}} - @onSelectedAuth={{action (mut this.selectedAuth)}} @onSubmit={{action "doSubmit"}} @onRoleName={{action (mut this.roleName)}} @roleName={{this.roleName}} diff --git a/ui/app/templates/components/configure-aws-secret.hbs b/ui/app/templates/components/configure-aws-secret.hbs index b7fa6d8bf5a45..208efcba62d1b 100644 --- a/ui/app/templates/components/configure-aws-secret.hbs +++ b/ui/app/templates/components/configure-aws-secret.hbs @@ -1,22 +1,38 @@
@@ -45,7 +61,6 @@ (hash access_key=@accessKey iam_endpoint=@iamEndpoint sts_endpoint=@stsEndpoint secret_key=@secretKey region=@region) }} data-test-aws-root-creds-form="true" - aria-label="save root creds form" >
diff --git a/ui/app/templates/components/configure-pki-secret.hbs b/ui/app/templates/components/configure-pki-secret.hbs index e0cd4d6180d17..6df1f17114cf6 100644 --- a/ui/app/templates/components/configure-pki-secret.hbs +++ b/ui/app/templates/components/configure-pki-secret.hbs @@ -1,19 +1,28 @@
\ No newline at end of file diff --git a/ui/app/templates/components/identity/entity-nav.hbs b/ui/app/templates/components/identity/entity-nav.hbs index 4464974a151e1..d4ce8541fa225 100644 --- a/ui/app/templates/components/identity/entity-nav.hbs +++ b/ui/app/templates/components/identity/entity-nav.hbs @@ -8,12 +8,18 @@
diff --git a/ui/app/templates/components/identity/item-metadata.hbs b/ui/app/templates/components/identity/item-metadata.hbs index ea329342d516b..921f076d0e0e7 100644 --- a/ui/app/templates/components/identity/item-metadata.hbs +++ b/ui/app/templates/components/identity/item-metadata.hbs @@ -23,10 +23,12 @@ (humanize @model.identityType) }}. Edit this {{lowercase (humanize @model.identityType)}} to get started." > - + {{! template-lint-configure no-unknown-arguments-for-builtin-components "warn" }} + Edit {{lowercase (humanize @model.identityType)}} + {{! template-lint-configure no-unknown-arguments-for-builtin-components "on" }} Learn more diff --git a/ui/app/templates/components/mount-backend-form.hbs b/ui/app/templates/components/mount-backend-form.hbs index 58a4c5eaad237..0d9612ca5c592 100644 --- a/ui/app/templates/components/mount-backend-form.hbs +++ b/ui/app/templates/components/mount-backend-form.hbs @@ -21,7 +21,7 @@
- + {{#if this.showEnable}}
- {{#unless @canReadSecretData}} + {{#if (eq @canReadSecretData false)}} - {{/unless}} + {{/if}} {{#if this.isCreateNewVersionFromOldVersion}}
diff --git a/ui/app/templates/components/secret-edit-toolbar.hbs b/ui/app/templates/components/secret-edit-toolbar.hbs index ecb0f5db82650..59a1ba780fe8f 100644 --- a/ui/app/templates/components/secret-edit-toolbar.hbs +++ b/ui/app/templates/components/secret-edit-toolbar.hbs @@ -92,12 +92,15 @@ {{#let (concat "vault.cluster.secrets.backend." (if (eq @mode "show") "edit" "show")) as |targetRoute|}} {{#if @isV2}} Create new version diff --git a/ui/app/templates/components/secret-edit.hbs b/ui/app/templates/components/secret-edit.hbs index dfac098dceb4d..a5bdcd7463813 100644 --- a/ui/app/templates/components/secret-edit.hbs +++ b/ui/app/templates/components/secret-edit.hbs @@ -27,25 +27,33 @@
diff --git a/ui/app/templates/components/secret-list-header-tab.hbs b/ui/app/templates/components/secret-list-header-tab.hbs index ba40a23715a0e..55455d5a109f3 100644 --- a/ui/app/templates/components/secret-list-header-tab.hbs +++ b/ui/app/templates/components/secret-list-header-tab.hbs @@ -1,10 +1,14 @@ {{#unless this.dontShowTab}} + {{! template-lint-configure no-unknown-arguments-for-builtin-components "warn" }} - {{@label}} + + {{@label}} + {{/unless}} \ No newline at end of file diff --git a/ui/app/templates/components/secret-list-header.hbs b/ui/app/templates/components/secret-list-header.hbs index 4d93c91a62351..f11fc9e90c844 100644 --- a/ui/app/templates/components/secret-list-header.hbs +++ b/ui/app/templates/components/secret-list-header.hbs @@ -27,11 +27,19 @@ {{#if options.tabs}}
-