diff --git a/addons/api/addon/abilities/host-set.js b/addons/api/addon/abilities/host-set.js
index 088683178..06a2e31f8 100644
--- a/addons/api/addon/abilities/host-set.js
+++ b/addons/api/addon/abilities/host-set.js
@@ -3,7 +3,7 @@ import ModelAbility from './model';
/**
* Provides abilities for host sets.
*/
-export default class UserAbility extends ModelAbility {
+export default class HostSetAbility extends ModelAbility {
// =permissions
/**
@@ -19,4 +19,11 @@ export default class UserAbility extends ModelAbility {
get canRemoveHosts() {
return this.hasAuthorizedAction('remove-hosts');
}
+
+ /**
+ * @type {boolean}
+ */
+ get canRead() {
+ return !this.model.isUnknown && this.hasAuthorizedAction('read');
+ }
}
diff --git a/ui/admin/app/templates/scopes/scope/targets/target/host-sources.hbs b/ui/admin/app/templates/scopes/scope/targets/target/host-sources.hbs
index 0e124dc9b..d3c8557ba 100644
--- a/ui/admin/app/templates/scopes/scope/targets/target/host-sources.hbs
+++ b/ui/admin/app/templates/scopes/scope/targets/target/host-sources.hbs
@@ -34,7 +34,19 @@
{{#each @model.hostSets as |hostSet|}}
- {{hostSet.model.displayName}}
+ {{#if (can 'read host-set' hostSet.model)}}
+
+ {{hostSet.model.displayName}}
+
+ {{else}}
+ {{hostSet.model.displayName}}
+ {{/if}}
{{hostSet.model.description}}
diff --git a/ui/admin/tests/acceptance/targets/host-sources-test.js b/ui/admin/tests/acceptance/targets/host-sources-test.js
index fb05b14ba..42426bc3b 100644
--- a/ui/admin/tests/acceptance/targets/host-sources-test.js
+++ b/ui/admin/tests/acceptance/targets/host-sources-test.js
@@ -50,6 +50,16 @@ module('Acceptance | targets | host-sources', function (hooks) {
},
'withChildren'
);
+ // creates "unknown" host-sets for target host sources
+ instances.hostCatalogPlugin = this.server.create(
+ 'host-catalog',
+ {
+ type: 'plugin',
+ plugin: { name: 'shh' },
+ scope: instances.scopes.project,
+ },
+ 'withChildren'
+ );
instances.target = this.server.create('target', {
scope: instances.scopes.project,
hostSets: instances.hostCatalog.hostSets,
@@ -62,6 +72,8 @@ module('Acceptance | targets | host-sources', function (hooks) {
urls.target = `${urls.targets}/${instances.target.id}`;
urls.targetHostSources = `${urls.target}/host-sources`;
urls.targetAddHostSources = `${urls.target}/add-host-sources`;
+ urls.hostSet = `${urls.projectScope}/host-catalogs/${instances.hostCatalog.id}/host-sets/${instances.hostCatalog.hostSetIds[0]}`;
+ urls.unknownHostSet = `${urls.projectScope}/host-catalogs/${instances.hostCatalogPlugin.id}/host-sets/${instances.hostCatalogPlugin.hostSetIds[0]}`;
authenticateSession({});
});
@@ -75,6 +87,30 @@ module('Acceptance | targets | host-sources', function (hooks) {
assert.strictEqual(findAll('tbody tr').length, targetHostSetCount);
});
+ test('can navigate to a known host set type', async function (assert) {
+ assert.expect(1);
+ await visit(urls.targetHostSources);
+ await click(
+ `main tbody .rose-table-header-cell:nth-child(1) a[href="${urls.hostSet}"]`
+ );
+ await a11yAudit();
+ assert.strictEqual(currentURL(), urls.hostSet);
+ });
+
+ test('cannot navigate to an unknown host set type', async function (assert) {
+ assert.expect(1);
+ instances.target.update({
+ hostSets: instances.hostCatalogPlugin.hostSets,
+ });
+
+ await visit(urls.targetHostSources);
+ assert
+ .dom(
+ `main tbody .rose-table-header-cell:nth-child(1) a [href="${urls.unknownHostSet}"]`
+ )
+ .doesNotExist();
+ });
+
test('can remove a host set', async function (assert) {
assert.expect(2);
const targetHostSetCount = instances.target.hostSets.length;