| /** |
| * Copyright (c) HashiCorp, Inc. |
| * SPDX-License-Identifier: MPL-2.0 |
| */ |
| |
| import TransformBase, { addToList, removeFromList } from './transform-edit-base'; |
| import { inject as service } from '@ember/service'; |
| |
| export default TransformBase.extend({ |
| flashMessages: service(), |
| store: service(), |
| initialRoles: null, |
| |
| init() { |
| this._super(...arguments); |
| if (!this.model) return; |
| this.set('initialRoles', this.model.allowed_roles); |
| }, |
| |
| updateOrCreateRole(role, transformationId, backend) { |
| return this.store |
| .queryRecord('transform/role', { |
| backend, |
| id: role.id, |
| }) |
| .then((roleStore) => { |
| let transformations = roleStore.transformations; |
| if (role.action === 'ADD') { |
| transformations = addToList(transformations, transformationId); |
| } else if (role.action === 'REMOVE') { |
| transformations = removeFromList(transformations, transformationId); |
| } |
| roleStore.setProperties({ |
| backend, |
| transformations, |
| }); |
| return roleStore.save().catch((e) => { |
| return { |
| errorStatus: e.httpStatus, |
| ...role, |
| }; |
| }); |
| }) |
| .catch((e) => { |
| if (e.httpStatus !== 403 && role.action === 'ADD') { |
| // If role doesn't yet exist, create it with this transformation attached |
| var newRole = this.store.createRecord('transform/role', { |
| id: role.id, |
| name: role.id, |
| transformations: [transformationId], |
| backend, |
| }); |
| return newRole.save().catch((e) => { |
| return { |
| errorStatus: e.httpStatus, |
| ...role, |
| action: 'CREATE', |
| }; |
| }); |
| } |
| |
| return { |
| ...role, |
| errorStatus: e.httpStatus, |
| }; |
| }); |
| }, |
| |
| handleUpdateRoles(updateRoles, transformationId) { |
| if (!updateRoles) return; |
| const backend = this.model.backend; |
| const promises = updateRoles.map((r) => this.updateOrCreateRole(r, transformationId, backend)); |
| |
| Promise.all(promises).then((results) => { |
| const hasError = results.find((role) => !!role.errorStatus); |
| |
| if (hasError) { |
| let message = |
| 'The edits to this transformation were successful, but transformations for its roles was not edited due to a lack of permissions.'; |
| if (results.find((e) => !!e.errorStatus && e.errorStatus !== 403)) { |
| // if the errors weren't all due to permissions show generic message |
| // eg. trying to update a role with empty array as transformations |
| message = `You've edited the allowed_roles for this transformation. However, the corresponding edits to some roles' transformations were not made`; |
| } |
| this.flashMessages.info(message, { |
| sticky: true, |
| priority: 300, |
| }); |
| } |
| }); |
| }, |
| |
| isWildcard(role) { |
| if (typeof role === 'string') { |
| return role.indexOf('*') >= 0; |
| } |
| if (role && role.id) { |
| return role.id.indexOf('*') >= 0; |
| } |
| return false; |
| }, |
| |
| actions: { |
| createOrUpdate(type, event) { |
| event.preventDefault(); |
| |
| this.applyChanges('save', () => { |
| const transformationId = this.model.id || this.model.name; |
| const newModelRoles = this.model.allowed_roles || []; |
| const initialRoles = this.initialRoles || []; |
| |
| const updateRoles = [...newModelRoles, ...initialRoles] |
| .filter((r) => !this.isWildcard(r)) // CBS TODO: expand wildcards into included roles instead |
| .map((role) => { |
| if (initialRoles.indexOf(role) < 0) { |
| return { |
| id: role, |
| action: 'ADD', |
| }; |
| } |
| if (newModelRoles.indexOf(role) < 0) { |
| return { |
| id: role, |
| action: 'REMOVE', |
| }; |
| } |
| return null; |
| }) |
| .filter((r) => !!r); |
| this.handleUpdateRoles(updateRoles, transformationId); |
| }); |
| }, |
| }, |
| }); |