open-nomad/ui/app/controllers/policies/policy.js
Phil Renaud dce8717866
[ui] Token management interface on policy pages (#15435)
* basic-functionality demo for token CRUD

* Styling for tokens crud

* Tokens crud styles

* Expires, not expiry

* Mobile styles etc

* Refresh and redirect rules for policy save and token creation

* Delete method and associated serializer change

* Ability-checking for tokens

* Update policies acceptance tests to reflect new redirect rules

* Token ability unit tests

* Mirage config methods for token crud

* Token CRUD acceptance tests

* A couple visual diff snapshots

* Add and Delete abilities referenced for token operations

* Changing timeouts and adding a copy to clipboard action

* replaced accessor with secret when copying to clipboard

* PR comments addressed

* Simplified error passing for policy editor
2022-12-15 13:11:28 -05:00

124 lines
2.9 KiB
JavaScript

// @ts-check
import Controller from '@ember/controller';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { alias } from '@ember/object/computed';
import { task } from 'ember-concurrency';
export default class PoliciesPolicyController extends Controller {
@service flashMessages;
@service router;
@service store;
@alias('model.policy') policy;
@alias('model.tokens') tokens;
@tracked
error = null;
@tracked isDeleting = false;
get newTokenString() {
return `nomad acl token create -name="<TOKEN_NAME>" -policy="${this.policy.name}" -type=client -ttl=<8h>`;
}
@action
onDeletePrompt() {
this.isDeleting = true;
}
@action
onDeleteCancel() {
this.isDeleting = false;
}
@task(function* () {
try {
yield this.policy.deleteRecord();
yield this.policy.save();
this.flashMessages.add({
title: 'Policy Deleted',
type: 'success',
destroyOnClick: false,
timeout: 5000,
});
this.router.transitionTo('policies');
} catch (err) {
this.flashMessages.add({
title: `Error deleting Policy ${this.policy.name}`,
message: err,
type: 'error',
destroyOnClick: false,
sticky: true,
});
}
})
deletePolicy;
async refreshTokens() {
this.tokens = this.store
.peekAll('token')
.filter((token) =>
token.policyNames?.includes(decodeURIComponent(this.policy.name))
);
}
@task(function* () {
try {
const newToken = this.store.createRecord('token', {
name: `Example Token for ${this.policy.name}`,
policies: [this.policy],
// New date 10 minutes into the future
expirationTime: new Date(Date.now() + 10 * 60 * 1000),
type: 'client',
});
yield newToken.save();
yield this.refreshTokens();
this.flashMessages.add({
title: 'Example Token Created',
message: `${newToken.secret}`,
type: 'success',
destroyOnClick: false,
timeout: 30000,
customAction: {
label: 'Copy to Clipboard',
action: () => {
navigator.clipboard.writeText(newToken.secret);
},
},
});
} catch (err) {
this.error = {
title: 'Error creating new token',
description: err,
};
throw err;
}
})
createTestToken;
@task(function* (token) {
try {
yield token.deleteRecord();
yield token.save();
yield this.refreshTokens();
this.flashMessages.add({
title: 'Token successfully deleted',
type: 'success',
destroyOnClick: false,
timeout: 5000,
});
} catch (err) {
this.error = {
title: 'Error deleting token',
description: err,
};
throw err;
}
})
deleteToken;
}