-
+
- {{#each this.model.tuneAttrs as |attr|}}
- {{#if (not (includes attr.name this.model.userLockoutConfig.modelAttrs))}}
-
+ {{#each @model.tuneAttrs as |attr|}}
+ {{#if (not (includes attr.name @model.userLockoutConfig.modelAttrs))}}
+
{{/if}}
{{/each}}
- {{#if this.model.supportsUserLockoutConfig}}
+ {{#if @model.supportsUserLockoutConfig}}
User lockout configuration
Specifies the user lockout settings for this auth mount.
- {{#each this.model.tuneAttrs as |attr|}}
- {{#if (includes attr.name this.model.userLockoutConfig.modelAttrs)}}
-
+ {{#each @model.tuneAttrs as |attr|}}
+ {{#if (includes attr.name @model.userLockoutConfig.modelAttrs)}}
+
{{/if}}
{{/each}}
{{/if}}
diff --git a/ui/app/components/auth-config-form/options.js b/ui/app/components/auth-config-form/options.js
index 9c12b16adf..5f345291d0 100644
--- a/ui/app/components/auth-config-form/options.js
+++ b/ui/app/components/auth-config-form/options.js
@@ -8,63 +8,61 @@ import AuthConfigComponent from './config';
import { service } from '@ember/service';
import { task } from 'ember-concurrency';
import { waitFor } from '@ember/test-waiters';
+import { tracked } from '@glimmer/tracking';
+import errorMessage from 'vault/utils/error-message';
/**
* @module AuthConfigForm/Options
* The `AuthConfigForm/Options` is options portion of the auth config form.
*
* @example
- * ```js
- * {{auth-config-form/options model.model}}
- * ```
+ *
*
* @property model=null {DS.Model} - The corresponding auth model that is being configured.
*
*/
-export default AuthConfigComponent.extend({
- flashMessages: service(),
- router: service(),
+export default class AuthConfigOptions extends AuthConfigComponent {
+ @service flashMessages;
+ @service router;
- saveModel: task(
- waitFor(function* () {
- const data = this.model.config.serialize();
- data.description = this.model.description;
+ @tracked errorMessage;
- if (this.model.supportsUserLockoutConfig) {
- data.user_lockout_config = {};
- this.model.userLockoutConfig.apiParams.forEach((attr) => {
- if (Object.keys(data).includes(attr)) {
- data.user_lockout_config[attr] = data[attr];
- delete data[attr];
- }
- });
- }
+ @task
+ @waitFor
+ *saveModel(evt) {
+ evt.preventDefault();
+ this.errorMessage = null;
+ const data = this.args.model.config.serialize();
+ data.description = this.args.model.description;
- // token_type should not be tuneable for the token auth method.
- if (this.model.methodType === 'token') {
- delete data.token_type;
- }
-
- try {
- yield this.model.tune(data);
- } catch (err) {
- // AdapterErrors are handled by the error-message component
- // in the form
- if (err instanceof AdapterError === false) {
- throw err;
+ if (this.args.model.supportsUserLockoutConfig) {
+ data.user_lockout_config = {};
+ this.args.model.userLockoutConfig.apiParams.forEach((attr) => {
+ if (Object.keys(data).includes(attr)) {
+ data.user_lockout_config[attr] = data[attr];
+ delete data[attr];
}
+ });
+ }
+
+ // token_type should not be tuneable for the token auth method.
+ if (this.args.model.methodType === 'token') {
+ delete data.token_type;
+ }
+
+ try {
+ yield this.args.model.tune(data);
+ } catch (err) {
+ if (err instanceof AdapterError) {
// because we're not calling model.save the model never updates with
- // the error. Forcing the error message by manually setting the errorMessage
- try {
- this.model.set('errorMessage', err.errors?.join(','));
- } catch {
- // do nothing
- }
+ // the error, so we set it manually in the component instead.
+ this.errorMessage = errorMessage(err);
return;
}
- this.router.transitionTo('vault.cluster.access.methods').followRedirects();
- this.flashMessages.success('The configuration was saved successfully.');
- })
- ),
-});
+ throw err;
+ }
+ this.router.transitionTo('vault.cluster.access.methods').followRedirects();
+ this.flashMessages.success('The configuration was saved successfully.');
+ }
+}
diff --git a/ui/app/templates/components/section-tabs.hbs b/ui/app/components/section-tabs.hbs
similarity index 68%
rename from ui/app/templates/components/section-tabs.hbs
rename to ui/app/components/section-tabs.hbs
index 6b408df60b..60ee2e2096 100644
--- a/ui/app/templates/components/section-tabs.hbs
+++ b/ui/app/components/section-tabs.hbs
@@ -3,14 +3,14 @@
SPDX-License-Identifier: BUSL-1.1
~}}
-{{#let (tabs-for-auth-section this.model this.tabType this.paths) as |tabs|}}
+{{#let (tabs-for-auth-section @model this.tabType @paths) as |tabs|}}
{{#if tabs.length}}
-
{{/if}}
-{{section-tabs this.model "authShow" this.paths}}
+
{{#if (eq this.section "configuration")}}
diff --git a/ui/app/templates/vault/cluster/settings/auth/configure.hbs b/ui/app/templates/vault/cluster/settings/auth/configure.hbs
index 4014d5310b..d75976c85d 100644
--- a/ui/app/templates/vault/cluster/settings/auth/configure.hbs
+++ b/ui/app/templates/vault/cluster/settings/auth/configure.hbs
@@ -19,7 +19,7 @@
-{{section-tabs this.model}}
+
diff --git a/ui/app/templates/vault/cluster/settings/auth/configure/section.hbs b/ui/app/templates/vault/cluster/settings/auth/configure/section.hbs
index 8dfd7c834a..8441f24ed1 100644
--- a/ui/app/templates/vault/cluster/settings/auth/configure/section.hbs
+++ b/ui/app/templates/vault/cluster/settings/auth/configure/section.hbs
@@ -4,7 +4,7 @@
~}}
{{#if (eq this.model.section "options")}}
- {{auth-config-form/options this.model.model}}
+
{{else}}
- {{auth-config-form/config this.model.model}}
+
{{/if}}
\ No newline at end of file
diff --git a/ui/tests/unit/lib/attach-capabilities-test.js b/ui/tests/unit/lib/attach-capabilities-test.js
deleted file mode 100644
index 3a5568d1f1..0000000000
--- a/ui/tests/unit/lib/attach-capabilities-test.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * Copyright (c) HashiCorp, Inc.
- * SPDX-License-Identifier: BUSL-1.1
- */
-
-import Model from '@ember-data/model';
-import { module, test } from 'qunit';
-import { setupTest } from 'ember-qunit';
-import attachCapabilities from 'vault/lib/attach-capabilities';
-import apiPath from 'vault/utils/api-path';
-
-const MODEL_TYPE = 'test-form-model';
-
-const makeModelClass = () => {
- return Model.extend();
-};
-
-module('Unit | lib | attach capabilities', function (hooks) {
- setupTest(hooks);
-
- test('it attaches passed capabilities', function (assert) {
- let mc = makeModelClass();
- mc = attachCapabilities(mc, {
- updatePath: apiPath`update/{'id'}`,
- deletePath: apiPath`delete/{'id'}`,
- });
- let relationship = mc.relationshipsByName.get('updatePath');
-
- assert.strictEqual(relationship.key, 'updatePath', 'has updatePath relationship');
- assert.strictEqual(relationship.kind, 'belongsTo', 'kind of relationship is belongsTo');
- assert.strictEqual(relationship.type, 'capabilities', 'updatePath is a related capabilities model');
-
- relationship = mc.relationshipsByName.get('deletePath');
- assert.strictEqual(relationship.key, 'deletePath', 'has deletePath relationship');
- assert.strictEqual(relationship.kind, 'belongsTo', 'kind of relationship is belongsTo');
- assert.strictEqual(relationship.type, 'capabilities', 'deletePath is a related capabilities model');
- });
-
- test('it adds a static method to the model class', function (assert) {
- let mc = makeModelClass();
- mc = attachCapabilities(mc, {
- updatePath: apiPath`update/{'id'}`,
- deletePath: apiPath`delete/{'id'}`,
- });
- const relatedCapabilities = !!mc.relatedCapabilities && typeof mc.relatedCapabilities === 'function';
- assert.true(relatedCapabilities, 'model class now has a relatedCapabilities static function');
- });
-
- test('calling static method with single response JSON-API document adds expected relationships', function (assert) {
- let mc = makeModelClass();
- mc = attachCapabilities(mc, {
- updatePath: apiPath`update/${'id'}`,
- deletePath: apiPath`delete/${'id'}`,
- });
- const jsonAPIDocSingle = {
- data: {
- id: 'test',
- type: MODEL_TYPE,
- attributes: {},
- relationships: {},
- },
- included: [],
- };
-
- const expected = {
- data: {
- id: 'test',
- type: MODEL_TYPE,
- attributes: {},
- relationships: {
- updatePath: {
- data: {
- type: 'capabilities',
- id: 'update/test',
- },
- },
- deletePath: {
- data: {
- type: 'capabilities',
- id: 'delete/test',
- },
- },
- },
- },
- included: [],
- };
-
- mc.relatedCapabilities(jsonAPIDocSingle);
-
- assert.strictEqual(
- Object.keys(jsonAPIDocSingle.data.relationships).length,
- 2,
- 'document now has 2 relationships'
- );
- assert.deepEqual(jsonAPIDocSingle, expected, 'has the exected new document structure');
- });
-
- test('calling static method with an arrary response JSON-API document adds expected relationships', function (assert) {
- let mc = makeModelClass();
- mc = attachCapabilities(mc, {
- updatePath: apiPath`update/${'id'}`,
- deletePath: apiPath`delete/${'id'}`,
- });
- const jsonAPIDocSingle = {
- data: [
- {
- id: 'test',
- type: MODEL_TYPE,
- attributes: {},
- relationships: {},
- },
- {
- id: 'foo',
- type: MODEL_TYPE,
- attributes: {},
- relationships: {},
- },
- ],
- included: [],
- };
-
- const expected = {
- data: [
- {
- id: 'test',
- type: MODEL_TYPE,
- attributes: {},
- relationships: {
- updatePath: {
- data: {
- type: 'capabilities',
- id: 'update/test',
- },
- },
- deletePath: {
- data: {
- type: 'capabilities',
- id: 'delete/test',
- },
- },
- },
- },
- {
- id: 'foo',
- type: MODEL_TYPE,
- attributes: {},
- relationships: {
- updatePath: {
- data: {
- type: 'capabilities',
- id: 'update/foo',
- },
- },
- deletePath: {
- data: {
- type: 'capabilities',
- id: 'delete/foo',
- },
- },
- },
- },
- ],
- included: [],
- };
- mc.relatedCapabilities(jsonAPIDocSingle);
- assert.deepEqual(jsonAPIDocSingle, expected, 'has the exected new document structure');
- });
-});