package fr.itldev.koya.patch; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.transaction.SystemException; import javax.transaction.UserTransaction; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.transaction.TransactionService; import org.apache.log4j.Logger; import org.springframework.extensions.webscripts.AbstractWebScript; import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptResponse; import fr.itldev.koya.alfservice.CompanyService; import fr.itldev.koya.alfservice.DossierService; import fr.itldev.koya.alfservice.KoyaNodeService; import fr.itldev.koya.alfservice.SpaceService; import fr.itldev.koya.model.KoyaNode; import fr.itldev.koya.model.impl.Company; import fr.itldev.koya.model.impl.Dossier; import fr.itldev.koya.model.impl.Space; public class ConvertPermissionsv010 extends AbstractWebScript { private Logger logger = Logger.getLogger(this.getClass()); private CompanyService companyService; private SpaceService spaceService; private DossierService dossierService; private KoyaNodeService koyaNodeService; private PermissionService permissionService; private AuthorityService authorityService; private OwnableService ownableService; private TransactionService transactionService; public CompanyService getCompanyService() { return companyService; } public void setCompanyService(CompanyService companyService) { this.companyService = companyService; } public SpaceService getSpaceService() { return spaceService; } public void setSpaceService(SpaceService spaceService) { this.spaceService = spaceService; } public DossierService getDossierService() { return dossierService; } public void setDossierService(DossierService dossierService) { this.dossierService = dossierService; } public KoyaNodeService getKoyaNodeService() { return koyaNodeService; } public void setKoyaNodeService(KoyaNodeService koyaNodeService) { this.koyaNodeService = koyaNodeService; } public PermissionService getPermissionService() { return permissionService; } public void setPermissionService(PermissionService permissionService) { this.permissionService = permissionService; } public AuthorityService getAuthorityService() { return authorityService; } public void setAuthorityService(AuthorityService authorityService) { this.authorityService = authorityService; } public OwnableService getOwnableService() { return ownableService; } public void setOwnableService(OwnableService ownableService) { this.ownableService = ownableService; } public void setTransactionService(TransactionService transactionService) { this.transactionService = transactionService; } @Override // protected String applyInternal() throws Exception { public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException { for (Company c : companyService.list()) { logger.error("start convert for company " + c.getName()); for (Space s : spaceService.list(c)) { // deployed versions only contains one space so ignore with log // spaces not 'defaultSpace' if (s.getName().equals("defaultSpace")) { try { convertDefaultSpaceAcl(s); } catch (Exception e) { logger.error("error converting permissions Space" + s.getName()); } for (Dossier d : dossierService.list(s.getNodeRef())) { try { convertDossierAcl(d); } catch (Exception e) { logger.error("error converting permissions Dossier" + d.getName() + " - " + e.toString()); e.printStackTrace(); } } } else { logger.error("space " + s.getName() + " found in company " + c.getName() + " : IGNORED"); } } logger.error("end convert for company " + c.getName()); } logger.error("Permissions convert process finished"); res.setContentType("application/json;charset=UTF-8"); res.getWriter().write(""); } private static Map<String, String> GROUP_KOYA_PERMISSIONS_SPACE = new HashMap<String, String>() { { put("KoyaResponsible", "KoyaResponsible"); put("KoyaMember", "KoyaMember"); put("KoyaClient", "KoyaClient"); put("KoyaPartner", "KoyaPartner"); put("KoyaSpaceReader", "KoyaClient"); } }; private static Map<String, String> GROUP_KOYA_PERMISSIONS_DOSSIER = new HashMap<String, String>() { { put("KoyaResponsible", "KoyaResponsible"); put("KoyaMember", "KoyaMember"); put("KoyaClient", "KoyaClient"); put("KoyaPartner", "KoyaPartner"); } }; private void convertDossierAcl(final Dossier dossier) { // getKoyaNodes Hierachy List<KoyaNode> parents = koyaNodeService.getParentsList( dossier.getNodeRef(), KoyaNodeService.NB_ANCESTOR_INFINTE); Company c = null; Space firstParentSpace = null; try { firstParentSpace = (Space) parents.get(0); c = (Company) parents.get(parents.size() - 1); } catch (Exception ex) { logger.error("Error in node hierachy " + ex.toString()); } // Clear the node inherited permissions permissionService.setInheritParentPermissions(dossier.getNodeRef(), false); String nodeHierachyPath = buildHierachyPath(parents); /* * Create master authority group for this node */ final String masterGroupAuthorityName = dossier.getAuthorityName(null); final String masterGroupDispAuthorityName = buildGroupDispName(dossier, "", nodeHierachyPath); UserTransaction transaction = transactionService .getNonPropagatingUserTransaction(); try { transaction.begin(); authorityService.createAuthority(AuthorityType.GROUP, masterGroupAuthorityName, masterGroupDispAuthorityName, null); transaction.commit(); } catch (Exception e) { try { transaction.rollback(); } catch (IllegalStateException | SecurityException | SystemException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } final String firstParentSpaceAuthorityName = firstParentSpace .getAuthorityName("KoyaSpaceReader"); // Add this authority to parent KoyaSpaceReader // authority to allow // listing permission authorityService.addAuthority("GROUP_" + firstParentSpaceAuthorityName, "GROUP_" + masterGroupAuthorityName); for (String permissionGroupName : GROUP_KOYA_PERMISSIONS_DOSSIER .keySet()) { final String authorityName = dossier .getAuthorityName(permissionGroupName); final String dispAuthorityName = buildGroupDispName(dossier, permissionGroupName, nodeHierachyPath); if (authorityService.getAuthorityNodeRef("GROUP_" + authorityName) != null) { // authority already exists .. pass continue; } authorityService.createAuthority(AuthorityType.GROUP, authorityName, dispAuthorityName, null); // Add to master authority group for this node authorityService.addAuthority("GROUP_" + masterGroupAuthorityName, "GROUP_" + authorityName); // set permission on node permissionService.setPermission(dossier.getNodeRef(), "GROUP_" + authorityName, GROUP_KOYA_PERMISSIONS_DOSSIER.get(permissionGroupName), true); } // convert old permissions to new ones // read all user setted permissions, add user to matching group for (AccessPermission ap : permissionService .getAllSetPermissions(dossier.getNodeRef())) { if (!ap.getAuthority().startsWith("GROUP_")) { String groupName = "GROUP_" + dossier.getAuthorityName(ap.getPermission()); authorityService.addAuthority(groupName, ap.getAuthority()); } } // removeOwner(dossier); removeAllUserPermissions(dossier); } private void convertDefaultSpaceAcl(final Space space) { List<KoyaNode> parents = koyaNodeService.getParentsList( space.getNodeRef(), KoyaNodeService.NB_ANCESTOR_INFINTE); // Clear the node inherited permissions permissionService .setInheritParentPermissions(space.getNodeRef(), false); String nodeHierachyPath = buildHierachyPath(parents); /* * Create master authority group for this node */ final String masterGroupAuthorityName = space.getAuthorityName(null); final String masterGroupDispAuthorityName = buildGroupDispName(space, "", nodeHierachyPath); UserTransaction transaction = transactionService .getNonPropagatingUserTransaction(); try { transaction.begin(); authorityService.createAuthority(AuthorityType.GROUP, masterGroupAuthorityName, masterGroupDispAuthorityName, null); transaction.commit(); } catch (Exception e) { try { transaction.rollback(); } catch (IllegalStateException | SecurityException | SystemException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } for (String permissionGroupName : GROUP_KOYA_PERMISSIONS_SPACE.keySet()) { final String authorityName = space .getAuthorityName(permissionGroupName); final String dispAuthorityName = buildGroupDispName(space, permissionGroupName, nodeHierachyPath); if (authorityService.getAuthorityNodeRef("GROUP_" + authorityName) != null) { // authority already exists .. pass continue; } authorityService.createAuthority(AuthorityType.GROUP, authorityName, dispAuthorityName, null); // Add to master authority group for this node authorityService.addAuthority("GROUP_" + masterGroupAuthorityName, "GROUP_" + authorityName); // set permission on node permissionService .setPermission(space.getNodeRef(), "GROUP_" + authorityName, GROUP_KOYA_PERMISSIONS_SPACE .get(permissionGroupName), true); } removeOwner(space); removeAllUserPermissions(space); } private void removeOwner(final Space space) { AuthenticationUtil .runAsSystem(new AuthenticationUtil.RunAsWork<Void>() { @Override public Void doWork() throws Exception { ownableService.setOwner(space.getNodeRef(), ownableService.NO_OWNER); return null; } }); } private void removeAllUserPermissions(Space s) { for (AccessPermission ap : permissionService.getAllSetPermissions(s .getNodeRef())) { if (!ap.getAuthority().startsWith("GROUP_")) { permissionService.deletePermission(s.getNodeRef(), ap.getAuthority(), ap.getPermission()); } } } private String buildHierachyPath(List<KoyaNode> parents) { String hierachy = ""; String sep = ""; for (KoyaNode n : parents) { hierachy += sep + n.getName(); sep = "/"; } return hierachy; } private String buildGroupDispName(Space s, String roleName, String hierachyPath) { String dispName = s.getKtype() + " " + s.getName() + " " + roleName; String sep = ""; if (!hierachyPath.isEmpty()) { dispName += "(" + hierachyPath + ")"; } return dispName; } }