001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Thomas Roger 016 */ 017 018package org.nuxeo.ecm.admin.permissions; 019 020import java.io.Serializable; 021import java.util.ArrayList; 022import java.util.List; 023import java.util.Map; 024 025import org.nuxeo.ecm.core.api.DocumentModel; 026import org.nuxeo.ecm.core.api.DocumentRef; 027import org.nuxeo.ecm.core.api.IdRef; 028import org.nuxeo.ecm.core.api.IterableQueryResult; 029import org.nuxeo.ecm.core.api.security.ACP; 030import org.nuxeo.ecm.core.query.sql.NXQL; 031import org.nuxeo.ecm.core.work.AbstractWork; 032import org.nuxeo.ecm.platform.query.api.PageProviderDefinition; 033import org.nuxeo.ecm.platform.query.api.PageProviderService; 034import org.nuxeo.ecm.platform.query.nxql.NXQLQueryBuilder; 035import org.nuxeo.runtime.api.Framework; 036import org.nuxeo.runtime.transaction.TransactionRuntimeException; 037 038/** 039 * @since 7.4 040 */ 041public class PermissionsPurgeWork extends AbstractWork { 042 043 public static final int DEFAULT_BATCH_SIZE = 20; 044 045 public static final String CATEGORY = "permissionsPurge"; 046 047 protected DocumentModel searchDocument; 048 049 protected int batchSize = DEFAULT_BATCH_SIZE; 050 051 public PermissionsPurgeWork(DocumentModel searchDocument) { 052 this.searchDocument = searchDocument; 053 } 054 055 @Override 056 public String getTitle() { 057 return String.format("Permissions purge for: %s, %s", searchDocument.getPropertyValue("rs:ace_username"), 058 searchDocument.getPropertyValue("rs:ecm_path")); 059 } 060 061 @Override 062 public String getCategory() { 063 return CATEGORY; 064 } 065 066 @Override 067 public void work() { 068 setStatus("Purging"); 069 initSession(); 070 071 PageProviderService pageProviderService = Framework.getService(PageProviderService.class); 072 PageProviderDefinition def = pageProviderService.getPageProviderDefinition("permissions_purge"); 073 String query = NXQLQueryBuilder.getQuery(searchDocument, def.getWhereClause(), null); 074 075 IterableQueryResult result = session.queryAndFetch(query, NXQL.NXQL); 076 List<String> docIds = new ArrayList<>(); 077 try { 078 for (Map<String, Serializable> map : result) { 079 docIds.add((String) map.get("ecm:uuid")); 080 } 081 } finally { 082 result.close(); 083 } 084 085 List<String> usernames = (List<String>) searchDocument.getPropertyValue("rs:ace_username"); 086 int acpUpdatedCount = 0; 087 for (String docId : docIds) { 088 DocumentRef ref = new IdRef(docId); 089 ACP acp = session.getACP(ref); 090 // cleanup acp for all principals 091 boolean changed = false; 092 for (String username : usernames) { 093 if (acp.removeACEsByUsername(username)) { 094 changed = true; 095 } 096 } 097 098 try { 099 if (changed) { 100 session.setACP(ref, acp, true); 101 acpUpdatedCount++; 102 if (acpUpdatedCount % batchSize == 0) { 103 commitOrRollbackTransaction(); 104 startTransaction(); 105 } 106 } 107 } catch (TransactionRuntimeException e) { 108 if (e.getMessage().contains("Transaction timeout")) { 109 batchSize = 1; 110 } 111 throw e; 112 } 113 114 } 115 setStatus(null); 116 } 117 118 @Override 119 public int getRetryCount() { 120 return 10; 121 } 122}