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  });