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:
parent
721905b628
commit
dc20fc88b9
|
@ -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,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue