Skip to content

Commit

Permalink
Capture ACL Token from self API call for Reverse Proxy use-case (#10563)
Browse files Browse the repository at this point in the history
* Proposed fix for #10561

Signed-off-by: Georges-Etienne Legendre <legege@legege.com>

* Add acceptance tests for reverse proxy use-case

Signed-off-by: Georges-Etienne Legendre <legege@legege.com>

* Use reads instead of computed/get

Signed-off-by: Georges-Etienne Legendre <legege@legege.com>

* Move back the line closer to the task

Signed-off-by: Georges-Etienne Legendre <legege@legege.com>

* skip a11y-audit-called lint rule on reverse proxy tests

Co-authored-by: Luiz Aoqui <luiz@hashicorp.com>
  • Loading branch information
legege and lgfa29 committed Jul 13, 2021
1 parent e7dbd5a commit 86fca8f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 7 deletions.
10 changes: 3 additions & 7 deletions ui/app/services/token.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Service, { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
import { alias, reads } from '@ember/object/computed';
import { getOwner } from '@ember/application';
import { assign } from '@ember/polyfills';
import { task } from 'ember-concurrency';
Expand Down Expand Up @@ -42,19 +42,15 @@ export default class TokenService extends Service {
})
fetchSelfToken;

@reads('fetchSelfToken.lastSuccessful.value') selfToken;

async exchangeOneTimeToken(oneTimeToken) {
const TokenAdapter = getOwner(this).lookup('adapter:token');

const token = await TokenAdapter.exchangeOneTimeToken(oneTimeToken);
this.secret = token.secret;
}

@computed('secret', 'fetchSelfToken.lastSuccessful.value')
get selfToken() {
if (this.secret) return this.get('fetchSelfToken.lastSuccessful.value');
return undefined;
}

@task(function*() {
try {
if (this.selfToken) {
Expand Down
51 changes: 51 additions & 0 deletions ui/tests/acceptance/proxy-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* eslint-disable ember-a11y-testing/a11y-audit-called */ // Tests for non-UI behaviour.
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import Jobs from 'nomad-ui/tests/pages/jobs/list';

let managementToken;

module('Acceptance | reverse proxy', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);

hooks.beforeEach(function() {
window.localStorage.clear();
window.sessionStorage.clear();

server.create('agent');
managementToken = server.create('token');

// Simulate a reverse proxy injecting X-Nomad-Token header for all requests
this._originalXMLHttpRequestSend = XMLHttpRequest.prototype.send;
(function(send) {
XMLHttpRequest.prototype.send = function(data) {
this.setRequestHeader('X-Nomad-Token', managementToken.secretId);
send.call(this, data);
};
})(this._originalXMLHttpRequestSend);
});

hooks.afterEach(function() {
XMLHttpRequest.prototype.send = this._originalXMLHttpRequestSend;
});

test('when token is inserted by a reverse proxy, the UI is adjusted', async function(assert) {
// when token is inserted by reserve proxy, the token is reverse proxy
const { secretId } = managementToken;

await Jobs.visit();
assert.ok(window.localStorage.nomadTokenSecret == null, 'No token secret set');

// Make sure that server received the header
assert.ok(
server.pretender.handledRequests
.mapBy('requestHeaders')
.every(headers => headers['X-Nomad-Token'] === secretId),
'The token header is always present'
);

assert.notOk(Jobs.runJobButton.isDisabled, 'Run job button is enabled');
});
});

0 comments on commit 86fca8f

Please sign in to comment.