Unload all records when a token is set or cleared

This guarantees no privileged data is shown to unprivileged credentials
This commit is contained in:
Michael Lange 2017-10-18 16:42:08 -07:00
parent 721905b628
commit dc20fc88b9
4 changed files with 51 additions and 6 deletions

View File

@ -4,6 +4,7 @@ const { Controller, inject, computed, getOwner } = Ember;
export default Controller.extend({
token: inject.service(),
store: inject.service(),
secret: computed.reads('token.secret'),
@ -11,6 +12,10 @@ export default Controller.extend({
tokenIsInvalid: false,
tokenRecord: null,
resetStore() {
this.get('store').unloadAll();
},
actions: {
clearTokenProperties() {
this.get('token').setProperties({
@ -22,6 +27,7 @@ export default Controller.extend({
tokenIsInvalid: false,
tokenRecord: null,
});
this.resetStore();
},
verifyToken() {
@ -32,10 +38,20 @@ export default Controller.extend({
TokenAdapter.findSelf().then(
token => {
// Capture the token ID before clearing the store
const tokenId = token.get('id');
// Clear out all data to ensure only data the new token is privileged to
// see is shown
this.resetStore();
// Immediately refetch the token now that the store is empty
const newToken = this.get('store').findRecord('token', tokenId);
this.setProperties({
tokenIsValid: true,
tokenIsInvalid: false,
tokenRecord: token,
tokenRecord: newToken,
});
},
() => {

View File

@ -22,7 +22,9 @@ export default Mixin.create({
listToSort: computed(() => []),
listSorted: computed('listToSort.[]', 'sortProperty', 'sortDescending', function() {
const sorted = this.get('listToSort').sortBy(this.get('sortProperty'));
const sorted = this.get('listToSort')
.compact()
.sortBy(this.get('sortProperty'));
if (this.get('sortDescending')) {
return sorted.reverse();
}

View File

@ -9,9 +9,6 @@ export default Route.extend({
model({ job_id }) {
return this.get('store')
.findRecord('job', job_id, { reload: true })
.then(job => {
return job.get('allocations').then(() => job);
})
.catch(notifyError(this));
},
});

View File

@ -67,7 +67,8 @@ test('the X-Nomad-Token header gets sent with requests once it is set', function
const newRequests = server.pretender.handledRequests.slice(requestPosition);
assert.ok(newRequests.length > 1, 'New requests have been made');
newRequests.forEach(req => {
// Cross-origin requests can't have a token
newRequests.filter(req => !req.url.startsWith('//')).forEach(req => {
assert.equal(req.requestHeaders['X-Nomad-Token'], secretId, `Token set for ${req.url}`);
});
});
@ -169,3 +170,32 @@ test('a success message and associated policies are shown when authenticating su
});
});
});
test('setting a token clears the store', function(assert) {
const { secretId } = clientToken;
visit('/jobs');
andThen(() => {
assert.ok(find('.job-row'), 'Jobs found');
});
visit('/settings/tokens');
andThen(() => {
fillIn('.token-secret', secretId);
click('.token-submit');
});
// Don't return jobs from the API the second time around
andThen(() => {
server.pretender.get('/v1/jobs', function() {
return [200, {}, '[]'];
});
});
visit('/jobs');
// If jobs are lingering in the store, they would show up
assert.notOk(find('.job-row'), 'No jobs found');
});