github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/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 import classic from 'ember-classic-decorator'; 10 11 @classic 12 export default class TokenService extends Service { 13 @service store; 14 @service system; 15 16 aclEnabled = true; 17 18 @computed 19 get secret() { 20 return window.localStorage.nomadTokenSecret; 21 } 22 23 set secret(value) { 24 if (value == null) { 25 window.localStorage.removeItem('nomadTokenSecret'); 26 } else { 27 window.localStorage.nomadTokenSecret = value; 28 } 29 } 30 31 @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 fetchSelfToken; 44 45 @computed('secret', 'fetchSelfToken.lastSuccessful.value') 46 get selfToken() { 47 if (this.secret) return this.get('fetchSelfToken.lastSuccessful.value'); 48 return undefined; 49 } 50 51 @task(function*() { 52 try { 53 if (this.selfToken) { 54 return yield this.selfToken.get('policies'); 55 } else { 56 let policy = yield this.store.findRecord('policy', 'anonymous'); 57 return [policy]; 58 } 59 } catch (e) { 60 return []; 61 } 62 }) 63 fetchSelfTokenPolicies; 64 65 @alias('fetchSelfTokenPolicies.lastSuccessful.value') selfTokenPolicies; 66 67 @task(function*() { 68 yield this.fetchSelfToken.perform(); 69 if (this.aclEnabled) { 70 yield this.fetchSelfTokenPolicies.perform(); 71 } 72 }) 73 fetchSelfTokenAndPolicies; 74 75 // All non Ember Data requests should go through authorizedRequest. 76 // However, the request that gets regions falls into that category. 77 // This authorizedRawRequest is necessary in order to fetch data 78 // with the guarantee of a token but without the automatic region 79 // param since the region cannot be known at this point. 80 authorizedRawRequest(url, options = {}) { 81 const credentials = 'include'; 82 const headers = {}; 83 const token = this.secret; 84 85 if (token) { 86 headers['X-Nomad-Token'] = token; 87 } 88 89 return fetch(url, assign(options, { headers, credentials })); 90 } 91 92 authorizedRequest(url, options) { 93 if (this.get('system.shouldIncludeRegion')) { 94 const region = this.get('system.activeRegion'); 95 if (region && url.indexOf('region=') === -1) { 96 url = addParams(url, { region }); 97 } 98 } 99 100 return this.authorizedRawRequest(url, options); 101 } 102 103 reset() { 104 this.fetchSelfToken.cancelAll({ resetState: true }); 105 this.fetchSelfTokenPolicies.cancelAll({ resetState: true }); 106 this.fetchSelfTokenAndPolicies.cancelAll({ resetState: true }); 107 } 108 } 109 110 function addParams(url, params) { 111 const paramsStr = queryString.stringify(params); 112 const delimiter = url.includes('?') ? '&' : '?'; 113 return `${url}${delimiter}${paramsStr}`; 114 }