mirror of https://github.com/hashicorp/consul
139 lines
5.1 KiB
JavaScript
139 lines
5.1 KiB
JavaScript
import Component from '@ember/component';
|
|
import { inject as service } from '@ember/service';
|
|
import { get, set, computed } from '@ember/object';
|
|
import { getOwner } from '@ember/application';
|
|
|
|
export default Component.extend({
|
|
dom: service('dom'),
|
|
env: service('env'),
|
|
feedback: service('feedback'),
|
|
router: service('router'),
|
|
http: service('repository/type/event-source'),
|
|
client: service('client/http'),
|
|
store: service('store'),
|
|
settings: service('settings'),
|
|
|
|
didInsertElement: function() {
|
|
this.dom.root().classList.remove('template-with-vertical-menu');
|
|
},
|
|
// TODO: Right now this is the only place where we need permissions
|
|
// but we are likely to need it elsewhere, so probably need a nice helper
|
|
canManageNspaces: computed('permissions', function() {
|
|
return (
|
|
typeof (this.permissions || []).find(function(item) {
|
|
return item.Resource === 'operator' && item.Access === 'write' && item.Allow;
|
|
}) !== 'undefined'
|
|
);
|
|
}),
|
|
forwardForACL: function(token) {
|
|
let routeName = this.router.currentRouteName;
|
|
const route = getOwner(this).lookup(`route:${routeName}`);
|
|
// a null AccessorID means we are in legacy mode
|
|
// take the user to the legacy acls
|
|
// otherwise just refresh the page
|
|
if (get(token, 'AccessorID') === null) {
|
|
// returning false for a feedback action means even though
|
|
// its successful, please skip this notification and don't display it
|
|
return route.transitionTo('dc.acls');
|
|
} else {
|
|
// TODO: Ideally we wouldn't need to use env() at a component level
|
|
// transitionTo should probably remove it instead if NSPACES aren't enabled
|
|
if (this.env.var('CONSUL_NSPACES_ENABLED') && get(token, 'Namespace') !== this.nspace) {
|
|
if (!routeName.startsWith('nspace')) {
|
|
routeName = `nspace.${routeName}`;
|
|
}
|
|
return route.transitionTo(`${routeName}`, `~${get(token, 'Namespace')}`, this.dc.Name);
|
|
} else {
|
|
if (route.routeName === 'dc.acls.index') {
|
|
return route.transitionTo('dc.acls.tokens.index');
|
|
}
|
|
return route.refresh();
|
|
}
|
|
}
|
|
},
|
|
actions: {
|
|
send: function(el, method, ...rest) {
|
|
const component = this.dom.component(el);
|
|
component.actions[method].apply(component, rest || []);
|
|
},
|
|
changeToken: function(token = {}) {
|
|
const prev = this.token;
|
|
if (token === '') {
|
|
token = {};
|
|
}
|
|
set(this, 'token', token);
|
|
// if this is just the initial 'find out what the current token is'
|
|
// then don't do anything
|
|
if (typeof prev === 'undefined') {
|
|
return;
|
|
}
|
|
let notification;
|
|
let action = () => this.forwardForACL(token);
|
|
switch (true) {
|
|
case get(this, 'token.AccessorID') === null && get(this, 'token.SecretID') === null:
|
|
// 'everything is null, 403 this needs deleting' token
|
|
this.settings.delete('token');
|
|
return;
|
|
case get(prev, 'AccessorID') === null && get(prev, 'SecretID') === null:
|
|
// we just had an 'everything is null, this needs deleting' token
|
|
// reject and break so this acts differently to just logging out
|
|
action = () => Promise.reject({});
|
|
notification = 'authorize';
|
|
break;
|
|
case typeof get(prev, 'AccessorID') !== 'undefined' &&
|
|
typeof get(this, 'token.AccessorID') !== 'undefined':
|
|
// change of both Accessor and Secret, means use
|
|
notification = 'use';
|
|
break;
|
|
case get(this, 'token.AccessorID') === null &&
|
|
typeof get(this, 'token.SecretID') !== 'undefined':
|
|
// legacy login, don't do anything as we don't use self for auth here but the endpoint itself
|
|
// self is successful, but skip this notification and don't display it
|
|
return this.forwardForACL(token);
|
|
case typeof get(prev, 'AccessorID') === 'undefined' &&
|
|
typeof get(this, 'token.AccessorID') !== 'undefined':
|
|
// normal login
|
|
notification = 'authorize';
|
|
break;
|
|
case (typeof get(prev, 'AccessorID') !== 'undefined' || get(prev, 'AccessorID') === null) &&
|
|
typeof get(this, 'token.AccessorID') === 'undefined':
|
|
//normal logout
|
|
notification = 'logout';
|
|
break;
|
|
}
|
|
this.actions.reauthorize.apply(this, [
|
|
{
|
|
type: notification,
|
|
action: action,
|
|
},
|
|
]);
|
|
},
|
|
reauthorize: function(e) {
|
|
this.client.abort();
|
|
this.http.resetCache();
|
|
this.store.init();
|
|
const type = get(e, 'type');
|
|
this.feedback.execute(
|
|
e.action,
|
|
type,
|
|
function(type, e) {
|
|
return type;
|
|
},
|
|
{}
|
|
);
|
|
},
|
|
change: function(e) {
|
|
const win = this.dom.viewport();
|
|
const $root = this.dom.root();
|
|
const $body = this.dom.element('body');
|
|
if (e.target.checked) {
|
|
$root.classList.add('template-with-vertical-menu');
|
|
$body.style.height = $root.style.height = win.innerHeight + 'px';
|
|
} else {
|
|
$root.classList.remove('template-with-vertical-menu');
|
|
$body.style.height = $root.style.height = null;
|
|
}
|
|
},
|
|
},
|
|
});
|