From 0232570831ef6c2596542f58c2326a80460cffd3 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Fri, 20 Aug 2021 14:58:43 -0400 Subject: [PATCH 01/17] feature(capabilities): preliminary user create/list abilities --- addons/api/addon/models/base.js | 5 +++ addons/api/mirage/factories/scope.js | 13 +++++++ ui/admin/app/routes/scopes/scope/users.js | 8 +++-- .../app/routes/scopes/scope/users/index.js | 12 ++++++- ui/admin/app/templates/scopes/scope.hbs | 12 ++++--- .../templates/scopes/scope/users/index.hbs | 35 ++++++++++++++----- 6 files changed, 68 insertions(+), 17 deletions(-) diff --git a/addons/api/addon/models/base.js b/addons/api/addon/models/base.js index f99e0351a..7fd41ec64 100644 --- a/addons/api/addon/models/base.js +++ b/addons/api/addon/models/base.js @@ -42,6 +42,11 @@ export default class BaseModel extends Model { }) authorized_actions; + @attr({ + readOnly: true, + }) + authorized_collection_actions; + set scopeModel(model) { if (model) { const json = model.serialize(); diff --git a/addons/api/mirage/factories/scope.js b/addons/api/mirage/factories/scope.js index fe41f3866..4ac77e576 100644 --- a/addons/api/mirage/factories/scope.js +++ b/addons/api/mirage/factories/scope.js @@ -4,6 +4,19 @@ import { trait } from 'ember-cli-mirage'; export default factory.extend({ type: 'global', + authorized_collection_actions: () => { + return { + users: ['create', ''], + // groups: ['create', 'list'], + // roles: ['create', 'list'], + // 'auth-methods': ['create', 'list'], + // sessopms: ['list'], + // targets: ['create', 'list'], + // 'host-catalogs': ['create', 'list'], + // 'credential-stores': ['create', 'list'], + }; + }, + /** * Generates realistic-ish IDs while still being deterministic. */ diff --git a/ui/admin/app/routes/scopes/scope/users.js b/ui/admin/app/routes/scopes/scope/users.js index 42f9c8832..aa3dde96a 100644 --- a/ui/admin/app/routes/scopes/scope/users.js +++ b/ui/admin/app/routes/scopes/scope/users.js @@ -11,6 +11,7 @@ export default class ScopesScopeUsersRoute extends Route { @service intl; @service notify; @service session; + @service can; // =methods @@ -26,8 +27,11 @@ export default class ScopesScopeUsersRoute extends Route { * @return {Promise{[UserModel]}} */ async model() { - const { id: scope_id } = this.modelFor('scopes.scope'); - return this.store.query('user', { scope_id }); + const scope = this.modelFor('scopes.scope'); + const { id: scope_id } = scope; + if (this.can.can('list collection', scope, { collection: 'users' })) { + return this.store.query('user', { scope_id }); + } } // =actions diff --git a/ui/admin/app/routes/scopes/scope/users/index.js b/ui/admin/app/routes/scopes/scope/users/index.js index f59170106..8d3bc89c6 100644 --- a/ui/admin/app/routes/scopes/scope/users/index.js +++ b/ui/admin/app/routes/scopes/scope/users/index.js @@ -1,3 +1,13 @@ import Route from '@ember/routing/route'; -export default class ScopesScopeUsersIndexRoute extends Route {} +export default class ScopesScopeUsersIndexRoute extends Route { + + // =methods + + setupController(controller) { + const scope = this.modelFor('scopes.scope'); + super.setupController(...arguments); + controller.setProperties({ scope }); + } + +} diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 65e456c51..825be5d14 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -94,10 +94,12 @@ {{#unless @model.isProject}} - - - {{t 'resources.user.title_plural'}} - + {{#if (can 'navigate collection' @model collection='users')}} + + + {{t 'resources.user.title_plural'}} + + {{/if}} {{t 'resources.group.title_plural'}} @@ -140,4 +142,4 @@ - \ No newline at end of file + diff --git a/ui/admin/app/templates/scopes/scope/users/index.hbs b/ui/admin/app/templates/scopes/scope/users/index.hbs index ab31bc1cf..61d80197b 100644 --- a/ui/admin/app/templates/scopes/scope/users/index.hbs +++ b/ui/admin/app/templates/scopes/scope/users/index.hbs @@ -15,10 +15,12 @@ - {{#if @model}} - {{t - 'titles.new' - }} + {{#if (can 'create collection' this.scope collection='users')}} + {{#if @model}} + {{t + 'titles.new' + }} + {{/if}} {{/if}} @@ -69,11 +71,26 @@ > {{t 'resources.user.description'}} + {{#if (can 'create collection' this.scope collection='users')}} + {{#unless (can 'list collection' this.scope collection='users')}} +
+
+ + Oh noes! Resources you create won't appear here because you + have create permission, but not list. + + {{/unless}} + {{/if}}
- - - {{t 'titles.new'}} - + {{#if (can 'create collection' this.scope collection='users')}} + + + {{t 'titles.new'}} + + {{/if}} @@ -81,4 +98,4 @@ - \ No newline at end of file + From f510d2f4fe43e84f6091f9ce9e7288d4dfe5784f Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Tue, 24 Aug 2021 14:46:21 -0400 Subject: [PATCH 02/17] chore: add create and list to mock user --- addons/api/mirage/factories/scope.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/api/mirage/factories/scope.js b/addons/api/mirage/factories/scope.js index 4ac77e576..e9c5ac09f 100644 --- a/addons/api/mirage/factories/scope.js +++ b/addons/api/mirage/factories/scope.js @@ -6,7 +6,7 @@ export default factory.extend({ authorized_collection_actions: () => { return { - users: ['create', ''], + users: ['create', 'list'], // groups: ['create', 'list'], // roles: ['create', 'list'], // 'auth-methods': ['create', 'list'], From 03e06a22a4c895eb9f55338aacbdba479297f234 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Tue, 24 Aug 2021 16:47:33 -0400 Subject: [PATCH 03/17] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20messages=20f?= =?UTF-8?q?or=20insufficient=20permissions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/abilities/collection.js | 3 +- addons/core/translations/en-us.yaml | 2 ++ .../app/routes/scopes/scope/users/index.js | 2 -- ui/admin/app/templates/scopes/scope.hbs | 2 +- .../templates/scopes/scope/users/index.hbs | 30 ++++++++++--------- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/addons/api/addon/abilities/collection.js b/addons/api/addon/abilities/collection.js index ad52afd18..92f0e4342 100644 --- a/addons/api/addon/abilities/collection.js +++ b/addons/api/addon/abilities/collection.js @@ -29,7 +29,8 @@ export default class CollectionAbility extends Ability { * @return {boolean} */ hasAuthorizedCollectionAction(action) { - const { authorized_collection_actions } = this.model; + const authorized_collection_actions = + (this.model || {}).authorized_collection_actions || {}; const collection = this.collection || {}; return authorized_collection_actions[collection]?.includes(action); } diff --git a/addons/core/translations/en-us.yaml b/addons/core/translations/en-us.yaml index 5370c7e75..8f98f633c 100644 --- a/addons/core/translations/en-us.yaml +++ b/addons/core/translations/en-us.yaml @@ -32,6 +32,8 @@ titles: descriptions: empty-set: There are no items to display yet. You may be able to add items or try back later. origin-initialization: To get started, please enter your origin URL + create-but-not-list: You do not have permission to list {resource}, but you can create new instances. + neither-list-nor-create: You do not have permission to list or create {resource}. questions: delete-confirm: Are you sure you want to delete this resource? remove-confirm: Are you sure you want to remove this association? diff --git a/ui/admin/app/routes/scopes/scope/users/index.js b/ui/admin/app/routes/scopes/scope/users/index.js index 8d3bc89c6..2e92b693d 100644 --- a/ui/admin/app/routes/scopes/scope/users/index.js +++ b/ui/admin/app/routes/scopes/scope/users/index.js @@ -1,7 +1,6 @@ import Route from '@ember/routing/route'; export default class ScopesScopeUsersIndexRoute extends Route { - // =methods setupController(controller) { @@ -9,5 +8,4 @@ export default class ScopesScopeUsersIndexRoute extends Route { super.setupController(...arguments); controller.setProperties({ scope }); } - } diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 825be5d14..fd20ca2a2 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -142,4 +142,4 @@ - + \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/users/index.hbs b/ui/admin/app/templates/scopes/scope/users/index.hbs index 61d80197b..ef9ef91b3 100644 --- a/ui/admin/app/templates/scopes/scope/users/index.hbs +++ b/ui/admin/app/templates/scopes/scope/users/index.hbs @@ -70,19 +70,21 @@ as |message| > - {{t 'resources.user.description'}} - {{#if (can 'create collection' this.scope collection='users')}} - {{#unless (can 'list collection' this.scope collection='users')}} -
-
- - Oh noes! Resources you create won't appear here because you - have create permission, but not list. - - {{/unless}} + {{#if (can 'list collection' this.scope collection='users')}} + {{! can list (at least): show default welcome message}} + {{t 'resources.user.description'}} + {{else if (can 'create collection' this.scope collection='users')}} + {{! can create (only): show create-but-not-list welcome message}} + {{t + 'descriptions.create-but-not-list' + resource=(t 'resources.user.title_plural') + }} + {{else}} + {{! can neither list nor create }} + {{t + 'descriptions.neither-list-nor-create' + resource=(t 'resources.user.title_plural') + }} {{/if}}
{{#if (can 'create collection' this.scope collection='users')}} @@ -98,4 +100,4 @@ - + \ No newline at end of file From b0326e0c994c294a715701b1a6d17329a4f1813f Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 25 Aug 2021 16:24:26 -0400 Subject: [PATCH 04/17] test: add user create test and stubbed list test --- .../{users-test.js => users/create-test.js} | 22 ++++++- ui/admin/tests/acceptance/users/list-test.js | 57 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) rename ui/admin/tests/acceptance/{users-test.js => users/create-test.js} (74%) create mode 100644 ui/admin/tests/acceptance/users/list-test.js diff --git a/ui/admin/tests/acceptance/users-test.js b/ui/admin/tests/acceptance/users/create-test.js similarity index 74% rename from ui/admin/tests/acceptance/users-test.js rename to ui/admin/tests/acceptance/users/create-test.js index b047a0d2a..069ca0102 100644 --- a/ui/admin/tests/acceptance/users-test.js +++ b/ui/admin/tests/acceptance/users/create-test.js @@ -10,23 +10,28 @@ import { //invalidateSession, } from 'ember-simple-auth/test-support'; -module('Acceptance | users', function (hooks) { +module('Acceptance | users | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let globalScope; let orgScope; + let orgURL; let usersURL; let newUserURL; hooks.beforeEach(function () { + globalScope = this.server.create('scope', { id: 'global' }); orgScope = this.server.create( 'scope', { type: 'org', + scope: { id: 'global', type: 'global' }, }, 'withChildren' ); + orgURL = `/scopes/${orgScope.id}`; usersURL = `/scopes/${orgScope.id}/users`; newUserURL = `${usersURL}/new`; @@ -42,6 +47,21 @@ module('Acceptance | users', function (hooks) { assert.equal(this.server.db.users.length, usersCount + 1); }); + test('can navigate to new users route with proper authorization', async function (assert) { + assert.expect(2); + await visit(orgURL); + assert.ok(orgScope.authorized_collection_actions.users.includes('create')); + assert.ok(find(`[href="${orgURL}/users"]`)); + }); + + test('cannot navigate to new users route without proper authorization', async function (assert) { + assert.expect(2); + orgScope.authorized_collection_actions.users = []; + await visit(orgURL); + assert.notOk(orgScope.authorized_collection_actions.users.includes('create')); + assert.notOk(find(`[href="${orgURL}/users"]`)); + }); + test('can cancel creation of a new user', async function (assert) { assert.expect(2); const usersCount = this.server.db.users.length; diff --git a/ui/admin/tests/acceptance/users/list-test.js b/ui/admin/tests/acceptance/users/list-test.js new file mode 100644 index 000000000..bf768b334 --- /dev/null +++ b/ui/admin/tests/acceptance/users/list-test.js @@ -0,0 +1,57 @@ +import { module, test } from 'qunit'; +import { visit, currentURL, find } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import a11yAudit from 'ember-a11y-testing/test-support/audit'; +import { + authenticateSession, + // These are left here intentionally for future reference. + //currentSession, + //invalidateSession, +} from 'ember-simple-auth/test-support'; + +module('Acceptance | users | list', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + let usersURL; + + const instances = { + scopes: { + global: null, + org: null, + } + }; + + const urls = { + scopes: { + org: null + }, + users: null + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.org = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); + instances.user = this.server.create('user', { + scope: instances.org, + }); + urls.users = `/scopes/${instances.org.id}/users`; + authenticateSession({}); + }); + + test('can navigate to users with proper authorization', async function (assert) { + // TODO + }); + + test('cannot navigate to users with proper authorization', async function (assert) { + // TODO + }); +}); From b2f11f712bd3dbad681576bdd64756dc17192ff5 Mon Sep 17 00:00:00 2001 From: dharini Date: Wed, 25 Aug 2021 23:43:07 -0700 Subject: [PATCH 05/17] grp --- addons/api/addon/abilities/collection.js | 3 +- addons/api/addon/models/base.js | 5 ++ addons/api/mirage/factories/scope.js | 5 ++ addons/core/translations/en-us.yaml | 2 + ui/admin/app/routes/scopes/scope/groups.js | 9 ++- .../app/routes/scopes/scope/groups/index.js | 9 ++- .../templates/scopes/scope/groups/index.hbs | 36 +++++++-- .../{groups-test.js => groups/create-test.js} | 20 ++++- .../tests/acceptance/groups/delete-test.js | 2 +- ui/admin/tests/acceptance/groups/list-test.js | 80 +++++++++++++++++++ 10 files changed, 154 insertions(+), 17 deletions(-) rename ui/admin/tests/acceptance/{groups-test.js => groups/create-test.js} (84%) create mode 100644 ui/admin/tests/acceptance/groups/list-test.js diff --git a/addons/api/addon/abilities/collection.js b/addons/api/addon/abilities/collection.js index ad52afd18..92f0e4342 100644 --- a/addons/api/addon/abilities/collection.js +++ b/addons/api/addon/abilities/collection.js @@ -29,7 +29,8 @@ export default class CollectionAbility extends Ability { * @return {boolean} */ hasAuthorizedCollectionAction(action) { - const { authorized_collection_actions } = this.model; + const authorized_collection_actions = + (this.model || {}).authorized_collection_actions || {}; const collection = this.collection || {}; return authorized_collection_actions[collection]?.includes(action); } diff --git a/addons/api/addon/models/base.js b/addons/api/addon/models/base.js index f99e0351a..7fd41ec64 100644 --- a/addons/api/addon/models/base.js +++ b/addons/api/addon/models/base.js @@ -42,6 +42,11 @@ export default class BaseModel extends Model { }) authorized_actions; + @attr({ + readOnly: true, + }) + authorized_collection_actions; + set scopeModel(model) { if (model) { const json = model.serialize(); diff --git a/addons/api/mirage/factories/scope.js b/addons/api/mirage/factories/scope.js index fe41f3866..e6a1071f5 100644 --- a/addons/api/mirage/factories/scope.js +++ b/addons/api/mirage/factories/scope.js @@ -4,6 +4,11 @@ import { trait } from 'ember-cli-mirage'; export default factory.extend({ type: 'global', + authorized_collection_actions: () => { + return { + groups: ['create', 'list'], + }; + }, /** * Generates realistic-ish IDs while still being deterministic. */ diff --git a/addons/core/translations/en-us.yaml b/addons/core/translations/en-us.yaml index 5370c7e75..8f98f633c 100644 --- a/addons/core/translations/en-us.yaml +++ b/addons/core/translations/en-us.yaml @@ -32,6 +32,8 @@ titles: descriptions: empty-set: There are no items to display yet. You may be able to add items or try back later. origin-initialization: To get started, please enter your origin URL + create-but-not-list: You do not have permission to list {resource}, but you can create new instances. + neither-list-nor-create: You do not have permission to list or create {resource}. questions: delete-confirm: Are you sure you want to delete this resource? remove-confirm: Are you sure you want to remove this association? diff --git a/ui/admin/app/routes/scopes/scope/groups.js b/ui/admin/app/routes/scopes/scope/groups.js index 7fa556182..1784799cc 100644 --- a/ui/admin/app/routes/scopes/scope/groups.js +++ b/ui/admin/app/routes/scopes/scope/groups.js @@ -11,7 +11,7 @@ export default class ScopesScopeGroupsRoute extends Route { @service intl; @service notify; @service session; - + @service can; // =methods /** @@ -26,8 +26,11 @@ export default class ScopesScopeGroupsRoute extends Route { * @return {Promise[GroupModel]} */ async model() { - const { id: scope_id } = this.modelFor('scopes.scope'); - return this.store.query('group', { scope_id }); + const scope = this.modelFor('scopes.scope'); + const { id: scope_id } = scope; + if (this.can.can('list collection', scope, { collection: 'groups' })) { + return this.store.query('group', { scope_id }); + } } // =actions diff --git a/ui/admin/app/routes/scopes/scope/groups/index.js b/ui/admin/app/routes/scopes/scope/groups/index.js index 7d2a20fb0..22e3d3593 100644 --- a/ui/admin/app/routes/scopes/scope/groups/index.js +++ b/ui/admin/app/routes/scopes/scope/groups/index.js @@ -1,3 +1,10 @@ import Route from '@ember/routing/route'; +export default class ScopesScopeGroupsIndexRoute extends Route { + // =methods -export default class ScopesScopeGroupsIndexRoute extends Route {} + setupController(controller) { + const scope = this.modelFor('scopes.scope'); + super.setupController(...arguments); + controller.setProperties({ scope }); + } +} diff --git a/ui/admin/app/templates/scopes/scope/groups/index.hbs b/ui/admin/app/templates/scopes/scope/groups/index.hbs index cb59fde2e..e1104e0c8 100644 --- a/ui/admin/app/templates/scopes/scope/groups/index.hbs +++ b/ui/admin/app/templates/scopes/scope/groups/index.hbs @@ -13,10 +13,12 @@ - {{#if @model}} - {{t - 'titles.new' - }} + {{#if (can 'create collection' this.scope collection='groups')}} + {{#if @model}} + {{t + 'titles.new' + }} + {{/if}} {{/if}} @@ -70,11 +72,29 @@ > {{t 'resources.group.description'}} + {{#if (can 'list collection' this.scope collection='groups')}} + {{! can list (at least): show default welcome message}} + {{t 'resources.group.description'}} + {{else if (can 'create collection' this.scope collection='groups')}} + {{! can create (only): show create-but-not-list welcome message}} + {{t + 'descriptions.create-but-not-list' + resource=(t 'resources.group.title_plural') + }} + {{else}} + {{! can neither list nor create }} + {{t + 'descriptions.neither-list-nor-create' + resource=(t 'resources.group.title_plural') + }} + {{/if}} - - - {{t 'titles.new'}} - + {{#if (can 'create collection' this.scope collection='groups')}} + + + {{t 'titles.new'}} + + {{/if}} diff --git a/ui/admin/tests/acceptance/groups-test.js b/ui/admin/tests/acceptance/groups/create-test.js similarity index 84% rename from ui/admin/tests/acceptance/groups-test.js rename to ui/admin/tests/acceptance/groups/create-test.js index 38b95d60d..291222647 100644 --- a/ui/admin/tests/acceptance/groups-test.js +++ b/ui/admin/tests/acceptance/groups/create-test.js @@ -10,10 +10,10 @@ import { //invalidateSession, } from 'ember-simple-auth/test-support'; -module('Acceptance | groups', function (hooks) { +module('Acceptance | groups | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - + let orgScope; const instances = { scopes: { global: null, @@ -22,7 +22,6 @@ module('Acceptance | groups', function (hooks) { group: null, }; const urls = { - orgScope: null, groups: null, group: null, newGroup: null, @@ -31,6 +30,14 @@ module('Acceptance | groups', function (hooks) { hooks.beforeEach(function () { authenticateSession({}); instances.scopes.global = this.server.create('scope', { id: 'global' }); + orgScope = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); instances.scopes.org = this.server.create('scope', { type: 'org', scope: { id: 'global', type: 'global' }, @@ -52,6 +59,13 @@ module('Acceptance | groups', function (hooks) { assert.equal(this.server.db.groups.length, groupsCount + 1); }); + test('cannot create new group without proper authorization', async function (assert) { + assert.expect(1); + orgScope.authorized_collection_actions.groups = ['list']; + await visit(urls.groups); + assert.notOk(find('.rose-layout-page-actions .rose-button-primary')); + }); + test('can cancel new group creation', async function (assert) { assert.expect(2); const groupsCount = this.server.db.groups.length; diff --git a/ui/admin/tests/acceptance/groups/delete-test.js b/ui/admin/tests/acceptance/groups/delete-test.js index c1dec7fdb..ed9838d24 100644 --- a/ui/admin/tests/acceptance/groups/delete-test.js +++ b/ui/admin/tests/acceptance/groups/delete-test.js @@ -1,4 +1,4 @@ -import { module, test } from 'qunit'; + import { module, test } from 'qunit'; import { visit, click, find } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; diff --git a/ui/admin/tests/acceptance/groups/list-test.js b/ui/admin/tests/acceptance/groups/list-test.js new file mode 100644 index 000000000..988136963 --- /dev/null +++ b/ui/admin/tests/acceptance/groups/list-test.js @@ -0,0 +1,80 @@ +import { module, test } from 'qunit'; +import { visit, find } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { + authenticateSession, + // These are left here intentionally for future reference. + //currentSession, + //invalidateSession, +} from 'ember-simple-auth/test-support'; + +module('Acceptance | groups | list', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + let orgScope; + let orgURL; + const instances = { + scopes: { + global: null, + org: null, + }, + }; + + const urls = { + scopes: { + org: null, + }, + groups: null, + orgScope: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + orgScope = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); + instances.org = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + instances.group = this.server.create('group', { + scope: instances.org, + }); + urls.groups = `/scopes/${instances.scopes.org.id}/groups`; + orgURL = `/scopes/${orgScope.id}`; + + authenticateSession({}); + }); + + test('can navigate to groups with proper authorization', async function (assert) { + assert.expect(2); + orgScope.authorized_collection_actions.groups = ['list']; + await visit(orgURL); + assert.ok(orgScope.authorized_collection_actions.groups.includes('list')); + assert.ok(find(`[href="${orgURL}/groups"]`)); + }); + + test('cannot navigate to groups without proper authorization', async function (assert) { + assert.expect(1); + orgScope.authorized_collection_actions.groups = []; + await visit(orgURL); + assert.notOk( + orgScope.authorized_collection_actions.groups.includes('list') + ); + //assert.notOk(find(`[href="${orgURL}/groups"]`)); + }); +}); From b5fdb850f6a14f7077439cdb35684144eae9917d Mon Sep 17 00:00:00 2001 From: dharini Date: Thu, 26 Aug 2021 00:02:57 -0700 Subject: [PATCH 06/17] =?UTF-8?q?test:=20=F0=9F=92=8D=20add=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/acceptance/users/create-test.js | 6 ++-- ui/admin/tests/acceptance/users/list-test.js | 36 ++++++++++++++----- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/ui/admin/tests/acceptance/users/create-test.js b/ui/admin/tests/acceptance/users/create-test.js index 069ca0102..fbff7fbee 100644 --- a/ui/admin/tests/acceptance/users/create-test.js +++ b/ui/admin/tests/acceptance/users/create-test.js @@ -14,14 +14,12 @@ module('Acceptance | users | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - let globalScope; let orgScope; let orgURL; let usersURL; let newUserURL; hooks.beforeEach(function () { - globalScope = this.server.create('scope', { id: 'global' }); orgScope = this.server.create( 'scope', { @@ -58,7 +56,9 @@ module('Acceptance | users | create', function (hooks) { assert.expect(2); orgScope.authorized_collection_actions.users = []; await visit(orgURL); - assert.notOk(orgScope.authorized_collection_actions.users.includes('create')); + assert.notOk( + orgScope.authorized_collection_actions.users.includes('create') + ); assert.notOk(find(`[href="${orgURL}/users"]`)); }); diff --git a/ui/admin/tests/acceptance/users/list-test.js b/ui/admin/tests/acceptance/users/list-test.js index bf768b334..8e071febc 100644 --- a/ui/admin/tests/acceptance/users/list-test.js +++ b/ui/admin/tests/acceptance/users/list-test.js @@ -1,8 +1,7 @@ import { module, test } from 'qunit'; -import { visit, currentURL, find } from '@ember/test-helpers'; +import { visit, find } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; -import a11yAudit from 'ember-a11y-testing/test-support/audit'; import { authenticateSession, // These are left here intentionally for future reference. @@ -13,25 +12,33 @@ import { module('Acceptance | users | list', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - - let usersURL; + let orgScope; + let orgURL; const instances = { scopes: { global: null, org: null, - } + }, }; const urls = { scopes: { - org: null + org: null, }, - users: null + users: null, }; hooks.beforeEach(function () { instances.scopes.global = this.server.create('scope', { id: 'global' }); + orgScope = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); instances.org = this.server.create( 'scope', { @@ -43,15 +50,26 @@ module('Acceptance | users | list', function (hooks) { instances.user = this.server.create('user', { scope: instances.org, }); + orgURL = `/scopes/${orgScope.id}`; + urls.users = `/scopes/${instances.org.id}/users`; authenticateSession({}); }); test('can navigate to users with proper authorization', async function (assert) { - // TODO + assert.expect(2); + await visit(orgURL); + assert.ok(orgScope.authorized_collection_actions.users.includes('create')); + assert.ok(find(`[href="${orgURL}/users"]`)); }); test('cannot navigate to users with proper authorization', async function (assert) { - // TODO + assert.expect(2); + orgScope.authorized_collection_actions.users = []; + await visit(orgURL); + assert.notOk( + orgScope.authorized_collection_actions.users.includes('create') + ); + assert.notOk(find(`[href="${orgURL}/users"]`)); }); }); From 350c4f5f70e2e4b67ee7df42506ce722557e1d56 Mon Sep 17 00:00:00 2001 From: dharini Date: Fri, 27 Aug 2021 08:06:24 -0700 Subject: [PATCH 07/17] =?UTF-8?q?fix:=20=F0=9F=90=9B=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/tests/acceptance/users/list-test.js | 30 +++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/ui/admin/tests/acceptance/users/list-test.js b/ui/admin/tests/acceptance/users/list-test.js index 8e071febc..0d8aaa60e 100644 --- a/ui/admin/tests/acceptance/users/list-test.js +++ b/ui/admin/tests/acceptance/users/list-test.js @@ -12,7 +12,6 @@ import { module('Acceptance | users | list', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - let orgScope; let orgURL; const instances = { @@ -27,11 +26,12 @@ module('Acceptance | users | list', function (hooks) { org: null, }, users: null, + orgScope: null, }; hooks.beforeEach(function () { instances.scopes.global = this.server.create('scope', { id: 'global' }); - orgScope = this.server.create( + urls.orgScope = this.server.create( 'scope', { type: 'org', @@ -50,26 +50,36 @@ module('Acceptance | users | list', function (hooks) { instances.user = this.server.create('user', { scope: instances.org, }); - orgURL = `/scopes/${orgScope.id}`; + orgURL = `/scopes/${urls.orgScope.id}`; + //urls.orgScope = `/scopes/${instances.org.id}/scopes`; - urls.users = `/scopes/${instances.org.id}/users`; + urls.users = `/scopes/${urls.orgScope.id}/users`; authenticateSession({}); }); test('can navigate to users with proper authorization', async function (assert) { assert.expect(2); await visit(orgURL); - assert.ok(orgScope.authorized_collection_actions.users.includes('create')); - assert.ok(find(`[href="${orgURL}/users"]`)); + assert.ok( + urls.orgScope.authorized_collection_actions.users.includes('list') + ); + assert.ok(find(`[href="${urls.users}"]`)); }); - test('cannot navigate to users with proper authorization', async function (assert) { + test('User cannot navigate to index without either list or create actions', async function (assert) { assert.expect(2); - orgScope.authorized_collection_actions.users = []; + urls.orgScope.authorized_collection_actions.users = []; await visit(orgURL); assert.notOk( - orgScope.authorized_collection_actions.users.includes('create') + urls.orgScope.authorized_collection_actions.users.includes('list') ); - assert.notOk(find(`[href="${orgURL}/users"]`)); + assert.notOk(find(`[href="${urls.usersorgURL}"]`)); + }); + + test('User can navigate to index with only create action', async function (assert) { + assert.expect(1); + urls.orgScope.authorized_collection_actions.users = ['create']; + await visit(orgURL); + assert.ok(find(`[href="${urls.users}"]`)); }); }); From 40c2acd6ab476c3b5863d5cafe76c06d174c3318 Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Fri, 27 Aug 2021 10:17:34 -0700 Subject: [PATCH 08/17] Update list-test.js --- ui/admin/tests/acceptance/users/list-test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/ui/admin/tests/acceptance/users/list-test.js b/ui/admin/tests/acceptance/users/list-test.js index 0d8aaa60e..d752d8687 100644 --- a/ui/admin/tests/acceptance/users/list-test.js +++ b/ui/admin/tests/acceptance/users/list-test.js @@ -51,8 +51,6 @@ module('Acceptance | users | list', function (hooks) { scope: instances.org, }); orgURL = `/scopes/${urls.orgScope.id}`; - //urls.orgScope = `/scopes/${instances.org.id}/scopes`; - urls.users = `/scopes/${urls.orgScope.id}/users`; authenticateSession({}); }); From 3a3fdf2396d917a2aeecfaff4632ba6261d07354 Mon Sep 17 00:00:00 2001 From: dharini Date: Fri, 27 Aug 2021 13:09:00 -0700 Subject: [PATCH 09/17] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20grp=20create/list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/templates/scopes/scope.hbs | 10 +++-- .../create-test.js => group-create-test.js} | 16 -------- .../tests/acceptance/groups/delete-test.js | 2 +- ui/admin/tests/acceptance/groups/list-test.js | 37 +++++++++++-------- 4 files changed, 28 insertions(+), 37 deletions(-) rename ui/admin/tests/acceptance/{groups/create-test.js => group-create-test.js} (86%) diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 65e456c51..fd768111d 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -98,10 +98,12 @@ {{t 'resources.user.title_plural'}}
- - - {{t 'resources.group.title_plural'}} - + {{#if (can 'navigate collection' @model collection='groups')}} + + + {{t 'resources.group.title_plural'}} + + {{/if}} {{t 'resources.role.title_plural'}} diff --git a/ui/admin/tests/acceptance/groups/create-test.js b/ui/admin/tests/acceptance/group-create-test.js similarity index 86% rename from ui/admin/tests/acceptance/groups/create-test.js rename to ui/admin/tests/acceptance/group-create-test.js index 291222647..616ce66b4 100644 --- a/ui/admin/tests/acceptance/groups/create-test.js +++ b/ui/admin/tests/acceptance/group-create-test.js @@ -13,7 +13,6 @@ import { module('Acceptance | groups | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - let orgScope; const instances = { scopes: { global: null, @@ -30,14 +29,6 @@ module('Acceptance | groups | create', function (hooks) { hooks.beforeEach(function () { authenticateSession({}); instances.scopes.global = this.server.create('scope', { id: 'global' }); - orgScope = this.server.create( - 'scope', - { - type: 'org', - scope: { id: 'global', type: 'global' }, - }, - 'withChildren' - ); instances.scopes.org = this.server.create('scope', { type: 'org', scope: { id: 'global', type: 'global' }, @@ -59,13 +50,6 @@ module('Acceptance | groups | create', function (hooks) { assert.equal(this.server.db.groups.length, groupsCount + 1); }); - test('cannot create new group without proper authorization', async function (assert) { - assert.expect(1); - orgScope.authorized_collection_actions.groups = ['list']; - await visit(urls.groups); - assert.notOk(find('.rose-layout-page-actions .rose-button-primary')); - }); - test('can cancel new group creation', async function (assert) { assert.expect(2); const groupsCount = this.server.db.groups.length; diff --git a/ui/admin/tests/acceptance/groups/delete-test.js b/ui/admin/tests/acceptance/groups/delete-test.js index ed9838d24..c1dec7fdb 100644 --- a/ui/admin/tests/acceptance/groups/delete-test.js +++ b/ui/admin/tests/acceptance/groups/delete-test.js @@ -1,4 +1,4 @@ - import { module, test } from 'qunit'; +import { module, test } from 'qunit'; import { visit, click, find } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; diff --git a/ui/admin/tests/acceptance/groups/list-test.js b/ui/admin/tests/acceptance/groups/list-test.js index 988136963..fd93645a7 100644 --- a/ui/admin/tests/acceptance/groups/list-test.js +++ b/ui/admin/tests/acceptance/groups/list-test.js @@ -12,8 +12,8 @@ import { module('Acceptance | groups | list', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - let orgScope; let orgURL; + const instances = { scopes: { global: null, @@ -31,7 +31,7 @@ module('Acceptance | groups | list', function (hooks) { hooks.beforeEach(function () { instances.scopes.global = this.server.create('scope', { id: 'global' }); - orgScope = this.server.create( + urls.orgScope = this.server.create( 'scope', { type: 'org', @@ -47,34 +47,39 @@ module('Acceptance | groups | list', function (hooks) { }, 'withChildren' ); - instances.scopes.org = this.server.create('scope', { - type: 'org', - scope: { id: 'global', type: 'global' }, - }); instances.group = this.server.create('group', { scope: instances.org, }); - urls.groups = `/scopes/${instances.scopes.org.id}/groups`; - orgURL = `/scopes/${orgScope.id}`; + orgURL = `/scopes/${urls.orgScope.id}`; + //urls.orgScope = `/scopes/${instances.org.id}/scopes`; + urls.groups = `/scopes/${urls.orgScope.id}/groups`; authenticateSession({}); }); test('can navigate to groups with proper authorization', async function (assert) { assert.expect(2); - orgScope.authorized_collection_actions.groups = ['list']; await visit(orgURL); - assert.ok(orgScope.authorized_collection_actions.groups.includes('list')); - assert.ok(find(`[href="${orgURL}/groups"]`)); + assert.ok( + urls.orgScope.authorized_collection_actions.groups.includes('list') + ); + assert.ok(find(`[href="${urls.groups}"]`)); }); - test('cannot navigate to groups without proper authorization', async function (assert) { - assert.expect(1); - orgScope.authorized_collection_actions.groups = []; + test('User cannot navigate to index without either list or create actions', async function (assert) { + assert.expect(2); + urls.orgScope.authorized_collection_actions.groups = []; await visit(orgURL); assert.notOk( - orgScope.authorized_collection_actions.groups.includes('list') + urls.orgScope.authorized_collection_actions.groups.includes('list') ); - //assert.notOk(find(`[href="${orgURL}/groups"]`)); + assert.notOk(find(`[href="${urls.groups}"]`)); + }); + + test('User can navigate to index with only create action', async function (assert) { + assert.expect(1); + urls.orgScope.authorized_collection_actions.groups = ['create']; + await visit(orgURL); + assert.ok(find(`[href="${urls.groups}"]`)); }); }); From fc4dab606e46decbb240127e561f826099462449 Mon Sep 17 00:00:00 2001 From: dharini Date: Sun, 29 Aug 2021 22:57:16 -0700 Subject: [PATCH 10/17] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20roles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/abilities/collection.js | 3 +- addons/api/addon/models/base.js | 5 ++ addons/api/mirage/factories/scope.js | 6 ++ addons/core/translations/en-us.yaml | 2 + ui/admin/app/routes/scopes/scope/roles.js | 8 +- .../app/routes/scopes/scope/roles/index.js | 9 +- ui/admin/app/templates/scopes/scope.hbs | 10 ++- .../templates/scopes/scope/roles/index.hbs | 37 ++++++-- .../{roles-test.js => roles/create-test.js} | 42 ++++++++-- ui/admin/tests/acceptance/roles/list-test.js | 84 +++++++++++++++++++ 10 files changed, 183 insertions(+), 23 deletions(-) rename ui/admin/tests/acceptance/{roles-test.js => roles/create-test.js} (73%) create mode 100644 ui/admin/tests/acceptance/roles/list-test.js diff --git a/addons/api/addon/abilities/collection.js b/addons/api/addon/abilities/collection.js index ad52afd18..92f0e4342 100644 --- a/addons/api/addon/abilities/collection.js +++ b/addons/api/addon/abilities/collection.js @@ -29,7 +29,8 @@ export default class CollectionAbility extends Ability { * @return {boolean} */ hasAuthorizedCollectionAction(action) { - const { authorized_collection_actions } = this.model; + const authorized_collection_actions = + (this.model || {}).authorized_collection_actions || {}; const collection = this.collection || {}; return authorized_collection_actions[collection]?.includes(action); } diff --git a/addons/api/addon/models/base.js b/addons/api/addon/models/base.js index f99e0351a..7fd41ec64 100644 --- a/addons/api/addon/models/base.js +++ b/addons/api/addon/models/base.js @@ -42,6 +42,11 @@ export default class BaseModel extends Model { }) authorized_actions; + @attr({ + readOnly: true, + }) + authorized_collection_actions; + set scopeModel(model) { if (model) { const json = model.serialize(); diff --git a/addons/api/mirage/factories/scope.js b/addons/api/mirage/factories/scope.js index fe41f3866..0121b9542 100644 --- a/addons/api/mirage/factories/scope.js +++ b/addons/api/mirage/factories/scope.js @@ -4,6 +4,12 @@ import { trait } from 'ember-cli-mirage'; export default factory.extend({ type: 'global', + authorized_collection_actions: () => { + return { + roles: ['create', 'list'], + }; + }, + /** * Generates realistic-ish IDs while still being deterministic. */ diff --git a/addons/core/translations/en-us.yaml b/addons/core/translations/en-us.yaml index 5370c7e75..8f98f633c 100644 --- a/addons/core/translations/en-us.yaml +++ b/addons/core/translations/en-us.yaml @@ -32,6 +32,8 @@ titles: descriptions: empty-set: There are no items to display yet. You may be able to add items or try back later. origin-initialization: To get started, please enter your origin URL + create-but-not-list: You do not have permission to list {resource}, but you can create new instances. + neither-list-nor-create: You do not have permission to list or create {resource}. questions: delete-confirm: Are you sure you want to delete this resource? remove-confirm: Are you sure you want to remove this association? diff --git a/ui/admin/app/routes/scopes/scope/roles.js b/ui/admin/app/routes/scopes/scope/roles.js index 88d05373b..cbc1dfcc5 100644 --- a/ui/admin/app/routes/scopes/scope/roles.js +++ b/ui/admin/app/routes/scopes/scope/roles.js @@ -11,6 +11,7 @@ export default class ScopesScopeRolesRoute extends Route { @service intl; @service notify; @service session; + @service can; // =methods @@ -26,8 +27,11 @@ export default class ScopesScopeRolesRoute extends Route { * @return {Promise{[RoleModel]}} */ async model() { - const { id: scope_id } = this.modelFor('scopes.scope'); - return this.store.query('role', { scope_id }); + const scope = this.modelFor('scopes.scope'); + const { id: scope_id } = scope; + if (this.can.can('list collection', scope, { collection: 'roles' })) { + return this.store.query('role', { scope_id }); + } } // =actions diff --git a/ui/admin/app/routes/scopes/scope/roles/index.js b/ui/admin/app/routes/scopes/scope/roles/index.js index f2a8d7af1..6020b0c6f 100644 --- a/ui/admin/app/routes/scopes/scope/roles/index.js +++ b/ui/admin/app/routes/scopes/scope/roles/index.js @@ -1,3 +1,10 @@ import Route from '@ember/routing/route'; +export default class ScopesScopeUsersIndexRoute extends Route { + // =methods -export default class ScopesScopeRolesIndexRoute extends Route {} + setupController(controller) { + const scope = this.modelFor('scopes.scope'); + super.setupController(...arguments); + controller.setProperties({ scope }); + } +} diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 65e456c51..f2b01f11b 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -102,10 +102,12 @@ {{t 'resources.group.title_plural'}} - - - {{t 'resources.role.title_plural'}} - + {{#if (can 'navigate collection' @model collection='roles')}} + + + {{t 'resources.role.title_plural'}} + + {{/if}} {{t 'resources.auth-method.title_plural'}} diff --git a/ui/admin/app/templates/scopes/scope/roles/index.hbs b/ui/admin/app/templates/scopes/scope/roles/index.hbs index d69351c8e..ac7664ece 100644 --- a/ui/admin/app/templates/scopes/scope/roles/index.hbs +++ b/ui/admin/app/templates/scopes/scope/roles/index.hbs @@ -15,10 +15,12 @@ - {{#if @model}} - {{t - 'titles.new' - }} + {{#if (can 'create collection' this.scope collection='users')}} + {{#if @model}} + {{t + 'titles.new' + }} + {{/if}} {{/if}} @@ -68,12 +70,29 @@ as |message| > - {{t 'resources.role.description'}} + {{#if (can 'list collection' this.scope collection='roles')}} + {{! can list (at least): show default welcome message}} + {{t 'resources.roles.description'}} + {{else if (can 'create collection' this.scope collection='roles')}} + {{! can create (only): show create-but-not-list welcome message}} + {{t + 'descriptions.create-but-not-list' + resource=(t 'resources.role.title_plural') + }} + {{else}} + {{! can neither list nor create }} + {{t + 'descriptions.neither-list-nor-create' + resource=(t 'resources.role.title_plural') + }} + {{/if}} - - - {{t 'titles.new'}} - + {{#if (can 'create collection' this.scope collection='roles')}} + + + {{t 'titles.new'}} + + {{/if}} diff --git a/ui/admin/tests/acceptance/roles-test.js b/ui/admin/tests/acceptance/roles/create-test.js similarity index 73% rename from ui/admin/tests/acceptance/roles-test.js rename to ui/admin/tests/acceptance/roles/create-test.js index 77b971f46..a0364c8b0 100644 --- a/ui/admin/tests/acceptance/roles-test.js +++ b/ui/admin/tests/acceptance/roles/create-test.js @@ -11,10 +11,13 @@ import { //invalidateSession, } from 'ember-simple-auth/test-support'; -module('Acceptance | roles', function (hooks) { +module('Acceptance | roles | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let orgURL; + let orgScope; + const instances = { scopes: { global: null, @@ -27,10 +30,20 @@ module('Acceptance | roles', function (hooks) { orgScope: null, roles: null, role: null, - newRole: null, + newRoleURL: null, }; hooks.beforeEach(function () { + orgScope = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); + + orgURL = `/scopes/${orgScope.id}`; authenticateSession({}); instances.scopes.global = this.server.create('scope', { id: 'global' }); instances.scopes.org = this.server.create('scope', { @@ -53,22 +66,39 @@ module('Acceptance | roles', function (hooks) { ); urls.roles = `/scopes/${instances.scopes.org.id}/roles`; urls.role = `${urls.roles}/${instances.role.id}`; - urls.newRole = `${urls.roles}/new`; + urls.newRoleURL = `${urls.roles}/new`; }); test('can create new role', async function (assert) { assert.expect(1); const rolesCount = this.server.db.roles.length; - await visit(urls.newRole); + await visit(urls.newRoleURL); await fillIn('[name="name"]', 'role name'); await click('[type="submit"]'); assert.equal(this.server.db.roles.length, rolesCount + 1); }); + test('can navigate to new roles route with proper authorization', async function (assert) { + assert.expect(2); + await visit(orgURL); + assert.ok(orgScope.authorized_collection_actions.roles.includes('create')); + assert.ok(find(`[href="${orgURL}/roles"]`)); + }); + + test('cannot navigate to new roles route without proper authorization', async function (assert) { + assert.expect(2); + orgScope.authorized_collection_actions.roles = []; + await visit(orgURL); + assert.notOk( + orgScope.authorized_collection_actions.roles.includes('create') + ); + assert.notOk(find(`[href="${orgURL}/roles"]`)); + }); + test('can cancel new role creation', async function (assert) { assert.expect(2); const rolesCount = this.server.db.roles.length; - await visit(urls.newRole); + await visit(urls.newRoleURL); await fillIn('[name="name"]', 'role name'); await click('.rose-form-actions [type="button"]'); assert.equal(currentURL(), urls.roles); @@ -96,7 +126,7 @@ module('Acceptance | roles', function (hooks) { } ); }); - await visit(urls.newRole); + await visit(urls.newRoleURL); await fillIn('[name="name"]', 'new target'); await click('form [type="submit"]'); await a11yAudit(); diff --git a/ui/admin/tests/acceptance/roles/list-test.js b/ui/admin/tests/acceptance/roles/list-test.js new file mode 100644 index 000000000..78e7d22fa --- /dev/null +++ b/ui/admin/tests/acceptance/roles/list-test.js @@ -0,0 +1,84 @@ +import { module, test } from 'qunit'; +import { visit, find } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { + authenticateSession, + // These are left here intentionally for future reference. + //currentSession, + //invalidateSession, +} from 'ember-simple-auth/test-support'; + +module('Acceptance | roles | list', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + let orgURL; + + const instances = { + scopes: { + global: null, + org: null, + }, + }; + + const urls = { + scopes: { + org: null, + }, + roles: null, + orgScope: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + urls.orgScope = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); + instances.org = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); + instances.role = this.server.create('role', { + scope: instances.org, + }); + orgURL = `/scopes/${urls.orgScope.id}`; + + urls.roles = `/scopes/${urls.orgScope.id}/roles`; + authenticateSession({}); + }); + + test('can navigate to roles with proper authorization', async function (assert) { + assert.expect(2); + await visit(orgURL); + assert.ok( + urls.orgScope.authorized_collection_actions.roles.includes('list') + ); + assert.ok(find(`[href="${urls.roles}"]`)); + }); + + test('User cannot navigate to index without either list or create actions', async function (assert) { + assert.expect(2); + urls.orgScope.authorized_collection_actions.roles = []; + await visit(orgURL); + assert.notOk( + urls.orgScope.authorized_collection_actions.roles.includes('list') + ); + assert.notOk(find(`[href="${urls.roles}"]`)); + }); + + test('User can navigate to index with only create action', async function (assert) { + assert.expect(1); + urls.orgScope.authorized_collection_actions.roles = ['create']; + await visit(orgURL); + assert.ok(find(`[href="${urls.roles}"]`)); + }); +}); From ce286964d11a85d3d1305de598a6a65e28a2e04c Mon Sep 17 00:00:00 2001 From: dharini Date: Mon, 30 Aug 2021 21:49:48 -0700 Subject: [PATCH 11/17] =?UTF-8?q?fix:=20=F0=9F=90=9B=20tests=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/tests/acceptance/users/list-test.js | 28 +++++++------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/ui/admin/tests/acceptance/users/list-test.js b/ui/admin/tests/acceptance/users/list-test.js index d752d8687..72a6e35eb 100644 --- a/ui/admin/tests/acceptance/users/list-test.js +++ b/ui/admin/tests/acceptance/users/list-test.js @@ -19,6 +19,7 @@ module('Acceptance | users | list', function (hooks) { global: null, org: null, }, + orgScope: null, }; const urls = { @@ -26,20 +27,11 @@ module('Acceptance | users | list', function (hooks) { org: null, }, users: null, - orgScope: null, }; hooks.beforeEach(function () { instances.scopes.global = this.server.create('scope', { id: 'global' }); - urls.orgScope = this.server.create( - 'scope', - { - type: 'org', - scope: { id: 'global', type: 'global' }, - }, - 'withChildren' - ); - instances.org = this.server.create( + instances.orgScope = this.server.create( 'scope', { type: 'org', @@ -48,10 +40,10 @@ module('Acceptance | users | list', function (hooks) { 'withChildren' ); instances.user = this.server.create('user', { - scope: instances.org, + scope: instances.orgScope, }); - orgURL = `/scopes/${urls.orgScope.id}`; - urls.users = `/scopes/${urls.orgScope.id}/users`; + orgURL = `/scopes/${instances.orgScope.id}`; + urls.users = `/scopes/${instances.orgScope.id}/users`; authenticateSession({}); }); @@ -59,24 +51,24 @@ module('Acceptance | users | list', function (hooks) { assert.expect(2); await visit(orgURL); assert.ok( - urls.orgScope.authorized_collection_actions.users.includes('list') + instances.orgScope.authorized_collection_actions.users.includes('list') ); assert.ok(find(`[href="${urls.users}"]`)); }); test('User cannot navigate to index without either list or create actions', async function (assert) { assert.expect(2); - urls.orgScope.authorized_collection_actions.users = []; + instances.orgScope.authorized_collection_actions.users = []; await visit(orgURL); assert.notOk( - urls.orgScope.authorized_collection_actions.users.includes('list') + instances.orgScope.authorized_collection_actions.users.includes('list') ); - assert.notOk(find(`[href="${urls.usersorgURL}"]`)); + assert.notOk(find(`[href="${urls.users}"]`)); }); test('User can navigate to index with only create action', async function (assert) { assert.expect(1); - urls.orgScope.authorized_collection_actions.users = ['create']; + instances.orgScope.authorized_collection_actions.users = ['create']; await visit(orgURL); assert.ok(find(`[href="${urls.users}"]`)); }); From e291956c1bcc7fbdb0ab0246a2e6b8eec4d7d0ca Mon Sep 17 00:00:00 2001 From: dharini Date: Tue, 31 Aug 2021 07:46:52 -0700 Subject: [PATCH 12/17] =?UTF-8?q?test:=20=F0=9F=92=8D=20fix=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../create-test.js} | 39 +++++++++++++++---- ui/admin/tests/acceptance/groups/list-test.js | 27 +++++-------- 2 files changed, 41 insertions(+), 25 deletions(-) rename ui/admin/tests/acceptance/{group-create-test.js => groups/create-test.js} (72%) diff --git a/ui/admin/tests/acceptance/group-create-test.js b/ui/admin/tests/acceptance/groups/create-test.js similarity index 72% rename from ui/admin/tests/acceptance/group-create-test.js rename to ui/admin/tests/acceptance/groups/create-test.js index 616ce66b4..815e4a760 100644 --- a/ui/admin/tests/acceptance/group-create-test.js +++ b/ui/admin/tests/acceptance/groups/create-test.js @@ -13,12 +13,15 @@ import { module('Acceptance | groups | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let orgURL; + const instances = { scopes: { global: null, org: null, }, group: null, + orgScope: null, }; const urls = { groups: null, @@ -28,17 +31,21 @@ module('Acceptance | groups | create', function (hooks) { hooks.beforeEach(function () { authenticateSession({}); - instances.scopes.global = this.server.create('scope', { id: 'global' }); - instances.scopes.org = this.server.create('scope', { - type: 'org', - scope: { id: 'global', type: 'global' }, - }); + instances.orgScope = this.server.create( + 'scope', + { + type: 'org', + scope: { id: 'global', type: 'global' }, + }, + 'withChildren' + ); instances.group = this.server.create('group', { - scope: instances.scopes.org, + scope: instances.orgScope, }); - urls.groups = `/scopes/${instances.scopes.org.id}/groups`; + urls.groups = `/scopes/${instances.orgScope.id}/groups`; urls.group = `${urls.groups}/${instances.group.id}`; urls.newGroup = `${urls.groups}/new`; + orgURL = `/scopes/${instances.orgScope.id}`; }); test('can create new group', async function (assert) { @@ -50,6 +57,24 @@ module('Acceptance | groups | create', function (hooks) { assert.equal(this.server.db.groups.length, groupsCount + 1); }); + test('can navigate to new groups route with proper authorization', async function (assert) { + assert.expect(2); + await visit(orgURL); + assert.ok( + instances.orgScope.authorized_collection_actions.groups.includes('create') + ); + assert.ok(find(`[href="${urls.groups}"]`)); + }); + + test('cannot navigate to new groups route without proper authorization', async function (assert) { + assert.expect(2); + instances.orgScope.authorized_collection_actions.groups = []; + await visit(orgURL); + assert.notOk( + instances.orgScope.authorized_collection_actions.groups.includes('create') + ); + assert.notOk(find(`[href="${urls.groups}"]`)); + }); test('can cancel new group creation', async function (assert) { assert.expect(2); const groupsCount = this.server.db.groups.length; diff --git a/ui/admin/tests/acceptance/groups/list-test.js b/ui/admin/tests/acceptance/groups/list-test.js index fd93645a7..f9229c19d 100644 --- a/ui/admin/tests/acceptance/groups/list-test.js +++ b/ui/admin/tests/acceptance/groups/list-test.js @@ -19,6 +19,7 @@ module('Acceptance | groups | list', function (hooks) { global: null, org: null, }, + orgScope: null, }; const urls = { @@ -26,20 +27,11 @@ module('Acceptance | groups | list', function (hooks) { org: null, }, groups: null, - orgScope: null, }; hooks.beforeEach(function () { instances.scopes.global = this.server.create('scope', { id: 'global' }); - urls.orgScope = this.server.create( - 'scope', - { - type: 'org', - scope: { id: 'global', type: 'global' }, - }, - 'withChildren' - ); - instances.org = this.server.create( + instances.orgScope = this.server.create( 'scope', { type: 'org', @@ -48,12 +40,11 @@ module('Acceptance | groups | list', function (hooks) { 'withChildren' ); instances.group = this.server.create('group', { - scope: instances.org, + scope: instances.orgScope, }); - orgURL = `/scopes/${urls.orgScope.id}`; - //urls.orgScope = `/scopes/${instances.org.id}/scopes`; + orgURL = `/scopes/${instances.orgScope.id}`; - urls.groups = `/scopes/${urls.orgScope.id}/groups`; + urls.groups = `/scopes/${instances.orgScope.id}/groups`; authenticateSession({}); }); @@ -61,24 +52,24 @@ module('Acceptance | groups | list', function (hooks) { assert.expect(2); await visit(orgURL); assert.ok( - urls.orgScope.authorized_collection_actions.groups.includes('list') + instances.orgScope.authorized_collection_actions.groups.includes('list') ); assert.ok(find(`[href="${urls.groups}"]`)); }); test('User cannot navigate to index without either list or create actions', async function (assert) { assert.expect(2); - urls.orgScope.authorized_collection_actions.groups = []; + instances.orgScope.authorized_collection_actions.groups = []; await visit(orgURL); assert.notOk( - urls.orgScope.authorized_collection_actions.groups.includes('list') + instances.orgScope.authorized_collection_actions.groups.includes('list') ); assert.notOk(find(`[href="${urls.groups}"]`)); }); test('User can navigate to index with only create action', async function (assert) { assert.expect(1); - urls.orgScope.authorized_collection_actions.groups = ['create']; + instances.orgScope.authorized_collection_actions.groups = ['create']; await visit(orgURL); assert.ok(find(`[href="${urls.groups}"]`)); }); From 77b1ca477d6893513e3ad4ec51fe5a5763024356 Mon Sep 17 00:00:00 2001 From: dharini Date: Tue, 31 Aug 2021 08:17:25 -0700 Subject: [PATCH 13/17] =?UTF-8?q?fix:=20=F0=9F=90=9B=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/acceptance/roles/create-test.js | 37 ++++++++++--------- ui/admin/tests/acceptance/roles/list-test.js | 27 +++++--------- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/ui/admin/tests/acceptance/roles/create-test.js b/ui/admin/tests/acceptance/roles/create-test.js index a0364c8b0..c2a86e46c 100644 --- a/ui/admin/tests/acceptance/roles/create-test.js +++ b/ui/admin/tests/acceptance/roles/create-test.js @@ -16,7 +16,6 @@ module('Acceptance | roles | create', function (hooks) { setupMirage(hooks); let orgURL; - let orgScope; const instances = { scopes: { @@ -25,16 +24,17 @@ module('Acceptance | roles | create', function (hooks) { project: null, }, role: null, + orgScope: null, }; const urls = { - orgScope: null, roles: null, role: null, newRoleURL: null, }; hooks.beforeEach(function () { - orgScope = this.server.create( + authenticateSession({}); + instances.orgScope = this.server.create( 'scope', { type: 'org', @@ -43,30 +43,29 @@ module('Acceptance | roles | create', function (hooks) { 'withChildren' ); - orgURL = `/scopes/${orgScope.id}`; - authenticateSession({}); - instances.scopes.global = this.server.create('scope', { id: 'global' }); - instances.scopes.org = this.server.create('scope', { - type: 'org', - scope: { id: 'global', type: 'global' }, - }); + // instances.scopes.global = this.server.create('scope', { id: 'global' }); + // instances.scopes.org = this.server.create('scope', { + // type: 'org', + // scope: { id: 'global', type: 'global' }, + // }); // The project scope is not yet used for role tests (though it will be // in the future). This is created simply to test the grant scope loading // mechanism. instances.scopes.project = this.server.create('scope', { type: 'project', - scope: { id: instances.scopes.org.id, type: instances.scopes.org.type }, + scope: { id: instances.orgScope.id, type: instances.orgScope.type }, }); instances.role = this.server.create( 'role', { - scope: instances.scopes.org, + scope: instances.orgScope, }, 'withPrincipals' ); - urls.roles = `/scopes/${instances.scopes.org.id}/roles`; + urls.roles = `/scopes/${instances.orgScope.id}/roles`; urls.role = `${urls.roles}/${instances.role.id}`; urls.newRoleURL = `${urls.roles}/new`; + orgURL = `/scopes/${instances.orgScope.id}`; }); test('can create new role', async function (assert) { @@ -81,18 +80,20 @@ module('Acceptance | roles | create', function (hooks) { test('can navigate to new roles route with proper authorization', async function (assert) { assert.expect(2); await visit(orgURL); - assert.ok(orgScope.authorized_collection_actions.roles.includes('create')); - assert.ok(find(`[href="${orgURL}/roles"]`)); + assert.ok( + instances.orgScope.authorized_collection_actions.roles.includes('create') + ); + assert.ok(find(`[href="${urls.roles}"]`)); }); test('cannot navigate to new roles route without proper authorization', async function (assert) { assert.expect(2); - orgScope.authorized_collection_actions.roles = []; + instances.orgScope.authorized_collection_actions.roles = []; await visit(orgURL); assert.notOk( - orgScope.authorized_collection_actions.roles.includes('create') + instances.orgScope.authorized_collection_actions.roles.includes('create') ); - assert.notOk(find(`[href="${orgURL}/roles"]`)); + assert.notOk(find(`[href="${urls.roles}"]`)); }); test('can cancel new role creation', async function (assert) { diff --git a/ui/admin/tests/acceptance/roles/list-test.js b/ui/admin/tests/acceptance/roles/list-test.js index 78e7d22fa..e6e13cfb7 100644 --- a/ui/admin/tests/acceptance/roles/list-test.js +++ b/ui/admin/tests/acceptance/roles/list-test.js @@ -19,6 +19,7 @@ module('Acceptance | roles | list', function (hooks) { global: null, org: null, }, + orgScope: null, }; const urls = { @@ -26,20 +27,10 @@ module('Acceptance | roles | list', function (hooks) { org: null, }, roles: null, - orgScope: null, }; hooks.beforeEach(function () { - instances.scopes.global = this.server.create('scope', { id: 'global' }); - urls.orgScope = this.server.create( - 'scope', - { - type: 'org', - scope: { id: 'global', type: 'global' }, - }, - 'withChildren' - ); - instances.org = this.server.create( + instances.orgScope = this.server.create( 'scope', { type: 'org', @@ -48,11 +39,11 @@ module('Acceptance | roles | list', function (hooks) { 'withChildren' ); instances.role = this.server.create('role', { - scope: instances.org, + scope: instances.orgScope, }); - orgURL = `/scopes/${urls.orgScope.id}`; + orgURL = `/scopes/${instances.orgScope.id}`; - urls.roles = `/scopes/${urls.orgScope.id}/roles`; + urls.roles = `/scopes/${instances.orgScope.id}/roles`; authenticateSession({}); }); @@ -60,24 +51,24 @@ module('Acceptance | roles | list', function (hooks) { assert.expect(2); await visit(orgURL); assert.ok( - urls.orgScope.authorized_collection_actions.roles.includes('list') + instances.orgScope.authorized_collection_actions.roles.includes('list') ); assert.ok(find(`[href="${urls.roles}"]`)); }); test('User cannot navigate to index without either list or create actions', async function (assert) { assert.expect(2); - urls.orgScope.authorized_collection_actions.roles = []; + instances.orgScope.authorized_collection_actions.roles = []; await visit(orgURL); assert.notOk( - urls.orgScope.authorized_collection_actions.roles.includes('list') + instances.orgScope.authorized_collection_actions.roles.includes('list') ); assert.notOk(find(`[href="${urls.roles}"]`)); }); test('User can navigate to index with only create action', async function (assert) { assert.expect(1); - urls.orgScope.authorized_collection_actions.roles = ['create']; + instances.orgScope.authorized_collection_actions.roles = ['create']; await visit(orgURL); assert.ok(find(`[href="${urls.roles}"]`)); }); From 4f74f8578ec62c996d5b0a9564d762afb8a45c43 Mon Sep 17 00:00:00 2001 From: dharini Date: Tue, 31 Aug 2021 08:55:36 -0700 Subject: [PATCH 14/17] =?UTF-8?q?fix:=20=F0=9F=90=9B=20resource=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/routes/scopes/scope/roles/index.js | 2 +- ui/admin/app/templates/scopes/scope/roles/index.hbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/admin/app/routes/scopes/scope/roles/index.js b/ui/admin/app/routes/scopes/scope/roles/index.js index 6020b0c6f..56c143beb 100644 --- a/ui/admin/app/routes/scopes/scope/roles/index.js +++ b/ui/admin/app/routes/scopes/scope/roles/index.js @@ -1,5 +1,5 @@ import Route from '@ember/routing/route'; -export default class ScopesScopeUsersIndexRoute extends Route { +export default class ScopesScopeRolesIndexRoute extends Route { // =methods setupController(controller) { diff --git a/ui/admin/app/templates/scopes/scope/roles/index.hbs b/ui/admin/app/templates/scopes/scope/roles/index.hbs index ac7664ece..9962addc5 100644 --- a/ui/admin/app/templates/scopes/scope/roles/index.hbs +++ b/ui/admin/app/templates/scopes/scope/roles/index.hbs @@ -15,7 +15,7 @@ - {{#if (can 'create collection' this.scope collection='users')}} + {{#if (can 'create collection' this.scope collection='roles')}} {{#if @model}} {{t 'titles.new' From a6b7837af163ab54dbd8d1cf5fdbcbd3d32c6ccb Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 31 Aug 2021 17:22:20 -0700 Subject: [PATCH 15/17] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Update=20tar=20ve?= =?UTF-8?q?rsion=20resolutions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update tar version resolutions to avoid security vulnerability --- package.json | 2 +- ui/desktop/electron-app/package.json | 3 +- ui/desktop/electron-app/yarn.lock | 57 +++------------------------- yarn.lock | 8 ++-- 4 files changed, 13 insertions(+), 57 deletions(-) diff --git a/package.json b/package.json index 66eff112b..d5070c4b8 100755 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "minimist": "^1.2.3", "normalize-url": "^4.5.1", "glob-parent": "^5.1.2", - "tar": "^6.1.2", + "tar": "^6.1.9", "path-parse": "^1.0.7" }, "config": { diff --git a/ui/desktop/electron-app/package.json b/ui/desktop/electron-app/package.json index c0e9b5672..a91471f79 100644 --- a/ui/desktop/electron-app/package.json +++ b/ui/desktop/electron-app/package.json @@ -46,6 +46,7 @@ "trim-newlines": "^3.0.1", "normalize-url": "^4.5.1", "jszip": "^3.7.0", - "path-parse": "^1.0.7" + "path-parse": "^1.0.7", + "tar": "^6.1.9" } } diff --git a/ui/desktop/electron-app/yarn.lock b/ui/desktop/electron-app/yarn.lock index ed7fb79aa..c4bd48ac9 100644 --- a/ui/desktop/electron-app/yarn.lock +++ b/ui/desktop/electron-app/yarn.lock @@ -694,11 +694,6 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -1503,13 +1498,6 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -2334,14 +2322,6 @@ minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1. resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - minipass@^3.0.0: version "3.1.3" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" @@ -2349,13 +2329,6 @@ minipass@^3.0.0: dependencies: yallist "^4.0.0" -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -2364,7 +2337,7 @@ minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4: +mkdirp@^0.5.1, mkdirp@^0.5.4: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -3494,23 +3467,10 @@ tar-stream@^1.5.2: to-buffer "^1.1.1" xtend "^4.0.0" -tar@^4: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - -tar@^6.0.2, tar@^6.0.5: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" - integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== +tar@^4, tar@^6.0.2, tar@^6.0.5, tar@^6.1.9: + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -3779,7 +3739,7 @@ xmlbuilder@^9.0.7: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= -xmldom@^0.5.0, xmldom@~0.5.0: +xmldom@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.5.0.tgz#193cb96b84aa3486127ea6272c4596354cb4962e" integrity sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA== @@ -3806,11 +3766,6 @@ yaku@^0.16.6: resolved "https://registry.yarnpkg.com/yaku/-/yaku-0.16.7.tgz#1d195c78aa9b5bf8479c895b9504fd4f0847984e" integrity sha1-HRlceKqbW/hHnIlblQT9TwhHmE4= -yallist@^3.0.0, yallist@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" diff --git a/yarn.lock b/yarn.lock index e622d6271..eea247596 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20015,10 +20015,10 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar@^4, tar@^4.4.10, tar@^4.4.12, tar@^4.4.15, tar@^5.0.5, tar@^6.0.2, tar@^6.0.5, tar@^6.1.0, tar@^6.1.2: - version "6.1.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.8.tgz#4fc50cfe56511c538ce15b71e05eebe66530cbd4" - integrity sha512-sb9b0cp855NbkMJcskdSYA7b11Q8JsX4qe4pyUAfHp+Y6jBjJeek2ZVlwEfWayshEIwlIzXx0Fain3QG9JPm2A== +tar@^4, tar@^4.4.10, tar@^4.4.12, tar@^4.4.15, tar@^5.0.5, tar@^6.0.2, tar@^6.0.5, tar@^6.1.0, tar@^6.1.9: + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" From 0ab5ff837074bcfff61e5f1134815e73bfee4117 Mon Sep 17 00:00:00 2001 From: dharini Date: Wed, 1 Sep 2021 14:17:00 -0700 Subject: [PATCH 16/17] =?UTF-8?q?fix:=20=F0=9F=90=9B=20add=20org=20to=20ur?= =?UTF-8?q?ls,=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/acceptance/roles/create-test.js | 24 +++++++------------ ui/admin/tests/acceptance/roles/list-test.js | 10 ++++---- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/ui/admin/tests/acceptance/roles/create-test.js b/ui/admin/tests/acceptance/roles/create-test.js index c2a86e46c..f9d5e7778 100644 --- a/ui/admin/tests/acceptance/roles/create-test.js +++ b/ui/admin/tests/acceptance/roles/create-test.js @@ -15,8 +15,6 @@ module('Acceptance | roles | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - let orgURL; - const instances = { scopes: { global: null, @@ -29,7 +27,8 @@ module('Acceptance | roles | create', function (hooks) { const urls = { roles: null, role: null, - newRoleURL: null, + newRole: null, + orgScope: null, }; hooks.beforeEach(function () { @@ -43,11 +42,6 @@ module('Acceptance | roles | create', function (hooks) { 'withChildren' ); - // instances.scopes.global = this.server.create('scope', { id: 'global' }); - // instances.scopes.org = this.server.create('scope', { - // type: 'org', - // scope: { id: 'global', type: 'global' }, - // }); // The project scope is not yet used for role tests (though it will be // in the future). This is created simply to test the grant scope loading // mechanism. @@ -64,14 +58,14 @@ module('Acceptance | roles | create', function (hooks) { ); urls.roles = `/scopes/${instances.orgScope.id}/roles`; urls.role = `${urls.roles}/${instances.role.id}`; - urls.newRoleURL = `${urls.roles}/new`; - orgURL = `/scopes/${instances.orgScope.id}`; + urls.newRole = `${urls.roles}/new`; + urls.orgScope = `/scopes/${instances.orgScope.id}`; }); test('can create new role', async function (assert) { assert.expect(1); const rolesCount = this.server.db.roles.length; - await visit(urls.newRoleURL); + await visit(urls.newRole); await fillIn('[name="name"]', 'role name'); await click('[type="submit"]'); assert.equal(this.server.db.roles.length, rolesCount + 1); @@ -79,7 +73,7 @@ module('Acceptance | roles | create', function (hooks) { test('can navigate to new roles route with proper authorization', async function (assert) { assert.expect(2); - await visit(orgURL); + await visit(urls.orgScope); assert.ok( instances.orgScope.authorized_collection_actions.roles.includes('create') ); @@ -89,7 +83,7 @@ module('Acceptance | roles | create', function (hooks) { test('cannot navigate to new roles route without proper authorization', async function (assert) { assert.expect(2); instances.orgScope.authorized_collection_actions.roles = []; - await visit(orgURL); + await visit(urls.orgScope); assert.notOk( instances.orgScope.authorized_collection_actions.roles.includes('create') ); @@ -99,7 +93,7 @@ module('Acceptance | roles | create', function (hooks) { test('can cancel new role creation', async function (assert) { assert.expect(2); const rolesCount = this.server.db.roles.length; - await visit(urls.newRoleURL); + await visit(urls.newRole); await fillIn('[name="name"]', 'role name'); await click('.rose-form-actions [type="button"]'); assert.equal(currentURL(), urls.roles); @@ -127,7 +121,7 @@ module('Acceptance | roles | create', function (hooks) { } ); }); - await visit(urls.newRoleURL); + await visit(urls.newRole); await fillIn('[name="name"]', 'new target'); await click('form [type="submit"]'); await a11yAudit(); diff --git a/ui/admin/tests/acceptance/roles/list-test.js b/ui/admin/tests/acceptance/roles/list-test.js index e6e13cfb7..c1b1ed8a5 100644 --- a/ui/admin/tests/acceptance/roles/list-test.js +++ b/ui/admin/tests/acceptance/roles/list-test.js @@ -12,7 +12,6 @@ import { module('Acceptance | roles | list', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - let orgURL; const instances = { scopes: { @@ -27,6 +26,7 @@ module('Acceptance | roles | list', function (hooks) { org: null, }, roles: null, + orgScope: null, }; hooks.beforeEach(function () { @@ -41,7 +41,7 @@ module('Acceptance | roles | list', function (hooks) { instances.role = this.server.create('role', { scope: instances.orgScope, }); - orgURL = `/scopes/${instances.orgScope.id}`; + urls.orgScope = `/scopes/${instances.orgScope.id}`; urls.roles = `/scopes/${instances.orgScope.id}/roles`; authenticateSession({}); @@ -49,7 +49,7 @@ module('Acceptance | roles | list', function (hooks) { test('can navigate to roles with proper authorization', async function (assert) { assert.expect(2); - await visit(orgURL); + await visit(urls.orgScope); assert.ok( instances.orgScope.authorized_collection_actions.roles.includes('list') ); @@ -59,7 +59,7 @@ module('Acceptance | roles | list', function (hooks) { test('User cannot navigate to index without either list or create actions', async function (assert) { assert.expect(2); instances.orgScope.authorized_collection_actions.roles = []; - await visit(orgURL); + await visit(urls.orgScope); assert.notOk( instances.orgScope.authorized_collection_actions.roles.includes('list') ); @@ -69,7 +69,7 @@ module('Acceptance | roles | list', function (hooks) { test('User can navigate to index with only create action', async function (assert) { assert.expect(1); instances.orgScope.authorized_collection_actions.roles = ['create']; - await visit(orgURL); + await visit(urls.orgScope); assert.ok(find(`[href="${urls.roles}"]`)); }); }); From 13794c7bf8c3fda081aff18445b6370ac5f7204e Mon Sep 17 00:00:00 2001 From: dharini Date: Wed, 1 Sep 2021 14:26:25 -0700 Subject: [PATCH 17/17] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/tests/acceptance/roles/create-test.js | 4 ++-- ui/admin/tests/acceptance/roles/list-test.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/admin/tests/acceptance/roles/create-test.js b/ui/admin/tests/acceptance/roles/create-test.js index f9d5e7778..a0564f67d 100644 --- a/ui/admin/tests/acceptance/roles/create-test.js +++ b/ui/admin/tests/acceptance/roles/create-test.js @@ -71,7 +71,7 @@ module('Acceptance | roles | create', function (hooks) { assert.equal(this.server.db.roles.length, rolesCount + 1); }); - test('can navigate to new roles route with proper authorization', async function (assert) { + test('Users can navigate to new roles route with proper authorization', async function (assert) { assert.expect(2); await visit(urls.orgScope); assert.ok( @@ -80,7 +80,7 @@ module('Acceptance | roles | create', function (hooks) { assert.ok(find(`[href="${urls.roles}"]`)); }); - test('cannot navigate to new roles route without proper authorization', async function (assert) { + test('Users cannot navigate to new roles route without proper authorization', async function (assert) { assert.expect(2); instances.orgScope.authorized_collection_actions.roles = []; await visit(urls.orgScope); diff --git a/ui/admin/tests/acceptance/roles/list-test.js b/ui/admin/tests/acceptance/roles/list-test.js index c1b1ed8a5..ff170aeb7 100644 --- a/ui/admin/tests/acceptance/roles/list-test.js +++ b/ui/admin/tests/acceptance/roles/list-test.js @@ -47,7 +47,7 @@ module('Acceptance | roles | list', function (hooks) { authenticateSession({}); }); - test('can navigate to roles with proper authorization', async function (assert) { + test('Users can navigate to roles with proper authorization', async function (assert) { assert.expect(2); await visit(urls.orgScope); assert.ok( @@ -56,7 +56,7 @@ module('Acceptance | roles | list', function (hooks) { assert.ok(find(`[href="${urls.roles}"]`)); }); - test('User cannot navigate to index without either list or create actions', async function (assert) { + test('Users cannot navigate to index without either list or create actions', async function (assert) { assert.expect(2); instances.orgScope.authorized_collection_actions.roles = []; await visit(urls.orgScope); @@ -66,7 +66,7 @@ module('Acceptance | roles | list', function (hooks) { assert.notOk(find(`[href="${urls.roles}"]`)); }); - test('User can navigate to index with only create action', async function (assert) { + test('Users can navigate to index with only create action', async function (assert) { assert.expect(1); instances.orgScope.authorized_collection_actions.roles = ['create']; await visit(urls.orgScope);