github.com/aminovpavel/nomad@v0.11.8/ui/app/abilities/abstract.js (about) 1 import { Ability } from 'ember-can'; 2 import { inject as service } from '@ember/service'; 3 import { computed, get } from '@ember/object'; 4 import { equal, not } from '@ember/object/computed'; 5 6 export default Ability.extend({ 7 system: service(), 8 token: service(), 9 10 bypassAuthorization: not('token.aclEnabled'), 11 selfTokenIsManagement: equal('token.selfToken.type', 'management'), 12 13 activeNamespace: computed('system.activeNamespace.name', function() { 14 return this.get('system.activeNamespace.name') || 'default'; 15 }), 16 17 rulesForActiveNamespace: computed('activeNamespace', 'token.selfTokenPolicies.[]', function() { 18 let activeNamespace = this.activeNamespace; 19 20 return (this.get('token.selfTokenPolicies') || []).toArray().reduce((rules, policy) => { 21 let policyNamespaces = get(policy, 'rulesJSON.Namespaces') || []; 22 23 let matchingNamespace = this._findMatchingNamespace(policyNamespaces, activeNamespace); 24 25 if (matchingNamespace) { 26 rules.push(policyNamespaces.find(namespace => namespace.Name === matchingNamespace)); 27 } 28 29 return rules; 30 }, []); 31 }), 32 33 // Chooses the closest namespace as described at the bottom here: 34 // https://www.nomadproject.io/guides/security/acl.html#namespace-rules 35 _findMatchingNamespace(policyNamespaces, activeNamespace) { 36 let namespaceNames = policyNamespaces.mapBy('Name'); 37 38 if (namespaceNames.includes(activeNamespace)) { 39 return activeNamespace; 40 } 41 42 let globNamespaceNames = namespaceNames.filter(namespaceName => namespaceName.includes('*')); 43 44 let matchingNamespaceName = globNamespaceNames.reduce( 45 (mostMatching, namespaceName) => { 46 // Convert * wildcards to .* for regex matching 47 let namespaceNameRegExp = new RegExp(namespaceName.replace(/\*/g, '.*')); 48 let characterDifference = activeNamespace.length - namespaceName.length; 49 50 if ( 51 characterDifference < mostMatching.mostMatchingCharacterDifference && 52 activeNamespace.match(namespaceNameRegExp) 53 ) { 54 return { 55 mostMatchingNamespaceName: namespaceName, 56 mostMatchingCharacterDifference: characterDifference, 57 }; 58 } else { 59 return mostMatching; 60 } 61 }, 62 { mostMatchingNamespaceName: null, mostMatchingCharacterDifference: Number.MAX_SAFE_INTEGER } 63 ).mostMatchingNamespaceName; 64 65 if (matchingNamespaceName) { 66 return matchingNamespaceName; 67 } else if (namespaceNames.includes('default')) { 68 return 'default'; 69 } 70 }, 71 });