REPO-830: 6.0 Cleanup: Remove link between IMAP, Calendar and Data Lists (#396)

* Added functionality to filter IMAP folders based on their component IDS
This commit is contained in:
eknizat
2019-04-15 09:40:26 +01:00
committed by GitHub
parent d5f6d3dc26
commit c6cd3a4552
2 changed files with 105 additions and 51 deletions

View File

@@ -1227,7 +1227,7 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
} }
List<AlfrescoImapFolder> fullList = new LinkedList<AlfrescoImapFolder>(); List<AlfrescoImapFolder> fullList = new LinkedList<AlfrescoImapFolder>();
ImapSubFolderFilter filter = new ImapSubFolderFilter(viewMode, name.replace('%', '*')); ImapSubFolderFilter filter = new ImapSubFolderFilter(viewMode, name.replace('%', '*'), Arrays.asList("calendar", "dataLists"));
List<FileInfo> list; List<FileInfo> list;
// Only list this folder if we have a wildcard name. Otherwise do a direct lookup by name. // Only list this folder if we have a wildcard name. Otherwise do a direct lookup by name.
if (name.contains("*") || name.contains("%")) if (name.contains("*") || name.contains("%"))
@@ -1652,6 +1652,10 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
private List<NodeRef> favs; private List<NodeRef> favs;
private String mailboxPattern; private String mailboxPattern;
private ImapViewMode imapViewMode; private ImapViewMode imapViewMode;
/**
* Exclude folders which represent components with these IDs
*/
private List<String> excludedComponentIds;
ImapSubFolderFilter(ImapViewMode imapViewMode) ImapSubFolderFilter(ImapViewMode imapViewMode)
{ {
@@ -1665,12 +1669,23 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
this(imapViewMode); this(imapViewMode);
this.mailboxPattern = mailboxPattern.replaceAll("\\*", "(.)*");; this.mailboxPattern = mailboxPattern.replaceAll("\\*", "(.)*");;
} }
ImapSubFolderFilter(ImapViewMode imapViewMode, String mailboxPattern, List<String> excludedComponentIds)
{
this(imapViewMode, mailboxPattern);
this.excludedComponentIds = excludedComponentIds;
}
@Override @Override
public boolean isEnterSubfolder(ChildAssociationRef subfolderRef) public boolean isEnterSubfolder(ChildAssociationRef subfolderRef)
{ {
return isEnterSubfolder(subfolderRef.getChildRef()); return isEnterSubfolder(subfolderRef.getChildRef());
} }
private boolean containsIgnoreCase(String s, List<String> list)
{
return list.stream().anyMatch((e) -> e.equalsIgnoreCase(s));
}
public boolean isEnterSubfolder(NodeRef folder) public boolean isEnterSubfolder(NodeRef folder)
{ {
@@ -1685,6 +1700,25 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
if (!name.matches(mailboxPattern)) if (!name.matches(mailboxPattern))
return false; return false;
} }
/**
* Exclude folders which represent unsupported components, like calendar and dataLists.
* See REPO-830
*/
if (excludedComponentIds != null && !excludedComponentIds.isEmpty())
{
String componentId = (String) nodeService.getProperty(folder, SiteModel.PROP_COMPONENT_ID);
if (componentId != null && containsIgnoreCase(componentId, excludedComponentIds))
{
if (logger.isDebugEnabled())
{
logger.debug("[ImapSubFolderFilter] Excluding folder with name: " + name
+ " because its componentID is: " + componentId);
}
return false;
}
}
QName typeOfFolder = nodeService.getType(folder); QName typeOfFolder = nodeService.getType(folder);
if (typesToExclude.contains(typeOfFolder)) if (typesToExclude.contains(typeOfFolder))
{ {

View File

@@ -1,28 +1,28 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.imap; package org.alfresco.repo.imap;
import java.io.FileInputStream; import java.io.FileInputStream;
@@ -67,6 +67,7 @@ import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.alfresco.repo.node.integrity.IntegrityChecker; import org.alfresco.repo.node.integrity.IntegrityChecker;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileFolderService;
@@ -136,7 +137,7 @@ public class ImapServiceImplTest extends TestCase
private ContentService contentService; private ContentService contentService;
private NodeRef testImapFolderNodeRef; private NodeRef testImapFolderNodeRef;
private Flags flags; private Flags flags;
private ImapServiceImpl imapServiceImpl; private ImapServiceImpl imapServiceImpl;
String anotherUserName; String anotherUserName;
@@ -144,7 +145,7 @@ public class ImapServiceImplTest extends TestCase
@Override @Override
public void setUp() throws Exception public void setUp() throws Exception
{ {
ctx = ApplicationContextHelper.getApplicationContext(); ctx = ApplicationContextHelper.getApplicationContext();
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry"); ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
transactionService = serviceRegistry.getTransactionService(); transactionService = serviceRegistry.getTransactionService();
@@ -171,22 +172,22 @@ public class ImapServiceImplTest extends TestCase
authenticationService.authenticate(USER_NAME, USER_PASSWORD.toCharArray()); authenticationService.authenticate(USER_NAME, USER_PASSWORD.toCharArray());
// downgrade integrity // downgrade integrity
IntegrityChecker.setWarnInTransaction(); IntegrityChecker.setWarnInTransaction();
anotherUserName = "user" + System.currentTimeMillis(); anotherUserName = "user" + System.currentTimeMillis();
PropertyMap testUser = new PropertyMap(); PropertyMap testUser = new PropertyMap();
testUser.put(ContentModel.PROP_USERNAME, anotherUserName); testUser.put(ContentModel.PROP_USERNAME, anotherUserName);
testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName); testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName);
testUser.put(ContentModel.PROP_LASTNAME, anotherUserName); testUser.put(ContentModel.PROP_LASTNAME, anotherUserName);
testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com"); testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com");
testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle"); testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle");
personService.createPerson(testUser); personService.createPerson(testUser);
// create the ACEGI Authentication instance for the new user // create the ACEGI Authentication instance for the new user
authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray()); authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray());
user = new AlfrescoImapUser(anotherUserName + "@alfresco.com", anotherUserName, anotherUserName); user = new AlfrescoImapUser(anotherUserName + "@alfresco.com", anotherUserName, anotherUserName);
NodeRef companyHomeNodeRef = findCompanyHomeNodeRef(); NodeRef companyHomeNodeRef = findCompanyHomeNodeRef();
@@ -351,6 +352,25 @@ public class ImapServiceImplTest extends TestCase
List<AlfrescoImapFolder> aif2 = imapService.listMailboxes(user, MAILBOX_PATTERN, true); List<AlfrescoImapFolder> aif2 = imapService.listMailboxes(user, MAILBOX_PATTERN, true);
assertEquals("not subscribed to one mailbox", 1, aif2.size()); assertEquals("not subscribed to one mailbox", 1, aif2.size());
} }
public void testExcludeFoldersByComponentIt()
{
NodeRef imapFolderA = imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true).getFolderInfo().getNodeRef();
NodeRef imapFolderB = imapService.getOrCreateMailbox(user, MAILBOX_NAME_B, false, true).getFolderInfo().getNodeRef();
NodeRef imapFolderC = imapService.getOrCreateMailbox(user, "mailboxCalendarFolder", false, true).getFolderInfo().getNodeRef();
NodeRef imapFolderD = imapService.getOrCreateMailbox(user, "mailboxDataListsFolder", false, true).getFolderInfo().getNodeRef();
NodeRef imapFolderE = imapService.getOrCreateMailbox(user, "mailboxDocumentLibraryFolder", false, true).getFolderInfo().getNodeRef();
List<AlfrescoImapFolder> mf = imapService.listMailboxes(user, MAILBOX_PATTERN, false);
assertEquals(5, mf.size());
nodeService.setProperty(imapFolderC, SiteModel.PROP_COMPONENT_ID, "calendar");
nodeService.setProperty(imapFolderD, SiteModel.PROP_COMPONENT_ID, "dataLists");
nodeService.setProperty(imapFolderE, SiteModel.PROP_COMPONENT_ID, "documentLibrary");
mf = imapService.listMailboxes(user, MAILBOX_PATTERN, false);
assertEquals("Imap folders with component IDs 'calendar' or 'dataLists' were not excluded.", 3, mf.size());
}
public void testListSubscribedMailbox() throws Exception public void testListSubscribedMailbox() throws Exception
{ {
@@ -1005,13 +1025,13 @@ public class ImapServiceImplTest extends TestCase
assertEquals("The parent should change to destination.", destinationNode.getNodeRef(), copiedParentNodeRef); assertEquals("The parent should change to destination.", destinationNode.getNodeRef(), copiedParentNodeRef);
assertEquals("There should be only one node in the destination folder", 1, nodeService.getChildAssocs(destinationNode.getNodeRef()).size()); assertEquals("There should be only one node in the destination folder", 1, nodeService.getChildAssocs(destinationNode.getNodeRef()).size());
assertTrue("New node should have original node aspects", nodeService.hasAspect(copiedNode.getNodeRef(), ContentModel.ASPECT_TAGGABLE)); assertTrue("New node should have original node aspects", nodeService.hasAspect(copiedNode.getNodeRef(), ContentModel.ASPECT_TAGGABLE));
} }
public void testListMailboxOnStartup() public void testListMailboxOnStartup()
{ {
authenticationService.clearCurrentSecurityContext(); authenticationService.clearCurrentSecurityContext();
// Starting IMAP // Starting IMAP
imapServiceImpl.startupInTxn(true); imapServiceImpl.startupInTxn(true);
} }
/** /**