From a8bbf91a0aaeb889a7073639f120a7f5f8b87a42 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Fri, 24 Feb 2023 13:11:17 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20generic-vault=20get?= =?UTF-8?q?ting=20extra=20null=20fields=20when=20saving=20(#1640)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 🐛 Fix generic-vault getting extra null fields when saving ✅ Closes: ICU-8141 --- .../generated/models/credential-library.js | 9 +++ .../addon/serializers/credential-library.js | 44 +++++++++++--- .../serializers/credential-library-test.js | 60 +++++++++---------- 3 files changed, 72 insertions(+), 41 deletions(-) diff --git a/addons/api/addon/generated/models/credential-library.js b/addons/api/addon/generated/models/credential-library.js index 80febf8dc..010dd06a6 100644 --- a/addons/api/addon/generated/models/credential-library.js +++ b/addons/api/addon/generated/models/credential-library.js @@ -48,6 +48,7 @@ export default class GeneratedCredentialLibraryModel extends BaseModel { //= attributes (vault) @attr('string', { + for: 'vault-generic', isNestedAttribute: true, description: 'The HTTP method the library uses when requesting credentials from Vault.', @@ -56,6 +57,7 @@ export default class GeneratedCredentialLibraryModel extends BaseModel { http_method; @attr('string', { + for: 'vault-generic', isNestedAttribute: true, description: 'The body of the HTTP request the library sends to Vault when requesting credentials. Only valid if `http_method` is set to `POST`.', @@ -69,18 +71,21 @@ export default class GeneratedCredentialLibraryModel extends BaseModel { path; @attr('string', { + for: 'vault-ssh-certificate', isNestedAttribute: true, description: 'The username to use when making an SSH connection.', }) username; @attr('string', { + for: 'vault-ssh-certificate', isNestedAttribute: true, description: 'The desired key type to use when generating a private key.', }) key_type; @attr('number', { + for: 'vault-ssh-certificate', isNestedAttribute: true, description: 'Specifies the number of bits used when generating the private key. Not used if key type is ed25519', @@ -88,12 +93,14 @@ export default class GeneratedCredentialLibraryModel extends BaseModel { key_bits; @attr('string', { + for: 'vault-ssh-certificate', isNestedAttribute: true, description: 'Specifies the requested time to live for the certificate.', }) ttl; @attr('string', { + for: 'vault-ssh-certificate', isNestedAttribute: true, description: 'Specifies the key id that the created certificate should have.', @@ -101,6 +108,7 @@ export default class GeneratedCredentialLibraryModel extends BaseModel { key_id; @attr('object-as-array', { + for: 'vault-ssh-certificate', isNestedAttribute: true, description: 'Specifies a map of the critical options that the certificate should be signed for.', @@ -108,6 +116,7 @@ export default class GeneratedCredentialLibraryModel extends BaseModel { critical_options; @attr('object-as-array', { + for: 'vault-ssh-certificate', isNestedAttribute: true, description: 'Specifies a map of the extensions that the certificate should be signed for.', diff --git a/addons/api/addon/serializers/credential-library.js b/addons/api/addon/serializers/credential-library.js index 4ecec3867..27cfb98b0 100644 --- a/addons/api/addon/serializers/credential-library.js +++ b/addons/api/addon/serializers/credential-library.js @@ -1,5 +1,8 @@ import ApplicationSerializer from './application'; -import { TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC } from '../models/credential-library'; +import { + TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC, + TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE, +} from '../models/credential-library'; export default class CredentialLibrarySerializer extends ApplicationSerializer { // =properties @@ -14,16 +17,41 @@ export default class CredentialLibrarySerializer extends ApplicationSerializer { * @method serialize * @param {Snapshot} snapshot */ - serialize() { + serialize(snapshot) { + switch (snapshot.record.type) { + case TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC: + return this.serializeVaultGeneric(...arguments); + case TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE: + default: + return super.serialize(...arguments); + } + } + + serializeAttribute(snapshot, json, key, attribute) { + super.serializeAttribute(...arguments); + const { options } = attribute; + const { type } = snapshot.record; + + // If an attribute has a `for` option, it must match the + // record's `type`, else the attribute is excluded + // from serialization. + if (options?.for && options.for !== type) { + if (options.isNestedAttribute) { + delete json.attributes[key]; + } else { + delete json[key]; + } + } + } + + serializeVaultGeneric() { const serialized = super.serialize(...arguments); if (serialized.attributes) { - if (serialized.type !== TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC) { - delete serialized.attributes.http_method; + // Set `http_request_body` only if `http_method` is POST + // otherwise set to null to have the field removed + if (!serialized.attributes?.http_method?.match(/post/i)) { + serialized.attributes.http_request_body = null; } - - // Serialize `http_request_body` only if `http_method` is POST - if (!serialized.attributes?.http_method?.match(/post/i)) - delete serialized.attributes.http_request_body; } return serialized; } diff --git a/addons/api/tests/unit/serializers/credential-library-test.js b/addons/api/tests/unit/serializers/credential-library-test.js index 249ae8f89..af66f4bfa 100644 --- a/addons/api/tests/unit/serializers/credential-library-test.js +++ b/addons/api/tests/unit/serializers/credential-library-test.js @@ -31,13 +31,7 @@ module('Unit | Serializer | credential library', function (hooks) { attributes: { path: '/vault/path', http_method: 'GET', - critical_options: null, - extensions: null, - key_bits: null, - key_id: null, - key_type: null, - ttl: null, - username: null, + http_request_body: null, }, }); }); @@ -71,41 +65,54 @@ module('Unit | Serializer | credential library', function (hooks) { attributes: { path: '/vault/path', http_method: 'GET', - critical_options: null, - extensions: null, - key_bits: null, - key_id: null, - key_type: null, - ttl: null, - username: null, + http_request_body: null, }, version: 1, }); }); test('it serializes empty strings to null', function (assert) { - assert.expect(1); + assert.expect(2); const store = this.owner.lookup('service:store'); - const record = store.createRecord('credential-library', { + const vaultGenericRecord = store.createRecord('credential-library', { + type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC, http_method: '', path: null, }); - let serializedRecord = record.serialize(); - assert.deepEqual(serializedRecord, { + const vaultSSHCertificateRecord = store.createRecord('credential-library', { + type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE, + http_method: '', + path: null, + }); + let serializedVaultGenericRecord = vaultGenericRecord.serialize(); + let serializedVaultSSHCertificateRecord = + vaultSSHCertificateRecord.serialize(); + assert.deepEqual(serializedVaultGenericRecord, { attributes: { path: null, + http_method: null, + http_request_body: null, + }, + credential_store_id: null, + description: null, + name: null, + type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC, + }); + assert.deepEqual(serializedVaultSSHCertificateRecord, { + attributes: { critical_options: null, extensions: null, key_bits: null, key_id: null, key_type: null, + path: null, ttl: null, username: null, }, credential_store_id: null, description: null, name: null, - type: null, + type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE, }); }); @@ -123,14 +130,8 @@ module('Unit | Serializer | credential library', function (hooks) { { attributes: { http_method: 'GET', + http_request_body: null, path: null, - critical_options: null, - extensions: null, - key_bits: null, - key_id: null, - key_type: null, - ttl: null, - username: null, }, credential_store_id: null, description: null, @@ -149,13 +150,6 @@ module('Unit | Serializer | credential library', function (hooks) { http_method: 'POST', http_request_body: 'body', path: null, - critical_options: null, - extensions: null, - key_bits: null, - key_id: null, - key_type: null, - ttl: null, - username: null, }, credential_store_id: null, description: null,