Skip to content

Commit

Permalink
KMSE Capabilities & Phase 1 Cleanup (#15143)
Browse files Browse the repository at this point in the history
* fixes issues in key-edit component

* adds capabilities checks for keys and providers

* adds distribute component to key and provider edit
  • Loading branch information
zofskeez committed Apr 26, 2022
1 parent b2b2ead commit cb14e18
Show file tree
Hide file tree
Showing 11 changed files with 528 additions and 385 deletions.
7 changes: 7 additions & 0 deletions ui/app/adapters/keymgmt/key.js
Expand Up @@ -149,4 +149,11 @@ export default class KeymgmtKeyAdapter extends ApplicationAdapter {
// TODO: re-fetch record data after
return this.ajax(this.url(backend, id, 'ROTATE'), 'PUT');
}

removeFromProvider(model) {
const url = `${this.buildURL()}/${model.backend}/kms/${model.provider.name}/key/${model.name}`;
return this.ajax(url, 'DELETE').then(() => {
model.provider = null;
});
}
}
2 changes: 1 addition & 1 deletion ui/app/components/keymgmt/distribute.js
Expand Up @@ -181,7 +181,7 @@ export default class KeymgmtDistribute extends Component {
.distribute(backend, kms, key, data)
.then(() => {
this.flashMessages.success(`Successfully distributed key ${key} to ${kms}`);
this.router.transitionTo('vault.cluster.secrets.backend.show', key);
this.args.onClose();
})
.catch((e) => {
this.flashMessages.danger(`Error distributing key: ${e.errors}`);
Expand Down
54 changes: 28 additions & 26 deletions ui/app/components/keymgmt/key-edit.js
Expand Up @@ -2,6 +2,8 @@ import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { task } from 'ember-concurrency';
import { waitFor } from '@ember/test-waiters';

/**
* @module KeymgmtKeyEdit
Expand Down Expand Up @@ -32,50 +34,50 @@ export default class KeymgmtKeyEdit extends Component {
return this.store.adapterFor('keymgmt/key');
}

@action
toggleModal(bool) {
this.isDeleteModalOpen = bool;
get isMutable() {
return ['create', 'edit'].includes(this.args.mode);
}

@action
createKey(evt) {
evt.preventDefault();
this.args.model.save();
get isCreating() {
return this.args.mode === 'create';
}

@action
updateKey(evt) {
toggleModal(bool) {
this.isDeleteModalOpen = bool;
}

@task
@waitFor
*saveKey(evt) {
evt.preventDefault();
const name = this.args.model.name;
this.args.model
.save()
.then(() => {
this.router.transitionTo(SHOW_ROUTE, name);
})
.catch((e) => {
this.flashMessages.danger(e.errors.join('. '));
});
const { model } = this.args;
try {
yield model.save();
this.router.transitionTo(SHOW_ROUTE, model.name);
} catch (error) {
this.flashMessages.danger(error.errors.join('. '));
}
}

@action
removeKey(id) {
// TODO: remove action
console.log('remove', id);
async removeKey() {
try {
await this.keyAdapter.removeFromProvider(this.args.model);
this.flashMessages.success('Key has been successfully removed from provider');
} catch (error) {
this.flashMessages.danger(error.errors?.join('. '));
}
}

@action
deleteKey() {
const secret = this.args.model;
const backend = secret.backend;
console.log({ secret });
secret
.destroyRecord()
.then(() => {
try {
this.router.transitionTo(LIST_ROOT_ROUTE, backend, { queryParams: { tab: 'key' } });
} catch (e) {
console.debug(e);
}
this.router.transitionTo(LIST_ROOT_ROUTE, backend);
})
.catch((e) => {
this.flashMessages.danger(e.errors?.join('. '));
Expand Down
36 changes: 34 additions & 2 deletions ui/app/models/keymgmt/key.js
@@ -1,5 +1,6 @@
import Model, { attr } from '@ember-data/model';
import { expandAttributeMeta } from 'vault/utils/field-to-attrs';
import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';

export const KEY_TYPES = [
'aes256-gcm96',
Expand All @@ -11,15 +12,23 @@ export const KEY_TYPES = [
'ecdsa-p521',
];
export default class KeymgmtKeyModel extends Model {
@attr('string') name;
@attr('string') backend;
@attr('string', {
label: 'Key name',
subText: 'This is the name of the key that shows in Vault.',
})
name;

@attr('string')
backend;

@attr('string', {
subText: 'The type of cryptographic key that will be created.',
possibleValues: KEY_TYPES,
})
type;

@attr('boolean', {
label: 'Allow deletion',
defaultValue: false,
})
deletionAllowed;
Expand Down Expand Up @@ -93,4 +102,27 @@ export default class KeymgmtKeyModel extends Model {
{ name: 'protection', type: 'string', subText: 'Where cryptographic operations are performed.' },
];
}

@lazyCapabilities(apiPath`${'backend'}/key/${'id'}`, 'backend', 'id') keyPath;
@lazyCapabilities(apiPath`${'backend'}/key`, 'backend') keysPath;
@lazyCapabilities(apiPath`${'backend'}/key/${'id'}/kms`, 'backend', 'id') keyProvidersPath;

get canCreate() {
return this.keyPath.get('canCreate');
}
get canDelete() {
return this.keyPath.get('canDelete');
}
get canEdit() {
return this.keyPath.get('canUpdate');
}
get canRead() {
return this.keyPath.get('canRead');
}
get canList() {
return this.keysPath.get('canList');
}
get canListProviders() {
return this.keyProvidersPath.get('canList');
}
}
59 changes: 47 additions & 12 deletions ui/app/models/keymgmt/provider.js
Expand Up @@ -2,6 +2,7 @@ import Model, { attr } from '@ember-data/model';
import { tracked } from '@glimmer/tracking';
import { expandAttributeMeta } from 'vault/utils/field-to-attrs';
import { withModelValidations } from 'vault/decorators/model-validations';
import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';

const CRED_PROPS = {
azurekeyvault: ['client_id', 'client_secret', 'tenant_id'],
Expand Down Expand Up @@ -80,7 +81,11 @@ export default class KeymgmtProviderModel extends Model {
const attrs = expandAttributeMeta(this, ['name', 'created', 'keyCollection']);
attrs.splice(1, 0, { hasBlock: true, label: 'Type', value: this.typeName, icon: this.icon });
const l = this.keys.length;
const value = l ? `${l} ${l > 1 ? 'keys' : 'key'}` : 'None';
const value = l
? `${l} ${l > 1 ? 'keys' : 'key'}`
: this.canListKeys
? 'None'
: 'You do not have permission to list keys';
attrs.push({ hasBlock: true, isLink: l, label: 'Keys', value });
return attrs;
}
Expand All @@ -104,18 +109,48 @@ export default class KeymgmtProviderModel extends Model {
}

async fetchKeys(page) {
try {
this.keys = await this.store.lazyPaginatedQuery('keymgmt/key', {
backend: 'keymgmt',
provider: this.name,
responsePath: 'data.keys',
page,
});
} catch (error) {
this.keys = [];
if (error.httpStatus !== 404) {
throw error;
if (this.canListKeys) {
try {
this.keys = await this.store.lazyPaginatedQuery('keymgmt/key', {
backend: 'keymgmt',
provider: this.name,
responsePath: 'data.keys',
page,
});
} catch (error) {
this.keys = [];
if (error.httpStatus !== 404) {
throw error;
}
}
} else {
this.keys = [];
}
}

@lazyCapabilities(apiPath`${'backend'}/kms/${'id'}`, 'backend', 'id') providerPath;
@lazyCapabilities(apiPath`${'backend'}/kms`, 'backend') providersPath;
@lazyCapabilities(apiPath`${'backend'}/kms/${'id'}/key`, 'backend', 'id') providerKeysPath;

get canCreate() {
return this.providerPath.get('canCreate');
}
get canDelete() {
return this.providerPath.get('canDelete');
}
get canEdit() {
return this.providerPath.get('canUpdate');
}
get canRead() {
return this.providerPath.get('canRead');
}
get canList() {
return this.providersPath.get('canList');
}
get canListKeys() {
return this.providerKeysPath.get('canList');
}
get canCreateKeys() {
return this.providerKeysPath.get('canCreate');
}
}
7 changes: 6 additions & 1 deletion ui/app/templates/components/keymgmt/distribute.hbs
Expand Up @@ -147,7 +147,12 @@
class="button is-primary"
data-test-secret-save={{true}}
>
Save
{{if (or (not @key) this.isNewKey) "Add key" "Distribute key"}}
</button>
</div>
<div class="control">
<button type="button" class="button" {{on "click" @onClose}}>
Cancel
</button>
</div>
</div>
Expand Down

0 comments on commit cb14e18

Please sign in to comment.