[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
This commit is contained in:
Jordan Reimer 2025-03-26 13:51:59 -06:00 committed by GitHub
parent 0d8e67abac
commit cd0cd0a175
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 16 additions and 113 deletions

View File

@ -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);
},
});

View File

@ -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}`);
}
})
),

View File

@ -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(),

View File

@ -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'
);

View File

@ -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`<ControlGroupSuccess @model={{this.model}} />`);
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}`);

View File

@ -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');
});
});