From 5224512da0bd4b6521667c590e7a88a285bd5342 Mon Sep 17 00:00:00 2001
From: Dharini Jeeva
Date: Tue, 20 Sep 2022 17:31:16 -0700
Subject: [PATCH] Icu 6153 unknown credential support (#1344)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: 🎸 Add support for unknown credential types
✅ Closes: ICU-6153
* fix: 🐛 add unknown cred type
* refactor: 💡 move credential type logic to a component
* chore: 🤖 fix component name
* fix: 🐛 update component name, remove unused translated string
* fix: 🐛 file name
Co-authored-by: Cameron Perera
---
.../api/addon/abilities/credential-library.js | 15 ++++++
addons/api/addon/abilities/credential.js | 15 ++++++
addons/api/addon/models/credential-library.js | 25 ++++++++-
addons/api/addon/models/credential.js | 13 +++++
.../api/app/abilities/credential-library.js | 1 +
addons/api/app/abilities/credential.js | 1 +
.../api/mirage/factories/credential-store.js | 2 +-
addons/api/mirage/factories/credential.js | 4 +-
.../unit/models/credential-library-test.js | 11 +++-
.../api/tests/unit/models/credential-test.js | 22 ++++++++
addons/core/translations/resources/en-us.yaml | 10 +---
.../cred-source-type-badge/index.hbs | 13 +++++
.../add-brokered-credential-sources/index.hbs | 7 +--
.../index.hbs | 7 +--
.../credential-libraries/index.hbs | 2 +-
.../credential-store/credentials/index.hbs | 6 +--
.../target/brokered-credential-sources.hbs | 49 +++++++++---------
...njected-application-credential-sources.hbs | 51 ++++++++++---------
18 files changed, 174 insertions(+), 80 deletions(-)
create mode 100644 addons/api/addon/abilities/credential-library.js
create mode 100644 addons/api/addon/abilities/credential.js
create mode 100644 addons/api/app/abilities/credential-library.js
create mode 100644 addons/api/app/abilities/credential.js
create mode 100644 ui/admin/app/components/cred-source-type-badge/index.hbs
diff --git a/addons/api/addon/abilities/credential-library.js b/addons/api/addon/abilities/credential-library.js
new file mode 100644
index 000000000..5968a80f0
--- /dev/null
+++ b/addons/api/addon/abilities/credential-library.js
@@ -0,0 +1,15 @@
+import ModelAbility from './model';
+/**
+ * Provides abilities for credential.
+ */
+export default class CredentialLibaryAbility extends ModelAbility {
+ // =permissions
+
+ /**
+ * Only "known" credential libary types may be read.
+ * @type {boolean}
+ */
+ get canRead() {
+ return !this.model.isUnknown && this.hasAuthorizedAction('read');
+ }
+}
diff --git a/addons/api/addon/abilities/credential.js b/addons/api/addon/abilities/credential.js
new file mode 100644
index 000000000..115856118
--- /dev/null
+++ b/addons/api/addon/abilities/credential.js
@@ -0,0 +1,15 @@
+import ModelAbility from "./model";
+/**
+ * Provides abilities for credential.
+ */
+export default class CredentialAbility extends ModelAbility {
+ // =permissions
+
+ /**
+ * Only "known" credential types may be read.
+ * @type {boolean}
+ */
+ get canRead() {
+ return !this.model.isUnknown && this.hasAuthorizedAction('read');
+ }
+}
\ No newline at end of file
diff --git a/addons/api/addon/models/credential-library.js b/addons/api/addon/models/credential-library.js
index 773478638..f864abcbb 100644
--- a/addons/api/addon/models/credential-library.js
+++ b/addons/api/addon/models/credential-library.js
@@ -7,4 +7,27 @@ export const options = {
http_method: ['GET', 'POST'],
};
-export default class CredentialLibraryModel extends GeneratedCredentialLibraryModel {}
+/**
+ * Supported Credential Library types.
+ */
+export const types = ['vault'];
+
+export default class CredentialLibraryModel extends GeneratedCredentialLibraryModel {
+ // =attributes
+
+ /**
+ * True if credential is an unknown type.
+ * @type {boolean}
+ */
+ get isUnknown() {
+ return !types.includes(this.type);
+ }
+
+ /**
+ * True if credential is a vault type.
+ * @type {boolean}
+ */
+ get isVault() {
+ return this.type === 'vault';
+ }
+}
diff --git a/addons/api/addon/models/credential.js b/addons/api/addon/models/credential.js
index 877de41dc..3fee8cf9d 100644
--- a/addons/api/addon/models/credential.js
+++ b/addons/api/addon/models/credential.js
@@ -1,10 +1,23 @@
import GeneratedCredentialModel from '../generated/models/credential';
import { equal } from '@ember/object/computed';
+/**
+ * Supported Credential types.
+ */
+export const types = ['username_password', 'ssh_private_key'];
+
export default class CredentialModel extends GeneratedCredentialModel {
// =attributes
/**
* @type {boolean}
*/
@equal('type', 'username_password') isUsernamePassword;
+
+ /**
+ * True if credential is an unknown type.
+ * @type {boolean}
+ */
+ get isUnknown() {
+ return !types.includes(this.type);
+ }
}
diff --git a/addons/api/app/abilities/credential-library.js b/addons/api/app/abilities/credential-library.js
new file mode 100644
index 000000000..c55e5afe7
--- /dev/null
+++ b/addons/api/app/abilities/credential-library.js
@@ -0,0 +1 @@
+export { default } from 'api/abilities/credential-library';
diff --git a/addons/api/app/abilities/credential.js b/addons/api/app/abilities/credential.js
new file mode 100644
index 000000000..af95b315a
--- /dev/null
+++ b/addons/api/app/abilities/credential.js
@@ -0,0 +1 @@
+export { default } from 'api/abilities/credential';
\ No newline at end of file
diff --git a/addons/api/mirage/factories/credential-store.js b/addons/api/mirage/factories/credential-store.js
index 39337f230..3b10f756e 100644
--- a/addons/api/mirage/factories/credential-store.js
+++ b/addons/api/mirage/factories/credential-store.js
@@ -59,7 +59,7 @@ export default factory.extend({
break;
case 'static':
default:
- server.createList('credential', 2, {
+ server.createList('credential', 3, {
scope,
credentialStore,
});
diff --git a/addons/api/mirage/factories/credential.js b/addons/api/mirage/factories/credential.js
index eac680c96..58e1f5351 100644
--- a/addons/api/mirage/factories/credential.js
+++ b/addons/api/mirage/factories/credential.js
@@ -3,7 +3,7 @@ import { faker } from '@faker-js/faker';
import permissions from '../helpers/permissions';
import generatedId from '../helpers/id';
-const types = ['username_password', 'ssh_private_key'];
+const types = ['username_password', 'ssh_private_key', 'json'];
export default factory.extend({
type: (i) => types[i % types.length],
@@ -13,6 +13,8 @@ export default factory.extend({
return generatedId('credspk_');
case 'username_password':
return generatedId('credup_');
+ case 'json':
+ return generatedId('credjson_');
}
},
authorized_actions: () =>
diff --git a/addons/api/tests/unit/models/credential-library-test.js b/addons/api/tests/unit/models/credential-library-test.js
index 4cd00ab05..12610cf8c 100644
--- a/addons/api/tests/unit/models/credential-library-test.js
+++ b/addons/api/tests/unit/models/credential-library-test.js
@@ -4,10 +4,19 @@ import { setupTest } from 'ember-qunit';
module('Unit | Model | credential library', function (hooks) {
setupTest(hooks);
- // Replace this with your real tests.
test('it exists', function (assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('credential-library', {});
assert.ok(model);
});
+
+ test('it has isUnknown property and returns the expected values', async function (assert) {
+ assert.expect(2);
+ const store = this.owner.lookup('service:store');
+ const modelA = store.createRecord('credential-library', { type: 'vault' });
+ const modelB = store.createRecord('credential-library', { type: 'unknown' });
+
+ assert.false(modelA.isUnknown);
+ assert.true(modelB.isUnknown);
+ });
});
diff --git a/addons/api/tests/unit/models/credential-test.js b/addons/api/tests/unit/models/credential-test.js
index 7cf89e154..1a091665a 100644
--- a/addons/api/tests/unit/models/credential-test.js
+++ b/addons/api/tests/unit/models/credential-test.js
@@ -9,4 +9,26 @@ module('Unit | Model | credential', function (hooks) {
const model = store.createRecord('credential', {});
assert.ok(model);
});
+
+ test('it has isUsernamePassword property and returns the expected values', async function (assert) {
+ assert.expect(2);
+ const store = this.owner.lookup('service:store');
+ const modelA = store.createRecord('credential', { type: 'username_password' });
+ const modelB = store.createRecord('credential', { type: 'ssh_private_key' });
+
+ assert.true(modelA.isUsernamePassword);
+ assert.false(modelB.isUsernamePassword);
+ });
+
+ test('it has isUnknown property and returns the expected values', async function (assert) {
+ assert.expect(3);
+ const store = this.owner.lookup('service:store');
+ const modelA = store.createRecord('credential', { type: 'username_password' });
+ const modelB = store.createRecord('credential', { type: 'ssh_private_key' });
+ const modelC = store.createRecord('credential', { type: 'unknown' });
+
+ assert.false(modelA.isUnknown);
+ assert.false(modelB.isUnknown);
+ assert.true(modelC.isUnknown);
+ });
});
diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml
index 3bb660319..74fd773ad 100644
--- a/addons/core/translations/resources/en-us.yaml
+++ b/addons/core/translations/resources/en-us.yaml
@@ -304,10 +304,6 @@ target:
brokered-credential-source:
title: Brokered Credential
title_plural: Brokered Credentials
- types:
- vault: Vault
- username_password: Username & Password
- ssh_private_key: Username & Key Pair
messages:
welcome:
title: Welcome to brokered credentials
@@ -321,10 +317,6 @@ target:
injected-application-credential-source:
title: Injected Application Credential
title_plural: Injected Application Credentials
- types:
- vault: Vault
- username_password: Username & Password
- ssh_private_key: Username & Key Pair
messages:
welcome:
title: Welcome to Injected Application credentials
@@ -403,7 +395,6 @@ credential-library:
types:
vault: Vault
static: Static
- username_password: Username & Password
credential:
title: Credential
title_plural: Credentials
@@ -418,6 +409,7 @@ credential:
types:
username_password: Username & Password
ssh_private_key: Username & Key Pair
+ unknown: Unknown
help:
username_password: This host requires a username and password to connect.
ssh_private_key: This host requires a username, public key, and private key to connect.
diff --git a/ui/admin/app/components/cred-source-type-badge/index.hbs b/ui/admin/app/components/cred-source-type-badge/index.hbs
new file mode 100644
index 000000000..122d02a18
--- /dev/null
+++ b/ui/admin/app/components/cred-source-type-badge/index.hbs
@@ -0,0 +1,13 @@
+{{#if @model.isUnknown}}
+
+ {{t 'resources.credential.types.unknown'}}
+
+{{else if @model.isVault}}
+
+ {{t (concat 'resources.credential-library.types.' @model.type)}}
+
+{{else}}
+
+ {{t (concat 'resources.credential.types.' @model.type)}}
+
+{{/if}}
diff --git a/ui/admin/app/components/form/target/add-brokered-credential-sources/index.hbs b/ui/admin/app/components/form/target/add-brokered-credential-sources/index.hbs
index 9e0945e13..e8c4070bc 100644
--- a/ui/admin/app/components/form/target/add-brokered-credential-sources/index.hbs
+++ b/ui/admin/app/components/form/target/add-brokered-credential-sources/index.hbs
@@ -31,12 +31,7 @@
{{credentialSource.name}}
- {{t
- (concat
- 'resources.target.brokered-credential-source.types.'
- credentialSource.type
- )
- }}
+
{{/each}}
diff --git a/ui/admin/app/components/form/target/add-injected-application-credential-sources/index.hbs b/ui/admin/app/components/form/target/add-injected-application-credential-sources/index.hbs
index 955d0f3fe..216f69108 100644
--- a/ui/admin/app/components/form/target/add-injected-application-credential-sources/index.hbs
+++ b/ui/admin/app/components/form/target/add-injected-application-credential-sources/index.hbs
@@ -32,12 +32,7 @@
{{credentialSource.name}}
- {{t
- (concat
- 'resources.target.injected-application-credential-source.types.'
- credentialSource.type
- )
- }}
+
{{/each}}
diff --git a/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/credential-libraries/index.hbs b/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/credential-libraries/index.hbs
index 77f9385b8..b5f65aba6 100644
--- a/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/credential-libraries/index.hbs
+++ b/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/credential-libraries/index.hbs
@@ -35,7 +35,7 @@
{{#each @model as |credentialLibrary|}}
- {{#if (can 'read model' credentialLibrary)}}
+ {{#if (can 'read credential-library' credentialLibrary)}}
- {{#if (can 'read model' credential)}}
+ {{#if (can 'read credential' credential)}}
{{credential.description}}
- {{t
- (concat 'resources.credential.types.' credential.type)
- }}
+
- {{#if brokeredCredentialSource.isUsernamePassword}}
-
- {{brokeredCredentialSource.displayName}}
-
+ {{#if brokeredCredentialSource.isUnknown}}
+ {{brokeredCredentialSource.displayName}}
{{else}}
-
- {{brokeredCredentialSource.displayName}}
-
+ {{#if brokeredCredentialSource.isUsernamePassword}}
+
+ {{brokeredCredentialSource.displayName}}
+
+ {{else}}
+
+ {{brokeredCredentialSource.displayName}}
+
+ {{/if}}
{{/if}}
{{brokeredCredentialSource.description}}
- {{t
- (concat
- 'resources.target.brokered-credential-source.types.'
- brokeredCredentialSource.type
- )
- }}
+
- {{#if injectedApplicationCredentialSource.isUsernamePassword}}
-
- {{injectedApplicationCredentialSource.displayName}}
-
+ {{#if injectedApplicationCredentialSource.isUnknown}}
+ {{injectedApplicationCredentialSource.displayName}}
{{else}}
-
- {{injectedApplicationCredentialSource.displayName}}
-
+ {{#if injectedApplicationCredentialSource.isUsernamePassword}}
+
+ {{injectedApplicationCredentialSource.displayName}}
+
+ {{else}}
+
+ {{injectedApplicationCredentialSource.displayName}}
+
+ {{/if}}
{{/if}}
{{injectedApplicationCredentialSource.description}}
- {{t
- (concat
- 'resources.target.injected-application-credential-source.types.'
- injectedApplicationCredentialSource.type
- )
- }}
+