From b02dc0aa43d37e319338ecb0f755d5c37dfd1e63 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Thu, 12 Jan 2023 16:28:43 -0600 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Remove=20json=5Fobject=20?= =?UTF-8?q?from=20payload=20for=20non-json=20credentials=20(#1576)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 🐛 Remove json_object from payload for non-json credentials * refactor: 💡 update new route logic for type specific attributes * test: 💍 remove typeIn and use fillIn for json credential test --- addons/api/addon/serializers/credential.js | 2 + .../tests/unit/serializers/credential-test.js | 61 +++++++++++++++++++ .../credential-store/credentials/new.js | 17 ++++-- .../credentials/create-test.js | 18 ++++++ 4 files changed, 92 insertions(+), 6 deletions(-) diff --git a/addons/api/addon/serializers/credential.js b/addons/api/addon/serializers/credential.js index 78878b38c..02720040a 100644 --- a/addons/api/addon/serializers/credential.js +++ b/addons/api/addon/serializers/credential.js @@ -25,6 +25,8 @@ export default class CredentialSerializer extends ApplicationSerializer { ); delete serialized.attributes.json_object; } + } else { + delete serialized.attributes.json_object; } return serialized; diff --git a/addons/api/tests/unit/serializers/credential-test.js b/addons/api/tests/unit/serializers/credential-test.js index ca492c280..a56bf2cfc 100644 --- a/addons/api/tests/unit/serializers/credential-test.js +++ b/addons/api/tests/unit/serializers/credential-test.js @@ -152,6 +152,67 @@ module('Unit | Serializer | credential', function (hooks) { }); }); + test('it serializes username_password type correctly by removing "json_object" attribute', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('credential'); + const record = store.createRecord('credential', { + password: '', + username: 'user', + json_object: '{"secret_key": "QWERTYUIOP"}', + credential_store_id: 'csst_i7p1eu0Nw8', + type: 'username_password', + name: 'Name', + description: 'Description', + version: 1, + }); + const snapshot = record._createSnapshot(); + const serializedRecord = serializer.serialize(snapshot); + + assert.deepEqual(serializedRecord, { + attributes: { + username: 'user', + }, + credential_store_id: 'csst_i7p1eu0Nw8', + type: 'username_password', + name: 'Name', + description: 'Description', + version: 1, + }); + }); + + test('it serializes ssh_private_key type correctly by removing "json_object" attribute', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('credential'); + const record = store.createRecord('credential', { + private_key_passphrase: 'passphrasesaresosecure', + private_key: 'superPriveKey', + json_object: '{"secret_key": "QWERTYUIOP"}', + username: 'user', + credential_store_id: 'csst_i7p1eu0Nw8', + type: 'ssh_private_key', + name: 'Name', + description: 'Description', + version: 1, + }); + const snapshot = record._createSnapshot(); + const serializedRecord = serializer.serialize(snapshot); + + assert.deepEqual(serializedRecord, { + attributes: { + private_key_passphrase: 'passphrasesaresosecure', + private_key: 'superPriveKey', + username: 'user', + }, + credential_store_id: 'csst_i7p1eu0Nw8', + type: 'ssh_private_key', + name: 'Name', + description: 'Description', + version: 1, + }); + }); + test('it normalizes "username_password" type credential record', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); diff --git a/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/credentials/new.js b/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/credentials/new.js index 65e8c3577..0ef9c9731 100644 --- a/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/credentials/new.js +++ b/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/credentials/new.js @@ -29,23 +29,28 @@ export default class ScopesScopeCredentialStoresCredentialStoreCredentialsNewRou 'scopes.scope.credential-stores.credential-store' ); let name, description; - /** - * this sets the credential attribute json_object to a string that - * replicates an empty json blob as CodeMirror expects a string - */ - const json_object = '{}'; if (this.currentModel?.isNew) { ({ name, description } = this.currentModel); this.currentModel.rollbackAttributes(); } + /** + * this sets the credential attribute json_object to a string that + * replicates an empty json blob as CodeMirror expects a string + */ + const typeSpecificAttrs = {}; + switch (type) { + case 'json': + typeSpecificAttrs.json_object = '{}'; + } + return this.store.createRecord('credential', { type, credential_store_id, name, description, - json_object, + ...typeSpecificAttrs, }); } diff --git a/ui/admin/tests/acceptance/credential-store/credentials/create-test.js b/ui/admin/tests/acceptance/credential-store/credentials/create-test.js index ce7f2040d..baa97d746 100644 --- a/ui/admin/tests/acceptance/credential-store/credentials/create-test.js +++ b/ui/admin/tests/acceptance/credential-store/credentials/create-test.js @@ -166,6 +166,24 @@ module( assert.strictEqual(getCredentialsCount(), credentialsCount); }); + test('users can switch away from JSON type credentials and the json_object value will be cleared', async function (assert) { + assert.expect(2); + const editorSelector = '[data-test-code-editor-field-editor]'; + const newSecret = '{"test": "value"}'; + + await visit(urls.credentials); + await click(`[href="${urls.newCredential}"]`); + await click('[value="json"]'); + + await fillIn(`${editorSelector} textarea`, newSecret); + assert.dom(editorSelector).includesText(newSecret); + + await click('[value="username_password"]'); + + await click('[value="json"]'); + assert.dom(editorSelector).includesText('{}'); + }); + test('users cannot navigate to new credential route without proper authorization', async function (assert) { assert.expect(2); instances.staticCredentialStore.authorized_collection_actions.credentials =