diff --git a/ui/app/adapters/generated-item-list.js b/ui/app/adapters/generated-item-list.js index 215631c17..2deec43d6 100644 --- a/ui/app/adapters/generated-item-list.js +++ b/ui/app/adapters/generated-item-list.js @@ -1,31 +1,39 @@ import { assign } from '@ember/polyfills'; import ApplicationAdapter from './application'; +import { task } from 'ember-concurrency'; export default ApplicationAdapter.extend({ namespace: 'v1', urlForItem() {}, + dynamicApiPath: '', + getDynamicApiPath: task(function*(id) { + let result = yield this.store.peekRecord('auth-method', id); + this.dynamicApiPath = result.apiPath; + return; + }), - fetchByQuery(store, query, isList) { + fetchByQuery: task(function*(store, query, isList) { const { id } = query; let data = {}; if (isList) { data.list = true; + yield this.getDynamicApiPath.perform(id); } - return this.ajax(this.urlForItem(id, isList), 'GET', { data }).then(resp => { + return this.ajax(this.urlForItem(id, isList, this.dynamicApiPath), 'GET', { data }).then(resp => { const data = { id, method: id, }; return assign({}, resp, data); }); - }, + }), query(store, type, query) { - return this.fetchByQuery(store, query, true); + return this.fetchByQuery.perform(store, query, true); }, queryRecord(store, type, query) { - return this.fetchByQuery(store, query); + return this.fetchByQuery.perform(store, query); }, }); diff --git a/ui/app/services/path-help.js b/ui/app/services/path-help.js index 9cd6a57e7..7beccd481 100644 --- a/ui/app/services/path-help.js +++ b/ui/app/services/path-help.js @@ -23,6 +23,7 @@ export function sanitizePath(path) { export default Service.extend({ attrs: null, + dynamicApiPath: '', ajax(url, options = {}) { let appAdapter = getOwner(this).lookup(`adapter:application`); let { data } = options; @@ -226,11 +227,16 @@ export default Service.extend({ const deletePath = paths.find(path => path.operations.includes('delete')); return generatedItemAdapter.extend({ - urlForItem(id, isList) { + urlForItem(id, isList, dynamicApiPath) { const itemType = getPath.path.slice(1); let url; id = encodePath(id); - + // the apiPath changes when you switch between routes but the apiPath variable does not unless the model is reloaded + // overwrite apiPath if dynamicApiPath exist. + // dynamicApiPath comes from the model->adapter + if (dynamicApiPath) { + apiPath = dynamicApiPath; + } // isList indicates whether we are viewing the list page // of a top-level item such as userpass if (isList) { diff --git a/ui/app/templates/components/generated-item-list.hbs b/ui/app/templates/components/generated-item-list.hbs index a9557d6af..057de11e8 100644 --- a/ui/app/templates/components/generated-item-list.hbs +++ b/ui/app/templates/components/generated-item-list.hbs @@ -41,6 +41,7 @@ - + Enable new method diff --git a/ui/tests/acceptance/auth-list-test.js b/ui/tests/acceptance/auth-list-test.js new file mode 100644 index 000000000..a934421fc --- /dev/null +++ b/ui/tests/acceptance/auth-list-test.js @@ -0,0 +1,59 @@ +import { click, fillIn, settled, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; +import enablePage from 'vault/tests/pages/settings/auth/enable'; + +module('Acceptance | userpass secret backend', function(hooks) { + setupApplicationTest(hooks); + + hooks.beforeEach(function() { + return authPage.login(); + }); + + hooks.afterEach(function() { + return logout.visit(); + }); + + test('userpass backend', async function(assert) { + let n = Math.random(); + const path1 = `userpass-${++n}`; + const path2 = `userpass-${++n}`; + const user1 = 'user1'; + const user2 = 'user2'; + + // enable the first userpass method with one username + await enablePage.enable('userpass', path1); + await click('[data-test-save-config="true"]'); + await visit(`/vault/access/${path1}/item/user/create`); + await fillIn('[data-test-input="username"]', user1); + await fillIn('[data-test-textarea]', user1); + await click('[data-test-save-config="true"]'); + + // enable the first userpass method with one username + await visit(`/vault/settings/auth/enable`); + await click('[data-test-mount-type="userpass"]'); + await click('[data-test-mount-next]'); + await fillIn('[data-test-input="path"]', path2); + await click('[data-test-mount-submit="true"]'); + await click('[data-test-save-config="true"]'); + await settled(); + await click(`[data-test-auth-backend-link="${path2}"]`); + await click('[data-test-create="user"]'); + await fillIn('[data-test-input="username"]', user2); + await fillIn('[data-test-textarea]', user2); + await click('[data-test-save-config="true"]'); + + //confirming that the user was created. There was a bug where the apiPath was not being updated when toggling between auth routes + assert + .dom('[data-test-list-item-content]') + .hasText(user2, 'user just created shows in current auth list'); + + //confirm that the auth method 1 shows the user1. There was a bug where it was not updated the list when toggling between auth routes + await visit(`/vault/access/${path1}/item/user`); + assert + .dom('[data-test-list-item-content]') + .hasText(user1, 'first user created shows in current auth list'); + }); +});