open-nomad/ui/app/abilities/job.js
2023-04-10 15:36:59 +00:00

77 lines
2.1 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import AbstractAbility from './abstract';
import { computed, get } from '@ember/object';
import { or } from '@ember/object/computed';
export default class Job extends AbstractAbility {
@or('bypassAuthorization', 'selfTokenIsManagement', 'policiesSupportRunning')
canRun;
@or(
'bypassAuthorization',
'selfTokenIsManagement',
'specificNamespaceSupportsRunning',
'policiesSupportScaling'
)
canScale;
// TODO: A person can also see all jobs if their token grants read access to all namespaces,
// but given the complexity of namespaces and policy precedence, there isn't a good quick way
// to confirm this.
@or('bypassAuthorization', 'selfTokenIsManagement')
canListAll;
@or(
'bypassAuthorization',
'selfTokenIsManagement',
'policiesSupportDispatching'
)
canDispatch;
policyNamespacesIncludePermissions(policies = [], permissions = []) {
// For each policy record, extract all policies of all namespaces
const allNamespacePolicies = policies
.toArray()
.filter((policy) => get(policy, 'rulesJSON.Namespaces'))
.map((policy) => get(policy, 'rulesJSON.Namespaces'))
.flat()
.map((namespace = {}) => {
return namespace.Capabilities;
})
.flat()
.compact();
// Check for requested permissions
return allNamespacePolicies.some((policy) => {
return permissions.includes(policy);
});
}
@computed('token.selfTokenPolicies.[]')
get policiesSupportRunning() {
return this.policyNamespacesIncludePermissions(
this.token.selfTokenPolicies,
['submit-job']
);
}
@computed('rulesForNamespace.@each.capabilities')
get specificNamespaceSupportsRunning() {
return this.namespaceIncludesCapability('submit-job');
}
@computed('rulesForNamespace.@each.capabilities')
get policiesSupportScaling() {
return this.namespaceIncludesCapability('scale-job');
}
@computed('rulesForNamespace.@each.capabilities')
get policiesSupportDispatching() {
return this.namespaceIncludesCapability('dispatch-job');
}
}