/*! * @license * Copyright 2016 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 } from 'rxjs/Observable'; import { AlfrescoApiService, SearchService, NodesApiService } from '@alfresco/adf-core'; import { QueryBody, MinimalNodeEntryEntity, MinimalNodeEntity, PathElement, GroupMemberEntry, GroupsPaging, GroupMemberPaging, PermissionElement } from 'alfresco-js-api'; import 'rxjs/add/operator/switchMap'; import { of } from 'rxjs/observable/of'; import { switchMap } from 'rxjs/operators'; @Injectable() export class NodePermissionService { constructor(private apiService: AlfrescoApiService, private searchApiService: SearchService, private nodeService: NodesApiService) { } getNodeRoles(node: MinimalNodeEntryEntity): Observable { const retrieveSiteQueryBody: QueryBody = this.buildRetrieveSiteQueryBody(node.path.elements); return this.searchApiService.searchByQueryBody(retrieveSiteQueryBody) .switchMap((siteNodeList: any) => { if ( siteNodeList.list.entries.length > 0 ) { let siteName = siteNodeList.list.entries[0].entry.name; return this.getGroupMembersBySiteName(siteName); } else { return Observable.of(node.permissions.settable); } }); } updatePermissionRole(node: MinimalNodeEntryEntity, updatedPermissionRole: PermissionElement): Observable { let permissionBody = { permissions: { locallySet: []} }; const index = node.permissions.locallySet.map((permission) => permission.authorityId).indexOf(updatedPermissionRole.authorityId); permissionBody.permissions.locallySet = permissionBody.permissions.locallySet.concat(node.permissions.locallySet); if (index !== -1) { permissionBody.permissions.locallySet[index] = updatedPermissionRole; } else { permissionBody.permissions.locallySet.push(updatedPermissionRole); } return this.nodeService.updateNode(node.id, permissionBody); } updateNodePermissions(nodeId: string, permissionList: MinimalNodeEntity[]): Observable { return this.nodeService.getNode(nodeId).pipe( switchMap(node => { return this.getNodeRoles(node).pipe( switchMap((nodeRoles) => of({node, nodeRoles}) ) ); }), switchMap(({node, nodeRoles}) => this.updateLocallySetPermissions(node, permissionList, nodeRoles)) ); } updateLocallySetPermissions(node: MinimalNodeEntryEntity, nodes: MinimalNodeEntity[], nodeRole: string[]): Observable { let permissionBody = { permissions: { locallySet: []} }; const permissionList = this.transformNodeToPermissionElement(nodes, nodeRole[0]); permissionBody.permissions.locallySet = node.permissions.locallySet ? node.permissions.locallySet.concat(permissionList) : permissionList; return this.nodeService.updateNode(node.id, permissionBody); } private transformNodeToPermissionElement(nodes: MinimalNodeEntity[], nodeRole: any): PermissionElement[] { return nodes.map((node) => { let newPermissionElement: PermissionElement = { 'authorityId': node.entry.properties['cm:authorityName'] ? node.entry.properties['cm:authorityName'] : node.entry.properties['cm:userName'], 'name': nodeRole, 'accessStatus': 'ALLOWED' }; return newPermissionElement; }); } removePermission(node: MinimalNodeEntryEntity, permissionToRemove: PermissionElement): Observable { let permissionBody = { permissions: { locallySet: [] } }; const index = node.permissions.locallySet.map((permission) => permission.authorityId).indexOf(permissionToRemove.authorityId); if (index !== -1) { node.permissions.locallySet.splice(index, 1); permissionBody.permissions.locallySet = node.permissions.locallySet; return this.nodeService.updateNode(node.id, permissionBody); } } private getGroupMembersBySiteName(siteName: string): Observable { const groupName = 'GROUP_site_' + siteName; return this.getGroupMemeberByGroupName(groupName) .map((res: GroupsPaging) => { let displayResult: string[] = []; res.list.entries.forEach((member: GroupMemberEntry) => { displayResult.push(this.formattedRoleName(member.entry.displayName, 'site_' + siteName)); }); return displayResult; }); } getGroupMemeberByGroupName(groupName: string, opts?: any): Observable { return Observable.fromPromise(this.apiService.groupsApi.getGroupMembers(groupName, opts)); } private formattedRoleName(displayName, siteName): string { return displayName.replace(siteName + '_', ''); } private buildRetrieveSiteQueryBody(nodePath: PathElement[]): QueryBody { const pathNames = nodePath.map((node: PathElement) => 'name: "' + node.name + '"'); const buildedPathNames = pathNames.join(' OR '); return { 'query': { 'query': buildedPathNames }, 'paging': { 'maxItems': 100, 'skipCount': 0 }, 'include': ['aspectNames', 'properties'], 'filterQueries': [ { 'query': "TYPE:'st:site'" } ] }; } }