mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-03 03:58:01 +00:00
Handle promise-proxy deprecation (#28563)
* fix promise issues on transformation-edit * fix one test and the transition problem * cannot call capabilities service directly inside template because its an unresolved promise * address transit capabilities issues * remove deprecations line for promise-proxies * handle hot mess of delete permissions and such * blah * update flash message language. It will now show a flash message for each role whose transformationw as not removed. * small wording change * one small change to the default flash message * Update ui/app/components/transformation-edit.js Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> * Update ui/app/components/transformation-edit.js Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> * Update ui/app/components/transformation-edit.js Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> * fix policy flow * fix linting and can't define let outside if block * fix flashmessage things * make show and edit use same param --------- Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>
This commit is contained in:
@@ -30,7 +30,7 @@
|
|||||||
{{#if (eq this.mode "show")}}
|
{{#if (eq this.mode "show")}}
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<ToolbarActions>
|
<ToolbarActions>
|
||||||
{{#if this.capabilities.canDelete}}
|
{{#if this.model.updatePath.canDelete}}
|
||||||
<Hds::Button
|
<Hds::Button
|
||||||
@text="Delete alphabet"
|
@text="Delete alphabet"
|
||||||
@color="secondary"
|
@color="secondary"
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
/>
|
/>
|
||||||
<div class="toolbar-separator"></div>
|
<div class="toolbar-separator"></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if this.capabilities.canUpdate}}
|
{{#if this.model.updatePath.canUpdate}}
|
||||||
<ToolbarSecretLink
|
<ToolbarSecretLink
|
||||||
@secret={{concat this.model.idPrefix this.model.id}}
|
@secret={{concat this.model.idPrefix this.model.id}}
|
||||||
@mode="edit"
|
@mode="edit"
|
||||||
|
|||||||
@@ -17,30 +17,12 @@ export default TransformBase.extend({
|
|||||||
this.set('initialRoles', this.model.allowed_roles);
|
this.set('initialRoles', this.model.allowed_roles);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateOrCreateRole(role, transformationId, backend) {
|
async updateOrCreateRole(role, transformationId, backend) {
|
||||||
return this.store
|
const roleRecord = await this.store
|
||||||
.queryRecord('transform/role', {
|
.queryRecord('transform/role', {
|
||||||
backend,
|
backend,
|
||||||
id: role.id,
|
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) => {
|
.catch((e) => {
|
||||||
if (e.httpStatus !== 403 && role.action === 'ADD') {
|
if (e.httpStatus !== 403 && role.action === 'ADD') {
|
||||||
// If role doesn't yet exist, create it with this transformation attached
|
// If role doesn't yet exist, create it with this transformation attached
|
||||||
@@ -64,29 +46,45 @@ export default TransformBase.extend({
|
|||||||
errorStatus: e.httpStatus,
|
errorStatus: e.httpStatus,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
// if an error occurs while querying the role, exit function and return the error
|
||||||
|
if (roleRecord.errorStatus) return roleRecord;
|
||||||
|
// otherwise update the role with the transformation and save
|
||||||
|
let transformations = roleRecord.transformations;
|
||||||
|
if (role.action === 'ADD') {
|
||||||
|
transformations = addToList(transformations, transformationId);
|
||||||
|
} else if (role.action === 'REMOVE') {
|
||||||
|
transformations = removeFromList(transformations, transformationId);
|
||||||
|
}
|
||||||
|
roleRecord.setProperties({
|
||||||
|
backend,
|
||||||
|
transformations,
|
||||||
|
});
|
||||||
|
return roleRecord.save().catch((e) => {
|
||||||
|
return {
|
||||||
|
errorStatus: e.httpStatus,
|
||||||
|
...role,
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleUpdateRoles(updateRoles, transformationId) {
|
handleUpdateRoles(updateRoles, transformationId) {
|
||||||
if (!updateRoles) return;
|
if (!updateRoles) return;
|
||||||
const backend = this.model.backend;
|
const { backend } = this.model;
|
||||||
const promises = updateRoles.map((r) => this.updateOrCreateRole(r, transformationId, backend));
|
updateRoles.forEach(async (record) => {
|
||||||
|
// For each role that needs to be updated, update the role with the transformation.
|
||||||
Promise.all(promises).then((results) => {
|
const updateOrCreateResponse = await this.updateOrCreateRole(record, transformationId, backend);
|
||||||
const hasError = results.find((role) => !!role.errorStatus);
|
// If an error was returned, check error type and show a message.
|
||||||
|
const errorStatus = updateOrCreateResponse?.errorStatus;
|
||||||
if (hasError) {
|
let message;
|
||||||
let message =
|
if (errorStatus == 403) {
|
||||||
'The edits to this transformation were successful, but transformations for its roles was not edited due to a lack of permissions.';
|
message = `The edits to this transformation were successful, but transformations for the role ${record.id} were not edited due to a lack of permissions.`;
|
||||||
if (results.find((e) => !!e.errorStatus && e.errorStatus !== 403)) {
|
} else if (errorStatus) {
|
||||||
// if the errors weren't all due to permissions show generic message
|
message = `You've edited the allowed_roles for this transformation. However, there was a problem updating the role: ${record.id}.`;
|
||||||
// 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,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
this.flashMessages.info(message, {
|
||||||
|
sticky: true,
|
||||||
|
priority: 300,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -122,11 +122,6 @@ export default class TransitKeyModel extends Model {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get canDelete() {
|
|
||||||
const deleteAttrChanged = Boolean(this.changedAttributes().deletionAllowed);
|
|
||||||
return this.deletionAllowed && deleteAttrChanged === false;
|
|
||||||
}
|
|
||||||
|
|
||||||
get keyVersions() {
|
get keyVersions() {
|
||||||
let maxVersion = Math.max(...this.validKeyVersions);
|
let maxVersion = Math.max(...this.validKeyVersions);
|
||||||
const versions = [];
|
const versions = [];
|
||||||
@@ -181,6 +176,17 @@ export default class TransitKeyModel extends Model {
|
|||||||
get canRead() {
|
get canRead() {
|
||||||
return this.secretPath.get('canUpdate') !== false;
|
return this.secretPath.get('canUpdate') !== false;
|
||||||
}
|
}
|
||||||
|
get canUpdate() {
|
||||||
|
return this.secretPath.get('canUpdate') !== false;
|
||||||
|
}
|
||||||
|
get canDelete() {
|
||||||
|
// there's more to just a permissions check here.
|
||||||
|
// must also check if there's a property on the key called deletionAllowed that is set to true
|
||||||
|
const deleteAttrChanged = Boolean(this.changedAttributes().deletionAllowed);
|
||||||
|
const keyAllowedDeletion = this.deletionAllowed && deleteAttrChanged === false;
|
||||||
|
return this.secretPath.get('canDelete') !== false && keyAllowedDeletion;
|
||||||
|
}
|
||||||
|
|
||||||
get canEdit() {
|
get canEdit() {
|
||||||
return this.secretPath.get('canUpdate') !== false;
|
return this.secretPath.get('canUpdate') !== false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export default Route.extend(UnloadModelRoute, {
|
|||||||
const type = this.policyType();
|
const type = this.policyType();
|
||||||
return hash({
|
return hash({
|
||||||
policy: this.store.findRecord(`policy/${type}`, params.policy_name),
|
policy: this.store.findRecord(`policy/${type}`, params.policy_name),
|
||||||
capabilities: this.store.findRecord('capabilities', `sys/policies/${type}/${params.policy_name}`),
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
{{#if (eq this.mode "show")}}
|
{{#if (eq this.mode "show")}}
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<ToolbarActions>
|
<ToolbarActions>
|
||||||
{{#if this.capabilities.canDelete}}
|
{{#if this.model.updatePath.canDelete}}
|
||||||
<ConfirmAction
|
<ConfirmAction
|
||||||
@buttonText="Delete role"
|
@buttonText="Delete role"
|
||||||
class="toolbar-button"
|
class="toolbar-button"
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
/>
|
/>
|
||||||
<div class="toolbar-separator"></div>
|
<div class="toolbar-separator"></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if this.capabilities.canUpdate}}
|
{{#if this.model.updatePath.canUpdate}}
|
||||||
<ToolbarSecretLink
|
<ToolbarSecretLink
|
||||||
@secret={{concat this.model.idPrefix this.model.id}}
|
@secret={{concat this.model.idPrefix this.model.id}}
|
||||||
@mode="edit"
|
@mode="edit"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
{{#if (eq this.mode "show")}}
|
{{#if (eq this.mode "show")}}
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<ToolbarActions>
|
<ToolbarActions>
|
||||||
{{#if this.capabilities.canDelete}}
|
{{#if this.model.updatePath.canDelete}}
|
||||||
<Hds::Button
|
<Hds::Button
|
||||||
@text="Delete template"
|
@text="Delete template"
|
||||||
@color="secondary"
|
@color="secondary"
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
/>
|
/>
|
||||||
<div class="toolbar-separator"></div>
|
<div class="toolbar-separator"></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if this.capabilities.canUpdate}}
|
{{#if this.model.updatePath.canUpdate}}
|
||||||
<ToolbarSecretLink
|
<ToolbarSecretLink
|
||||||
@secret={{concat this.model.idPrefix this.model.id}}
|
@secret={{concat this.model.idPrefix this.model.id}}
|
||||||
@mode="edit"
|
@mode="edit"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
{{#if (eq this.mode "show")}}
|
{{#if (eq this.mode "show")}}
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<ToolbarActions>
|
<ToolbarActions>
|
||||||
{{#if this.capabilities.canDelete}}
|
{{#if this.model.updatePath.canDelete}}
|
||||||
{{#if (gt this.model.allowed_roles.length 0)}}
|
{{#if (gt this.model.allowed_roles.length 0)}}
|
||||||
<ToolTip @verticalPosition="above" @horizontalPosition="center" as |T|>
|
<ToolTip @verticalPosition="above" @horizontalPosition="center" as |T|>
|
||||||
<T.Trigger @tabindex="-1">
|
<T.Trigger @tabindex="-1">
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="toolbar-separator"></div>
|
<div class="toolbar-separator"></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if this.capabilities.canUpdate}}
|
{{#if this.model.updatePath.canUpdate}}
|
||||||
{{#if (gt this.model.allowed_roles.length 0)}}
|
{{#if (gt this.model.allowed_roles.length 0)}}
|
||||||
<Hds::Button
|
<Hds::Button
|
||||||
@text="Edit transformation"
|
@text="Edit transformation"
|
||||||
|
|||||||
@@ -40,14 +40,13 @@
|
|||||||
@deleteKey={{action "deleteKey"}}
|
@deleteKey={{action "deleteKey"}}
|
||||||
@key={{this.key}}
|
@key={{this.key}}
|
||||||
@requestInFlight={{this.requestInFlight}}
|
@requestInFlight={{this.requestInFlight}}
|
||||||
@capabilities={{this.capabilities}}
|
@model={{this.model}}
|
||||||
/>
|
/>
|
||||||
{{else if (eq this.mode "show")}}
|
{{else if (eq this.mode "show")}}
|
||||||
<TransitFormShow
|
<TransitFormShow
|
||||||
@refresh={{action "refresh"}}
|
@refresh={{action "refresh"}}
|
||||||
@tab={{this.tab}}
|
@tab={{this.tab}}
|
||||||
@key={{this.key}}
|
@key={{this.key}}
|
||||||
@capabilities={{this.capabilities}}
|
|
||||||
@mode={{this.mode}}
|
@mode={{this.mode}}
|
||||||
@model={{this.model}}
|
@model={{this.model}}
|
||||||
@backend={{this.backend}}
|
@backend={{this.backend}}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="field is-grouped is-grouped-split box is-fullwidth is-bottomless">
|
<div class="field is-grouped is-grouped-split box is-fullwidth is-bottomless">
|
||||||
<div class="field is-grouped">
|
<div class="field is-grouped">
|
||||||
{{#if @capabilities.canUpdate}}
|
{{#if @model.canUpdate}}
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<Hds::Button
|
<Hds::Button
|
||||||
@text="Update transit key"
|
@text="Update transit key"
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{#if (and @key.canDelete @capabilities.canDelete)}}
|
{{#if @model.canDelete}}
|
||||||
<ConfirmAction @buttonText="Delete transit key" @onConfirmAction={{@deleteKey}} />
|
<ConfirmAction @buttonText="Delete transit key" @onConfirmAction={{@deleteKey}} />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
/>
|
/>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq @mode "show")}}
|
{{#if (eq @mode "show")}}
|
||||||
{{#if (or @capabilities.canUpdate @capabilities.canDelete)}}
|
{{#if (or @model.canUpdate @model.canDelete)}}
|
||||||
<ToolbarSecretLink @secret={{@key.id}} @backend={{@key.backend}} @mode="edit" replace={{true}}>
|
<ToolbarSecretLink @secret={{@key.id}} @backend={{@key.backend}} @mode="edit" replace={{true}}>
|
||||||
Edit key
|
Edit key
|
||||||
</ToolbarSecretLink>
|
</ToolbarSecretLink>
|
||||||
|
|||||||
@@ -27,10 +27,10 @@
|
|||||||
</h1>
|
</h1>
|
||||||
</p.levelLeft>
|
</p.levelLeft>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
{{#if (and (not-eq this.model.id "root") (or this.capabilities.canUpdate this.capabilities.canDelete))}}
|
{{#if (and (not-eq this.model.id "root") (or this.model.canUpdate this.model.canDelete))}}
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<ToolbarActions>
|
<ToolbarActions>
|
||||||
{{#if (and (not-eq this.model.id "default") this.capabilities.canDelete)}}
|
{{#if (and (not-eq this.model.id "default") this.model.canDelete)}}
|
||||||
<ConfirmAction
|
<ConfirmAction
|
||||||
@buttonText="Delete policy"
|
@buttonText="Delete policy"
|
||||||
class="toolbar-button"
|
class="toolbar-button"
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
@extension={{if (eq this.policyType "acl") this.model.format "sentinel"}}
|
@extension={{if (eq this.policyType "acl") this.model.format "sentinel"}}
|
||||||
@text="Download policy"
|
@text="Download policy"
|
||||||
/>
|
/>
|
||||||
{{#if (and (not-eq this.model.id "root") (or this.capabilities.canUpdate this.capabilities.canDelete))}}
|
{{#if (and (not-eq this.model.id "root") (or this.model.canUpdate this.model.canDelete))}}
|
||||||
<ToolbarLink
|
<ToolbarLink
|
||||||
@route="vault.cluster.policy.edit"
|
@route="vault.cluster.policy.edit"
|
||||||
@models={{array this.policyType this.model.id}}
|
@models={{array this.policyType this.model.id}}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ self.deprecationWorkflow.config = {
|
|||||||
workflow: [
|
workflow: [
|
||||||
{ handler: 'silence', matchId: 'ember-engines.deprecation-router-service-from-host' },
|
{ handler: 'silence', matchId: 'ember-engines.deprecation-router-service-from-host' },
|
||||||
// ember-data
|
// ember-data
|
||||||
{ handler: 'silence', matchId: 'ember-data:deprecate-promise-proxies' }, // Transform secrets
|
|
||||||
{ handler: 'silence', matchId: 'ember-data:no-a-with-array-like' }, // MFA
|
{ handler: 'silence', matchId: 'ember-data:no-a-with-array-like' }, // MFA
|
||||||
{ handler: 'silence', matchId: 'ember-data:deprecate-promise-many-array-behaviors' }, // MFA
|
{ handler: 'silence', matchId: 'ember-data:deprecate-promise-many-array-behaviors' }, // MFA
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import { module, test } from 'qunit';
|
|||||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||||
import { click, fillIn, render } from '@ember/test-helpers';
|
import { click, fillIn, render } from '@ember/test-helpers';
|
||||||
import { hbs } from 'ember-cli-htmlbars';
|
import { hbs } from 'ember-cli-htmlbars';
|
||||||
|
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||||
|
import { capabilitiesStub } from 'vault/tests/helpers/stubs';
|
||||||
|
|
||||||
const SELECTORS = {
|
const SELECTORS = {
|
||||||
createForm: '[data-test-transit-create-form]',
|
createForm: '[data-test-transit-create-form]',
|
||||||
@@ -16,9 +18,13 @@ const SELECTORS = {
|
|||||||
};
|
};
|
||||||
module('Integration | Component | transit-edit', function (hooks) {
|
module('Integration | Component | transit-edit', function (hooks) {
|
||||||
setupRenderingTest(hooks);
|
setupRenderingTest(hooks);
|
||||||
|
setupMirage(hooks);
|
||||||
|
|
||||||
hooks.beforeEach(function () {
|
hooks.beforeEach(function () {
|
||||||
this.store = this.owner.lookup('service:store');
|
this.store = this.owner.lookup('service:store');
|
||||||
|
this.server.post('/sys/capabilities-self', () =>
|
||||||
|
capabilitiesStub('transit-backend/keys/some-key', ['sudo'])
|
||||||
|
);
|
||||||
this.model = this.store.createRecord('transit-key', { backend: 'transit-backend', id: 'some-key' });
|
this.model = this.store.createRecord('transit-key', { backend: 'transit-backend', id: 'some-key' });
|
||||||
this.backendCrumb = {
|
this.backendCrumb = {
|
||||||
label: 'transit',
|
label: 'transit',
|
||||||
|
|||||||
Reference in New Issue
Block a user