Merge branch 'main' into feature-auth-methods-filters
This commit is contained in:
43 files changed
+763
-15
No files matched your search
@@ -5,6 +5,14 @@ import { A } from '@ember/array';
|
||||
|
||||
export default class ManagedGroupModel extends GeneratedManagedGroupModel {
|
||||
// =attributes
|
||||
|
||||
// =error attributes
|
||||
// These attributes exist solely to capture errors on nested fields.
|
||||
// See the application adapter's error normalization method for
|
||||
// more information.
|
||||
|
||||
@attr('string', { readOnly: true }) attributes_filter;
|
||||
|
||||
/**
|
||||
* Members is read-only under normal circumstances. But members can
|
||||
* be persisted via calls to `addMembers()` or `removeMembers()`.
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
export default class ManagedGroupSerializer extends ApplicationSerializer {}
|
||||
export default class ManagedGroupSerializer extends ApplicationSerializer {
|
||||
// =properties
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
serializeScopeID = false;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/managed-group';
|
||||
@@ -522,6 +522,9 @@ export default function () {
|
||||
return managedGroups.where({ authMethodId });
|
||||
}
|
||||
);
|
||||
this.get('/managed-groups/:id');
|
||||
this.del('/managed-groups/:id');
|
||||
this.post('/managed-groups');
|
||||
|
||||
/* Uncomment the following line and the Response import above
|
||||
* Then change the response code to simulate error responses.
|
||||
|
||||
@@ -15,6 +15,7 @@ export default factory.extend({
|
||||
authorized_collection_actions: () => {
|
||||
return {
|
||||
accounts: ['create', 'list'],
|
||||
'managed-groups': ['create', 'list'],
|
||||
};
|
||||
},
|
||||
id: (i) => `auth-method-id-${i}`,
|
||||
@@ -34,7 +35,9 @@ export default factory.extend({
|
||||
user.update({ accountIds: [id] });
|
||||
});
|
||||
|
||||
server.createList('managed-group', 2, { scope, authMethod });
|
||||
if (type === 'oidc') {
|
||||
server.createList('managed-group', 2, { scope, authMethod });
|
||||
}
|
||||
},
|
||||
}),
|
||||
});
|
||||
@@ -1,8 +1,12 @@
|
||||
import factory from '../generated/factories/managed-group';
|
||||
import { random } from 'faker';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
const types = ['oidc'];
|
||||
|
||||
export default factory.extend({
|
||||
id: (i) => `managed-groups-id-${i}`,
|
||||
type: (i) => types[i % types.length],
|
||||
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('managed-group') || [
|
||||
@@ -11,4 +15,13 @@ export default factory.extend({
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
|
||||
attributes() {
|
||||
switch (this.type) {
|
||||
case 'oidc':
|
||||
return {
|
||||
filter: random.words(),
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -11,15 +11,4 @@ export default Factory.extend({
|
||||
created_time: () => date.recent(),
|
||||
updated_time: () => date.recent(),
|
||||
version: () => datatype.number(),
|
||||
type: 'oidc',
|
||||
attributes: function () {
|
||||
switch (this.type) {
|
||||
case 'oidc':
|
||||
return {
|
||||
filter: random.words(),
|
||||
};
|
||||
default:
|
||||
return;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -22,7 +22,7 @@ export default function (server) {
|
||||
// Auth
|
||||
const globalAuthMethods = server.createList(
|
||||
'auth-method',
|
||||
1,
|
||||
4,
|
||||
{ scope: globalScope },
|
||||
'withAccountsAndUsersAndManagedGroups'
|
||||
);
|
||||
|
||||
File renamed without changes.
@@ -115,3 +115,6 @@ value:
|
||||
callback_url:
|
||||
label: Callback URL
|
||||
help: The URL to which the third-party provider sends the authentication response. Paste this into the provider configuration.
|
||||
filter:
|
||||
label: Filter
|
||||
help: A boolean expression defining a filter run against the provided information.
|
||||
@@ -351,3 +351,14 @@ scope:
|
||||
title_plural: Scopes
|
||||
messages:
|
||||
cannot_read: While you do not have permission to read this scope, you may have permission to view resources within it.
|
||||
managed-group:
|
||||
title: Managed Group
|
||||
title_plural: Managed Groups
|
||||
description: A managed group represents a collection of accounts.
|
||||
actions:
|
||||
delete: Delete Managed Group
|
||||
create: Create Managed Group
|
||||
messages:
|
||||
welcome:
|
||||
title: Welcome to Managed Groups
|
||||
description: Create and manage managed groups for an auth method.
|
||||
@@ -0,0 +1,80 @@
|
||||
<Rose::Form
|
||||
@onSubmit={{@submit}}
|
||||
@cancel={{@cancel}}
|
||||
@disabled={{@model.isSaving}}
|
||||
@error={{@model.errors.base}}
|
||||
@showEditToggle={{if @model.isNew false true}}
|
||||
as |form|
|
||||
>
|
||||
<form.input
|
||||
@value={{@model.type}}
|
||||
@label={{t 'form.type.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.error.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
<form.textarea
|
||||
@name='description'
|
||||
@type='description'
|
||||
@value={{@model.description}}
|
||||
@label={{t 'form.description.label'}}
|
||||
@error={{@model.errors.description}}
|
||||
@helperText={{t 'form.description.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.description}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.description as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.input
|
||||
@name='filter'
|
||||
@type='text'
|
||||
@value={{@model.attributes.filter}}
|
||||
@label={{t 'form.filter.label'}}
|
||||
@error={{@model.errors.attributes_filter}}
|
||||
@helperText={{t 'form.filter.help'}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.filter}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.filter as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -0,0 +1,18 @@
|
||||
import Controller from '@ember/controller';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsController extends Controller {
|
||||
// =services
|
||||
|
||||
@service intl;
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Translated managed groups breadcrumb
|
||||
* @type {string}
|
||||
*/
|
||||
get breadCrumb() {
|
||||
return this.intl.t('resources.managed-group.title_plural');
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import Controller from '@ember/controller';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsManagedGroupController extends Controller {
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* A managed group breadcrumb
|
||||
* @type {string}
|
||||
*/
|
||||
get breadCrumb() {
|
||||
return this.model.displayName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import Controller from '@ember/controller';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsNewController extends Controller {
|
||||
// =services
|
||||
|
||||
@service intl;
|
||||
|
||||
// =attributes
|
||||
/**
|
||||
* Translated new managed group breadcrumb
|
||||
* @type {string}
|
||||
*/
|
||||
get breadCrumb() {
|
||||
return this.intl.t('titles.new');
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,14 @@ Router.map(function () {
|
||||
});
|
||||
this.route('new');
|
||||
});
|
||||
this.route('managed-groups', function () {
|
||||
this.route(
|
||||
'managed-group',
|
||||
{ path: ':managed_group_id' },
|
||||
function () {}
|
||||
);
|
||||
this.route('new');
|
||||
});
|
||||
});
|
||||
this.route('new');
|
||||
});
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { action } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import loading from 'ember-loading/decorator';
|
||||
import { confirm } from 'core/decorators/confirm';
|
||||
import { notifySuccess, notifyError } from 'core/decorators/notify';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsRoute extends Route {
|
||||
// =services
|
||||
|
||||
@service intl;
|
||||
@service notify;
|
||||
@service can;
|
||||
|
||||
//=methods
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {Promise{[ManagedGroupsModel]}}
|
||||
*/
|
||||
model() {
|
||||
const authMethod = this.modelFor('scopes.scope.auth-methods.auth-method');
|
||||
const { id: auth_method_id } = authMethod;
|
||||
const canListManagedGroups = this.can.can('list collection', authMethod, {
|
||||
collection: 'managed-groups',
|
||||
});
|
||||
|
||||
if (canListManagedGroups) {
|
||||
return this.store.query('managed-group', { auth_method_id });
|
||||
}
|
||||
}
|
||||
|
||||
// =actions
|
||||
/**
|
||||
* Rollback changes on a managed group.
|
||||
* @param {ManagedGroupModel} managedGroup
|
||||
*/
|
||||
@action
|
||||
cancel(managedGroup) {
|
||||
const { isNew } = managedGroup;
|
||||
managedGroup.rollbackAttributes();
|
||||
if (isNew) {
|
||||
this.transitionTo('scopes.scope.auth-methods.auth-method.managed-groups');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a managed group in current scope.
|
||||
* @param {ManagedGroupModel} managedGroup
|
||||
*/
|
||||
@action
|
||||
@loading
|
||||
@notifyError(({ message }) => message)
|
||||
@notifySuccess(({ isNew }) =>
|
||||
isNew ? 'notifications.create-success' : 'notifications.save-success'
|
||||
)
|
||||
async save(managedGroup) {
|
||||
await managedGroup.save();
|
||||
if (this.can.can('read model', managedGroup)) {
|
||||
await this.transitionTo(
|
||||
'scopes.scope.auth-methods.auth-method.managed-groups.managed-group',
|
||||
managedGroup
|
||||
);
|
||||
} else {
|
||||
await this.transitionTo(
|
||||
'scopes.scope.auth-methods.auth-method.managed-groups'
|
||||
);
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a managed group in current scope and redirect to index
|
||||
* @param {ManagedGroupModel} managed group
|
||||
*/
|
||||
@action
|
||||
@loading
|
||||
@confirm('questions.delete-confirm')
|
||||
@notifyError(({ message }) => message, { catch: true })
|
||||
@notifySuccess('notifications.delete-success')
|
||||
async delete(managedGroup) {
|
||||
await managedGroup.destroyRecord();
|
||||
await this.replaceWith(
|
||||
'scopes.scope.auth-methods.auth-method.managed-groups'
|
||||
);
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsIndexRoute extends Route {
|
||||
setupController(controller) {
|
||||
const authMethod = this.modelFor('scopes.scope.auth-methods.auth-method');
|
||||
super.setupController(...arguments);
|
||||
controller.setProperties({ authMethod });
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsManagedGroupRoute extends Route {
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Load managed group by ID.
|
||||
* @param {object} params
|
||||
* @param {string} params.managed_group_id
|
||||
* @returns {ManagedGroupModel}
|
||||
*/
|
||||
model({ managed_group_id }) {
|
||||
return this.store.findRecord('managed-group', managed_group_id, {
|
||||
reload: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the route-set specific page sections
|
||||
* @override
|
||||
*/
|
||||
renderTemplate() {
|
||||
super.renderTemplate(...arguments);
|
||||
|
||||
this.render(
|
||||
'scopes/scope/auth-methods/auth-method/managed-groups/managed-group/-header',
|
||||
{
|
||||
into: 'scopes/scope/auth-methods/auth-method',
|
||||
outlet: 'header',
|
||||
}
|
||||
);
|
||||
|
||||
this.render(
|
||||
'scopes/scope/auth-methods/auth-method/managed-groups/managed-group/-actions',
|
||||
{
|
||||
into: 'scopes/scope/auth-methods/auth-method',
|
||||
outlet: 'actions',
|
||||
}
|
||||
);
|
||||
|
||||
this.render(
|
||||
'scopes/scope/auth-methods/auth-method/managed-groups/managed-group/-navigation',
|
||||
{
|
||||
into: 'scopes/scope/auth-methods/auth-method',
|
||||
outlet: 'navigation',
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsManagedGroupIndexRoute extends Route {}
|
||||
@@ -0,0 +1,36 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsNewRoute extends Route {
|
||||
// =methods
|
||||
model() {
|
||||
const { id: auth_method_id, type } = this.modelFor(
|
||||
'scopes.scope.auth-methods.auth-method'
|
||||
);
|
||||
return this.store.createRecord('managed-group', {
|
||||
type,
|
||||
auth_method_id,
|
||||
});
|
||||
}
|
||||
|
||||
renderTemplate() {
|
||||
super.renderTemplate(...arguments);
|
||||
|
||||
this.render(
|
||||
'scopes/scope/auth-methods/auth-method/managed-groups/new/-header',
|
||||
{
|
||||
into: 'scopes/scope/auth-methods/auth-method',
|
||||
outlet: 'header',
|
||||
}
|
||||
);
|
||||
|
||||
this.render('_empty', {
|
||||
into: 'scopes/scope/auth-methods/auth-method',
|
||||
outlet: 'actions',
|
||||
});
|
||||
|
||||
this.render('_empty', {
|
||||
into: 'scopes/scope/auth-methods/auth-method',
|
||||
outlet: 'navigation',
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,19 @@
|
||||
</dropdown.link>
|
||||
{{/if}}
|
||||
|
||||
{{#if (feature-flag 'managed-groups')}}
|
||||
{{#if (can 'create collection' @model collection='managed-groups')}}
|
||||
{{#if @model.isOIDC}}
|
||||
<dropdown.link
|
||||
@route='scopes.scope.auth-methods.auth-method.managed-groups.new'
|
||||
@model={{@model}}
|
||||
>
|
||||
{{t 'resources.managed-group.actions.create'}}
|
||||
</dropdown.link>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (can 'delete model' @model)}}
|
||||
<dropdown.separator />
|
||||
<dropdown.button
|
||||
|
||||
@@ -8,4 +8,14 @@
|
||||
{{t 'resources.account.title_plural'}}
|
||||
</nav.link>
|
||||
{{/if}}
|
||||
|
||||
{{#if (feature-flag 'managed-groups')}}
|
||||
{{#if (can 'navigate collection' @model collection='managed-groups')}}
|
||||
{{#if @model.isOIDC}}
|
||||
<nav.link @route='scopes.scope.auth-methods.auth-method.managed-groups'>
|
||||
{{t 'resources.managed-group.title_plural'}}
|
||||
</nav.link>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</Rose::Nav::Tabs>
|
||||
@@ -1,5 +1,4 @@
|
||||
{{#if @model}}
|
||||
|
||||
{{! OIDC accounts display more fields }}
|
||||
{{#if @model.firstObject.isOIDC}}
|
||||
<Rose::Table as |table|>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{{page-title (t 'resources.managed-group.title_plural')}}
|
||||
|
||||
{{outlet}}
|
||||
@@ -0,0 +1,86 @@
|
||||
{{#if @model}}
|
||||
<Rose::Table as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell>{{t 'form.name.label'}}</row.headerCell>
|
||||
<row.headerCell>{{t 'form.description.label'}}</row.headerCell>
|
||||
<row.headerCell>{{t 'form.type.label'}}</row.headerCell>
|
||||
<row.headerCell>{{t 'form.id.label'}}</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
|
||||
<table.body as |body|>
|
||||
{{#each @model as |managed-group|}}
|
||||
<body.row as |row|>
|
||||
<row.headerCell>
|
||||
{{#if (can 'read model' managed-group)}}
|
||||
<LinkTo
|
||||
@route='scopes.scope.auth-methods.auth-method.managed-groups.managed-group'
|
||||
@model={{managed-group.id}}
|
||||
>
|
||||
{{managed-group.displayName}}
|
||||
</LinkTo>
|
||||
{{else}}
|
||||
{{managed-group.displayName}}
|
||||
{{/if}}
|
||||
</row.headerCell>
|
||||
<row.cell>{{managed-group.description}}</row.cell>
|
||||
<row.cell>
|
||||
<Rose::Badge>{{managed-group.type}}</Rose::Badge>
|
||||
</row.cell>
|
||||
<row.cell>
|
||||
<Copyable
|
||||
@text={{managed-group.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{managed-group.id}}</code>
|
||||
</Copyable>
|
||||
</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
{{else}}
|
||||
<Rose::Layout::Centered>
|
||||
<Rose::Message
|
||||
@title={{t 'resources.managed-group.messages.welcome.title'}}
|
||||
as |message|
|
||||
>
|
||||
<message.description>
|
||||
|
||||
{{#if
|
||||
(can 'list collection' this.authMethod collection='managed-groups')
|
||||
}}
|
||||
{{! Can list (at least): show default welcome message }}
|
||||
{{t 'resources.managed-group.description'}}
|
||||
{{else if (can
|
||||
'create collection' this.authMethod collection='managed-groups'
|
||||
)}}
|
||||
{{! Can create only: show create but not list welcome message }}
|
||||
{{t
|
||||
'descriptions.create-but-not-list'
|
||||
resource=(t 'resources.managed-group.title_plural')
|
||||
}}
|
||||
{{else}}
|
||||
{{! Can neither list nor create }}
|
||||
{{t
|
||||
'descriptions.neither-list-nor-create'
|
||||
resource=(t 'resources.managed-group.title_plural')
|
||||
}}
|
||||
{{/if}}
|
||||
</message.description>
|
||||
|
||||
{{#if
|
||||
(can 'create collection' this.authMethod collection='managed-groups')
|
||||
}}
|
||||
<message.link
|
||||
@route='scopes.scope.auth-methods.auth-method.managed-groups.new'
|
||||
>
|
||||
<Rose::Icon @name='flight-icons/svg/plus-circle-16' />
|
||||
{{t 'resources.managed-group.actions.create'}}
|
||||
</message.link>
|
||||
{{/if}}
|
||||
</Rose::Message>
|
||||
</Rose::Layout::Centered>
|
||||
{{/if}}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
{{page-title 'ManagedGroup'}}
|
||||
{{outlet}}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{{#if (can 'delete model' @model)}}
|
||||
<Rose::Dropdown
|
||||
@text={{t 'actions.manage'}}
|
||||
@dropdownRight={{true}}
|
||||
as |dropdown|
|
||||
>
|
||||
<dropdown.button
|
||||
@style='danger'
|
||||
@disabled={{@model.canSave}}
|
||||
{{on 'click' (route-action 'delete' @model)}}
|
||||
>
|
||||
{{t 'resources.managed-group.actions.delete'}}
|
||||
</dropdown.button>
|
||||
</Rose::Dropdown>
|
||||
{{/if}}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<h2>
|
||||
{{t 'resources.managed-group.title'}}
|
||||
<DocLink @doc='managed-groups' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.managed-group.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<Rose::Nav::Tabs as |nav|>
|
||||
<nav.link
|
||||
@route='scopes.scope.auth-methods.auth-method.managed-groups.managed-group.index'
|
||||
>
|
||||
{{t 'titles.details'}}
|
||||
</nav.link>
|
||||
</Rose::Nav::Tabs>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<Form::ManagedGroup
|
||||
@model={{@model}}
|
||||
@submit={{route-action 'save' @model}}
|
||||
@cancel={{route-action 'cancel' @model}}
|
||||
/>
|
||||
@@ -0,0 +1,5 @@
|
||||
<Form::ManagedGroup
|
||||
@model={{@model}}
|
||||
@submit={{route-action 'save' @model}}
|
||||
@cancel={{route-action 'cancel' @model}}
|
||||
/>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<h2>
|
||||
{{t 'titles.new'}}
|
||||
{{! TODO: change the icon link }}
|
||||
<DocLink @doc='account.new' @iconSize='large' />
|
||||
</h2>
|
||||
@@ -48,6 +48,7 @@ module.exports = function (environment) {
|
||||
account: '/accounts',
|
||||
'account.new': '/accounts/new',
|
||||
'auth-method': '/auth-methods',
|
||||
'managed-groups': '/managed-groups',
|
||||
group: '/groups',
|
||||
'group.add-members': '/groups/add-members',
|
||||
'host-catalog': '/host-catalogs',
|
||||
@@ -96,6 +97,7 @@ module.exports = function (environment) {
|
||||
filter: false,
|
||||
capabilities: true,
|
||||
'credential-store': true,
|
||||
'managed-groups': false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -133,6 +135,7 @@ module.exports = function (environment) {
|
||||
// Enable features in development
|
||||
ENV.featureFlags['capabilities'] = true;
|
||||
ENV.featureFlags['filter'] = true;
|
||||
ENV.featureFlags['managed-groups'] = true;
|
||||
}
|
||||
|
||||
if (environment === 'test') {
|
||||
@@ -159,6 +162,7 @@ module.exports = function (environment) {
|
||||
// Enable tests for development features
|
||||
ENV.featureFlags['capabilities'] = true;
|
||||
ENV.featureFlags['filter'] = true;
|
||||
ENV.featureFlags['managed-groups'] = true;
|
||||
}
|
||||
|
||||
if (environment === 'production') {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
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';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
|
||||
module('Acceptance | managed-groups | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
const instances = {
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
},
|
||||
authMethod: null,
|
||||
managedGroup: null,
|
||||
};
|
||||
const urls = {
|
||||
orgScope: null,
|
||||
authMethods: null,
|
||||
managedGroups: null,
|
||||
newManagedGroup: null,
|
||||
managedGroup: null,
|
||||
};
|
||||
|
||||
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.authMethod = this.server.create('auth-method', {
|
||||
scope: instances.scopes.org,
|
||||
type: 'oidc',
|
||||
});
|
||||
instances.managedGroup = this.server.create('managed-group', {
|
||||
scope: instances.scopes.org,
|
||||
authMethod: instances.authMethod,
|
||||
});
|
||||
// Generate route URLs for resources
|
||||
urls.orgScope = `/scopes/${instances.scopes.org.id}`;
|
||||
urls.authMethods = `${urls.orgScope}/auth-methods`;
|
||||
urls.authMethod = `${urls.authMethods}/${instances.authMethod.id}`;
|
||||
urls.managedGroups = `${urls.authMethod}/managed-groups`;
|
||||
urls.newManagedGroup = `${urls.managedGroups}/new`;
|
||||
urls.managedGroup = `${urls.managedGroups}/${instances.authMethod.id}`;
|
||||
});
|
||||
|
||||
hooks.afterEach(async function () {
|
||||
const notification = find('.rose-notification');
|
||||
if (notification) {
|
||||
await click('.rose-notification-dismiss');
|
||||
}
|
||||
});
|
||||
|
||||
test('User can navigate to managed groups with proper authorization', async function (assert) {
|
||||
assert.expect(2);
|
||||
await visit(urls.authMethod);
|
||||
assert.ok(
|
||||
instances.authMethod.authorized_collection_actions[
|
||||
'managed-groups'
|
||||
].includes('list')
|
||||
);
|
||||
assert.ok(find(`[href="${urls.managedGroups}"]`));
|
||||
});
|
||||
|
||||
test('User cannot navigate to index without either list or create actions', async function (assert) {
|
||||
assert.expect(2);
|
||||
instances.authMethod.authorized_collection_actions['managed-groups'] = [];
|
||||
await visit(urls.authMethod);
|
||||
assert.notOk(
|
||||
instances.authMethod.authorized_collection_actions[
|
||||
'managed-groups'
|
||||
].includes('list')
|
||||
);
|
||||
assert.notOk(find(`[href="${urls.managedGroups}"]`));
|
||||
});
|
||||
|
||||
test('User can navigate to index with only create action', async function (assert) {
|
||||
assert.expect(2);
|
||||
instances.authMethod.authorized_collection_actions['managed-groups'] = [
|
||||
'create',
|
||||
];
|
||||
await visit(urls.authMethod);
|
||||
assert.ok(find(`[href="${urls.managedGroups}"]`));
|
||||
assert.ok(
|
||||
find(`.rose-layout-page-actions [href="${urls.newManagedGroup}"]`)
|
||||
);
|
||||
});
|
||||
});
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Controller | scopes/scope/auth-methods/auth-method/managed-groups',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let controller = this.owner.lookup(
|
||||
'controller:scopes/scope/auth-methods/auth-method/managed-groups'
|
||||
);
|
||||
assert.ok(controller);
|
||||
});
|
||||
}
|
||||
);
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Controller | scopes/scope/auth-methods/auth-method/managed-groups/managed-group',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let controller = this.owner.lookup(
|
||||
'controller:scopes/scope/auth-methods/auth-method/managed-groups/managed-group'
|
||||
);
|
||||
assert.ok(controller);
|
||||
});
|
||||
}
|
||||
);
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Controller | scopes/scope/auth-methods/auth-method/managed-groups/new',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let controller = this.owner.lookup(
|
||||
'controller:scopes/scope/auth-methods/auth-method/managed-groups/new'
|
||||
);
|
||||
assert.ok(controller);
|
||||
});
|
||||
}
|
||||
);
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Route | scopes/scope/auth-methods/auth-method/managed-groups',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup(
|
||||
'route:scopes/scope/auth-methods/auth-method/managed-groups'
|
||||
);
|
||||
assert.ok(route);
|
||||
});
|
||||
}
|
||||
);
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Route | scopes/scope/auth-methods/auth-method/managed-groups/index',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup(
|
||||
'route:scopes/scope/auth-methods/auth-method/managed-groups/index'
|
||||
);
|
||||
assert.ok(route);
|
||||
});
|
||||
}
|
||||
);
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Route | scopes/scope/auth-methods/auth-method/managed-groups/managed-group',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup(
|
||||
'route:scopes/scope/auth-methods/auth-method/managed-groups/managed-group'
|
||||
);
|
||||
assert.ok(route);
|
||||
});
|
||||
}
|
||||
);
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Route | scopes/scope/auth-methods/auth-method/managed-groups/managed-group/index',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup(
|
||||
'route:scopes/scope/auth-methods/auth-method/managed-groups/managed-group/index'
|
||||
);
|
||||
assert.ok(route);
|
||||
});
|
||||
}
|
||||
);
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Route | scopes/scope/auth-methods/auth-method/managed-groups/new',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup(
|
||||
'route:scopes/scope/auth-methods/auth-method/managed-groups/new'
|
||||
);
|
||||
assert.ok(route);
|
||||
});
|
||||
}
|
||||
);
|
||||
Reference in new issue
Block a user