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}}
+
{{brokeredCredentialSource.description}}
{{injectedApplicationCredentialSource.description}}