github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/ui/app/services/token.js (about) 1 import Service, { inject as service } from '@ember/service'; 2 import { computed } from '@ember/object'; 3 import { alias } from '@ember/object/computed'; 4 import { getOwner } from '@ember/application'; 5 import { assign } from '@ember/polyfills'; 6 import { task } from 'ember-concurrency'; 7 import queryString from 'query-string'; 8 import fetch from 'nomad-ui/utils/fetch'; 9 10 export default Service.extend({ 11 store: service(), 12 system: service(), 13 14 aclEnabled: true, 15 16 secret: computed({ 17 get() { 18 return window.localStorage.nomadTokenSecret; 19 }, 20 set(key, value) { 21 if (value == null) { 22 window.localStorage.removeItem('nomadTokenSecret'); 23 } else { 24 window.localStorage.nomadTokenSecret = value; 25 } 26 27 return value; 28 }, 29 }), 30 31 fetchSelfToken: task(function*() { 32 const TokenAdapter = getOwner(this).lookup('adapter:token'); 33 try { 34 return yield TokenAdapter.findSelf(); 35 } catch (e) { 36 const errors = e.errors ? e.errors.mapBy('detail') : []; 37 if (errors.find(error => error === 'ACL support disabled')) { 38 this.set('aclEnabled', false); 39 } 40 return null; 41 } 42 }), 43 44 selfToken: computed('secret', 'fetchSelfToken.lastSuccessful.value', function() { 45 if (this.secret) return this.get('fetchSelfToken.lastSuccessful.value'); 46 }), 47 48 fetchSelfTokenPolicies: task(function*() { 49 try { 50 if (this.selfToken) { 51 return yield this.selfToken.get('policies'); 52 } else { 53 let policy = yield this.store.findRecord('policy', 'anonymous'); 54 return [policy]; 55 } 56 } catch (e) { 57 return []; 58 } 59 }), 60 61 selfTokenPolicies: alias('fetchSelfTokenPolicies.lastSuccessful.value'), 62 63 fetchSelfTokenAndPolicies: task(function*() { 64 yield this.fetchSelfToken.perform(); 65 if (this.aclEnabled) { 66 yield this.fetchSelfTokenPolicies.perform(); 67 } 68 }), 69 70 // All non Ember Data requests should go through authorizedRequest. 71 // However, the request that gets regions falls into that category. 72 // This authorizedRawRequest is necessary in order to fetch data 73 // with the guarantee of a token but without the automatic region 74 // param since the region cannot be known at this point. 75 authorizedRawRequest(url, options = {}) { 76 const credentials = 'include'; 77 const headers = {}; 78 const token = this.secret; 79 80 if (token) { 81 headers['X-Nomad-Token'] = token; 82 } 83 84 return fetch(url, assign(options, { headers, credentials })); 85 }, 86 87 authorizedRequest(url, options) { 88 if (this.get('system.shouldIncludeRegion')) { 89 const region = this.get('system.activeRegion'); 90 if (region) { 91 url = addParams(url, { region }); 92 } 93 } 94 95 return this.authorizedRawRequest(url, options); 96 }, 97 98 reset() { 99 this.fetchSelfToken.cancelAll({ resetState: true }); 100 this.fetchSelfTokenPolicies.cancelAll({ resetState: true }); 101 this.fetchSelfTokenAndPolicies.cancelAll({ resetState: true }); 102 }, 103 }); 104 105 function addParams(url, params) { 106 const paramsStr = queryString.stringify(params); 107 const delimiter = url.includes('?') ? '&' : '?'; 108 return `${url}${delimiter}${paramsStr}`; 109 }