mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-4738] [Process -Cloud] Move GroupCloudService to adf-core (#4928)
* [ADF-4738] [Process -Cloud] Move GroupCloudService to adf-core lib. * * Changed GroupModel to IdentityGroupModel * Updated unit tests the recent changes. * * Added documentation to the identityGroupService * Updated GroupInitial and GroupCoudcomponent doc. * * Created groupCount model. * Updated unit test to the recent changes * * After rebase updated doc * * Fixed comments.
This commit is contained in:
committed by
Eugenio Romano
parent
4ead51d2a6
commit
eb2811fdd0
@@ -16,8 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, ViewEncapsulation } from '@angular/core';
|
import { Component, ViewEncapsulation } from '@angular/core';
|
||||||
import { PeopleCloudComponent, GroupCloudComponent, GroupModel } from '@alfresco/adf-process-services-cloud';
|
import { PeopleCloudComponent, GroupCloudComponent } from '@alfresco/adf-process-services-cloud';
|
||||||
import { MatRadioChange, MatCheckboxChange } from '@angular/material';
|
import { MatRadioChange, MatCheckboxChange } from '@angular/material';
|
||||||
|
import { IdentityGroupModel } from '@alfresco/adf-core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-people-groups-cloud',
|
selector: 'app-people-groups-cloud',
|
||||||
@@ -39,8 +40,8 @@ export class PeopleGroupCloudDemoComponent {
|
|||||||
peoplePreselectValidation: Boolean = false;
|
peoplePreselectValidation: Boolean = false;
|
||||||
|
|
||||||
groupMode: string = GroupCloudComponent.MODE_SINGLE;
|
groupMode: string = GroupCloudComponent.MODE_SINGLE;
|
||||||
preSelectGroup: GroupModel[] = [];
|
preSelectGroup: IdentityGroupModel[] = [];
|
||||||
selectedGroupList: GroupModel[] = [];
|
selectedGroupList: IdentityGroupModel[] = [];
|
||||||
groupRoles: string[];
|
groupRoles: string[];
|
||||||
groupAppName: string;
|
groupAppName: string;
|
||||||
groupFilterMode: string = this.DEFAULT_FILTER_MODE;
|
groupFilterMode: string = this.DEFAULT_FILTER_MODE;
|
||||||
@@ -144,11 +145,11 @@ export class PeopleGroupCloudDemoComponent {
|
|||||||
return this.groupMode === GroupCloudComponent.MODE_MULTIPLE;
|
return this.groupMode === GroupCloudComponent.MODE_MULTIPLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemoveGroup(group: GroupModel) {
|
onRemoveGroup(group: IdentityGroupModel) {
|
||||||
this.preSelectGroup = this.preSelectGroup.filter((value: any) => value.id !== group.id);
|
this.preSelectGroup = this.preSelectGroup.filter((value: any) => value.id !== group.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectGroup(group: GroupModel) {
|
onSelectGroup(group: IdentityGroupModel) {
|
||||||
if (this.groupMode === GroupCloudComponent.MODE_MULTIPLE) {
|
if (this.groupMode === GroupCloudComponent.MODE_MULTIPLE) {
|
||||||
this.preSelectGroup.push(group);
|
this.preSelectGroup.push(group);
|
||||||
}
|
}
|
||||||
|
75
docs/core/services/identity-group.service.md
Normal file
75
docs/core/services/identity-group.service.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
Title: Identity Group service
|
||||||
|
Added: v3.4.0
|
||||||
|
Status: Active
|
||||||
|
Last reviewed: 2019-07-13
|
||||||
|
---
|
||||||
|
|
||||||
|
# [Identity Group service](../../../lib/core/userinfo/services/identity-group.service.ts "Defined in identity-group.service.ts")
|
||||||
|
|
||||||
|
Performs CRUD operations on identity groups.
|
||||||
|
|
||||||
|
## Class members
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
- **checkGroupHasAnyClientAppRole**(groupId: `string`, clientId: `string`, roleNames: `string[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<boolean>`<br/>
|
||||||
|
Check if a group has any of the client app roles in the supplied list.
|
||||||
|
- _groupId:_ `string` - Id of the target group
|
||||||
|
- _clientId:_ `string` - Id of the client
|
||||||
|
- _roleNames:_ `string[]` - Array of role names to check
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<boolean>` - True if the group has one or more of the roles, false otherwise
|
||||||
|
- **checkGroupHasClientApp**(groupId: `string`, clientId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<boolean>`<br/>
|
||||||
|
Checks if a group has a client app.
|
||||||
|
- _groupId:_ `string` - Id of the target group
|
||||||
|
- _clientId:_ `string` - Id of the client
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<boolean>` - True if the group has the client app, false otherwise
|
||||||
|
- **checkGroupHasRole**(groupId: `string`, roleNames: `string[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<boolean>`<br/>
|
||||||
|
Check that a group has one or more roles from the supplied list.
|
||||||
|
- _groupId:_ `string` - Id of the target group
|
||||||
|
- _roleNames:_ `string[]` - Array of role names
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<boolean>` - True if the group has one or more of the roles, false otherwise
|
||||||
|
- **createGroup**(newGroup: [`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
|
||||||
|
Creates new group.
|
||||||
|
- _newGroup:_ [`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts) - Object of containing the new group details.
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - Empty response when the group created.
|
||||||
|
- **deleteGroup**(groupId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
|
||||||
|
Deletes Group.
|
||||||
|
- _groupId:_ `string` - Id of the group.
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - Empty response when the group deleted.
|
||||||
|
- **findGroupsByName**(searchParams: [`IdentityGroupSearchParam`](../../../lib/core/userinfo/models/identity-group.model.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
|
||||||
|
Finds groups filtered by name.
|
||||||
|
- _searchParams:_ [`IdentityGroupSearchParam`](../../../lib/core/userinfo/models/identity-group.model.ts) - Object containing the name filter string
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - List of group information
|
||||||
|
- **getClientIdByApplicationName**(applicationName: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<string>`<br/>
|
||||||
|
Gets the client ID using the app name.
|
||||||
|
- _applicationName:_ `string` - Name of the app
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<string>` - client ID string
|
||||||
|
- **getClientRoles**(groupId: `string`, clientId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityRoleModel`](../../../lib/core/userinfo/models/identity-role.model.ts)`[]>`<br/>
|
||||||
|
Gets client roles.
|
||||||
|
- _groupId:_ `string` - ID of the target group
|
||||||
|
- _clientId:_ `string` - ID of the client
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityRoleModel`](../../../lib/core/userinfo/models/identity-role.model.ts)`[]>` - List of roles
|
||||||
|
- **getGroupRoles**(groupId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityRoleModel`](../../../lib/core/userinfo/models/identity-role.model.ts)`[]>`<br/>
|
||||||
|
Gets details for a specified group.
|
||||||
|
- _groupId:_ `string` - ID of the target group
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityRoleModel`](../../../lib/core/userinfo/models/identity-role.model.ts)`[]>` - Group details
|
||||||
|
- **getGroups**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts)`[]>`<br/>
|
||||||
|
Gets all groups.
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts)`[]>` - Array of group information objects
|
||||||
|
- **getTotalGroupsCount**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityGroupCountModel`](../../../lib/core/userinfo/models/identity-group.model.ts)`>`<br/>
|
||||||
|
Gets groups total count.
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityGroupCountModel`](../../../lib/core/userinfo/models/identity-group.model.ts)`>` - Number of groups count.
|
||||||
|
- **queryGroups**(requestQuery: [`IdentityGroupQueryCloudRequestModel`](../../../lib/core/userinfo/models/identity-group.model.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityGroupQueryResponse`](../../../lib/core/userinfo/models/identity-group.model.ts)`>`<br/>
|
||||||
|
Queries groups.
|
||||||
|
- _requestQuery:_ [`IdentityGroupQueryCloudRequestModel`](../../../lib/core/userinfo/models/identity-group.model.ts) -
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityGroupQueryResponse`](../../../lib/core/userinfo/models/identity-group.model.ts)`>` - Array of user information objects
|
||||||
|
- **updateGroup**(groupId: `string`, updatedGroup: [`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
|
||||||
|
Updates group details.
|
||||||
|
- _groupId:_ `string` - Id of the targeted group.
|
||||||
|
- _updatedGroup:_ [`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts) - Object of containing the group details
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - Empty response when the group updated.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Identity user service](../../core/userInfo/services/identity-user.service.md)
|
@@ -28,7 +28,7 @@ Searches Groups.
|
|||||||
| ---- | ---- | ------------- | ----------- |
|
| ---- | ---- | ------------- | ----------- |
|
||||||
| appName | `string` | | Name of the application. If specified this shows the users who have access to the app. |
|
| appName | `string` | | Name of the application. If specified this shows the users who have access to the app. |
|
||||||
| mode | `string` | | User selection mode (single/multiple). |
|
| mode | `string` | | User selection mode (single/multiple). |
|
||||||
| preSelectGroups | [`GroupModel`](../../../lib/process-services-cloud/src/lib/group/models/group.model.ts)`[]` | \[] | Array of users to be pre-selected. This pre-selects all users in multi selection mode and only the first user of the array in single selection mode. |
|
| preSelectGroups | [`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts)`[]` | \[] | Array of users to be pre-selected. This pre-selects all users in multi selection mode and only the first user of the array in single selection mode. |
|
||||||
| roles | `string[]` | \[] | Role names of the groups to be listed. |
|
| roles | `string[]` | \[] | Role names of the groups to be listed. |
|
||||||
| searchGroupsControl | `FormControl` | new FormControl() | FormControl to search the group |
|
| searchGroupsControl | `FormControl` | new FormControl() | FormControl to search the group |
|
||||||
| title | `string` | | Title of the field |
|
| title | `string` | | Title of the field |
|
||||||
@@ -37,8 +37,8 @@ Searches Groups.
|
|||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| ---- | ---- | ----------- |
|
| ---- | ---- | ----------- |
|
||||||
| removeGroup | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`GroupModel`](../../../lib/process-services-cloud/src/lib/group/models/group.model.ts)`>` | Emitted when a group is removed. |
|
| removeGroup | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts)`>` | Emitted when a group is removed. |
|
||||||
| selectGroup | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`GroupModel`](../../../lib/process-services-cloud/src/lib/group/models/group.model.ts)`>` | Emitted when a group is selected. |
|
| selectGroup | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts)`>` | Emitted when a group is selected. |
|
||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@ Extracts the initial character from a group name.
|
|||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
This pipe takes a [`GroupModel`](../../../lib/process-services-cloud/src/lib/group/models/group.model.ts)
|
This pipe takes a [`IdentityGroupModel`](../../../lib/core/userinfo/models/identity-group.model.ts)
|
||||||
object as its parameter and extracts the initial character from the `name`
|
object as its parameter and extracts the initial character from the `name`
|
||||||
property. The initial is a handy way to identify the group in lists and
|
property. The initial is a handy way to identify the group in lists and
|
||||||
other situations where there is limited screen space available.
|
other situations where there is limited screen space available.
|
||||||
|
163
lib/core/mock/identity-group.service.mock.ts
Normal file
163
lib/core/mock/identity-group.service.mock.ts
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { IdentityGroupModel, IdentityGroupCountModel } from '../userinfo/models/identity-group.model';
|
||||||
|
import { IdentityRoleModel } from '../userinfo/models/identity-role.model';
|
||||||
|
|
||||||
|
export let mockIdentityGroup1 = new IdentityGroupModel({
|
||||||
|
id: 'mock-group-id-1', name: 'Mock Group 1', path: '/mock', subGroups: []
|
||||||
|
});
|
||||||
|
|
||||||
|
export let mockIdentityGroup2 = new IdentityGroupModel({
|
||||||
|
id: 'mock-group-id-2', name: 'Mock Group 2', path: '', subGroups: []
|
||||||
|
});
|
||||||
|
|
||||||
|
export let mockIdentityGroup3 = new IdentityGroupModel({
|
||||||
|
id: 'mock-group-id-3', name: 'Mock Group 3', path: '', subGroups: []
|
||||||
|
});
|
||||||
|
|
||||||
|
export let mockIdentityGroup4 = new IdentityGroupModel({
|
||||||
|
id: 'mock-group-id-4', name: 'Mock Group 4', path: '', subGroups: []
|
||||||
|
});
|
||||||
|
|
||||||
|
export let mockIdentityGroup5 = new IdentityGroupModel({
|
||||||
|
id: 'mock-group-id-5', name: 'Mock Group 5', path: '', subGroups: []
|
||||||
|
});
|
||||||
|
|
||||||
|
export let mockIdentityGroupsCount = <IdentityGroupCountModel> { count: 10 };
|
||||||
|
|
||||||
|
export let mockIdentityGroups = [
|
||||||
|
mockIdentityGroup1, mockIdentityGroup2, mockIdentityGroup3, mockIdentityGroup5, mockIdentityGroup5
|
||||||
|
];
|
||||||
|
|
||||||
|
export let mockApplicationDetails = {id: 'mock-app-id', name: 'mock-app-name'};
|
||||||
|
|
||||||
|
export let groupAPIMockError = {
|
||||||
|
error: {
|
||||||
|
errorKey: 'failed',
|
||||||
|
statusCode: 400,
|
||||||
|
stackTrace: 'For security reasons the stack trace is no longer displayed, but the property is kept for previous versions.'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let mockApiError = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.reject(groupAPIMockError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let roleMappingMock = [
|
||||||
|
{ id: 'role-id-1', name: 'role-name-1' }, { id: 'role-id-2', name: 'role-name-2' }
|
||||||
|
];
|
||||||
|
|
||||||
|
export let roleMappingApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve(roleMappingMock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let noRoleMappingApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let groupsMockApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve(mockIdentityGroups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let getGroupsCountMockApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let queryGroupsMockApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve(mockIdentityGroups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let createGroupMappingApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let updateGroupMappingApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let deleteGroupMappingApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let returnCallQueryParameters = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: (queryUrl, operation, context, queryParams) => {
|
||||||
|
return Promise.resolve(queryParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let returnCallUrl = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: (queryUrl, operation, context, queryParams) => {
|
||||||
|
return Promise.resolve(queryUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let applicationDetailsMockApi = {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi: () => {
|
||||||
|
return Promise.resolve([mockApplicationDetails]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let mockIdentityRoles = [
|
||||||
|
new IdentityRoleModel({id: 'mock-role-id', name: 'MOCK-ADMIN-ROLE'}),
|
||||||
|
new IdentityRoleModel({id: 'mock-role-id', name: 'MOCK-USER-ROLE'}),
|
||||||
|
new IdentityRoleModel({id: 'mock-role-id', name: 'MOCK-ROLE-1'})
|
||||||
|
];
|
||||||
|
|
||||||
|
export let clientRoles = [ 'MOCK-ADMIN-ROLE', 'MOCK-USER-ROLE'];
|
@@ -37,3 +37,4 @@ export * from './form/start-form.component.mock';
|
|||||||
export * from './form/form.service.mock';
|
export * from './form/form.service.mock';
|
||||||
export * from './form/widget-visibility.service.mock';
|
export * from './form/widget-visibility.service.mock';
|
||||||
export * from './jwt-helper.service.spec';
|
export * from './jwt-helper.service.spec';
|
||||||
|
export * from './identity-group.service.mock';
|
||||||
|
@@ -14,6 +14,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Pagination } from '@alfresco/js-api';
|
||||||
|
|
||||||
export class IdentityGroupModel {
|
export class IdentityGroupModel {
|
||||||
|
|
||||||
id: string;
|
id: string;
|
||||||
@@ -36,3 +39,30 @@ export class IdentityGroupModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IdentityGroupSearchParam {
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IdentityGroupQueryResponse {
|
||||||
|
|
||||||
|
entries: IdentityGroupModel[];
|
||||||
|
pagination: Pagination;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IdentityGroupQueryCloudRequestModel {
|
||||||
|
|
||||||
|
first: number;
|
||||||
|
max: number;
|
||||||
|
|
||||||
|
constructor(obj?: any) {
|
||||||
|
if (obj) {
|
||||||
|
this.first = obj.first;
|
||||||
|
this.max = obj.max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IdentityGroupCountModel {
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
@@ -19,8 +19,10 @@ export * from './components/user-info.component';
|
|||||||
export * from './services/bpm-user.service';
|
export * from './services/bpm-user.service';
|
||||||
export * from './services/ecm-user.service';
|
export * from './services/ecm-user.service';
|
||||||
export * from './services/identity-user.service';
|
export * from './services/identity-user.service';
|
||||||
|
export * from './services/identity-group.service';
|
||||||
export * from './models/bpm-user.model';
|
export * from './models/bpm-user.model';
|
||||||
export * from './models/ecm-user.model';
|
export * from './models/ecm-user.model';
|
||||||
|
export * from './models/identity-group.model';
|
||||||
export * from './models/identity-user.model';
|
export * from './models/identity-user.model';
|
||||||
export * from './models/identity-role.model';
|
export * from './models/identity-role.model';
|
||||||
export * from './models/identity-group.model';
|
export * from './models/identity-group.model';
|
||||||
|
@@ -17,32 +17,37 @@
|
|||||||
|
|
||||||
import { async } from '@angular/core/testing';
|
import { async } from '@angular/core/testing';
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { GroupCloudService } from './group-cloud.service';
|
|
||||||
import {
|
import {
|
||||||
AlfrescoApiServiceMock,
|
AlfrescoApiServiceMock,
|
||||||
CoreModule,
|
CoreModule,
|
||||||
setupTestBed,
|
setupTestBed,
|
||||||
AlfrescoApiService,
|
AlfrescoApiService,
|
||||||
LogService
|
LogService,
|
||||||
|
IdentityGroupService,
|
||||||
|
IdentityGroupSearchParam,
|
||||||
|
groupAPIMockError
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import {
|
|
||||||
applicationDetailsMockApi,
|
|
||||||
groupsMockApi,
|
|
||||||
returnCallQueryParameters,
|
|
||||||
returnCallUrl,
|
|
||||||
mockApiError,
|
|
||||||
mockError,
|
|
||||||
roleMappingApi,
|
|
||||||
noRoleMappingApi,
|
|
||||||
groupRoles,
|
|
||||||
clientRoles
|
|
||||||
} from '../mock/group-cloud.mock';
|
|
||||||
import { GroupSearchParam } from '../models/group.model';
|
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { throwError, of } from 'rxjs';
|
import { throwError, of } from 'rxjs';
|
||||||
|
import {
|
||||||
|
noRoleMappingApi,
|
||||||
|
mockIdentityRoles,
|
||||||
|
groupsMockApi,
|
||||||
|
roleMappingApi,
|
||||||
|
clientRoles,
|
||||||
|
returnCallQueryParameters,
|
||||||
|
returnCallUrl,
|
||||||
|
applicationDetailsMockApi,
|
||||||
|
mockApiError,
|
||||||
|
mockIdentityGroup1,
|
||||||
|
createGroupMappingApi,
|
||||||
|
updateGroupMappingApi,
|
||||||
|
deleteGroupMappingApi,
|
||||||
|
mockIdentityGroupsCount
|
||||||
|
} from '../../mock/identity-group.service.mock';
|
||||||
|
|
||||||
describe('GroupCloudService', () => {
|
describe('IdentityGroupService', () => {
|
||||||
let service: GroupCloudService;
|
let service: IdentityGroupService;
|
||||||
let apiService: AlfrescoApiService;
|
let apiService: AlfrescoApiService;
|
||||||
let logService: LogService;
|
let logService: LogService;
|
||||||
|
|
||||||
@@ -54,23 +59,23 @@ describe('GroupCloudService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
service = TestBed.get(GroupCloudService);
|
service = TestBed.get(IdentityGroupService);
|
||||||
apiService = TestBed.get(AlfrescoApiService);
|
apiService = TestBed.get(AlfrescoApiService);
|
||||||
logService = TestBed.get(LogService);
|
logService = TestBed.get(LogService);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should be able to fetch groups', (done) => {
|
it('should be able to fetch groups based on group name', (done) => {
|
||||||
spyOn(apiService, 'getInstance').and.returnValue(groupsMockApi);
|
spyOn(apiService, 'getInstance').and.returnValue(groupsMockApi);
|
||||||
service.findGroupsByName(<GroupSearchParam> {name: 'mock'}).subscribe((res) => {
|
service.findGroupsByName(<IdentityGroupSearchParam> {name: 'mock'}).subscribe((res) => {
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
expect(res).not.toBeNull();
|
expect(res).not.toBeNull();
|
||||||
expect(res.length).toBe(3);
|
expect(res.length).toBe(5);
|
||||||
expect(res[0].id).toBe('mock-id-1');
|
expect(res[0].id).toBe('mock-group-id-1');
|
||||||
expect(res[0].name).toBe('Mock Group 1');
|
expect(res[0].name).toBe('Mock Group 1');
|
||||||
expect(res[1].id).toBe('mock-id-2');
|
expect(res[1].id).toBe('mock-group-id-2');
|
||||||
expect(res[1].name).toBe('Mock Group 2');
|
expect(res[1].name).toBe('Mock Group 2');
|
||||||
expect(res[2].id).toBe('mock-id-3');
|
expect(res[2].id).toBe('mock-group-id-3');
|
||||||
expect(res[2].name).toBe('Fake Group 3');
|
expect(res[2].name).toBe('Mock Group 3');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -94,7 +99,7 @@ describe('GroupCloudService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should able to fetch group roles by groupId', (done) => {
|
it('should able to fetch group roles by groupId', (done) => {
|
||||||
spyOn(service, 'getGroupRoles').and.returnValue(of(groupRoles));
|
spyOn(service, 'getGroupRoles').and.returnValue(of(mockIdentityRoles));
|
||||||
service.getGroupRoles('mock-group-id').subscribe(
|
service.getGroupRoles('mock-group-id').subscribe(
|
||||||
(res: any) => {
|
(res: any) => {
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
@@ -130,7 +135,7 @@ describe('GroupCloudService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return true if group has given role', (done) => {
|
it('should return true if group has given role', (done) => {
|
||||||
spyOn(service, 'getGroupRoles').and.returnValue(of(groupRoles));
|
spyOn(service, 'getGroupRoles').and.returnValue(of(mockIdentityRoles));
|
||||||
service.checkGroupHasRole('mock-group-id', ['MOCK-ADMIN-ROLE']).subscribe(
|
service.checkGroupHasRole('mock-group-id', ['MOCK-ADMIN-ROLE']).subscribe(
|
||||||
(res: boolean) => {
|
(res: boolean) => {
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
@@ -141,7 +146,7 @@ describe('GroupCloudService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if group does not have given role', (done) => {
|
it('should return false if group does not have given role', (done) => {
|
||||||
spyOn(service, 'getGroupRoles').and.returnValue(of(groupRoles));
|
spyOn(service, 'getGroupRoles').and.returnValue(of(mockIdentityRoles));
|
||||||
service.checkGroupHasRole('mock-group-id', ['MOCK-ADMIN-MODELER']).subscribe(
|
service.checkGroupHasRole('mock-group-id', ['MOCK-ADMIN-MODELER']).subscribe(
|
||||||
(res: boolean) => {
|
(res: boolean) => {
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
@@ -231,7 +236,7 @@ describe('GroupCloudService', () => {
|
|||||||
|
|
||||||
it('should append to the call all the parameters', (done) => {
|
it('should append to the call all the parameters', (done) => {
|
||||||
spyOn(apiService, 'getInstance').and.returnValue(returnCallQueryParameters);
|
spyOn(apiService, 'getInstance').and.returnValue(returnCallQueryParameters);
|
||||||
service.findGroupsByName(<GroupSearchParam> {name: 'mock'}).subscribe((res) => {
|
service.findGroupsByName(<IdentityGroupSearchParam> {name: 'mock'}).subscribe((res) => {
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
expect(res).not.toBeNull();
|
expect(res).not.toBeNull();
|
||||||
expect(res.search).toBe('mock');
|
expect(res.search).toBe('mock');
|
||||||
@@ -241,7 +246,7 @@ describe('GroupCloudService', () => {
|
|||||||
|
|
||||||
it('should request groups api url', (done) => {
|
it('should request groups api url', (done) => {
|
||||||
spyOn(apiService, 'getInstance').and.returnValue(returnCallUrl);
|
spyOn(apiService, 'getInstance').and.returnValue(returnCallUrl);
|
||||||
service.findGroupsByName(<GroupSearchParam> {name: 'mock'}).subscribe((requestUrl) => {
|
service.findGroupsByName(<IdentityGroupSearchParam> {name: 'mock'}).subscribe((requestUrl) => {
|
||||||
expect(requestUrl).toBeDefined();
|
expect(requestUrl).toBeDefined();
|
||||||
expect(requestUrl).not.toBeNull();
|
expect(requestUrl).not.toBeNull();
|
||||||
expect(requestUrl).toContain('/groups');
|
expect(requestUrl).toContain('/groups');
|
||||||
@@ -262,14 +267,184 @@ describe('GroupCloudService', () => {
|
|||||||
it('should notify errors returned from the API', (done) => {
|
it('should notify errors returned from the API', (done) => {
|
||||||
const logServiceSpy = spyOn(logService, 'error').and.callThrough();
|
const logServiceSpy = spyOn(logService, 'error').and.callThrough();
|
||||||
spyOn(apiService, 'getInstance').and.returnValue(mockApiError);
|
spyOn(apiService, 'getInstance').and.returnValue(mockApiError);
|
||||||
service.findGroupsByName(<GroupSearchParam> {name: 'mock'}).subscribe(
|
service.findGroupsByName(<IdentityGroupSearchParam> {name: 'mock'}).subscribe(
|
||||||
() => {},
|
() => {},
|
||||||
(res: any) => {
|
(res: any) => {
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
expect(res).toEqual(mockError);
|
expect(res).toEqual(groupAPIMockError);
|
||||||
expect(logServiceSpy).toHaveBeenCalled();
|
expect(logServiceSpy).toHaveBeenCalled();
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to all fetch groups', (done) => {
|
||||||
|
spyOn(apiService, 'getInstance').and.returnValue(groupsMockApi);
|
||||||
|
service.getGroups().subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.length).toBe(5);
|
||||||
|
expect(res[0].id).toBe('mock-group-id-1');
|
||||||
|
expect(res[0].name).toBe('Mock Group 1');
|
||||||
|
expect(res[1].id).toBe('mock-group-id-2');
|
||||||
|
expect(res[1].name).toBe('Mock Group 2');
|
||||||
|
expect(res[2].id).toBe('mock-group-id-3');
|
||||||
|
expect(res[2].name).toBe('Mock Group 3');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not able to fetch all group if error occurred', (done) => {
|
||||||
|
const errorResponse = new HttpErrorResponse({
|
||||||
|
error: 'Mock Error',
|
||||||
|
status: 404, statusText: 'Not Found'
|
||||||
|
});
|
||||||
|
|
||||||
|
spyOn(service, 'getGroups').and.returnValue(throwError(errorResponse));
|
||||||
|
|
||||||
|
service.getGroups()
|
||||||
|
.subscribe(
|
||||||
|
() => {
|
||||||
|
fail('expected an error, not groups');
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
expect(error.status).toEqual(404);
|
||||||
|
expect(error.statusText).toEqual('Not Found');
|
||||||
|
expect(error.error).toEqual('Mock Error');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to query groups based on first & max params', (done) => {
|
||||||
|
spyOn(service, 'getTotalGroupsCount').and.returnValue(of(mockIdentityGroupsCount));
|
||||||
|
spyOn(apiService, 'getInstance').and.returnValue(groupsMockApi);
|
||||||
|
service.queryGroups({first: 0, max: 5}).subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.entries.length).toBe(5);
|
||||||
|
expect(res.entries[0].id).toBe('mock-group-id-1');
|
||||||
|
expect(res.entries[0].name).toBe('Mock Group 1');
|
||||||
|
expect(res.entries[1].id).toBe('mock-group-id-2');
|
||||||
|
expect(res.entries[1].name).toBe('Mock Group 2');
|
||||||
|
expect(res.entries[2].id).toBe('mock-group-id-3');
|
||||||
|
expect(res.entries[2].name).toBe('Mock Group 3');
|
||||||
|
expect(res.pagination.totalItems).toBe(10);
|
||||||
|
expect(res.pagination.skipCount).toBe(0);
|
||||||
|
expect(res.pagination.maxItems).toBe(5);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not able to query groups if error occurred', (done) => {
|
||||||
|
const errorResponse = new HttpErrorResponse({
|
||||||
|
error: 'Mock Error',
|
||||||
|
status: 404, statusText: 'Not Found'
|
||||||
|
});
|
||||||
|
|
||||||
|
spyOn(service, 'queryGroups').and.returnValue(throwError(errorResponse));
|
||||||
|
|
||||||
|
service.queryGroups({first: 0, max: 5})
|
||||||
|
.subscribe(
|
||||||
|
() => {
|
||||||
|
fail('expected an error, not query groups');
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
expect(error.status).toEqual(404);
|
||||||
|
expect(error.statusText).toEqual('Not Found');
|
||||||
|
expect(error.error).toEqual('Mock Error');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to create group', (done) => {
|
||||||
|
const createCustomApiSpy = spyOn(apiService, 'getInstance').and.returnValue(createGroupMappingApi);
|
||||||
|
service.createGroup(mockIdentityGroup1).subscribe((res) => {
|
||||||
|
expect(createCustomApiSpy).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not able to create group if error occurred', (done) => {
|
||||||
|
const errorResponse = new HttpErrorResponse({
|
||||||
|
error: 'Mock Error',
|
||||||
|
status: 404, statusText: 'Not Found'
|
||||||
|
});
|
||||||
|
|
||||||
|
spyOn(service, 'createGroup').and.returnValue(throwError(errorResponse));
|
||||||
|
|
||||||
|
service.createGroup(mockIdentityGroup1)
|
||||||
|
.subscribe(
|
||||||
|
() => {
|
||||||
|
fail('expected an error, not to create group');
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
expect(error.status).toEqual(404);
|
||||||
|
expect(error.statusText).toEqual('Not Found');
|
||||||
|
expect(error.error).toEqual('Mock Error');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to update group', (done) => {
|
||||||
|
const updateCustomApiSpy = spyOn(apiService, 'getInstance').and.returnValue(updateGroupMappingApi);
|
||||||
|
service.updateGroup('mock-group-id', mockIdentityGroup1).subscribe((res) => {
|
||||||
|
expect(updateCustomApiSpy).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not able to update group if error occurred', (done) => {
|
||||||
|
const errorResponse = new HttpErrorResponse({
|
||||||
|
error: 'Mock Error',
|
||||||
|
status: 404, statusText: 'Not Found'
|
||||||
|
});
|
||||||
|
|
||||||
|
spyOn(service, 'updateGroup').and.returnValue(throwError(errorResponse));
|
||||||
|
|
||||||
|
service.updateGroup('mock-group-id', mockIdentityGroup1)
|
||||||
|
.subscribe(
|
||||||
|
() => {
|
||||||
|
fail('expected an error, not to update group');
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
expect(error.status).toEqual(404);
|
||||||
|
expect(error.statusText).toEqual('Not Found');
|
||||||
|
expect(error.error).toEqual('Mock Error');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to delete group', (done) => {
|
||||||
|
const deleteCustomApiSpy = spyOn(apiService, 'getInstance').and.returnValue(deleteGroupMappingApi);
|
||||||
|
service.deleteGroup('mock-group-id').subscribe((res) => {
|
||||||
|
expect(deleteCustomApiSpy).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not able to delete group if error occurred', (done) => {
|
||||||
|
const errorResponse = new HttpErrorResponse({
|
||||||
|
error: 'Mock Error',
|
||||||
|
status: 404, statusText: 'Not Found'
|
||||||
|
});
|
||||||
|
|
||||||
|
spyOn(service, 'deleteGroup').and.returnValue(throwError(errorResponse));
|
||||||
|
|
||||||
|
service.deleteGroup('mock-group-id')
|
||||||
|
.subscribe(
|
||||||
|
() => {
|
||||||
|
fail('expected an error, not to delete group');
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
expect(error.status).toEqual(404);
|
||||||
|
expect(error.statusText).toEqual('Not Found');
|
||||||
|
expect(error.error).toEqual('Mock Error');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
347
lib/core/userinfo/services/identity-group.service.ts
Normal file
347
lib/core/userinfo/services/identity-group.service.ts
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable, of, from, throwError } from 'rxjs';
|
||||||
|
import { catchError, map, switchMap } from 'rxjs/operators';
|
||||||
|
import { AppConfigService } from '../../app-config/app-config.service';
|
||||||
|
import { AlfrescoApiService } from '../../services/alfresco-api.service';
|
||||||
|
import { LogService } from '../../services/log.service';
|
||||||
|
import {
|
||||||
|
IdentityGroupSearchParam,
|
||||||
|
IdentityGroupQueryCloudRequestModel,
|
||||||
|
IdentityGroupModel,
|
||||||
|
IdentityGroupQueryResponse,
|
||||||
|
IdentityGroupCountModel
|
||||||
|
} from '../models/identity-group.model';
|
||||||
|
import { IdentityRoleModel } from '../models/identity-role.model';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class IdentityGroupService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private alfrescoApiService: AlfrescoApiService,
|
||||||
|
private appConfigService: AppConfigService,
|
||||||
|
private logService: LogService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all groups.
|
||||||
|
* @returns Array of group information objects
|
||||||
|
*/
|
||||||
|
getGroups(): Observable<IdentityGroupModel[]> {
|
||||||
|
const url = this.getGroupsApi();
|
||||||
|
const httpMethod = 'GET', pathParams = {},
|
||||||
|
queryParams = {}, bodyParam = {}, headerParams = {},
|
||||||
|
formParams = {}, authNames = [], contentTypes = ['application/json'];
|
||||||
|
|
||||||
|
return from(this.alfrescoApiService.getInstance().oauth2Auth.callCustomApi(
|
||||||
|
url, httpMethod, pathParams, queryParams,
|
||||||
|
headerParams, formParams, bodyParam, authNames,
|
||||||
|
contentTypes, null, null, null
|
||||||
|
)).pipe(
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries groups.
|
||||||
|
* @returns Array of user information objects
|
||||||
|
*/
|
||||||
|
queryGroups(requestQuery: IdentityGroupQueryCloudRequestModel): Observable<IdentityGroupQueryResponse> {
|
||||||
|
const url = this.getGroupsApi();
|
||||||
|
const httpMethod = 'GET', pathParams = {},
|
||||||
|
queryParams = { first: requestQuery.first || 0, max: requestQuery.max || 5 }, bodyParam = {}, headerParams = {},
|
||||||
|
formParams = {}, authNames = [], contentTypes = ['application/json'];
|
||||||
|
return this.getTotalGroupsCount().pipe(
|
||||||
|
switchMap((totalCount: IdentityGroupCountModel) =>
|
||||||
|
from(this.alfrescoApiService.getInstance().oauth2Auth.callCustomApi(
|
||||||
|
url, httpMethod, pathParams, queryParams,
|
||||||
|
headerParams, formParams, bodyParam, authNames,
|
||||||
|
contentTypes, null, null, null)
|
||||||
|
).pipe(
|
||||||
|
map((response: any[]) => {
|
||||||
|
return <IdentityGroupQueryResponse> {
|
||||||
|
entries: response,
|
||||||
|
pagination: {
|
||||||
|
skipCount: requestQuery.first,
|
||||||
|
maxItems: requestQuery.max,
|
||||||
|
count: totalCount.count,
|
||||||
|
hasMoreItems: false,
|
||||||
|
totalItems: totalCount.count
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets groups total count.
|
||||||
|
* @returns Number of groups count.
|
||||||
|
*/
|
||||||
|
getTotalGroupsCount(): Observable<IdentityGroupCountModel> {
|
||||||
|
const url = this.getGroupsApi() + `/count`;
|
||||||
|
const contentTypes = ['application/json'], accepts = ['application/json'];
|
||||||
|
return from(this.alfrescoApiService.getInstance()
|
||||||
|
.oauth2Auth.callCustomApi(url, 'GET',
|
||||||
|
null, null, null,
|
||||||
|
null, null, contentTypes,
|
||||||
|
accepts, null, null, null)).pipe(
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new group.
|
||||||
|
* @param newGroup Object of containing the new group details.
|
||||||
|
* @returns Empty response when the group created.
|
||||||
|
*/
|
||||||
|
createGroup(newGroup: IdentityGroupModel): Observable<any> {
|
||||||
|
const url = this.getGroupsApi();
|
||||||
|
const httpMethod = 'POST', pathParams = {}, queryParams = {}, bodyParam = newGroup, headerParams = {},
|
||||||
|
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
||||||
|
|
||||||
|
return from(this.alfrescoApiService.getInstance().oauth2Auth.callCustomApi(
|
||||||
|
url, httpMethod, pathParams, queryParams,
|
||||||
|
headerParams, formParams, bodyParam,
|
||||||
|
contentTypes, accepts, null, null, null
|
||||||
|
)).pipe(
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates group details.
|
||||||
|
* @param groupId Id of the targeted group.
|
||||||
|
* @param updatedGroup Object of containing the group details
|
||||||
|
* @returns Empty response when the group updated.
|
||||||
|
*/
|
||||||
|
updateGroup(groupId: string, updatedGroup: IdentityGroupModel): Observable<any> {
|
||||||
|
const url = this.getGroupsApi() + `/${groupId}`;
|
||||||
|
const request = JSON.stringify(updatedGroup);
|
||||||
|
const httpMethod = 'PUT', pathParams = {} , queryParams = {}, bodyParam = request, headerParams = {},
|
||||||
|
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
||||||
|
|
||||||
|
return from(this.alfrescoApiService.getInstance().oauth2Auth.callCustomApi(
|
||||||
|
url, httpMethod, pathParams, queryParams,
|
||||||
|
headerParams, formParams, bodyParam,
|
||||||
|
contentTypes, accepts, null, null, null
|
||||||
|
)).pipe(
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes Group.
|
||||||
|
* @param groupId Id of the group.
|
||||||
|
* @returns Empty response when the group deleted.
|
||||||
|
*/
|
||||||
|
deleteGroup(groupId: string): Observable<any> {
|
||||||
|
const url = this.getGroupsApi() + `/${groupId}`;
|
||||||
|
const httpMethod = 'DELETE', pathParams = {} , queryParams = {}, bodyParam = {}, headerParams = {},
|
||||||
|
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
||||||
|
|
||||||
|
return from(this.alfrescoApiService.getInstance().oauth2Auth.callCustomApi(
|
||||||
|
url, httpMethod, pathParams, queryParams,
|
||||||
|
headerParams, formParams, bodyParam,
|
||||||
|
contentTypes, accepts, null, null, null
|
||||||
|
)).pipe(
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds groups filtered by name.
|
||||||
|
* @param searchParams Object containing the name filter string
|
||||||
|
* @returns List of group information
|
||||||
|
*/
|
||||||
|
findGroupsByName(searchParams: IdentityGroupSearchParam): Observable<any> {
|
||||||
|
if (searchParams.name === '') {
|
||||||
|
return of([]);
|
||||||
|
}
|
||||||
|
const url = this.getGroupsApi();
|
||||||
|
const httpMethod = 'GET', pathParams = {}, queryParams = {search: searchParams.name}, bodyParam = {}, headerParams = {},
|
||||||
|
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
||||||
|
|
||||||
|
return (from(this.alfrescoApiService.getInstance().oauth2Auth.callCustomApi(
|
||||||
|
url, httpMethod, pathParams, queryParams,
|
||||||
|
headerParams, formParams, bodyParam,
|
||||||
|
contentTypes, accepts, Object, null, null)
|
||||||
|
)).pipe(
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets details for a specified group.
|
||||||
|
* @param groupId Id of the target group
|
||||||
|
* @returns Group details
|
||||||
|
*/
|
||||||
|
getGroupRoles(groupId: string): Observable<IdentityRoleModel[]> {
|
||||||
|
const url = this.buildRolesUrl(groupId);
|
||||||
|
const httpMethod = 'GET', pathParams = {}, queryParams = {}, bodyParam = {}, headerParams = {},
|
||||||
|
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
||||||
|
|
||||||
|
return (from(this.alfrescoApiService.getInstance().oauth2Auth.callCustomApi(
|
||||||
|
url, httpMethod, pathParams, queryParams,
|
||||||
|
headerParams, formParams, bodyParam,
|
||||||
|
contentTypes, accepts, Object, null, null)
|
||||||
|
)).pipe(
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that a group has one or more roles from the supplied list.
|
||||||
|
* @param groupId Id of the target group
|
||||||
|
* @param roleNames Array of role names
|
||||||
|
* @returns True if the group has one or more of the roles, false otherwise
|
||||||
|
*/
|
||||||
|
checkGroupHasRole(groupId: string, roleNames: string[]): Observable<boolean> {
|
||||||
|
return this.getGroupRoles(groupId).pipe(map((groupRoles: IdentityRoleModel[]) => {
|
||||||
|
let hasRole = false;
|
||||||
|
if (groupRoles && groupRoles.length > 0) {
|
||||||
|
roleNames.forEach((roleName: string) => {
|
||||||
|
const role = groupRoles.find((groupRole) => {
|
||||||
|
return roleName === groupRole.name;
|
||||||
|
});
|
||||||
|
if (role) {
|
||||||
|
hasRole = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return hasRole;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the client Id using the app name.
|
||||||
|
* @param applicationName Name of the app
|
||||||
|
* @returns client Id string
|
||||||
|
*/
|
||||||
|
getClientIdByApplicationName(applicationName: string): Observable<string> {
|
||||||
|
const url = this.getApplicationIdApi();
|
||||||
|
const httpMethod = 'GET', pathParams = {}, queryParams = {clientId: applicationName}, bodyParam = {}, headerParams = {}, formParams = {},
|
||||||
|
contentTypes = ['application/json'], accepts = ['application/json'];
|
||||||
|
return from(this.alfrescoApiService.getInstance()
|
||||||
|
.oauth2Auth.callCustomApi(url, httpMethod, pathParams, queryParams, headerParams,
|
||||||
|
formParams, bodyParam, contentTypes,
|
||||||
|
accepts, Object, null, null)
|
||||||
|
).pipe(
|
||||||
|
map((response: any[]) => {
|
||||||
|
const clientId = response && response.length > 0 ? response[0].id : '';
|
||||||
|
return clientId;
|
||||||
|
}),
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets client roles.
|
||||||
|
* @param groupId Id of the target group
|
||||||
|
* @param clientId Id of the client
|
||||||
|
* @returns List of roles
|
||||||
|
*/
|
||||||
|
getClientRoles(groupId: string, clientId: string): Observable<IdentityRoleModel[]> {
|
||||||
|
const url = this.groupClientRoleMappingApi(groupId, clientId);
|
||||||
|
const httpMethod = 'GET', pathParams = {}, queryParams = {}, bodyParam = {}, headerParams = {},
|
||||||
|
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
||||||
|
|
||||||
|
return from(this.alfrescoApiService.getInstance().oauth2Auth.callCustomApi(
|
||||||
|
url, httpMethod, pathParams, queryParams,
|
||||||
|
headerParams, formParams, bodyParam,
|
||||||
|
contentTypes, accepts, Object, null, null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a group has a client app.
|
||||||
|
* @param groupId Id of the target group
|
||||||
|
* @param clientId Id of the client
|
||||||
|
* @returns True if the group has the client app, false otherwise
|
||||||
|
*/
|
||||||
|
checkGroupHasClientApp(groupId: string, clientId: string): Observable<boolean> {
|
||||||
|
return this.getClientRoles(groupId, clientId).pipe(
|
||||||
|
map((response: any[]) => {
|
||||||
|
if (response && response.length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}),
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a group has any of the client app roles in the supplied list.
|
||||||
|
* @param groupId Id of the target group
|
||||||
|
* @param clientId Id of the client
|
||||||
|
* @param roleNames Array of role names to check
|
||||||
|
* @returns True if the group has one or more of the roles, false otherwise
|
||||||
|
*/
|
||||||
|
checkGroupHasAnyClientAppRole(groupId: string, clientId: string, roleNames: string[]): Observable<boolean> {
|
||||||
|
return this.getClientRoles(groupId, clientId).pipe(
|
||||||
|
map((clientRoles: any[]) => {
|
||||||
|
let hasRole = false;
|
||||||
|
if (clientRoles.length > 0) {
|
||||||
|
roleNames.forEach((roleName) => {
|
||||||
|
const role = clientRoles.find((availableRole) => {
|
||||||
|
return availableRole.name === roleName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (role) {
|
||||||
|
hasRole = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return hasRole;
|
||||||
|
}),
|
||||||
|
catchError((error) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private groupClientRoleMappingApi(groupId: string, clientId: string): string {
|
||||||
|
return `${this.appConfigService.get('identityHost')}/groups/${groupId}/role-mappings/clients/${clientId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getApplicationIdApi(): string {
|
||||||
|
return `${this.appConfigService.get('identityHost')}/clients`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getGroupsApi(): string {
|
||||||
|
return `${this.appConfigService.get('identityHost')}/groups`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildRolesUrl(groupId: string): string {
|
||||||
|
return `${this.appConfigService.get('identityHost')}/groups/${groupId}/role-mappings/realm/composite`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throw the error
|
||||||
|
* @param error
|
||||||
|
*/
|
||||||
|
private handleError(error: Response) {
|
||||||
|
this.logService.error(error);
|
||||||
|
return throwError(error || 'Server error');
|
||||||
|
}
|
||||||
|
}
|
@@ -667,19 +667,19 @@ export class IdentityUserService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildUserUrl(): any {
|
private buildUserUrl(): string {
|
||||||
return `${this.appConfigService.get('identityHost')}/users`;
|
return `${this.appConfigService.get('identityHost')}/users`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildUserClientRoleMapping(userId: string, clientId: string): any {
|
private buildUserClientRoleMapping(userId: string, clientId: string): string {
|
||||||
return `${this.appConfigService.get('identityHost')}/users/${userId}/role-mappings/clients/${clientId}`;
|
return `${this.appConfigService.get('identityHost')}/users/${userId}/role-mappings/clients/${clientId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildRolesUrl(userId: string): any {
|
private buildRolesUrl(userId: string): string {
|
||||||
return `${this.appConfigService.get('identityHost')}/users/${userId}/role-mappings/realm/composite`;
|
return `${this.appConfigService.get('identityHost')}/users/${userId}/role-mappings/realm/composite`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildGetClientsUrl() {
|
private buildGetClientsUrl(): string {
|
||||||
return `${this.appConfigService.get('identityHost')}/clients`;
|
return `${this.appConfigService.get('identityHost')}/clients`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,17 +22,20 @@ import { ProcessServiceCloudTestingModule } from './../../testing/process-servic
|
|||||||
|
|
||||||
import { GroupCloudModule } from '../group-cloud.module';
|
import { GroupCloudModule } from '../group-cloud.module';
|
||||||
import { GroupCloudComponent } from './group-cloud.component';
|
import { GroupCloudComponent } from './group-cloud.component';
|
||||||
import { GroupCloudService } from '../services/group-cloud.service';
|
import {
|
||||||
import { setupTestBed, AlfrescoApiServiceMock } from '@alfresco/adf-core';
|
setupTestBed,
|
||||||
import { mockGroups } from '../mock/group-cloud.mock';
|
AlfrescoApiServiceMock,
|
||||||
import { GroupModel } from '../models/group.model';
|
IdentityGroupService,
|
||||||
|
IdentityGroupModel,
|
||||||
|
mockIdentityGroups
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
import { SimpleChange } from '@angular/core';
|
import { SimpleChange } from '@angular/core';
|
||||||
|
|
||||||
describe('GroupCloudComponent', () => {
|
describe('GroupCloudComponent', () => {
|
||||||
let component: GroupCloudComponent;
|
let component: GroupCloudComponent;
|
||||||
let fixture: ComponentFixture<GroupCloudComponent>;
|
let fixture: ComponentFixture<GroupCloudComponent>;
|
||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
let service: GroupCloudService;
|
let service: IdentityGroupService;
|
||||||
let findGroupsByNameSpy: jasmine.Spy;
|
let findGroupsByNameSpy: jasmine.Spy;
|
||||||
let getClientIdByApplicationNameSpy: jasmine.Spy;
|
let getClientIdByApplicationNameSpy: jasmine.Spy;
|
||||||
let checkGroupHasAccessSpy: jasmine.Spy;
|
let checkGroupHasAccessSpy: jasmine.Spy;
|
||||||
@@ -40,15 +43,15 @@ describe('GroupCloudComponent', () => {
|
|||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [ProcessServiceCloudTestingModule, GroupCloudModule],
|
imports: [ProcessServiceCloudTestingModule, GroupCloudModule],
|
||||||
providers: [AlfrescoApiServiceMock, GroupCloudService]
|
providers: [AlfrescoApiServiceMock, IdentityGroupService]
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(GroupCloudComponent);
|
fixture = TestBed.createComponent(GroupCloudComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
element = fixture.nativeElement;
|
element = fixture.nativeElement;
|
||||||
service = TestBed.get(GroupCloudService);
|
service = TestBed.get(IdentityGroupService);
|
||||||
findGroupsByNameSpy = spyOn(service, 'findGroupsByName').and.returnValue(of(mockGroups));
|
findGroupsByNameSpy = spyOn(service, 'findGroupsByName').and.returnValue(of(mockIdentityGroups));
|
||||||
getClientIdByApplicationNameSpy = spyOn(service, 'getClientIdByApplicationName').and.returnValue(of('mock-client-id'));
|
getClientIdByApplicationNameSpy = spyOn(service, 'getClientIdByApplicationName').and.returnValue(of('mock-client-id'));
|
||||||
checkGroupHasAccessSpy = spyOn(service, 'checkGroupHasClientApp').and.returnValue(of(true));
|
checkGroupHasAccessSpy = spyOn(service, 'checkGroupHasClientApp').and.returnValue(of(true));
|
||||||
checkGroupHasGivenRoleSpy = spyOn(service, 'checkGroupHasRole').and.returnValue(of(true));
|
checkGroupHasGivenRoleSpy = spyOn(service, 'checkGroupHasRole').and.returnValue(of(true));
|
||||||
@@ -72,7 +75,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
|
|
||||||
it('should show the groups if the typed result match', async(() => {
|
it('should show the groups if the typed result match', async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
component.searchGroups$ = of(<GroupModel[]> mockGroups);
|
component.searchGroups$.next(<IdentityGroupModel[]> mockIdentityGroups);
|
||||||
const inputHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('input');
|
const inputHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('input');
|
||||||
inputHTMLElement.focus();
|
inputHTMLElement.focus();
|
||||||
inputHTMLElement.dispatchEvent(new Event('input'));
|
inputHTMLElement.dispatchEvent(new Event('input'));
|
||||||
@@ -103,7 +106,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
it('should emit selectedGroup if option is valid', async(() => {
|
it('should emit selectedGroup if option is valid', async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const selectEmitSpy = spyOn(component.selectGroup, 'emit');
|
const selectEmitSpy = spyOn(component.selectGroup, 'emit');
|
||||||
component.onSelect(new GroupModel({ name: 'group name'}));
|
component.onSelect(new IdentityGroupModel({ name: 'group name'}));
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
expect(selectEmitSpy).toHaveBeenCalled();
|
expect(selectEmitSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@@ -147,7 +150,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
|
|
||||||
it('should pre-select all preSelectGroups when mode=multiple', async(() => {
|
it('should pre-select all preSelectGroups when mode=multiple', async(() => {
|
||||||
component.mode = 'multiple';
|
component.mode = 'multiple';
|
||||||
component.preSelectGroups = <any> [{id: mockGroups[1].id}, {id: mockGroups[2].id}];
|
component.preSelectGroups = <any> [{id: mockIdentityGroups[1].id}, {id: mockIdentityGroups[2].id}];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -168,11 +171,11 @@ describe('GroupCloudComponent', () => {
|
|||||||
|
|
||||||
it('should pre-select preSelectGroups[0] when mode=single', async(() => {
|
it('should pre-select preSelectGroups[0] when mode=single', async(() => {
|
||||||
component.mode = 'single';
|
component.mode = 'single';
|
||||||
component.preSelectGroups = <any> [{id: mockGroups[1].id}, {id: mockGroups[2].id}];
|
component.preSelectGroups = <any> [{id: mockIdentityGroups[1].id}, {id: mockIdentityGroups[2].id}];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
const selectedGroup = component.searchGroupsControl.value;
|
const selectedGroup = component.searchGroupsControl.value;
|
||||||
expect(selectedGroup.id).toBe(mockGroups[1].id);
|
expect(selectedGroup.id).toBe(mockIdentityGroups[1].id);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -189,7 +192,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
const removeGroupSpy = spyOn(component.removeGroup, 'emit');
|
const removeGroupSpy = spyOn(component.removeGroup, 'emit');
|
||||||
|
|
||||||
component.mode = 'multiple';
|
component.mode = 'multiple';
|
||||||
component.preSelectGroups = <any> [{id: mockGroups[1].id}, {id: mockGroups[2].id}];
|
component.preSelectGroups = <any> [{id: mockIdentityGroups[1].id}, {id: mockIdentityGroups[2].id}];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
@@ -197,7 +200,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
const removeIcon = fixture.debugElement.query(By.css('mat-chip mat-icon'));
|
const removeIcon = fixture.debugElement.query(By.css('mat-chip mat-icon'));
|
||||||
removeIcon.nativeElement.click();
|
removeIcon.nativeElement.click();
|
||||||
|
|
||||||
expect(removeGroupSpy).toHaveBeenCalledWith({ id: mockGroups[1].id });
|
expect(removeGroupSpy).toHaveBeenCalledWith({ id: mockIdentityGroups[1].id });
|
||||||
});
|
});
|
||||||
|
|
||||||
}));
|
}));
|
||||||
@@ -213,7 +216,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const groupsList = fixture.debugElement.queryAll(By.css('mat-option'));
|
const groupsList = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||||
expect(groupsList.length).toBe(mockGroups.length);
|
expect(groupsList.length).toBe(mockIdentityGroups.length);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -246,7 +249,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const groupsList = fixture.debugElement.queryAll(By.css('mat-option'));
|
const groupsList = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||||
expect(groupsList.length).toBe(mockGroups.length);
|
expect(groupsList.length).toBe(mockIdentityGroups.length);
|
||||||
expect(checkGroupHasGivenRoleSpy).toHaveBeenCalled();
|
expect(checkGroupHasGivenRoleSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
@@ -263,13 +266,13 @@ describe('GroupCloudComponent', () => {
|
|||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const groupsList = fixture.debugElement.queryAll(By.css('mat-option'));
|
const groupsList = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||||
expect(groupsList.length).toBe(mockGroups.length);
|
expect(groupsList.length).toBe(mockIdentityGroups.length);
|
||||||
expect(checkGroupHasGivenRoleSpy).not.toHaveBeenCalled();
|
expect(checkGroupHasGivenRoleSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should validate access to the app when appName is specified', async(() => {
|
it('should validate access to the app when appName is specified', async(() => {
|
||||||
findGroupsByNameSpy.and.returnValue(of(mockGroups));
|
findGroupsByNameSpy.and.returnValue(of(mockIdentityGroups));
|
||||||
checkGroupHasAccessSpy.and.returnValue(of(true));
|
checkGroupHasAccessSpy.and.returnValue(of(true));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const inputHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('input');
|
const inputHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('input');
|
||||||
@@ -279,7 +282,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(checkGroupHasAccessSpy).toHaveBeenCalledTimes(mockGroups.length);
|
expect(checkGroupHasAccessSpy).toHaveBeenCalledTimes(mockIdentityGroups.length);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@@ -25,15 +25,15 @@ import {
|
|||||||
ViewEncapsulation,
|
ViewEncapsulation,
|
||||||
Input,
|
Input,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
OnChanges
|
OnChanges,
|
||||||
|
OnDestroy
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { FormControl } from '@angular/forms';
|
import { FormControl } from '@angular/forms';
|
||||||
import { trigger, state, style, transition, animate } from '@angular/animations';
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||||
import { Observable, of, BehaviorSubject } from 'rxjs';
|
import { Observable, of, BehaviorSubject, Subject } from 'rxjs';
|
||||||
import { GroupModel, GroupSearchParam } from '../models/group.model';
|
|
||||||
import { GroupCloudService } from '../services/group-cloud.service';
|
|
||||||
import { debounceTime } from 'rxjs/internal/operators/debounceTime';
|
import { debounceTime } from 'rxjs/internal/operators/debounceTime';
|
||||||
import { distinctUntilChanged, switchMap, mergeMap, filter, tap, map } from 'rxjs/operators';
|
import { distinctUntilChanged, switchMap, mergeMap, filter, tap, map, takeUntil } from 'rxjs/operators';
|
||||||
|
import { IdentityGroupModel, IdentityGroupSearchParam, IdentityGroupService } from '@alfresco/adf-core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-cloud-group',
|
selector: 'adf-cloud-group',
|
||||||
@@ -50,7 +50,7 @@ import { distinctUntilChanged, switchMap, mergeMap, filter, tap, map } from 'rxj
|
|||||||
],
|
],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class GroupCloudComponent implements OnInit, OnChanges {
|
export class GroupCloudComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
static MODE_SINGLE = 'single';
|
static MODE_SINGLE = 'single';
|
||||||
static MODE_MULTIPLE = 'multiple';
|
static MODE_MULTIPLE = 'multiple';
|
||||||
@@ -69,7 +69,7 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
/** Array of users to be pre-selected. This pre-selects all users in multi selection mode and only the first user of the array in single selection mode. */
|
/** Array of users to be pre-selected. This pre-selects all users in multi selection mode and only the first user of the array in single selection mode. */
|
||||||
@Input()
|
@Input()
|
||||||
preSelectGroups: GroupModel[] = [];
|
preSelectGroups: IdentityGroupModel[] = [];
|
||||||
|
|
||||||
/** FormControl to search the group */
|
/** FormControl to search the group */
|
||||||
@Input()
|
@Input()
|
||||||
@@ -81,26 +81,22 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
/** Emitted when a group is selected. */
|
/** Emitted when a group is selected. */
|
||||||
@Output()
|
@Output()
|
||||||
selectGroup: EventEmitter<GroupModel> = new EventEmitter<GroupModel>();
|
selectGroup = new EventEmitter<IdentityGroupModel>();
|
||||||
|
|
||||||
/** Emitted when a group is removed. */
|
/** Emitted when a group is removed. */
|
||||||
@Output()
|
@Output()
|
||||||
removeGroup: EventEmitter<GroupModel> = new EventEmitter<GroupModel>();
|
removeGroup = new EventEmitter<IdentityGroupModel>();
|
||||||
|
|
||||||
@ViewChild('groupInput')
|
@ViewChild('groupInput')
|
||||||
private groupInput: ElementRef<HTMLInputElement>;
|
private groupInput: ElementRef<HTMLInputElement>;
|
||||||
|
|
||||||
private selectedGroups: GroupModel[] = [];
|
private selectedGroups: IdentityGroupModel[] = [];
|
||||||
|
|
||||||
private searchGroups: GroupModel[] = [];
|
private searchGroups: IdentityGroupModel[] = [];
|
||||||
|
|
||||||
private searchGroupsSubject: BehaviorSubject<GroupModel[]>;
|
searchGroups$ = new BehaviorSubject<IdentityGroupModel[]>([]);
|
||||||
|
|
||||||
private selectedGroupsSubject: BehaviorSubject<GroupModel[]>;
|
selectedGroups$ = new BehaviorSubject<IdentityGroupModel[]>([]);
|
||||||
|
|
||||||
searchGroups$: Observable<GroupModel[]>;
|
|
||||||
|
|
||||||
selectedGroups$: Observable<GroupModel[]>;
|
|
||||||
|
|
||||||
_subscriptAnimationState = 'enter';
|
_subscriptAnimationState = 'enter';
|
||||||
|
|
||||||
@@ -112,12 +108,9 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
isDisabled: boolean;
|
isDisabled: boolean;
|
||||||
|
|
||||||
constructor(private groupService: GroupCloudService) {
|
private onDestroy$ = new Subject<boolean>();
|
||||||
this.selectedGroupsSubject = new BehaviorSubject<GroupModel[]>(this.selectedGroups);
|
|
||||||
this.searchGroupsSubject = new BehaviorSubject<GroupModel[]>(this.searchGroups);
|
constructor(private identityGroupService: IdentityGroupService) { }
|
||||||
this.selectedGroups$ = this.selectedGroupsSubject.asObservable();
|
|
||||||
this.searchGroups$ = this.searchGroupsSubject.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.initSearch();
|
this.initSearch();
|
||||||
@@ -136,12 +129,12 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private isAppNameChanged(change) {
|
private isAppNameChanged(change): boolean {
|
||||||
return change.previousValue !== change.currentValue && this.appName && this.appName.length > 0;
|
return change.previousValue !== change.currentValue && this.appName && this.appName.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadClientId() {
|
private async loadClientId() {
|
||||||
this.clientId = await this.groupService.getClientIdByApplicationName(this.appName).toPromise();
|
this.clientId = await this.identityGroupService.getClientIdByApplicationName(this.appName).toPromise();
|
||||||
if (this.clientId) {
|
if (this.clientId) {
|
||||||
this.enableSearch();
|
this.enableSearch();
|
||||||
}
|
}
|
||||||
@@ -165,7 +158,7 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
}),
|
}),
|
||||||
switchMap((inputValue) => {
|
switchMap((inputValue) => {
|
||||||
const queryParams = this.createSearchParam(inputValue);
|
const queryParams = this.createSearchParam(inputValue);
|
||||||
return this.groupService.findGroupsByName(queryParams);
|
return this.identityGroupService.findGroupsByName(queryParams);
|
||||||
}),
|
}),
|
||||||
mergeMap((groups) => {
|
mergeMap((groups) => {
|
||||||
return groups;
|
return groups;
|
||||||
@@ -185,23 +178,24 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
} else {
|
} else {
|
||||||
return of(group);
|
return of(group);
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
).subscribe((searchedGroup) => {
|
takeUntil(this.onDestroy$)
|
||||||
|
).subscribe((searchedGroup: any) => {
|
||||||
this.searchGroups.push(searchedGroup);
|
this.searchGroups.push(searchedGroup);
|
||||||
this.searchGroupsSubject.next(this.searchGroups);
|
this.searchGroups$.next(this.searchGroups);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
checkGroupHasAccess(groupId: string): Observable<boolean> {
|
checkGroupHasAccess(groupId: string): Observable<boolean> {
|
||||||
if (this.hasRoles()) {
|
if (this.hasRoles()) {
|
||||||
return this.groupService.checkGroupHasAnyClientAppRole(groupId, this.clientId, this.roles);
|
return this.identityGroupService.checkGroupHasAnyClientAppRole(groupId, this.clientId, this.roles);
|
||||||
} else {
|
} else {
|
||||||
return this.groupService.checkGroupHasClientApp(groupId, this.clientId);
|
return this.identityGroupService.checkGroupHasClientApp(groupId, this.clientId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isGroupAlreadySelected(group: GroupModel): boolean {
|
isGroupAlreadySelected(group: IdentityGroupModel): boolean {
|
||||||
const result = this.selectedGroups.find((selectedGroup: GroupModel) => {
|
const result = this.selectedGroups.find((selectedGroup: IdentityGroupModel) => {
|
||||||
return selectedGroup.id === group.id;
|
return selectedGroup.id === group.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -211,30 +205,30 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
private loadPreSelectGroups() {
|
private loadPreSelectGroups() {
|
||||||
if (this.isMultipleMode()) {
|
if (this.isMultipleMode()) {
|
||||||
this.selectedGroups = [];
|
this.selectedGroups = [];
|
||||||
this.preSelectGroups.forEach((group: GroupModel) => {
|
this.preSelectGroups.forEach((group: IdentityGroupModel) => {
|
||||||
this.selectedGroups.push(group);
|
this.selectedGroups.push(group);
|
||||||
});
|
});
|
||||||
this.selectedGroupsSubject.next(this.selectedGroups);
|
this.selectedGroups$.next(this.selectedGroups);
|
||||||
} else {
|
} else {
|
||||||
this.searchGroupsControl.setValue(this.preSelectGroups[0]);
|
this.searchGroupsControl.setValue(this.preSelectGroups[0]);
|
||||||
this.onSelect(this.preSelectGroups[0]);
|
this.onSelect(this.preSelectGroups[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filterGroupsByRoles(group: GroupModel): Observable<GroupModel> {
|
filterGroupsByRoles(group: IdentityGroupModel): Observable<IdentityGroupModel> {
|
||||||
return this.groupService.checkGroupHasRole(group.id, this.roles).pipe(
|
return this.identityGroupService.checkGroupHasRole(group.id, this.roles).pipe(
|
||||||
map((hasRole: boolean) => ({ hasRole: hasRole, group: group })),
|
map((hasRole: boolean) => ({ hasRole: hasRole, group: group })),
|
||||||
filter((filteredGroup: { hasRole: boolean, group: GroupModel }) => filteredGroup.hasRole),
|
filter((filteredGroup: { hasRole: boolean, group: IdentityGroupModel }) => filteredGroup.hasRole),
|
||||||
map((filteredGroup: { hasRole: boolean, group: GroupModel }) => filteredGroup.group));
|
map((filteredGroup: { hasRole: boolean, group: IdentityGroupModel }) => filteredGroup.group));
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelect(selectedGroup: GroupModel) {
|
onSelect(selectedGroup: IdentityGroupModel) {
|
||||||
if (this.isMultipleMode()) {
|
if (this.isMultipleMode()) {
|
||||||
if (!this.isGroupAlreadySelected(selectedGroup)) {
|
if (!this.isGroupAlreadySelected(selectedGroup)) {
|
||||||
this.selectedGroups.push(selectedGroup);
|
this.selectedGroups.push(selectedGroup);
|
||||||
this.selectedGroupsSubject.next(this.selectedGroups);
|
this.selectedGroups$.next(this.selectedGroups);
|
||||||
this.selectGroup.emit(selectedGroup);
|
this.selectGroup.emit(selectedGroup);
|
||||||
this.searchGroupsSubject.next([]);
|
this.searchGroups$.next([]);
|
||||||
}
|
}
|
||||||
this.groupInput.nativeElement.value = '';
|
this.groupInput.nativeElement.value = '';
|
||||||
this.searchGroupsControl.setValue('');
|
this.searchGroupsControl.setValue('');
|
||||||
@@ -246,25 +240,25 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
this.resetSearchGroups();
|
this.resetSearchGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove(selectedGroup: GroupModel) {
|
onRemove(selectedGroup: IdentityGroupModel) {
|
||||||
this.removeGroup.emit(selectedGroup);
|
this.removeGroup.emit(selectedGroup);
|
||||||
const indexToRemove = this.selectedGroups.findIndex((group: GroupModel) => {
|
const indexToRemove = this.selectedGroups.findIndex((group: IdentityGroupModel) => {
|
||||||
return group.id === selectedGroup.id;
|
return group.id === selectedGroup.id;
|
||||||
});
|
});
|
||||||
this.selectedGroups.splice(indexToRemove, 1);
|
this.selectedGroups.splice(indexToRemove, 1);
|
||||||
this.selectedGroupsSubject.next(this.selectedGroups);
|
this.selectedGroups$.next(this.selectedGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
private resetSearchGroups() {
|
private resetSearchGroups() {
|
||||||
this.searchGroups = [];
|
this.searchGroups = [];
|
||||||
this.searchGroupsSubject.next([]);
|
this.searchGroups$.next([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
isMultipleMode(): boolean {
|
isMultipleMode(): boolean {
|
||||||
return this.mode === GroupCloudComponent.MODE_MULTIPLE;
|
return this.mode === GroupCloudComponent.MODE_MULTIPLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDisplayName(group: GroupModel): string {
|
getDisplayName(group: IdentityGroupModel): string {
|
||||||
return group ? group.name : '';
|
return group ? group.name : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,8 +266,8 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
return this.preSelectGroups && this.preSelectGroups.length > 0;
|
return this.preSelectGroups && this.preSelectGroups.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createSearchParam(value: string): GroupSearchParam {
|
private createSearchParam(value: string): IdentityGroupSearchParam {
|
||||||
const queryParams: GroupSearchParam = { name: value };
|
const queryParams: IdentityGroupSearchParam = { name: value };
|
||||||
return queryParams;
|
return queryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,4 +304,9 @@ export class GroupCloudComponent implements OnInit, OnChanges {
|
|||||||
hasErrorMessage(): boolean {
|
hasErrorMessage(): boolean {
|
||||||
return !this.isFocused && this.hasError();
|
return !this.isFocused && this.hasError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.onDestroy$.next(true);
|
||||||
|
this.onDestroy$.complete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,112 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { GroupModel, GroupRoleModel } from '../models/group.model';
|
|
||||||
|
|
||||||
export let mockGroup1 = new GroupModel({
|
|
||||||
id: 'mock-id-1', name: 'Mock Group 1', path: '/mock', subGroups: []
|
|
||||||
});
|
|
||||||
|
|
||||||
export let mockGroup2 = new GroupModel({
|
|
||||||
id: 'mock-id-2', name: 'Mock Group 2', path: '', subGroups: []
|
|
||||||
});
|
|
||||||
|
|
||||||
export let mockGroup3 = new GroupModel({
|
|
||||||
id: 'mock-id-3', name: 'Fake Group 3', path: '', subGroups: []
|
|
||||||
});
|
|
||||||
|
|
||||||
export let mockGroups = [
|
|
||||||
mockGroup1, mockGroup2, mockGroup3
|
|
||||||
];
|
|
||||||
|
|
||||||
export let mockApplicationDetails = {id: 'mock-app-id', name: 'mock-app-name'};
|
|
||||||
|
|
||||||
export let mockError = {
|
|
||||||
error: {
|
|
||||||
errorKey: 'failed',
|
|
||||||
statusCode: 400,
|
|
||||||
stackTrace: 'For security reasons the stack trace is no longer displayed, but the property is kept for previous versions.'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let mockApiError = {
|
|
||||||
oauth2Auth: {
|
|
||||||
callCustomApi: () => {
|
|
||||||
return Promise.reject(mockError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let roleMappingMock = [
|
|
||||||
{ id: 'role-id-1', name: 'role-name-1' }, { id: 'role-id-2', name: 'role-name-2' }
|
|
||||||
];
|
|
||||||
|
|
||||||
export let roleMappingApi = {
|
|
||||||
oauth2Auth: {
|
|
||||||
callCustomApi: () => {
|
|
||||||
return Promise.resolve(roleMappingMock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let noRoleMappingApi = {
|
|
||||||
oauth2Auth: {
|
|
||||||
callCustomApi: () => {
|
|
||||||
return Promise.resolve([]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let groupsMockApi = {
|
|
||||||
oauth2Auth: {
|
|
||||||
callCustomApi: () => {
|
|
||||||
return Promise.resolve(mockGroups);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let returnCallQueryParameters = {
|
|
||||||
oauth2Auth: {
|
|
||||||
callCustomApi: (queryUrl, operation, context, queryParams) => {
|
|
||||||
return Promise.resolve(queryParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let returnCallUrl = {
|
|
||||||
oauth2Auth: {
|
|
||||||
callCustomApi: (queryUrl, operation, context, queryParams) => {
|
|
||||||
return Promise.resolve(queryUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let applicationDetailsMockApi = {
|
|
||||||
oauth2Auth: {
|
|
||||||
callCustomApi: () => {
|
|
||||||
return Promise.resolve([mockApplicationDetails]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let groupRoles = [
|
|
||||||
new GroupRoleModel({id: 'mock-id', name: 'MOCK-ADMIN-ROLE'}),
|
|
||||||
new GroupRoleModel({id: 'mock-id', name: 'MOCK-USER-ROLE'}),
|
|
||||||
new GroupRoleModel({id: 'mock-id', name: 'MOCK-ROLE-1'})
|
|
||||||
];
|
|
||||||
|
|
||||||
export let clientRoles = [ 'MOCK-ADMIN-ROLE', 'MOCK-USER-ROLE'];
|
|
@@ -1,54 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class GroupModel {
|
|
||||||
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
path: string;
|
|
||||||
realmRoles: string[];
|
|
||||||
access: any;
|
|
||||||
attributes: any;
|
|
||||||
clientRoles: any;
|
|
||||||
|
|
||||||
constructor(obj?: any) {
|
|
||||||
this.id = obj.id || null;
|
|
||||||
this.name = obj.name || null;
|
|
||||||
this.path = obj.path || null;
|
|
||||||
this.realmRoles = obj.realmRoles || null;
|
|
||||||
this.access = obj.access || null;
|
|
||||||
this.attributes = obj.attributes || null;
|
|
||||||
this.clientRoles = obj.clientRoles || null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GroupSearchParam {
|
|
||||||
name?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class GroupRoleModel {
|
|
||||||
|
|
||||||
id?: string;
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
constructor(obj?: any) {
|
|
||||||
if (obj) {
|
|
||||||
this.id = obj.id || null;
|
|
||||||
this.name = obj.name || null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -16,16 +16,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { InitialGroupNamePipe } from './group-initial.pipe';
|
import { InitialGroupNamePipe } from './group-initial.pipe';
|
||||||
import { GroupModel } from '../models/group.model';
|
import { IdentityGroupModel } from '@alfresco/adf-core';
|
||||||
|
|
||||||
describe('InitialGroupNamePipe', () => {
|
describe('InitialGroupNamePipe', () => {
|
||||||
|
|
||||||
let pipe: InitialGroupNamePipe;
|
let pipe: InitialGroupNamePipe;
|
||||||
let fakeGroup: GroupModel;
|
let fakeGroup: IdentityGroupModel;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
pipe = new InitialGroupNamePipe();
|
pipe = new InitialGroupNamePipe();
|
||||||
fakeGroup = new GroupModel({name: 'mock'});
|
fakeGroup = new IdentityGroupModel({name: 'mock'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return with the group initial', () => {
|
it('should return with the group initial', () => {
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Pipe, PipeTransform } from '@angular/core';
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
import { GroupModel } from '../models/group.model';
|
import { IdentityGroupModel } from '@alfresco/adf-core';
|
||||||
|
|
||||||
@Pipe({
|
@Pipe({
|
||||||
name: 'groupNameInitial'
|
name: 'groupNameInitial'
|
||||||
@@ -25,7 +25,7 @@ export class InitialGroupNamePipe implements PipeTransform {
|
|||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
transform(group: GroupModel): string {
|
transform(group: IdentityGroupModel): string {
|
||||||
let result = '';
|
let result = '';
|
||||||
if (group) {
|
if (group) {
|
||||||
result = this.getInitialGroupName(group.name).toUpperCase();
|
result = this.getInitialGroupName(group.name).toUpperCase();
|
||||||
|
@@ -15,7 +15,5 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './models/group.model';
|
|
||||||
export * from './services/group-cloud.service';
|
|
||||||
export * from './components/group-cloud.component';
|
export * from './components/group-cloud.component';
|
||||||
export * from './group-cloud.module';
|
export * from './group-cloud.module';
|
||||||
|
@@ -1,212 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { from, of, Observable, throwError } from 'rxjs';
|
|
||||||
import { map, catchError } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { AlfrescoApiService, AppConfigService, LogService } from '@alfresco/adf-core';
|
|
||||||
import { GroupSearchParam, GroupRoleModel } from '../models/group.model';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class GroupCloudService {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private apiService: AlfrescoApiService,
|
|
||||||
private appConfigService: AppConfigService,
|
|
||||||
private logService: LogService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds groups filtered by name.
|
|
||||||
* @param searchParams Object containing the name filter string
|
|
||||||
* @returns List of group information
|
|
||||||
*/
|
|
||||||
findGroupsByName(searchParams: GroupSearchParam): Observable<any> {
|
|
||||||
if (searchParams.name === '') {
|
|
||||||
return of([]);
|
|
||||||
}
|
|
||||||
const url = this.getGroupsApi();
|
|
||||||
const httpMethod = 'GET', pathParams = {}, queryParams = {search: searchParams.name}, bodyParam = {}, headerParams = {},
|
|
||||||
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
|
||||||
|
|
||||||
return (from(this.apiService.getInstance().oauth2Auth.callCustomApi(
|
|
||||||
url, httpMethod, pathParams, queryParams,
|
|
||||||
headerParams, formParams, bodyParam,
|
|
||||||
contentTypes, accepts, Object, null, null)
|
|
||||||
)).pipe(
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets details for a specified group.
|
|
||||||
* @param groupId ID of the target group
|
|
||||||
* @returns Group details
|
|
||||||
*/
|
|
||||||
getGroupRoles(groupId: string): Observable<GroupRoleModel[]> {
|
|
||||||
const url = this.buildRolesUrl(groupId);
|
|
||||||
const httpMethod = 'GET', pathParams = {}, queryParams = {}, bodyParam = {}, headerParams = {},
|
|
||||||
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
|
||||||
|
|
||||||
return (from(this.apiService.getInstance().oauth2Auth.callCustomApi(
|
|
||||||
url, httpMethod, pathParams, queryParams,
|
|
||||||
headerParams, formParams, bodyParam,
|
|
||||||
contentTypes, accepts, Object, null, null)
|
|
||||||
)).pipe(
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that a group has one or more roles from the supplied list.
|
|
||||||
* @param groupId ID of the target group
|
|
||||||
* @param roleNames Array of role names
|
|
||||||
* @returns True if the group has one or more of the roles, false otherwise
|
|
||||||
*/
|
|
||||||
checkGroupHasRole(groupId: string, roleNames: string[]): Observable<boolean> {
|
|
||||||
return this.getGroupRoles(groupId).pipe(map((groupRoles: GroupRoleModel[]) => {
|
|
||||||
let hasRole = false;
|
|
||||||
if (groupRoles && groupRoles.length > 0) {
|
|
||||||
roleNames.forEach((roleName: string) => {
|
|
||||||
const role = groupRoles.find((groupRole) => {
|
|
||||||
return roleName === groupRole.name;
|
|
||||||
});
|
|
||||||
if (role) {
|
|
||||||
hasRole = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return hasRole;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the client ID using the app name.
|
|
||||||
* @param applicationName Name of the app
|
|
||||||
* @returns client ID string
|
|
||||||
*/
|
|
||||||
getClientIdByApplicationName(applicationName: string): Observable<string> {
|
|
||||||
const url = this.getApplicationIdApi();
|
|
||||||
const httpMethod = 'GET', pathParams = {}, queryParams = {clientId: applicationName}, bodyParam = {}, headerParams = {}, formParams = {},
|
|
||||||
contentTypes = ['application/json'], accepts = ['application/json'];
|
|
||||||
return from(this.apiService.getInstance()
|
|
||||||
.oauth2Auth.callCustomApi(url, httpMethod, pathParams, queryParams, headerParams,
|
|
||||||
formParams, bodyParam, contentTypes,
|
|
||||||
accepts, Object, null, null)
|
|
||||||
).pipe(
|
|
||||||
map((response: any[]) => {
|
|
||||||
const clientId = response && response.length > 0 ? response[0].id : '';
|
|
||||||
return clientId;
|
|
||||||
}),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets client roles.
|
|
||||||
* @param groupId ID of the target group
|
|
||||||
* @param clientId ID of the client
|
|
||||||
* @returns List of roles
|
|
||||||
*/
|
|
||||||
getClientRoles(groupId: string, clientId: string): Observable<any[]> {
|
|
||||||
const url = this.groupClientRoleMappingApi(groupId, clientId);
|
|
||||||
const httpMethod = 'GET', pathParams = {}, queryParams = {}, bodyParam = {}, headerParams = {},
|
|
||||||
formParams = {}, contentTypes = ['application/json'], accepts = ['application/json'];
|
|
||||||
|
|
||||||
return from(this.apiService.getInstance().oauth2Auth.callCustomApi(
|
|
||||||
url, httpMethod, pathParams, queryParams,
|
|
||||||
headerParams, formParams, bodyParam,
|
|
||||||
contentTypes, accepts, Object, null, null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a group has a client app.
|
|
||||||
* @param groupId ID of the target group
|
|
||||||
* @param clientId ID of the client
|
|
||||||
* @returns True if the group has the client app, false otherwise
|
|
||||||
*/
|
|
||||||
checkGroupHasClientApp(groupId: string, clientId: string): Observable<boolean> {
|
|
||||||
return this.getClientRoles(groupId, clientId).pipe(
|
|
||||||
map((response: any[]) => {
|
|
||||||
if (response && response.length > 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a group has any of the client app roles in the supplied list.
|
|
||||||
* @param groupId ID of the target group
|
|
||||||
* @param clientId ID of the client
|
|
||||||
* @param roleNames Array of role names to check
|
|
||||||
* @returns True if the group has one or more of the roles, false otherwise
|
|
||||||
*/
|
|
||||||
checkGroupHasAnyClientAppRole(groupId: string, clientId: string, roleNames: string[]): Observable<boolean> {
|
|
||||||
return this.getClientRoles(groupId, clientId).pipe(
|
|
||||||
map((clientRoles: any[]) => {
|
|
||||||
let hasRole = false;
|
|
||||||
if (clientRoles.length > 0) {
|
|
||||||
roleNames.forEach((roleName) => {
|
|
||||||
const role = clientRoles.find((availableRole) => {
|
|
||||||
return availableRole.name === roleName;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (role) {
|
|
||||||
hasRole = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return hasRole;
|
|
||||||
}),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private groupClientRoleMappingApi(groupId: string, clientId: string): any {
|
|
||||||
return `${this.appConfigService.get('identityHost')}/groups/${groupId}/role-mappings/clients/${clientId}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getApplicationIdApi() {
|
|
||||||
return `${this.appConfigService.get('identityHost')}/clients`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getGroupsApi() {
|
|
||||||
return `${this.appConfigService.get('identityHost')}/groups`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildRolesUrl(groupId: string): any {
|
|
||||||
return `${this.appConfigService.get('identityHost')}/groups/${groupId}/role-mappings/realm/composite`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throw the error
|
|
||||||
* @param error
|
|
||||||
*/
|
|
||||||
private handleError(error: Response) {
|
|
||||||
this.logService.error(error);
|
|
||||||
return throwError(error || 'Server error');
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user