From cd0cd0a175ab6bc762df7bd5c2cc9f40b26d9402 Mon Sep 17 00:00:00 2001 From: Jordan Reimer Date: Wed, 26 Mar 2025 13:51:59 -0600 Subject: [PATCH] [UI] Ember Data Migration - Remove Tools Adapter (#30030) * updates unwrap request in auth-form and control-group-success components to use api service * removes tools adapter and test * fixes tests --- ui/app/adapters/tools.js | 28 --------- ui/app/components/auth-form.js | 8 ++- ui/app/components/control-group-success.js | 9 +-- .../integration/components/auth/page-test.js | 2 +- .../components/control-group-success-test.js | 19 ++---- ui/tests/unit/adapters/tools-test.js | 63 ------------------- 6 files changed, 16 insertions(+), 113 deletions(-) delete mode 100644 ui/app/adapters/tools.js delete mode 100644 ui/tests/unit/adapters/tools-test.js diff --git a/ui/app/adapters/tools.js b/ui/app/adapters/tools.js deleted file mode 100644 index 3c7e4ab979..0000000000 --- a/ui/app/adapters/tools.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 - */ - -import ApplicationAdapter from './application'; - -const WRAPPING_ENDPOINTS = ['lookup', 'wrap', 'unwrap', 'rewrap']; -const TOOLS_ENDPOINTS = ['random', 'hash']; - -export default ApplicationAdapter.extend({ - toolUrlFor(action) { - const isWrapping = WRAPPING_ENDPOINTS.includes(action); - const isTool = TOOLS_ENDPOINTS.includes(action); - const prefix = isWrapping ? 'wrapping' : 'tools'; - if (!isWrapping && !isTool) { - throw new Error(`Calls to a ${action} endpoint are not currently allowed in the tool adapter`); - } - return `${this.buildURL()}/${prefix}/${action}`; - }, - - toolAction(action, data, options = {}) { - const { wrapTTL, clientToken } = options; - const url = this.toolUrlFor(action); - const ajaxOptions = wrapTTL ? { data, wrapTTL, clientToken } : { data, clientToken }; - return this.ajax(url, 'POST', ajaxOptions); - }, -}); diff --git a/ui/app/components/auth-form.js b/ui/app/components/auth-form.js index 0eb61abbf1..68bbb2473b 100644 --- a/ui/app/components/auth-form.js +++ b/ui/app/components/auth-form.js @@ -13,6 +13,7 @@ import { allSupportedAuthBackends, supportedAuthBackends } from 'vault/helpers/s import { task } from 'ember-concurrency'; import { waitFor } from '@ember/test-waiters'; import { v4 as uuidv4 } from 'uuid'; +import apiErrorMessage from 'vault/utils/api-error-message'; /** * @module AuthForm @@ -45,6 +46,7 @@ export default Component.extend(DEFAULTS, { store: service(), csp: service('csp-event'), version: service(), + api: service(), // set by query params, passed from parent Auth::Page component selectedAuth: null, @@ -183,13 +185,13 @@ export default Component.extend(DEFAULTS, { waitFor(function* (token) { // will be using the Token Auth Method, so set it here this.set('selectedAuth', 'token'); - const adapter = this.store.adapterFor('tools'); try { - const response = yield adapter.toolAction('unwrap', null, { clientToken: token }); + const response = yield this.api.sys.unwrap({}, this.api.buildHeaders({ token })); this.set('token', response.auth.client_token); this.send('doSubmit'); } catch (e) { - this.set('error', `Token unwrap failed: ${e.errors[0]}`); + const error = yield apiErrorMessage(e); + this.set('error', `Token unwrap failed: ${error}`); } }) ), diff --git a/ui/app/components/control-group-success.js b/ui/app/components/control-group-success.js index 8433b368ce..b731283e7a 100644 --- a/ui/app/components/control-group-success.js +++ b/ui/app/components/control-group-success.js @@ -6,11 +6,12 @@ import { service } from '@ember/service'; import Component from '@ember/component'; import { task } from 'ember-concurrency'; +import apiErrorMessage from 'vault/utils/api-error-message'; export default Component.extend({ router: service(), controlGroup: service(), - store: service(), + api: service(), // public attrs model: null, @@ -21,14 +22,14 @@ export default Component.extend({ unwrapData: null, unwrap: task(function* (token) { - const adapter = this.store.adapterFor('tools'); this.set('error', null); try { - const response = yield adapter.toolAction('unwrap', null, { clientToken: token }); + const response = yield this.api.sys.unwrap({}, this.api.buildHeaders({ token })); this.set('unwrapData', response.auth || response.data); this.controlGroup.deleteControlGroupToken(this.model.id); } catch (e) { - this.set('error', `Token unwrap failed: ${e.errors[0]}`); + const error = yield apiErrorMessage(e); + this.error = `Token unwrap failed: ${error}`; } }).drop(), diff --git a/ui/tests/integration/components/auth/page-test.js b/ui/tests/integration/components/auth/page-test.js index d6d88e8a5a..33fd56014a 100644 --- a/ui/tests/integration/components/auth/page-test.js +++ b/ui/tests/integration/components/auth/page-test.js @@ -144,7 +144,7 @@ module('Integration | Component | auth | page ', function (hooks) { this.server.post('/sys/wrapping/unwrap', (_, req) => { assert.strictEqual(req.url, '/v1/sys/wrapping/unwrap', 'makes call to unwrap the token'); assert.strictEqual( - req.requestHeaders['X-Vault-Token'], + req.requestHeaders['x-vault-token'], this.wrappedToken, 'uses passed wrapped token for the unwrap' ); diff --git a/ui/tests/integration/components/control-group-success-test.js b/ui/tests/integration/components/control-group-success-test.js index 3f63208fa4..06a1cc58e0 100644 --- a/ui/tests/integration/components/control-group-success-test.js +++ b/ui/tests/integration/components/control-group-success-test.js @@ -3,8 +3,6 @@ * SPDX-License-Identifier: BUSL-1.1 */ -import { resolve } from 'rsvp'; -import Service from '@ember/service'; import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { click, fillIn, find, render } from '@ember/test-helpers'; @@ -25,7 +23,6 @@ module('Integration | Component | control group success', function (hooks) { setupRenderingTest(hooks); hooks.beforeEach(function () { - this.store = this.owner.lookup('service:store'); this.transitionStub = sinon.stub(this.owner.lookup('service:router'), 'transitionTo'); this.controlGroup = this.owner.lookup('service:control-group'); this.markTokenForUnwrapStub = sinon.stub(this.controlGroup, 'markTokenForUnwrap'); @@ -75,21 +72,15 @@ module('Integration | Component | control group success', function (hooks) { test('it unwraps data on submit', async function (assert) { assert.expect(2); - const storeService = Service.extend({ - adapterFor() { - return { - toolAction() { - return resolve({ data: { foo: 'bar' } }); - }, - }; - }, - }); - this.owner.unregister('service:store'); - this.owner.register('service:store', storeService); + + sinon.stub(this.owner.lookup('service:api').sys, 'unwrap').resolves({ data: { foo: 'bar' } }); + await render(hbs``); assert.dom(SELECTORS.tokenInput).hasValue(''); + await fillIn(SELECTORS.tokenInput, 'token'); await click(SELECTORS.unwrap); + const actual = find(SELECTORS.jsonViewer).innerText; const expected = JSON.stringify({ foo: 'bar' }, null, 2); assert.strictEqual(actual, expected, `it renders unwrapped data: ${actual}`); diff --git a/ui/tests/unit/adapters/tools-test.js b/ui/tests/unit/adapters/tools-test.js deleted file mode 100644 index 9a72810264..0000000000 --- a/ui/tests/unit/adapters/tools-test.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 - */ - -import { resolve } from 'rsvp'; -import { module, test } from 'qunit'; -import { setupTest } from 'ember-qunit'; - -module('Unit | Adapter | tools', function (hooks) { - setupTest(hooks); - - test('wrapping api urls', function (assert) { - let url, method, options; - const adapter = this.owner.factoryFor('adapter:tools').create({ - ajax: (...args) => { - [url, method, options] = args; - return resolve(); - }, - }); - - let clientToken; - let data = { foo: 'bar' }; - adapter.toolAction('wrap', data, { wrapTTL: '30m' }); - assert.strictEqual(url, '/v1/sys/wrapping/wrap', 'wrapping:wrap url OK'); - assert.strictEqual(method, 'POST', 'wrapping:wrap method OK'); - assert.deepEqual({ data: data, wrapTTL: '30m', clientToken }, options, 'wrapping:wrap options OK'); - - data = { token: 'token' }; - adapter.toolAction('lookup', data); - assert.strictEqual(url, '/v1/sys/wrapping/lookup', 'wrapping:lookup url OK'); - assert.strictEqual(method, 'POST', 'wrapping:lookup method OK'); - assert.deepEqual({ data, clientToken }, options, 'wrapping:lookup options OK'); - - adapter.toolAction('unwrap', data); - assert.strictEqual(url, '/v1/sys/wrapping/unwrap', 'wrapping:unwrap url OK'); - assert.strictEqual(method, 'POST', 'wrapping:unwrap method OK'); - assert.deepEqual({ data, clientToken }, options, 'wrapping:unwrap options OK'); - - adapter.toolAction('rewrap', data); - assert.strictEqual(url, '/v1/sys/wrapping/rewrap', 'wrapping:rewrap url OK'); - assert.strictEqual(method, 'POST', 'wrapping:rewrap method OK'); - assert.deepEqual({ data, clientToken }, options, 'wrapping:rewrap options OK'); - }); - - test('tools api urls', function (assert) { - let url, method; - const adapter = this.owner.factoryFor('adapter:tools').create({ - ajax: (...args) => { - [url, method] = args; - return resolve(); - }, - }); - - adapter.toolAction('hash', { input: 'someBase64' }); - assert.strictEqual(url, '/v1/sys/tools/hash', 'sys tools hash: url OK'); - assert.strictEqual(method, 'POST', 'sys tools hash: method OK'); - - adapter.toolAction('random', { bytes: '32' }); - assert.strictEqual(url, '/v1/sys/tools/random', 'sys tools random: url OK'); - assert.strictEqual(method, 'POST', 'sys tools random: method OK'); - }); -});