import { resolve, reject } from 'rsvp'; import { observer } from '@ember/object'; import { alias } from '@ember/object/computed'; import { on } from '@ember/object/evented'; import { next } from '@ember/runloop'; import { hash } from 'rsvp' import Service, { inject as service } from '@ember/service'; import C from 'shared/utils/constants'; import { get, set } from '@ember/object'; import { isArray } from '@ember/array'; export default Service.extend({ cookies: service(), settings: service(), session: service(), shibbolethAuth: service(), globalStore: service(), clusterStore: service(), projectStore: service('store'), app: service(), me: null, userCode: null, firstLogin: null, // These are set by authenticated/route // Is access control enabled enabled: true, // @TODO-2.0 remove this, always enabled // What kind of access control provider: null, // @TODO-2.0 remove this, and how do i check? providers: null, principal: null, // Are you an admin admin: alias('me.hasAdmin'), mustChangePassword: alias('me.mustChangePassword'), // The identity from the session isn't an actual identity model... identity: null, identityObsvr: on('init', observer(`session.${ C.SESSION.IDENTITY }`, function() { var obj = this.get(`session.${ C.SESSION.IDENTITY }`) || {}; obj.type = 'identity'; this.set('identity', this.get('globalStore').createRecord(obj)); })), testAuth() { // make a call to api base because it is authenticated return this.get('globalStore').rawRequest({ url: '', }).then((/* xhr*/) => { // Auth token still good return resolve('Auth Succeeded'); }, (/* err */) => { // Auth token expired return reject('Auth Failed'); }); }, detect() { const globalStore = get(this, 'globalStore'); return hash({ pl: globalStore.request({ url: `settings/${ C.SETTING.PL }` }), firstSetting: globalStore.request({ url: `settings/${ C.SETTING.FIRST_LOGIN }` }), providers: globalStore.request({ url: '/v3-public/authProviders' }), }).then(({ providers, pl, firstSetting }) => { if ( providers && get(providers, 'length') ) { set(this, 'providers', providers); if (get(providers, 'length') === 1) { set(this, 'provider', get(providers, 'firstObject.id')); } } else { set(this, 'providers', []); } if ( pl ) { get(this, 'settings').notifyPropertyChange(C.SETTING.PL); } set(this, 'firstLogin', (`${ firstSetting.value }`) === 'true'); return this.loadMe(); }).catch((err) => { next(() => { set(this, 'app.initError', ( err && err.message ) ? err : { message: 'No response received' } ); }); set(this, 'providers', []); }); }, loadMe() { const globalStore = get(this, 'globalStore'); return globalStore.request({ url: 'users?me=true' }).then((users) => { const me = get(users, 'firstObject'); set(this, 'me', me); return me; }).catch((err) => { return err; }); }, shibbolethConfigured(token) { let rv = false; if ((token.authProvider || '') === 'shibbolethconfig' && token.userIdentity) { rv = true; } return rv; }, login(providerId, body) { body.description = C.SESSION.DESCRIPTION; body.responseType = 'cookie'; body.ttl = C.SESSION.TTL; body.labels = { 'ui-session': 'true', }; let url; let provider = (get(this, 'providers') || []).findBy('id', providerId); if ( provider ) { url = provider.actionLinks.login; } else { return reject({ type: 'error', message: 'Provider config not found' }); } console.log('Logging into', url); let req = this.get('globalStore').rawRequest({ method: 'POST', url, data: body, }).then(() => { return this.loadMe() .catch((res) => { let err; try { err = res.body; } catch (e) { console.log('Error loading user', e, res); err = { type: 'error', message: 'Error loading user' }; } return reject(err); }); }).catch((res) => { let err; try { err = res.body; } catch (e) { console.log('Error logging in', e, res); err = { type: 'error', message: 'Error logging in' }; } return reject(err); }); return req; }, clearToken() { return this.get('globalStore').rawRequest({ url: 'tokens?action=logout', method: 'POST', }).then(() => { return true; }); }, clearSessionKeys(all) { if ( all === true ) { this.get('session').clear(); } else { var values = {}; C.TOKEN_TO_SESSION_KEYS.forEach((key) => { values[key] = undefined; }); this.get('session').setProperties(values); } this.get('cookies').remove(C.COOKIE.TOKEN); }, allows(resource, permission, scope) { // console.log('rbac-allows',resource,permission,scope); if (!resource) { // console.log('rbac-result 1 false'); return false; } scope = scope ? scope : 'global'; permission = permission ? permission : 'list'; if (!isArray(resource)) { resource = [resource]; } const store = get(this, `${ scope }Store`); if ( !store ) { // console.log('rbac-result 2 false'); return false; } if (permission === 'list') { // console.log('rbac-result 3',!!resource.some(r => store.canList(r))); return resource.some((r) => store.canList(r)); } else if (permission === 'create') { // console.log('rbac-result 4',!!resource.some(r => store.canCreate(r))); return resource.some((r) => store.canCreate(r)); } // console.log('rbac-result 5 false'); return false; }, });