751f8552b2
In order to continue supporting the legacy ACL system, we replace the 500 error from a non-existent `self` endpoint with a response of a `null` `AccessorID` - which makes sense (a null AccessorID means old API) We then redirect the user to the old ACL pages which then gives a 403 if their token was wrong which then redirects them back to the login page. Due to the multiple redirects and not wanting to test the validity of the token before redirecting (thus calling the same API endpoint twice), it is not straightforwards to turn the 'faked' response from the `self` endpoint into an error (flash messages are 'lost' through multiple redirects). In order to make this a slightly better experience, you can now return a `false` during execution of an action requiring success/failure feedback, this essentially skips the notification, so if the action is 'successful' but you don't want to show the notification, you can. This resolves showing a successful notification when the `self` endpoint response is faked. The last part of the puzzle is to make sure that the global 403 catching error in the application Route also produces an erroneous notification. Please note this can only happen with a ui client using the new ACL system when communicating with a cluster using the old ACL system, and only when you enter the wrong token. Lastly, further acceptance tests have been added around this This commit also adds functionality to avoid any possible double notification messages, to avoid UI overlapping
103 lines
3.5 KiB
JavaScript
103 lines
3.5 KiB
JavaScript
import Route from '@ember/routing/route';
|
|
import { inject as service } from '@ember/service';
|
|
import { hash } from 'rsvp';
|
|
import { get } from '@ember/object';
|
|
import { next } from '@ember/runloop';
|
|
import { Promise } from 'rsvp';
|
|
import WithBlockingActions from 'consul-ui/mixins/with-blocking-actions';
|
|
const $html = document.documentElement;
|
|
const removeLoading = function() {
|
|
return $html.classList.remove('ember-loading');
|
|
};
|
|
export default Route.extend(WithBlockingActions, {
|
|
init: function() {
|
|
this._super(...arguments);
|
|
},
|
|
repo: service('repository/dc'),
|
|
settings: service('settings'),
|
|
actions: {
|
|
loading: function(transition, originRoute) {
|
|
let dc = null;
|
|
if (originRoute.routeName !== 'dc') {
|
|
const model = this.modelFor('dc') || { dcs: null, dc: { Name: null } };
|
|
dc = get(this, 'repo').getActive(model.dc.Name, model.dcs);
|
|
}
|
|
hash({
|
|
loading: !$html.classList.contains('ember-loading'),
|
|
dc: dc,
|
|
}).then(model => {
|
|
next(() => {
|
|
const controller = this.controllerFor('application');
|
|
controller.setProperties(model);
|
|
transition.promise.finally(function() {
|
|
removeLoading();
|
|
controller.setProperties({
|
|
loading: false,
|
|
dc: model.dc,
|
|
});
|
|
});
|
|
});
|
|
});
|
|
return true;
|
|
},
|
|
error: function(e, transition) {
|
|
// TODO: Normalize all this better
|
|
let error = {
|
|
status: e.code || '',
|
|
message: e.message || e.detail || 'Error',
|
|
};
|
|
if (e.errors && e.errors[0]) {
|
|
error = e.errors[0];
|
|
error.message = error.title || error.detail || 'Error';
|
|
}
|
|
// TODO: Unfortunately ember will not maintain the correct URL
|
|
// for you i.e. when this happens the URL in your browser location bar
|
|
// will be the URL where you clicked on the link to come here
|
|
// not the URL where you got the 403 response
|
|
// Currently this is dealt with a lot better with the new ACLs system, in that
|
|
// if you get a 403 in the ACLs area, the URL is correct
|
|
// Moving that app wide right now wouldn't be ideal, therefore simply redirect
|
|
// to the ACLs URL instead of maintaining the actual URL, which is better than the old
|
|
// 403 page
|
|
// To note: Consul only gives you back a 403 if a non-existent token has been sent in the header
|
|
// if a token has not been sent at all, it just gives you a 200 with an empty dataset
|
|
const model = this.modelFor('dc');
|
|
if (error.status === '403') {
|
|
return get(this, 'feedback').execute(() => {
|
|
return get(this, 'settings')
|
|
.delete('token')
|
|
.then(() => {
|
|
return Promise.reject(this.transitionTo('dc.acls.tokens', model.dc.Name));
|
|
});
|
|
}, 'authorize');
|
|
}
|
|
if (error.status === '') {
|
|
error.message = 'Error';
|
|
}
|
|
hash({
|
|
error: error,
|
|
dc:
|
|
error.status.toString().indexOf('5') !== 0
|
|
? get(this, 'repo').getActive()
|
|
: model && model.dc
|
|
? model.dc
|
|
: { Name: 'Error' },
|
|
dcs: model && model.dcs ? model.dcs : [],
|
|
})
|
|
.then(model => {
|
|
removeLoading();
|
|
next(() => {
|
|
this.controllerFor('error').setProperties(model);
|
|
});
|
|
})
|
|
.catch(e => {
|
|
removeLoading();
|
|
next(() => {
|
|
this.controllerFor('error').setProperties({ error: error });
|
|
});
|
|
});
|
|
return true;
|
|
},
|
|
},
|
|
});
|