github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/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  import classic from 'ember-classic-decorator';
     6  
     7  @classic
     8  export default class Abstract extends Ability {
     9    @service system;
    10    @service token;
    11  
    12    @not('token.aclEnabled') bypassAuthorization;
    13    @equal('token.selfToken.type', 'management') selfTokenIsManagement;
    14  
    15    @computed('system.activeNamespace.name')
    16    get activeNamespace() {
    17      return this.get('system.activeNamespace.name') || 'default';
    18    }
    19  
    20    @computed('activeNamespace', 'token.selfTokenPolicies.[]')
    21    get rulesForActiveNamespace() {
    22      let activeNamespace = this.activeNamespace;
    23  
    24      return (this.get('token.selfTokenPolicies') || []).toArray().reduce((rules, policy) => {
    25        let policyNamespaces = get(policy, 'rulesJSON.Namespaces') || [];
    26  
    27        let matchingNamespace = this._findMatchingNamespace(policyNamespaces, activeNamespace);
    28  
    29        if (matchingNamespace) {
    30          rules.push(policyNamespaces.find(namespace => namespace.Name === matchingNamespace));
    31        }
    32  
    33        return rules;
    34      }, []);
    35    }
    36  
    37    @computed('token.selfTokenPolicies.[]')
    38    get capabilitiesForAllNamespaces() {
    39      return (this.get('token.selfTokenPolicies') || [])
    40        .toArray()
    41        .reduce((allCapabilities, policy) => {
    42          (get(policy, 'rulesJSON.Namespaces') || []).forEach(({ Capabilities }) => {
    43            allCapabilities = allCapabilities.concat(Capabilities);
    44          });
    45          return allCapabilities;
    46        }, []);
    47    }
    48  
    49    activeNamespaceIncludesCapability(capability) {
    50      return this.rulesForActiveNamespace.some(rules => {
    51        let capabilities = get(rules, 'Capabilities') || [];
    52        return capabilities.includes(capability);
    53      });
    54    }
    55  
    56    @computed('system.features.[]')
    57    get features() {
    58      return this.system.features;
    59    }
    60  
    61    featureIsPresent(featureName) {
    62      return this.features.includes(featureName);
    63    }
    64  
    65    // Chooses the closest namespace as described at the bottom here:
    66    // https://learn.hashicorp.com/tutorials/nomad/access-control-policies?in=nomad/access-control#namespace-rules
    67    _findMatchingNamespace(policyNamespaces, activeNamespace) {
    68      let namespaceNames = policyNamespaces.mapBy('Name');
    69  
    70      if (namespaceNames.includes(activeNamespace)) {
    71        return activeNamespace;
    72      }
    73  
    74      let globNamespaceNames = namespaceNames.filter(namespaceName => namespaceName.includes('*'));
    75  
    76      let matchingNamespaceName = globNamespaceNames.reduce(
    77        (mostMatching, namespaceName) => {
    78          // Convert * wildcards to .* for regex matching
    79          let namespaceNameRegExp = new RegExp(namespaceName.replace(/\*/g, '.*'));
    80          let characterDifference = activeNamespace.length - namespaceName.length;
    81  
    82          if (
    83            characterDifference < mostMatching.mostMatchingCharacterDifference &&
    84            activeNamespace.match(namespaceNameRegExp)
    85          ) {
    86            return {
    87              mostMatchingNamespaceName: namespaceName,
    88              mostMatchingCharacterDifference: characterDifference,
    89            };
    90          } else {
    91            return mostMatching;
    92          }
    93        },
    94        { mostMatchingNamespaceName: null, mostMatchingCharacterDifference: Number.MAX_SAFE_INTEGER }
    95      ).mostMatchingNamespaceName;
    96  
    97      if (matchingNamespaceName) {
    98        return matchingNamespaceName;
    99      } else if (namespaceNames.includes('default')) {
   100        return 'default';
   101      }
   102    }
   103  }