diff --git a/.secrets.baseline b/.secrets.baseline
index 64703dba5e..78ef96fb85 100644
--- a/.secrets.baseline
+++ b/.secrets.baseline
@@ -1377,7 +1377,7 @@
"filename": "repository/src/test/java/org/alfresco/repo/imap/ImapMessageTest.java",
"hashed_secret": "d033e22ae348aeb5660fc2140aec35850c4da997",
"is_verified": false,
- "line_number": 118,
+ "line_number": 116,
"is_secret": false
}
],
@@ -1868,5 +1868,5 @@
}
]
},
- "generated_at": "2025-02-11T13:28:51Z"
+ "generated_at": "2025-02-18T15:50:35Z"
}
diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml
index 2a8715fb99..bcfb20b7e7 100644
--- a/amps/ags/rm-community/rm-community-repo/pom.xml
+++ b/amps/ags/rm-community/rm-community-repo/pom.xml
@@ -63,10 +63,6 @@
jakarta.servlet
jakarta.servlet-api
-
- jakarta.mail
- jakarta.mail-api
-
org.alfresco.surf
spring-webscripts
diff --git a/packaging/distribution/src/main/resources/licenses/notice.txt b/packaging/distribution/src/main/resources/licenses/notice.txt
index 3fa5e4c0a6..1bb810715f 100644
--- a/packaging/distribution/src/main/resources/licenses/notice.txt
+++ b/packaging/distribution/src/main/resources/licenses/notice.txt
@@ -180,13 +180,13 @@ Lightbox JS http://lokeshdhakar.com/projects/lightbox/
=== Eclipse Public License 1.0 ===
+Angus Mail Provider https://eclipse-ee4j.github.io/angus-mail/
AspectJ http://eclipse.org/aspectj/
Bliki http://code.google.com/p/gwtwiki/
JUnit http://junit.org/
TrueLicense http://truelicense.java.net/
truezip http://truezip.java.net/
-
=== ICU License ===
icu4j http://icu-project.org/
diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml
index dad531730c..c8a908d234 100644
--- a/packaging/tests/tas-integration/pom.xml
+++ b/packaging/tests/tas-integration/pom.xml
@@ -57,8 +57,8 @@
- com.sun.mail
- jakarta.mail
+ org.eclipse.angus
+ angus-mail
diff --git a/pom.xml b/pom.xml
index d438da32db..59c866d9ab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,6 +97,7 @@
2.0.6.1
3.1.6
2.3.0
+ 2.0.3
4.0.2
4.0.5
@@ -105,7 +106,7 @@
3.0.0
2.0.1
3.0.0
- 2.0.1
+ 2.1.3
2.0.1
3.1.0
1.2.0
@@ -219,15 +220,14 @@
- com.sun.mail
- jakarta.mail
- ${dependency.jakarta-ee-mail.version}
+ org.eclipse.angus
+ angus-mail
+ ${dependency.angus-mail.version}
jakarta.mail
jakarta.mail-api
${dependency.jakarta-ee-mail.version}
- provided
com.sun.activation
diff --git a/repository/pom.xml b/repository/pom.xml
index e695ca3df4..3fc185861a 100644
--- a/repository/pom.xml
+++ b/repository/pom.xml
@@ -56,8 +56,8 @@
jakarta.mail-api
- com.sun.mail
- jakarta.mail
+ org.eclipse.angus
+ angus-mail
@@ -190,7 +190,7 @@
com.github.davidmoten
subethasmtp
- 6.0.6
+ 7.1.3
diff --git a/repository/src/test/java/org/alfresco/email/server/EmailServiceImplTest.java b/repository/src/test/java/org/alfresco/email/server/EmailServiceImplTest.java
index 3536da694b..f5d7205486 100644
--- a/repository/src/test/java/org/alfresco/email/server/EmailServiceImplTest.java
+++ b/repository/src/test/java/org/alfresco/email/server/EmailServiceImplTest.java
@@ -1,1220 +1,1190 @@
-/*
- * #%L
- * Alfresco Repository
- * %%
- * Copyright (C) 2005 - 2023 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * 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
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- * #L%
- */
-package org.alfresco.email.server;
-
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Vector;
-import java.util.concurrent.CountDownLatch;
-
-import jakarta.mail.Message;
-import jakarta.mail.Session;
-import jakarta.mail.internet.InternetAddress;
-
-import junit.framework.TestCase;
-
-import org.alfresco.email.server.handler.FolderEmailMessageHandler;
-import org.alfresco.email.server.impl.subetha.SubethaEmailMessage;
-import org.alfresco.model.ContentModel;
-import org.alfresco.model.ForumModel;
-import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.alfresco.repo.transfer.TransferModel;
-import org.alfresco.repo.transaction.RetryingTransactionHelper;
-import org.alfresco.service.cmr.email.EmailDelivery;
-import org.alfresco.service.cmr.email.EmailMessageException;
-import org.alfresco.service.cmr.email.EmailService;
-import org.alfresco.service.cmr.repository.ChildAssociationRef;
-import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.repository.NodeService;
-import org.alfresco.service.cmr.repository.StoreRef;
-import org.alfresco.service.cmr.search.SearchService;
-import org.alfresco.service.cmr.security.AuthorityService;
-import org.alfresco.service.cmr.security.PersonService;
-import org.alfresco.service.namespace.NamespaceService;
-import org.alfresco.service.namespace.QName;
-import org.alfresco.service.namespace.RegexQNamePattern;
-import org.alfresco.test_category.OwnJVMTestsCategory;
-import org.alfresco.util.ApplicationContextHelper;
-import org.alfresco.util.testing.category.LuceneTests;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.experimental.categories.Category;
-import org.springframework.context.ApplicationContext;
-
-import com.sun.mail.smtp.SMTPMessage;
-
-/**
- * Unit test of EmailServiceImplTest
- * @author mrogers
- *
- */
-@Category({OwnJVMTestsCategory.class})
-public class EmailServiceImplTest extends TestCase
-{
- /**
- * Services used by the tests
- */
- private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
-
- private static Log logger = LogFactory.getLog(EmailServiceImplTest.class);
-
- private NodeService nodeService;
- private EmailService emailService;
- private PersonService personService;
- private AuthorityService authorityService;
- private SearchService searchService;
- private NamespaceService namespaceService;
- private FolderEmailMessageHandler folderEmailMessageHandler;
- private RetryingTransactionHelper transactionHelper;
-
- String TEST_USER="EmailServiceImplTestUser";
-
- @Override
- public void setUp() throws Exception
- {
- AuthenticationUtil.setRunAsUserSystem();
- nodeService = (NodeService)ctx.getBean("NodeService");
- assertNotNull("nodeService", nodeService);
- authorityService = (AuthorityService)ctx.getBean("AuthorityService");
- assertNotNull("authorityService", authorityService);
- ChildApplicationContextFactory emailSubsystem = (ChildApplicationContextFactory) ctx.getBean("InboundSMTP");
- assertNotNull("emailSubsystem", emailSubsystem);
- ApplicationContext emailCtx = emailSubsystem.getApplicationContext();
- emailService = (EmailService)emailCtx.getBean("emailService");
- assertNotNull("emailService", emailService);
- personService = (PersonService)emailCtx.getBean("PersonService");
- assertNotNull("personService", personService);
- namespaceService = (NamespaceService)emailCtx.getBean("NamespaceService");
- assertNotNull("namespaceService", namespaceService);
- searchService = (SearchService)emailCtx.getBean("SearchService");
- assertNotNull("searchService", searchService);
- folderEmailMessageHandler = (FolderEmailMessageHandler) emailCtx.getBean("folderEmailMessageHandler");
- assertNotNull("folderEmailMessageHandler", folderEmailMessageHandler);
- transactionHelper = (RetryingTransactionHelper) emailCtx.getBean("retryingTransactionHelper");
- assertNotNull("transactionHelper", transactionHelper);
- }
-
- public void tearDown() throws Exception
- {
- AuthenticationUtil.setRunAsUserSystem();
- try
- {
- personService.deletePerson(TEST_USER);
- }
- catch (Exception e)
- {
- }
- }
-
- /**
- * Test the from name.
- *
- * Step 1:
- * User admin will map to the "unknownUser" which out of the box is "anonymous"
- * Sending email From "admin" will fail.
- *
- * Step 2:
- * Send from the test user to the test' user's home folder.
- */
- public void testFromName() throws Exception
- {
-
- folderEmailMessageHandler.setOverwriteDuplicates(true);
-
- logger.debug("Start testFromName");
-
- String TEST_EMAIL="buffy@sunnydale.high";
-
- // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
- NodeRef person = personService.getPerson(TEST_USER);
- if(person == null)
- {
- logger.debug("new person created");
- Map props = new HashMap();
- props.put(ContentModel.PROP_USERNAME, TEST_USER);
- props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
- person = personService.createPerson(props);
- }
- nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
-
- Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
- if(!auths.contains(TEST_USER))
- {
- authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
- }
-
- String companyHomePathInStore = "/app:company_home";
- String storePath = "workspace://SpacesStore";
- StoreRef storeRef = new StoreRef(storePath);
-
- NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
- NodeRef companyHomeNodeRef = nodeRefs.get(0);
- assertNotNull("company home is null", companyHomeNodeRef);
- String companyHomeDBID = ((Long)nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- String testUserDBID = ((Long)nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- NodeRef testUserHomeFolder = (NodeRef)nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
- assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
- String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
-
- /**
- * Step 1
- * Negative test - send from "Bert" who does not exist.
- * User will be mapped to anonymous who is not an email contributor.
- */
- try
- {
- String from = "admin";
- String to = "bertie";
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress("Bert"));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("JavaMail APIs transport.java Test");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
-
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- fail("anonymous user not rejected");
- }
- catch (EmailMessageException e)
- {
- // Check the exception is for the anonymous user.
- assertTrue("Message is not for anonymous", e.getMessage().contains("anonymous"));
- }
-
- /**
- * Step 2
- *
- * Send From the test user TEST_EMAIL to the test user's home
- */
- {
- logger.debug("Step 2");
-
- String from = TEST_EMAIL;
- String to = testUserHomeDBID;
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("JavaMail APIs transport.java Test");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
-
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- }
-
- /**
- * Step 3
- *
- * message.from From with "name" < name@ domain > format
- * SMTP.FROM="dummy"
- *
- * Send From the test user to the test user's home
- */
- {
- logger.debug("Step 3");
-
- String from = " \"Joe Bloggs\" <" + TEST_EMAIL + ">";
- String to = testUserHomeDBID;
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(from));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("JavaMail APIs transport.java Test");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(System.out);
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
-
- EmailDelivery delivery = new EmailDelivery(to, "dummy", null);
-
- emailService.importMessage(delivery,m);
- }
-
- /**
- * Step 4
- *
- * From with "name" < name@ domain > format
- *
- * Send From the test user to the test user's home
- */
- {
- logger.debug("Step 4");
-
- String from = " \"Joe Bloggs\" <" + TEST_EMAIL + ">";
- String to = testUserHomeDBID;
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(from));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("JavaMail APIs transport.java Test");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(System.out);
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
-
- InternetAddress a = new InternetAddress(from);
- String x = a.getAddress();
-
- EmailDelivery delivery = new EmailDelivery(to, x, null);
-
- emailService.importMessage(delivery,m);
- }
-
-// /**
-// * Step 5
-// *
-// * From with format
-// *
-// * RFC3696
-// *
-// * Send From the test user to the test user's home
-// */
-// {
-// logger.debug("Step 4 format");
-//
-// String from = "\"Joe Bloggs\" ";
-// String to = testUserHomeDBID;
-// String content = "hello world";
-//
-// Session sess = Session.getDefaultInstance(new Properties());
-// assertNotNull("sess is null", sess);
-// SMTPMessage msg = new SMTPMessage(sess);
-// InternetAddress[] toa = { new InternetAddress(to) };
-//
-// msg.setFrom(new InternetAddress(from));
-// msg.setRecipients(Message.RecipientType.TO, toa);
-// msg.setSubject("JavaMail APIs transport.java Test");
-// msg.setContent(content, "text/plain");
-//
-// StringBuffer sb = new StringBuffer();
-// ByteArrayOutputStream bos = new ByteArrayOutputStream();
-// msg.writeTo(System.out);
-// msg.writeTo(bos);
-// InputStream is = IOUtils.toInputStream(bos.toString());
-// assertNotNull("is is null", is);
-//
-// SubethaEmailMessage m = new SubethaEmailMessage(is);
-//
-// emailService.importMessage(m);
-// }
- }
-
-
- /**
- * ALF-9544
- * ALF-751
- *
- * Inbound email to a folder restricts file name to 86 characters or less.
- *
- * Also has tests for other variations of subject
- */
- public void testFolderSubject() throws Exception
- {
- logger.debug("Start testFromName");
-
- String TEST_EMAIL="buffy@sunnydale.high";
-
- folderEmailMessageHandler.setOverwriteDuplicates(true);
-
- // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
- NodeRef person = personService.getPerson(TEST_USER);
- if(person == null)
- {
- logger.debug("new person created");
- Map props = new HashMap();
- props.put(ContentModel.PROP_USERNAME, TEST_USER);
- props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
- person = personService.createPerson(props);
- }
- nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
-
- Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
- if(!auths.contains(TEST_USER))
- {
- authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
- }
-
- String companyHomePathInStore = "/app:company_home";
- String storePath = "workspace://SpacesStore";
- StoreRef storeRef = new StoreRef(storePath);
-
- NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
- NodeRef companyHomeNodeRef = nodeRefs.get(0);
- assertNotNull("company home is null", companyHomeNodeRef);
- String companyHomeDBID = ((Long)nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- String testUserDBID = ((Long)nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- NodeRef testUserHomeFolder = (NodeRef)nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
- assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
- String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
-
- /**
- * Send From the test user TEST_EMAIL to the test user's home
- */
- String from = TEST_EMAIL;
- String to = testUserHomeDBID;
- String content = "hello world";
-
- {
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("This is a very very long name in particular it is greater than eitghty six characters which was a problem explored in ALF-9544");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- }
-
- // Check import with subject containing some "illegal chars"
- {
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("Illegal<>!*/\\.txt");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- }
-
- // Check with null subject
- {
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- //msg.setSubject();
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- }
-
-
- // ALF-751 Email ends with period
- {
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("Foobar.");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- }
-
- // ALF-751 Email ends with ...
- {
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("Foobar...");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- }
-
- // ALF-751 Email subject is blank " ... "
- {
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject(" ... ");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- }
-
- // ALF-751 Email subject is a single .
- {
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject(".");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- }
-
- }
-
- /**
- * ALF-1878
- *
- * Duplicate incoming email Subjects over-write each other
- */
- public void testMultipleMessagesToFolder() throws Exception
- {
- logger.debug("Start testFromName");
-
- String TEST_EMAIL="buffy@sunnydale.high";
-
- String TEST_SUBJECT="Practical Bee Keeping";
-
- String TEST_LONG_SUBJECT = "This is a very very long name in particular it is greater than eitghty six characters which was a problem explored in ALF-9544";
-
-
- // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
- NodeRef person = personService.getPerson(TEST_USER);
- if(person == null)
- {
- logger.debug("new person created");
- Map props = new HashMap();
- props.put(ContentModel.PROP_USERNAME, TEST_USER);
- props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
- person = personService.createPerson(props);
- }
- nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
-
- Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
- if(!auths.contains(TEST_USER))
- {
- authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
- }
-
- String companyHomePathInStore = "/app:company_home";
- String storePath = "workspace://SpacesStore";
- StoreRef storeRef = new StoreRef(storePath);
-
- NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
- NodeRef companyHomeNodeRef = nodeRefs.get(0);
- assertNotNull("company home is null", companyHomeNodeRef);
- String companyHomeDBID = ((Long)nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- String testUserDBID = ((Long)nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- NodeRef testUserHomeFolder = (NodeRef)nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
- assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
- String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
-
- // Clean up old messages in test folder
- List assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- for(ChildAssociationRef assoc : assocs)
- {
- nodeService.deleteNode(assoc.getChildRef());
- }
-
- /**
- * Send From the test user TEST_EMAIL to the test user's home
- */
- String from = TEST_EMAIL;
- String to = testUserHomeDBID;
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject(TEST_SUBJECT);
- msg.setContent(content, "text/plain");
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
-
- /**
- * Turn on overwriteDuplicates
- */
- logger.debug("Step 1: turn on Overwite Duplicates");
- folderEmailMessageHandler.setOverwriteDuplicates(true);
-
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- assertEquals("assocs not 1", 1, assocs.size());
- assertEquals("name of link not as expected", assocs.get(0).getQName(), QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, TEST_SUBJECT));
- emailService.importMessage(delivery, m);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- assertEquals("assocs not 1", 1, assocs.size());
-
- /**
- * Turn off overwrite Duplicates
- */
- logger.debug("Step 2: turn off Overwite Duplicates");
- folderEmailMessageHandler.setOverwriteDuplicates(false);
- emailService.importMessage(delivery, m);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- assertEquals("assocs not 2", 2, assocs.size());
- emailService.importMessage(delivery, m);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- assertEquals("assocs not 3", 3, assocs.size());
-
- /**
- * Check assoc rename with long names. So truncation and rename need to work together.
- */
- logger.debug("Step 3: turn off Overwite Duplicates with long subject name");
- msg.setSubject(TEST_LONG_SUBJECT);
- ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
- msg.writeTo(bos2);
- is = IOUtils.toInputStream(bos2.toString());
- assertNotNull("is is null", is);
- m = new SubethaEmailMessage(is);
-
- folderEmailMessageHandler.setOverwriteDuplicates(false);
- emailService.importMessage(delivery, m);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- assertEquals("assocs not 4", 4, assocs.size());
- emailService.importMessage(delivery, m);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- assertEquals("assocs not 5", 5, assocs.size());
-
- /**
- * Check assoc rename with long names and an extension. So truncation and rename need to
- * work together and not muck up a .extension.
- */
- logger.debug("Step 4: turn off Overwite Duplicates with long subject name with extension");
- String EXT_NAME = "Blob.xls";
-
- msg.setSubject(EXT_NAME);
- ByteArrayOutputStream bos3 = new ByteArrayOutputStream();
- msg.writeTo(bos3);
- is = IOUtils.toInputStream(bos3.toString());
- assertNotNull("is is null", is);
- m = new SubethaEmailMessage(is);
- folderEmailMessageHandler.setOverwriteDuplicates(false);
- emailService.importMessage(delivery, m);
- emailService.importMessage(delivery, m);
- emailService.importMessage(delivery, m);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
-
- List assocNames = new Vector();
- for(ChildAssociationRef assoc : assocs)
- {
- logger.debug("assocName: " + assoc.getQName());
- System.out.println(assoc.getQName());
- assocNames.add(assoc.getQName());
- }
- assertTrue(EXT_NAME + "not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Blob.xls")));
- assertTrue("Blob(1).xls not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Blob(1).xls")));
- assertTrue("Blob(2).xls not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Blob(2).xls")));
- assertTrue(TEST_SUBJECT + "not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, TEST_SUBJECT)));
- assertTrue(TEST_SUBJECT+"(1) not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Practical Bee Keeping(1)")));
-
- /**
- * Check concurrent deliver of the same message. Reuse message from the previous test.
- */
- logger.debug("Step 5: turn off Overwite Duplicates and check concurrent deliver of the same message");
- folderEmailMessageHandler.setOverwriteDuplicates(false);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- int numBeforeConcurrentDeliver = assocs.size();
- deliverConcurrently(delivery, m);
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- int numAfterConcurrentDeliver = assocs.size();
- assertEquals("Two messages must be added", numBeforeConcurrentDeliver + 2, numAfterConcurrentDeliver);
- }
-
- private void deliverConcurrently(final EmailDelivery delivery, final SubethaEmailMessage m) throws Exception
- {
- final CountDownLatch cdl = new CountDownLatch(1);
- class ConcurrentMessageImporter implements Runnable
- {
- private Throwable throwable;
- @Override
- public void run()
- {
- try
- {
- transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback()
- {
- public Void execute() throws Throwable
- {
- cdl.countDown();
- emailService.importMessage(delivery, m);
- return null;
- }
- }, false, true);
- }
- catch (Throwable t)
- {
- throwable = t;
- }
- }
- }
- ConcurrentMessageImporter messageImporter = new ConcurrentMessageImporter();
- final Thread messageImporterThread = new Thread(messageImporter);
- transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback()
- {
- public Void execute() throws Throwable
- {
- emailService.importMessage(delivery, m);
- messageImporterThread.start();
- // wait until concurrent transaction has started
- cdl.await();
- return null;
- }
- }, false, true);
- messageImporterThread.join();
- if (null != messageImporter.throwable)
- {
- fail(messageImporter.throwable.getMessage());
- }
- }
-
- /**
- * MNT-9289
- *
- * Change in case in email Subject causes DuplicateChildNodeNameException
- */
- public void testCaseSensitivity() throws Exception
- {
- NodeRef person = personService.getPerson(TEST_USER);
- String TEST_EMAIL="buffy@sunnydale.high";
- NodeRef testUserHomeFolder = (NodeRef)nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
- if(person == null)
- {
- logger.debug("new person created");
- Map props = new HashMap();
- props.put(ContentModel.PROP_USERNAME, TEST_USER);
- props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
- person = personService.createPerson(props);
- }
-
- nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
-
- Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
- if(!auths.contains(TEST_USER))
- {
- authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
- }
-
- String companyHomePathInStore = "/app:company_home";
- String storePath = "workspace://SpacesStore";
- StoreRef storeRef = new StoreRef(storePath);
-
- NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
- NodeRef companyHomeNodeRef = nodeRefs.get(0);
- assertNotNull("company home is null", companyHomeNodeRef);
-
- String TEST_CASE_SENSITIVITY_SUBJECT = "Test (Mail)";
- String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
-
- String from = TEST_EMAIL;
- String to = testUserHomeDBID;
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setContent(content, "text/plain");
-
- msg.setSubject(TEST_CASE_SENSITIVITY_SUBJECT);
- ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
- msg.writeTo(bos1);
- InputStream is = IOUtils.toInputStream(bos1.toString());
- assertNotNull("is is null", is);
- SubethaEmailMessage m = new SubethaEmailMessage(is);
- folderEmailMessageHandler.setOverwriteDuplicates(false);
- emailService.importMessage(delivery, m);
-
- QName safeQName = QName.createQNameWithValidLocalName(NamespaceService.CONTENT_MODEL_1_0_URI, TEST_CASE_SENSITIVITY_SUBJECT);
- List assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, safeQName);
- assertEquals(1, assocs.size());
-
- msg.setSubject(TEST_CASE_SENSITIVITY_SUBJECT.toUpperCase());
- ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
- msg.writeTo(bos2);
- is = IOUtils.toInputStream(bos2.toString());
- assertNotNull("is is null", is);
- m = new SubethaEmailMessage(is);
- folderEmailMessageHandler.setOverwriteDuplicates(false);
- emailService.importMessage(delivery, m);
-
- safeQName = QName.createQNameWithValidLocalName(NamespaceService.CONTENT_MODEL_1_0_URI, TEST_CASE_SENSITIVITY_SUBJECT.toUpperCase() + "(1)");
- assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, safeQName);
- assertEquals(1, assocs.size());
- }
-
-
- /**
- * ALF-12297
- *
- * Test messages being sent to a cm:content node
- */
- public void testMessagesToDocument() throws Exception
- {
- logger.debug("Start testMessagesToDocument");
-
- String TEST_EMAIL="buffy@sunnydale.high";
-
- String TEST_SUBJECT="Practical Bee Keeping";
-
- String TEST_LONG_SUBJECT = "This is a very very long name in particular it is greater than eitghty six characters which was a problem explored in ALF-9544";
-
-
- // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
- NodeRef person = personService.getPerson(TEST_USER);
- if(person == null)
- {
- logger.debug("new person created");
- Map props = new HashMap();
- props.put(ContentModel.PROP_USERNAME, TEST_USER);
- props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
- person = personService.createPerson(props);
- }
- nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
-
- Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
- if(!auths.contains(TEST_USER))
- {
- authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
- }
-
- String companyHomePathInStore = "/app:company_home";
- String storePath = "workspace://SpacesStore";
- StoreRef storeRef = new StoreRef(storePath);
-
- NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
- NodeRef companyHomeNodeRef = nodeRefs.get(0);
- assertNotNull("company home is null", companyHomeNodeRef);
- String companyHomeDBID = ((Long)nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- // String testUserDBID = ((Long)nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- NodeRef testUserHomeFolder = (NodeRef)nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
- assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
-// String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
-
- // Clean up old messages in test folder
- List assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- for(ChildAssociationRef assoc : assocs)
- {
- nodeService.deleteNode(assoc.getChildRef());
- }
-
-
- Map properties = new HashMap();
- properties.put(ContentModel.PROP_NAME, "bees");
- properties.put(ContentModel.PROP_DESCRIPTION, "bees - test doc for email tests");
- ChildAssociationRef testDoc = nodeService.createNode(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "bees"), ContentModel.TYPE_CONTENT, properties);
- NodeRef testDocNodeRef = testDoc.getChildRef();
-
- String testDocDBID = ((Long)nodeService.getProperty(testDocNodeRef, ContentModel.PROP_NODE_DBID)).toString();
-
- /**
- * Send From the test user TEST_EMAIL to the test user's home
- */
- String from = TEST_EMAIL;
- String to = testDocDBID + "@alfresco.com";
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject(TEST_SUBJECT);
- msg.setContent(content, "text/plain");
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
-
- /**
- * Turn on overwriteDuplicates
- */
- logger.debug("Step 1: send an email to a doc");
-
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
-
- assertTrue(nodeService.hasAspect(testDocNodeRef, ForumModel.ASPECT_DISCUSSABLE));
-
-
-
- } // end of test sending to cm:content node
-
-
- /**
- * ENH-560 - Inbound email server not working with custom types
- */
- public void testMessagesToSubTypeOfDocument() throws Exception
- {
- logger.debug("Start testMessagesToSubTypesOfDocument");
-
- String TEST_EMAIL="buffy@sunnydale.high";
-
- String TEST_SUBJECT="Practical Bee Keeping";
-
- String TEST_LONG_SUBJECT = "This is a very very long name in particular it is greater than eitghty six characters which was a problem explored in ALF-9544";
-
-
- // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
- NodeRef person = personService.getPerson(TEST_USER);
- if(person == null)
- {
- logger.debug("new person created");
- Map props = new HashMap();
- props.put(ContentModel.PROP_USERNAME, TEST_USER);
- props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
- person = personService.createPerson(props);
- }
- nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
-
- Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
- if(!auths.contains(TEST_USER))
- {
- authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
- }
-
- String companyHomePathInStore = "/app:company_home";
- String storePath = "workspace://SpacesStore";
- StoreRef storeRef = new StoreRef(storePath);
-
- NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
- NodeRef companyHomeNodeRef = nodeRefs.get(0);
- assertNotNull("company home is null", companyHomeNodeRef);
- String companyHomeDBID = ((Long)nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
-// String testUserDBID = ((Long)nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- NodeRef testUserHomeFolder = (NodeRef)nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
- assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
-// String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
-
- // Clean up old messages in test folder
- List assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
- for(ChildAssociationRef assoc : assocs)
- {
- nodeService.deleteNode(assoc.getChildRef());
- }
-
-
- Map properties = new HashMap();
- properties.put(ContentModel.PROP_NAME, "hamster");
- properties.put(ContentModel.PROP_DESCRIPTION, "syrian hamsters - test doc for email tests, sending to a subtype of cm:content");
-
- // Transfer report is a subtype of cm:content
- ChildAssociationRef testDoc = nodeService.createNode(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "bees"), TransferModel.TYPE_TRANSFER_REPORT, properties);
- NodeRef testDocNodeRef = testDoc.getChildRef();
-
- String testDocDBID = ((Long)nodeService.getProperty(testDocNodeRef, ContentModel.PROP_NODE_DBID)).toString();
-
- /**
- * Send From the test user TEST_EMAIL to the test user's home
- */
- String from = TEST_EMAIL;
- String to = testDocDBID + "@alfresco.com";
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject(TEST_SUBJECT);
- msg.setContent(content, "text/plain");
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
-
- /**
- * Turn on overwriteDuplicates
- */
- logger.debug("Step 1: send an email to a transfer report");
-
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
-
- } // end of test sending to trx:transferReport
-
-
-
-
-
- /**
- * The Email contributors authority controls who can add email.
- *
- * This test switches between the EMAIL_CONTRIBUTORS group and EVERYONE
- */
- public void testEmailContributorsAuthority() throws Exception
- {
- EmailServiceImpl emailServiceImpl = (EmailServiceImpl)emailService;
-
- folderEmailMessageHandler.setOverwriteDuplicates(true);
-
- logger.debug("Start testEmailContributorsAuthority");
-
- String TEST_EMAIL="buffy@sunnydale.high";
-
- // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
- NodeRef person = personService.getPerson(TEST_USER);
- if(person == null)
- {
- logger.debug("new person created");
- Map props = new HashMap();
- props.put(ContentModel.PROP_USERNAME, TEST_USER);
- props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
- person = personService.createPerson(props);
- }
- nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
-
- Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
- if(auths.contains(TEST_USER))
- {
- authorityService.removeAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
- }
-
- String companyHomePathInStore = "/app:company_home";
- String storePath = "workspace://SpacesStore";
- StoreRef storeRef = new StoreRef(storePath);
-
- NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
- NodeRef companyHomeNodeRef = nodeRefs.get(0);
- assertNotNull("company home is null", companyHomeNodeRef);
- String companyHomeDBID = ((Long)nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- String testUserDBID = ((Long)nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
- NodeRef testUserHomeFolder = (NodeRef)nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
- assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
- String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
-
- /**
- * Step 1
- * Set the email contributors authority to EVERYONE
- *
- * Test that TEST_USER is allowed to send email - so even though TEST_USER is not
- * a contributor
- */
- emailServiceImpl.setEmailContributorsAuthority("EVERYONE");
-
- String from = "admin";
- String to = testUserHomeDBID;
- String content = "hello world";
-
- Session sess = Session.getDefaultInstance(new Properties());
- assertNotNull("sess is null", sess);
- SMTPMessage msg = new SMTPMessage(sess);
- InternetAddress[] toa = { new InternetAddress(to) };
-
- msg.setFrom(new InternetAddress(TEST_EMAIL));
- msg.setRecipients(Message.RecipientType.TO, toa);
- msg.setSubject("JavaMail APIs transport.java Test");
- msg.setContent(content, "text/plain");
-
- StringBuffer sb = new StringBuffer();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- msg.writeTo(bos);
- InputStream is = IOUtils.toInputStream(bos.toString());
- assertNotNull("is is null", is);
-
- SubethaEmailMessage m = new SubethaEmailMessage(is);
-
- EmailDelivery delivery = new EmailDelivery(to, from, null);
-
- emailService.importMessage(delivery, m);
-
- /**
- * Step 2
- * Negative test
- *
- * Send From the test user TEST_EMAIL to the test user's home
- */
- try
- {
- logger.debug("Step 2");
- emailServiceImpl.setEmailContributorsAuthority("EMAIL_CONTRIBUTORS");
- emailService.importMessage(delivery, m);
- fail("not thrown out");
- }
- catch (EmailMessageException e)
- {
- // Check the exception is for the anonymous user.
- // assertTrue(e.getMessage().contains("anonymous"));
- }
- }
-
-} // end of EmailServiceImplTest
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2005 - 2025 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.email.server;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.CountDownLatch;
+import jakarta.mail.Message;
+import jakarta.mail.Session;
+import jakarta.mail.internet.InternetAddress;
+
+import junit.framework.TestCase;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.angus.mail.smtp.SMTPMessage;
+import org.junit.experimental.categories.Category;
+import org.springframework.context.ApplicationContext;
+
+import org.alfresco.email.server.handler.FolderEmailMessageHandler;
+import org.alfresco.email.server.impl.subetha.SubethaEmailMessage;
+import org.alfresco.model.ContentModel;
+import org.alfresco.model.ForumModel;
+import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.RetryingTransactionHelper;
+import org.alfresco.repo.transfer.TransferModel;
+import org.alfresco.service.cmr.email.EmailDelivery;
+import org.alfresco.service.cmr.email.EmailMessageException;
+import org.alfresco.service.cmr.email.EmailService;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.search.SearchService;
+import org.alfresco.service.cmr.security.AuthorityService;
+import org.alfresco.service.cmr.security.PersonService;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.RegexQNamePattern;
+import org.alfresco.test_category.OwnJVMTestsCategory;
+import org.alfresco.util.ApplicationContextHelper;
+
+/**
+ * Unit test of EmailServiceImplTest
+ *
+ * @author mrogers
+ *
+ */
+@Category({OwnJVMTestsCategory.class})
+public class EmailServiceImplTest extends TestCase
+{
+ /**
+ * Services used by the tests
+ */
+ private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
+
+ private static Log logger = LogFactory.getLog(EmailServiceImplTest.class);
+
+ private NodeService nodeService;
+ private EmailService emailService;
+ private PersonService personService;
+ private AuthorityService authorityService;
+ private SearchService searchService;
+ private NamespaceService namespaceService;
+ private FolderEmailMessageHandler folderEmailMessageHandler;
+ private RetryingTransactionHelper transactionHelper;
+
+ String TEST_USER = "EmailServiceImplTestUser";
+
+ @Override
+ public void setUp() throws Exception
+ {
+ AuthenticationUtil.setRunAsUserSystem();
+ nodeService = (NodeService) ctx.getBean("NodeService");
+ assertNotNull("nodeService", nodeService);
+ authorityService = (AuthorityService) ctx.getBean("AuthorityService");
+ assertNotNull("authorityService", authorityService);
+ ChildApplicationContextFactory emailSubsystem = (ChildApplicationContextFactory) ctx.getBean("InboundSMTP");
+ assertNotNull("emailSubsystem", emailSubsystem);
+ ApplicationContext emailCtx = emailSubsystem.getApplicationContext();
+ emailService = (EmailService) emailCtx.getBean("emailService");
+ assertNotNull("emailService", emailService);
+ personService = (PersonService) emailCtx.getBean("PersonService");
+ assertNotNull("personService", personService);
+ namespaceService = (NamespaceService) emailCtx.getBean("NamespaceService");
+ assertNotNull("namespaceService", namespaceService);
+ searchService = (SearchService) emailCtx.getBean("SearchService");
+ assertNotNull("searchService", searchService);
+ folderEmailMessageHandler = (FolderEmailMessageHandler) emailCtx.getBean("folderEmailMessageHandler");
+ assertNotNull("folderEmailMessageHandler", folderEmailMessageHandler);
+ transactionHelper = (RetryingTransactionHelper) emailCtx.getBean("retryingTransactionHelper");
+ assertNotNull("transactionHelper", transactionHelper);
+ }
+
+ public void tearDown() throws Exception
+ {
+ AuthenticationUtil.setRunAsUserSystem();
+ try
+ {
+ personService.deletePerson(TEST_USER);
+ }
+ catch (Exception e)
+ {}
+ }
+
+ /**
+ * Test the from name.
+ *
+ * Step 1: User admin will map to the "unknownUser" which out of the box is "anonymous" Sending email From "admin" will fail.
+ *
+ * Step 2: Send from the test user to the test' user's home folder.
+ */
+ public void testFromName() throws Exception
+ {
+
+ folderEmailMessageHandler.setOverwriteDuplicates(true);
+
+ logger.debug("Start testFromName");
+
+ String TEST_EMAIL = "buffy@sunnydale.high";
+
+ // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
+ NodeRef person = personService.getPerson(TEST_USER);
+ if (person == null)
+ {
+ logger.debug("new person created");
+ Map props = new HashMap();
+ props.put(ContentModel.PROP_USERNAME, TEST_USER);
+ props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
+ person = personService.createPerson(props);
+ }
+ nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
+
+ Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
+ if (!auths.contains(TEST_USER))
+ {
+ authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
+ }
+
+ String companyHomePathInStore = "/app:company_home";
+ String storePath = "workspace://SpacesStore";
+ StoreRef storeRef = new StoreRef(storePath);
+
+ NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
+ NodeRef companyHomeNodeRef = nodeRefs.get(0);
+ assertNotNull("company home is null", companyHomeNodeRef);
+ String companyHomeDBID = ((Long) nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ String testUserDBID = ((Long) nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ NodeRef testUserHomeFolder = (NodeRef) nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
+ assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
+ String testUserHomeDBID = ((Long) nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+
+ /**
+ * Step 1 Negative test - send from "Bert" who does not exist. User will be mapped to anonymous who is not an email contributor.
+ */
+ try
+ {
+ String from = "admin";
+ String to = "bertie";
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress("Bert"));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("JavaMail APIs transport.java Test");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ fail("anonymous user not rejected");
+ }
+ catch (EmailMessageException e)
+ {
+ // Check the exception is for the anonymous user.
+ assertTrue("Message is not for anonymous", e.getMessage().contains("anonymous"));
+ }
+
+ /**
+ * Step 2
+ *
+ * Send From the test user TEST_EMAIL to the test user's home
+ */
+ {
+ logger.debug("Step 2");
+
+ String from = TEST_EMAIL;
+ String to = testUserHomeDBID;
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("JavaMail APIs transport.java Test");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ /**
+ * Step 3
+ *
+ * message.from From with "name" < name@ domain > format SMTP.FROM="dummy"
+ *
+ * Send From the test user to the test user's home
+ */
+ {
+ logger.debug("Step 3");
+
+ String from = " \"Joe Bloggs\" <" + TEST_EMAIL + ">";
+ String to = testUserHomeDBID;
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(from));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("JavaMail APIs transport.java Test");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(System.out);
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+
+ EmailDelivery delivery = new EmailDelivery(to, "dummy", null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ /**
+ * Step 4
+ *
+ * From with "name" < name@ domain > format
+ *
+ * Send From the test user to the test user's home
+ */
+ {
+ logger.debug("Step 4");
+
+ String from = " \"Joe Bloggs\" <" + TEST_EMAIL + ">";
+ String to = testUserHomeDBID;
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(from));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("JavaMail APIs transport.java Test");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(System.out);
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+
+ InternetAddress a = new InternetAddress(from);
+ String x = a.getAddress();
+
+ EmailDelivery delivery = new EmailDelivery(to, x, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ // /**
+ // * Step 5
+ // *
+ // * From with format
+ // *
+ // * RFC3696
+ // *
+ // * Send From the test user to the test user's home
+ // */
+ // {
+ // logger.debug("Step 4 format");
+ //
+ // String from = "\"Joe Bloggs\" ";
+ // String to = testUserHomeDBID;
+ // String content = "hello world";
+ //
+ // Session sess = Session.getDefaultInstance(new Properties());
+ // assertNotNull("sess is null", sess);
+ // SMTPMessage msg = new SMTPMessage(sess);
+ // InternetAddress[] toa = { new InternetAddress(to) };
+ //
+ // msg.setFrom(new InternetAddress(from));
+ // msg.setRecipients(Message.RecipientType.TO, toa);
+ // msg.setSubject("JavaMail APIs transport.java Test");
+ // msg.setContent(content, "text/plain");
+ //
+ // StringBuffer sb = new StringBuffer();
+ // ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ // msg.writeTo(System.out);
+ // msg.writeTo(bos);
+ // InputStream is = IOUtils.toInputStream(bos.toString());
+ // assertNotNull("is is null", is);
+ //
+ // SubethaEmailMessage m = new SubethaEmailMessage(is);
+ //
+ // emailService.importMessage(m);
+ // }
+ }
+
+ /**
+ * ALF-9544 ALF-751
+ *
+ * Inbound email to a folder restricts file name to 86 characters or less.
+ *
+ * Also has tests for other variations of subject
+ */
+ public void testFolderSubject() throws Exception
+ {
+ logger.debug("Start testFromName");
+
+ String TEST_EMAIL = "buffy@sunnydale.high";
+
+ folderEmailMessageHandler.setOverwriteDuplicates(true);
+
+ // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
+ NodeRef person = personService.getPerson(TEST_USER);
+ if (person == null)
+ {
+ logger.debug("new person created");
+ Map props = new HashMap();
+ props.put(ContentModel.PROP_USERNAME, TEST_USER);
+ props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
+ person = personService.createPerson(props);
+ }
+ nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
+
+ Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
+ if (!auths.contains(TEST_USER))
+ {
+ authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
+ }
+
+ String companyHomePathInStore = "/app:company_home";
+ String storePath = "workspace://SpacesStore";
+ StoreRef storeRef = new StoreRef(storePath);
+
+ NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
+ NodeRef companyHomeNodeRef = nodeRefs.get(0);
+ assertNotNull("company home is null", companyHomeNodeRef);
+ String companyHomeDBID = ((Long) nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ String testUserDBID = ((Long) nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ NodeRef testUserHomeFolder = (NodeRef) nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
+ assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
+ String testUserHomeDBID = ((Long) nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+
+ /**
+ * Send From the test user TEST_EMAIL to the test user's home
+ */
+ String from = TEST_EMAIL;
+ String to = testUserHomeDBID;
+ String content = "hello world";
+
+ {
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("This is a very very long name in particular it is greater than eitghty six characters which was a problem explored in ALF-9544");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ // Check import with subject containing some "illegal chars"
+ {
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("Illegal<>!*/\\.txt");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ // Check with null subject
+ {
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ // msg.setSubject();
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ // ALF-751 Email ends with period
+ {
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("Foobar.");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ // ALF-751 Email ends with ...
+ {
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("Foobar...");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ // ALF-751 Email subject is blank " ... "
+ {
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject(" ... ");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ // ALF-751 Email subject is a single .
+ {
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject(".");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ }
+
+ }
+
+ /**
+ * ALF-1878
+ *
+ * Duplicate incoming email Subjects over-write each other
+ */
+ public void testMultipleMessagesToFolder() throws Exception
+ {
+ logger.debug("Start testFromName");
+
+ String TEST_EMAIL = "buffy@sunnydale.high";
+
+ String TEST_SUBJECT = "Practical Bee Keeping";
+
+ String TEST_LONG_SUBJECT = "This is a very very long name in particular it is greater than eitghty six characters which was a problem explored in ALF-9544";
+
+ // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
+ NodeRef person = personService.getPerson(TEST_USER);
+ if (person == null)
+ {
+ logger.debug("new person created");
+ Map props = new HashMap();
+ props.put(ContentModel.PROP_USERNAME, TEST_USER);
+ props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
+ person = personService.createPerson(props);
+ }
+ nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
+
+ Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
+ if (!auths.contains(TEST_USER))
+ {
+ authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
+ }
+
+ String companyHomePathInStore = "/app:company_home";
+ String storePath = "workspace://SpacesStore";
+ StoreRef storeRef = new StoreRef(storePath);
+
+ NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
+ NodeRef companyHomeNodeRef = nodeRefs.get(0);
+ assertNotNull("company home is null", companyHomeNodeRef);
+ String companyHomeDBID = ((Long) nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ String testUserDBID = ((Long) nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ NodeRef testUserHomeFolder = (NodeRef) nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
+ assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
+ String testUserHomeDBID = ((Long) nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+
+ // Clean up old messages in test folder
+ List assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef assoc : assocs)
+ {
+ nodeService.deleteNode(assoc.getChildRef());
+ }
+
+ /**
+ * Send From the test user TEST_EMAIL to the test user's home
+ */
+ String from = TEST_EMAIL;
+ String to = testUserHomeDBID;
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject(TEST_SUBJECT);
+ msg.setContent(content, "text/plain");
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+
+ /**
+ * Turn on overwriteDuplicates
+ */
+ logger.debug("Step 1: turn on Overwite Duplicates");
+ folderEmailMessageHandler.setOverwriteDuplicates(true);
+
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ assertEquals("assocs not 1", 1, assocs.size());
+ assertEquals("name of link not as expected", assocs.get(0).getQName(), QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, TEST_SUBJECT));
+ emailService.importMessage(delivery, m);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ assertEquals("assocs not 1", 1, assocs.size());
+
+ /**
+ * Turn off overwrite Duplicates
+ */
+ logger.debug("Step 2: turn off Overwite Duplicates");
+ folderEmailMessageHandler.setOverwriteDuplicates(false);
+ emailService.importMessage(delivery, m);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ assertEquals("assocs not 2", 2, assocs.size());
+ emailService.importMessage(delivery, m);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ assertEquals("assocs not 3", 3, assocs.size());
+
+ /**
+ * Check assoc rename with long names. So truncation and rename need to work together.
+ */
+ logger.debug("Step 3: turn off Overwite Duplicates with long subject name");
+ msg.setSubject(TEST_LONG_SUBJECT);
+ ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
+ msg.writeTo(bos2);
+ is = IOUtils.toInputStream(bos2.toString());
+ assertNotNull("is is null", is);
+ m = new SubethaEmailMessage(is);
+
+ folderEmailMessageHandler.setOverwriteDuplicates(false);
+ emailService.importMessage(delivery, m);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ assertEquals("assocs not 4", 4, assocs.size());
+ emailService.importMessage(delivery, m);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ assertEquals("assocs not 5", 5, assocs.size());
+
+ /**
+ * Check assoc rename with long names and an extension. So truncation and rename need to work together and not muck up a .extension.
+ */
+ logger.debug("Step 4: turn off Overwite Duplicates with long subject name with extension");
+ String EXT_NAME = "Blob.xls";
+
+ msg.setSubject(EXT_NAME);
+ ByteArrayOutputStream bos3 = new ByteArrayOutputStream();
+ msg.writeTo(bos3);
+ is = IOUtils.toInputStream(bos3.toString());
+ assertNotNull("is is null", is);
+ m = new SubethaEmailMessage(is);
+ folderEmailMessageHandler.setOverwriteDuplicates(false);
+ emailService.importMessage(delivery, m);
+ emailService.importMessage(delivery, m);
+ emailService.importMessage(delivery, m);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+
+ List assocNames = new Vector();
+ for (ChildAssociationRef assoc : assocs)
+ {
+ logger.debug("assocName: " + assoc.getQName());
+ System.out.println(assoc.getQName());
+ assocNames.add(assoc.getQName());
+ }
+ assertTrue(EXT_NAME + "not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Blob.xls")));
+ assertTrue("Blob(1).xls not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Blob(1).xls")));
+ assertTrue("Blob(2).xls not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Blob(2).xls")));
+ assertTrue(TEST_SUBJECT + "not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, TEST_SUBJECT)));
+ assertTrue(TEST_SUBJECT + "(1) not found", assocNames.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Practical Bee Keeping(1)")));
+
+ /**
+ * Check concurrent deliver of the same message. Reuse message from the previous test.
+ */
+ logger.debug("Step 5: turn off Overwite Duplicates and check concurrent deliver of the same message");
+ folderEmailMessageHandler.setOverwriteDuplicates(false);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ int numBeforeConcurrentDeliver = assocs.size();
+ deliverConcurrently(delivery, m);
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ int numAfterConcurrentDeliver = assocs.size();
+ assertEquals("Two messages must be added", numBeforeConcurrentDeliver + 2, numAfterConcurrentDeliver);
+ }
+
+ private void deliverConcurrently(final EmailDelivery delivery, final SubethaEmailMessage m) throws Exception
+ {
+ final CountDownLatch cdl = new CountDownLatch(1);
+ class ConcurrentMessageImporter implements Runnable
+ {
+ private Throwable throwable;
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() {
+ public Void execute() throws Throwable
+ {
+ cdl.countDown();
+ emailService.importMessage(delivery, m);
+ return null;
+ }
+ }, false, true);
+ }
+ catch (Throwable t)
+ {
+ throwable = t;
+ }
+ }
+ }
+ ConcurrentMessageImporter messageImporter = new ConcurrentMessageImporter();
+ final Thread messageImporterThread = new Thread(messageImporter);
+ transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() {
+ public Void execute() throws Throwable
+ {
+ emailService.importMessage(delivery, m);
+ messageImporterThread.start();
+ // wait until concurrent transaction has started
+ cdl.await();
+ return null;
+ }
+ }, false, true);
+ messageImporterThread.join();
+ if (null != messageImporter.throwable)
+ {
+ fail(messageImporter.throwable.getMessage());
+ }
+ }
+
+ /**
+ * MNT-9289
+ *
+ * Change in case in email Subject causes DuplicateChildNodeNameException
+ */
+ public void testCaseSensitivity() throws Exception
+ {
+ NodeRef person = personService.getPerson(TEST_USER);
+ String TEST_EMAIL = "buffy@sunnydale.high";
+ NodeRef testUserHomeFolder = (NodeRef) nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
+ if (person == null)
+ {
+ logger.debug("new person created");
+ Map props = new HashMap();
+ props.put(ContentModel.PROP_USERNAME, TEST_USER);
+ props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
+ person = personService.createPerson(props);
+ }
+
+ nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
+
+ Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
+ if (!auths.contains(TEST_USER))
+ {
+ authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
+ }
+
+ String companyHomePathInStore = "/app:company_home";
+ String storePath = "workspace://SpacesStore";
+ StoreRef storeRef = new StoreRef(storePath);
+
+ NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
+ NodeRef companyHomeNodeRef = nodeRefs.get(0);
+ assertNotNull("company home is null", companyHomeNodeRef);
+
+ String TEST_CASE_SENSITIVITY_SUBJECT = "Test (Mail)";
+ String testUserHomeDBID = ((Long) nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+
+ String from = TEST_EMAIL;
+ String to = testUserHomeDBID;
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setContent(content, "text/plain");
+
+ msg.setSubject(TEST_CASE_SENSITIVITY_SUBJECT);
+ ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
+ msg.writeTo(bos1);
+ InputStream is = IOUtils.toInputStream(bos1.toString());
+ assertNotNull("is is null", is);
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+ folderEmailMessageHandler.setOverwriteDuplicates(false);
+ emailService.importMessage(delivery, m);
+
+ QName safeQName = QName.createQNameWithValidLocalName(NamespaceService.CONTENT_MODEL_1_0_URI, TEST_CASE_SENSITIVITY_SUBJECT);
+ List assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, safeQName);
+ assertEquals(1, assocs.size());
+
+ msg.setSubject(TEST_CASE_SENSITIVITY_SUBJECT.toUpperCase());
+ ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
+ msg.writeTo(bos2);
+ is = IOUtils.toInputStream(bos2.toString());
+ assertNotNull("is is null", is);
+ m = new SubethaEmailMessage(is);
+ folderEmailMessageHandler.setOverwriteDuplicates(false);
+ emailService.importMessage(delivery, m);
+
+ safeQName = QName.createQNameWithValidLocalName(NamespaceService.CONTENT_MODEL_1_0_URI, TEST_CASE_SENSITIVITY_SUBJECT.toUpperCase() + "(1)");
+ assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, safeQName);
+ assertEquals(1, assocs.size());
+ }
+
+ /**
+ * ALF-12297
+ *
+ * Test messages being sent to a cm:content node
+ */
+ public void testMessagesToDocument() throws Exception
+ {
+ logger.debug("Start testMessagesToDocument");
+
+ String TEST_EMAIL = "buffy@sunnydale.high";
+
+ String TEST_SUBJECT = "Practical Bee Keeping";
+
+ String TEST_LONG_SUBJECT = "This is a very very long name in particular it is greater than eitghty six characters which was a problem explored in ALF-9544";
+
+ // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
+ NodeRef person = personService.getPerson(TEST_USER);
+ if (person == null)
+ {
+ logger.debug("new person created");
+ Map props = new HashMap();
+ props.put(ContentModel.PROP_USERNAME, TEST_USER);
+ props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
+ person = personService.createPerson(props);
+ }
+ nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
+
+ Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
+ if (!auths.contains(TEST_USER))
+ {
+ authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
+ }
+
+ String companyHomePathInStore = "/app:company_home";
+ String storePath = "workspace://SpacesStore";
+ StoreRef storeRef = new StoreRef(storePath);
+
+ NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
+ NodeRef companyHomeNodeRef = nodeRefs.get(0);
+ assertNotNull("company home is null", companyHomeNodeRef);
+ String companyHomeDBID = ((Long) nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ // String testUserDBID = ((Long)nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ NodeRef testUserHomeFolder = (NodeRef) nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
+ assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
+ // String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+
+ // Clean up old messages in test folder
+ List assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef assoc : assocs)
+ {
+ nodeService.deleteNode(assoc.getChildRef());
+ }
+
+ Map properties = new HashMap();
+ properties.put(ContentModel.PROP_NAME, "bees");
+ properties.put(ContentModel.PROP_DESCRIPTION, "bees - test doc for email tests");
+ ChildAssociationRef testDoc = nodeService.createNode(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "bees"), ContentModel.TYPE_CONTENT, properties);
+ NodeRef testDocNodeRef = testDoc.getChildRef();
+
+ String testDocDBID = ((Long) nodeService.getProperty(testDocNodeRef, ContentModel.PROP_NODE_DBID)).toString();
+
+ /**
+ * Send From the test user TEST_EMAIL to the test user's home
+ */
+ String from = TEST_EMAIL;
+ String to = testDocDBID + "@alfresco.com";
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject(TEST_SUBJECT);
+ msg.setContent(content, "text/plain");
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+
+ /**
+ * Turn on overwriteDuplicates
+ */
+ logger.debug("Step 1: send an email to a doc");
+
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+
+ assertTrue(nodeService.hasAspect(testDocNodeRef, ForumModel.ASPECT_DISCUSSABLE));
+
+ } // end of test sending to cm:content node
+
+ /**
+ * ENH-560 - Inbound email server not working with custom types
+ */
+ public void testMessagesToSubTypeOfDocument() throws Exception
+ {
+ logger.debug("Start testMessagesToSubTypesOfDocument");
+
+ String TEST_EMAIL = "buffy@sunnydale.high";
+
+ String TEST_SUBJECT = "Practical Bee Keeping";
+
+ String TEST_LONG_SUBJECT = "This is a very very long name in particular it is greater than eitghty six characters which was a problem explored in ALF-9544";
+
+ // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
+ NodeRef person = personService.getPerson(TEST_USER);
+ if (person == null)
+ {
+ logger.debug("new person created");
+ Map props = new HashMap();
+ props.put(ContentModel.PROP_USERNAME, TEST_USER);
+ props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
+ person = personService.createPerson(props);
+ }
+ nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
+
+ Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
+ if (!auths.contains(TEST_USER))
+ {
+ authorityService.addAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
+ }
+
+ String companyHomePathInStore = "/app:company_home";
+ String storePath = "workspace://SpacesStore";
+ StoreRef storeRef = new StoreRef(storePath);
+
+ NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
+ NodeRef companyHomeNodeRef = nodeRefs.get(0);
+ assertNotNull("company home is null", companyHomeNodeRef);
+ String companyHomeDBID = ((Long) nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ // String testUserDBID = ((Long)nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ NodeRef testUserHomeFolder = (NodeRef) nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
+ assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
+ // String testUserHomeDBID = ((Long)nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+
+ // Clean up old messages in test folder
+ List assocs = nodeService.getChildAssocs(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef assoc : assocs)
+ {
+ nodeService.deleteNode(assoc.getChildRef());
+ }
+
+ Map properties = new HashMap();
+ properties.put(ContentModel.PROP_NAME, "hamster");
+ properties.put(ContentModel.PROP_DESCRIPTION, "syrian hamsters - test doc for email tests, sending to a subtype of cm:content");
+
+ // Transfer report is a subtype of cm:content
+ ChildAssociationRef testDoc = nodeService.createNode(testUserHomeFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "bees"), TransferModel.TYPE_TRANSFER_REPORT, properties);
+ NodeRef testDocNodeRef = testDoc.getChildRef();
+
+ String testDocDBID = ((Long) nodeService.getProperty(testDocNodeRef, ContentModel.PROP_NODE_DBID)).toString();
+
+ /**
+ * Send From the test user TEST_EMAIL to the test user's home
+ */
+ String from = TEST_EMAIL;
+ String to = testDocDBID + "@alfresco.com";
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject(TEST_SUBJECT);
+ msg.setContent(content, "text/plain");
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+
+ /**
+ * Turn on overwriteDuplicates
+ */
+ logger.debug("Step 1: send an email to a transfer report");
+
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+
+ } // end of test sending to trx:transferReport
+
+ /**
+ * The Email contributors authority controls who can add email.
+ *
+ * This test switches between the EMAIL_CONTRIBUTORS group and EVERYONE
+ */
+ public void testEmailContributorsAuthority() throws Exception
+ {
+ EmailServiceImpl emailServiceImpl = (EmailServiceImpl) emailService;
+
+ folderEmailMessageHandler.setOverwriteDuplicates(true);
+
+ logger.debug("Start testEmailContributorsAuthority");
+
+ String TEST_EMAIL = "buffy@sunnydale.high";
+
+ // TODO Investigate why setting PROP_EMAIL on createPerson does not work.
+ NodeRef person = personService.getPerson(TEST_USER);
+ if (person == null)
+ {
+ logger.debug("new person created");
+ Map props = new HashMap();
+ props.put(ContentModel.PROP_USERNAME, TEST_USER);
+ props.put(ContentModel.PROP_EMAIL, TEST_EMAIL);
+ person = personService.createPerson(props);
+ }
+ nodeService.setProperty(person, ContentModel.PROP_EMAIL, TEST_EMAIL);
+
+ Set auths = authorityService.getContainedAuthorities(null, "GROUP_EMAIL_CONTRIBUTORS", true);
+ if (auths.contains(TEST_USER))
+ {
+ authorityService.removeAuthority("GROUP_EMAIL_CONTRIBUTORS", TEST_USER);
+ }
+
+ String companyHomePathInStore = "/app:company_home";
+ String storePath = "workspace://SpacesStore";
+ StoreRef storeRef = new StoreRef(storePath);
+
+ NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
+ NodeRef companyHomeNodeRef = nodeRefs.get(0);
+ assertNotNull("company home is null", companyHomeNodeRef);
+ String companyHomeDBID = ((Long) nodeService.getProperty(companyHomeNodeRef, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ String testUserDBID = ((Long) nodeService.getProperty(person, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+ NodeRef testUserHomeFolder = (NodeRef) nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER);
+ assertNotNull("testUserHomeFolder is null", testUserHomeFolder);
+ String testUserHomeDBID = ((Long) nodeService.getProperty(testUserHomeFolder, ContentModel.PROP_NODE_DBID)).toString() + "@Alfresco.com";
+
+ /**
+ * Step 1 Set the email contributors authority to EVERYONE
+ *
+ * Test that TEST_USER is allowed to send email - so even though TEST_USER is not a contributor
+ */
+ emailServiceImpl.setEmailContributorsAuthority("EVERYONE");
+
+ String from = "admin";
+ String to = testUserHomeDBID;
+ String content = "hello world";
+
+ Session sess = Session.getDefaultInstance(new Properties());
+ assertNotNull("sess is null", sess);
+ SMTPMessage msg = new SMTPMessage(sess);
+ InternetAddress[] toa = {new InternetAddress(to)};
+
+ msg.setFrom(new InternetAddress(TEST_EMAIL));
+ msg.setRecipients(Message.RecipientType.TO, toa);
+ msg.setSubject("JavaMail APIs transport.java Test");
+ msg.setContent(content, "text/plain");
+
+ StringBuffer sb = new StringBuffer();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ msg.writeTo(bos);
+ InputStream is = IOUtils.toInputStream(bos.toString());
+ assertNotNull("is is null", is);
+
+ SubethaEmailMessage m = new SubethaEmailMessage(is);
+
+ EmailDelivery delivery = new EmailDelivery(to, from, null);
+
+ emailService.importMessage(delivery, m);
+
+ /**
+ * Step 2 Negative test
+ *
+ * Send From the test user TEST_EMAIL to the test user's home
+ */
+ try
+ {
+ logger.debug("Step 2");
+ emailServiceImpl.setEmailContributorsAuthority("EMAIL_CONTRIBUTORS");
+ emailService.importMessage(delivery, m);
+ fail("not thrown out");
+ }
+ catch (EmailMessageException e)
+ {
+ // Check the exception is for the anonymous user.
+ // assertTrue(e.getMessage().contains("anonymous"));
+ }
+ }
+
+} // end of EmailServiceImplTest
diff --git a/repository/src/test/java/org/alfresco/repo/imap/ImapMessageTest.java b/repository/src/test/java/org/alfresco/repo/imap/ImapMessageTest.java
index 24f5c9739e..2ae7b74e6a 100644
--- a/repository/src/test/java/org/alfresco/repo/imap/ImapMessageTest.java
+++ b/repository/src/test/java/org/alfresco/repo/imap/ImapMessageTest.java
@@ -1,871 +1,866 @@
-/*
- * #%L
- * Alfresco Repository
- * %%
- * Copyright (C) 2005 - 2023 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * 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
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- * #L%
- */
-package org.alfresco.repo.imap;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.SequenceInputStream;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-
-import jakarta.mail.Address;
-import jakarta.mail.Folder;
-import jakarta.mail.Message;
-import jakarta.mail.MessagingException;
-import jakarta.mail.Session;
-import jakarta.mail.Store;
-import jakarta.mail.internet.InternetAddress;
-import jakarta.mail.internet.MimeMessage;
-import jakarta.mail.internet.MimeMultipart;
-import jakarta.mail.internet.MimeUtility;
-import jakarta.transaction.UserTransaction;
-
-import junit.framework.TestCase;
-
-import org.alfresco.model.ContentModel;
-import org.alfresco.model.ImapModel;
-import org.alfresco.repo.importer.ACPImportPackageHandler;
-import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
-import org.alfresco.repo.node.integrity.IntegrityChecker;
-import org.alfresco.repo.search.QueryParameterDefImpl;
-import org.alfresco.service.ServiceRegistry;
-import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
-import org.alfresco.service.cmr.model.FileFolderService;
-import org.alfresco.service.cmr.model.FileFolderUtil;
-import org.alfresco.service.cmr.model.FileInfo;
-import org.alfresco.service.cmr.repository.ContentWriter;
-import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.repository.NodeService;
-import org.alfresco.service.cmr.repository.StoreRef;
-import org.alfresco.service.cmr.search.QueryParameterDefinition;
-import org.alfresco.service.cmr.search.SearchService;
-import org.alfresco.service.cmr.security.MutableAuthenticationService;
-import org.alfresco.service.cmr.security.PersonService;
-import org.alfresco.service.cmr.view.ImporterService;
-import org.alfresco.service.cmr.view.Location;
-import org.alfresco.service.namespace.NamespaceService;
-import org.alfresco.service.namespace.QName;
-import org.alfresco.service.transaction.TransactionService;
-import org.alfresco.test_category.OwnJVMTestsCategory;
-import org.alfresco.util.ApplicationContextHelper;
-import org.alfresco.util.GUID;
-import org.alfresco.util.PropertyMap;
-import org.alfresco.util.config.RepositoryFolderConfigBean;
-import org.alfresco.util.testing.category.LuceneTests;
-import org.alfresco.util.testing.category.RedundantTests;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.springframework.context.ApplicationContext;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.mail.javamail.MimeMessageHelper;
-
-import com.sun.mail.iap.ProtocolException;
-import com.sun.mail.iap.Response;
-import com.sun.mail.imap.IMAPFolder;
-import com.sun.mail.imap.protocol.BODY;
-import com.sun.mail.imap.protocol.FetchResponse;
-import com.sun.mail.imap.protocol.IMAPProtocol;
-import com.sun.mail.imap.protocol.IMAPResponse;
-import com.sun.mail.imap.protocol.RFC822DATA;
-import com.sun.mail.imap.protocol.UID;
-import com.sun.mail.util.ASCIIUtility;
-
-import static org.alfresco.model.ContentModel.PROP_MODIFIED;
-
-@Category({OwnJVMTestsCategory.class, LuceneTests.class})
-public class ImapMessageTest extends TestCase
-{
- private static Log logger = LogFactory.getLog(ImapMessageTest.class);
-
- // IMAP client settings
- private static final String PROTOCOL = "imap";
- private static final String HOST = "localhost";
- private static final int PORT = 7143;
-
- private static final String ADMIN_USER_NAME = "admin";
- private static final String ADMIN_USER_PASSWORD = "admin";
- private static final String IMAP_FOLDER_NAME = "test";
-
- private Session session = null;
- private Store store = null;
- private IMAPFolder folder = null;
-
- private ApplicationContext ctx;
- private ServiceRegistry serviceRegistry;
- private TransactionService transactionService;
- private NodeService nodeService;
- private ImporterService importerService;
- private PersonService personService;
- private SearchService searchService;
- private NamespaceService namespaceService;
- private FileFolderService fileFolderService;
- private MutableAuthenticationService authenticationService;
- private AlfrescoImapServer imapServer;
-
- String anotherUserName;
- private NodeRef testImapFolderNodeRef;
- private NodeRef storeRootNodeRef;
- private final String storePath = "workspace://SpacesStore";
- private final String companyHomePathInStore = "/app:company_home";
-
- private static final String TEST_FOLDER = "Alfresco IMAP/" + IMAP_FOLDER_NAME + "/___-___folder_a/" + "___-___folder_a_a";
- private static final String TEST_FILE = "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME + "/" + NamespaceService.CONTENT_MODEL_PREFIX
- + ":___-___folder_a/" + NamespaceService.CONTENT_MODEL_PREFIX + ":___-___folder_a_a/" + NamespaceService.CONTENT_MODEL_PREFIX + ":___-___file_a_a";
-
- @Override
- public void setUp() throws Exception
- {
- ctx = ApplicationContextHelper.getApplicationContext();
- logger.debug("In SetUp");
- serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
- transactionService = serviceRegistry.getTransactionService();
- nodeService = serviceRegistry.getNodeService();
- importerService = serviceRegistry.getImporterService();
- personService = serviceRegistry.getPersonService();
- authenticationService = serviceRegistry.getAuthenticationService();
- searchService = serviceRegistry.getSearchService();
- namespaceService = serviceRegistry.getNamespaceService();
- fileFolderService = serviceRegistry.getFileFolderService();
-
-
- // start the transaction
- UserTransaction txn = transactionService.getUserTransaction();
- txn.begin();
- authenticationService.authenticate(ADMIN_USER_NAME, ADMIN_USER_PASSWORD.toCharArray());
-
- // downgrade integrity
- IntegrityChecker.setWarnInTransaction();
-
- anotherUserName = "user" + System.currentTimeMillis();
-
- PropertyMap testUser = new PropertyMap();
- testUser.put(ContentModel.PROP_USERNAME, anotherUserName);
- testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName);
- testUser.put(ContentModel.PROP_LASTNAME, anotherUserName);
- testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com");
- testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle");
-
- personService.createPerson(testUser);
-
- // create the ACEGI Authentication instance for the new user
- authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray());
-
- StoreRef storeRef = new StoreRef(storePath);
- storeRootNodeRef = nodeService.getRootNode(storeRef);
-
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
- NodeRef companyHomeNodeRef = nodeRefs.get(0);
-
- nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
- namespaceService, false);
- if (nodeRefs != null && nodeRefs.size() > 0)
- {
- fileFolderService.delete(nodeRefs.get(0));
- }
-
- ChildApplicationContextFactory imap = (ChildApplicationContextFactory) ctx.getBean("imap");
- ApplicationContext imapCtx = imap.getApplicationContext();
- ImapServiceImpl imapServiceImpl = (ImapServiceImpl) imapCtx.getBean("imapService");
- imapServer = (AlfrescoImapServer) imapCtx.getBean("imapServer");
-
- if(!imapServer.isImapServerEnabled())
- {
- imapServer.setImapServerEnabled(true);
- imapServer.setHost(HOST);
- imapServer.setPort(PORT);
- imapServer.startup();
- }
-
- // Creating IMAP test folder for IMAP root
- LinkedList folders = new LinkedList();
- folders.add(IMAP_FOLDER_NAME);
- FileFolderUtil.makeFolders(fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);
-
- // Setting IMAP root
- RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
- imapHome.setStore(storePath);
- imapHome.setRootPath(companyHomePathInStore);
- imapHome.setFolderPath(NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME);
- imapServiceImpl.setImapHome(imapHome);
-
-
- // Starting IMAP
- imapServiceImpl.startupInTxn(true);
-
- nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
- namespaceService, false);
- testImapFolderNodeRef = nodeRefs.get(0);
-
- /*
- * Importing test folders: Test folder contains: "___-___folder_a" "___-___folder_a" contains: "___-___folder_a_a", "___-___file_a", "Message_485.eml" (this is IMAP
- * Message) "___-___folder_a_a" contains: "____-____file_a_a"
- */
- importInternal("imap/imapservice_test_folder_a.acp", testImapFolderNodeRef);
-
- txn.commit();
-
- // Init mail client session
- Properties props = new Properties();
- props.setProperty("mail.imap.partialfetch", "false");
- this.session = Session.getDefaultInstance(props, null);
-
- // Get the store
- this.store = session.getStore(PROTOCOL);
- //this.store.connect(HOST, PORT, anotherUserName, anotherUserName);
- this.store.connect(imapServer.getHost(), imapServer.getPort(), anotherUserName, anotherUserName);
-
- // Get folder
- folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
- folder.open(Folder.READ_ONLY);
-
- logger.debug("End SetUp");
-
- }
-
- private void importInternal(String acpName, NodeRef space) throws IOException
- {
- // Importing IMAP test acp
- ClassPathResource acpResource = new ClassPathResource(acpName);
- ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
- Location importLocation = new Location(space);
- importerService.importView(acpHandler, importLocation, null, null);
- }
-
- public void testMessageModifiedBetweenReads() throws Exception
- {
- // Get test message UID
- final Long uid = getMessageUid(folder, 1);
-
- // Get unmodified message
- BODY body = getMessageBody(folder, uid);
-
- // Parse the multipart MIME message
- MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new BufferedInputStream(body.getByteArrayInputStream()));
-
- // Reading first part - should be successful
- MimeMultipart content = (MimeMultipart) message.getContent();
- assertNotNull(content.getBodyPart(0).getContent());
- // Reading second part - should be successful
- assertNotNull(content.getBodyPart(1).getContent());
-
- // Modify message. The size of letter describing the node may change
- // These changes should be committed because it should be visible from client
- NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
- UserTransaction txn = transactionService.getUserTransaction();
- txn.begin();
- ContentWriter writer = fileFolderService.getWriter(contentNode);
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < 2000; i++)
- {
- sb.append("test string");
- }
- writer.putContent(sb.toString());
- txn.commit();
-
- // Read updated message part
- BODY bodyNew = getMessageBody(folder, uid);
-
- // The body should be updated
- assertFalse(Arrays.equals(bodyNew.getByteArray().getBytes(), body.getByteArray().getBytes()));
-
- // Parse the multipart MIME message
- message = new MimeMessage(Session.getDefaultInstance(new Properties()), new BufferedInputStream(bodyNew.getByteArrayInputStream()));
-
- // Reading first part - should be successful
- content = (MimeMultipart) message.getContent();
- assertNotNull(content.getBodyPart(0).getContent());
- // Reading second part - should be successful
- assertNotNull(content.getBodyPart(1).getContent());
- }
-
- public void testMessageRenamedBetweenReads() throws Exception
- {
- // Get test message UID
- final Long uid = getMessageUid(folder, 1);
- // Get Message size
- final int count = getMessageSize(folder, uid);
-
- // Get first part
- // Split the message into 2 part using a non multiple of 4 - 103 is a prime number
- // as the BASE64Decoder may not throw the IOException
- // see MNT-12995
- BODY body = getMessageBodyPart(folder, uid, 0, count - 103);
-
- // Rename message. The size of letter describing the node will change
- // These changes should be committed because it should be visible from client
- NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
- UserTransaction txn = transactionService.getUserTransaction();
- txn.begin();
- fileFolderService.rename(contentNode, "testtesttesttesttesttesttesttesttesttest");
- txn.commit();
-
- // Read second message part
- BODY bodyRest = getMessageBodyPart(folder, uid, count - 103, 103);
-
- // Creating and parsing message from 2 parts
- MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
- new BufferedInputStream(bodyRest.getByteArrayInputStream())));
-
- // Reading first part - should be successful
- MimeMultipart content = (MimeMultipart) message.getContent();
- assertNotNull(content.getBodyPart(0).getContent());
-
- try
- {
- // Reading second part cause error
- content.getBodyPart(1).getContent();
- fail("Should raise an IOException");
- }
- catch (IOException e)
- {
- }
- }
-
- public void dontTestMessageCache() throws Exception
- {
-
- // Create messages
- NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
- UserTransaction txn = transactionService.getUserTransaction();
- txn.begin();
-
- // Create messages more than cache capacity
- for (int i = 0; i < 51; i++)
- {
- FileInfo fi = fileFolderService.create(nodeService.getParentAssocs(contentNode).get(0).getParentRef(), "test" + i, ContentModel.TYPE_CONTENT);
- ContentWriter writer = fileFolderService.getWriter(fi.getNodeRef());
- writer.putContent("test");
- }
-
- txn.commit();
-
- // Reload folder
- folder.close(false);
- folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
- folder.open(Folder.READ_ONLY);
-
- // Read all messages
- for (int i = 1; i < 51; i++)
- {
- // Get test message UID
- final Long uid = getMessageUid(folder, i);
- // Get Message size
- final int count = getMessageSize(folder, uid);
-
- // Get first part
- BODY body = getMessageBodyPart(folder, uid, 0, count - 100);
- // Read second message part
- BODY bodyRest = getMessageBodyPart(folder, uid, count - 100, 100);
-
- // Creating and parsing message from 2 parts
- MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
- new BufferedInputStream(bodyRest.getByteArrayInputStream())));
-
- // Reading first part - should be successful
- MimeMultipart content = (MimeMultipart) message.getContent();
- assertNotNull(content.getBodyPart(0).getContent());
- assertNotNull(content.getBodyPart(1).getContent());
- }
- }
-
- @Test
- public void testSearchTermWithNonEnglishLocale() throws Exception
- {
- folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
- folder.open(Folder.READ_ONLY);
-
- Locale defaultLocale = Locale.getDefault();
- try
- {
- Locale.setDefault(Locale.FRENCH);
- String dateStr = "12-Jul-2020";
- final IMAPFolder.ProtocolCommand uid_search_since = new IMAPFolder.ProtocolCommand()
- {
- @Override
- public Object doCommand(IMAPProtocol protocol)
- {
- return protocol.command("UID SEARCH SINCE " + dateStr, null);
- }
- };
- // UID SEARCH SINCE
- Response[] ret = (Response[]) folder.doCommand(uid_search_since);
- IMAPResponse response = (IMAPResponse) ret[0];
- assertEquals("* SEARCH ", response.toString());
- }
- catch (MessagingException e)
- {
- fail("Date cannot be parsed");
- }
- finally
- {
- Locale.setDefault(defaultLocale);
- }
- }
-
- @Test
- public void testSearchTermWithNonEnglishLocaleFalsePositive() throws Exception
- {
- Locale defaultLocale = Locale.getDefault();
- try
- {
- folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
- folder.open(Folder.READ_ONLY);
-
- Locale.setDefault(Locale.FRENCH);
- String dateStr = "12-juil.-2020";
- final IMAPFolder.ProtocolCommand uid_search_since = new IMAPFolder.ProtocolCommand()
- {
- @Override
- public Object doCommand(IMAPProtocol protocol)
- {
- return protocol.command("UID SEARCH SINCE " + dateStr, null);
- }
- };
- // UID SEARCH SINCE
- Response[] ret = (Response[]) folder.doCommand(uid_search_since);
- assertEquals("java.io.IOException: Connection dropped by server?", ret[0].getException().toString());
- }
- catch (MessagingException e)
- {
- // expected
- }
- finally
- {
- Locale.setDefault(defaultLocale);
- }
- }
-
- public void testUnmodifiedMessage() throws Exception
- {
- // Get test message UID
- final Long uid = getMessageUid(folder, 1);
- // Get Message size
- final int count = getMessageSize(folder, uid);
-
- // Make multiple message reading
- for (int i = 0; i < 100; i++)
- {
- // Get random offset
- int n = (int) ((int) 100 * Math.random());
-
- // Get first part
- BODY body = getMessageBodyPart(folder, uid, 0, count - n);
- // Read second message part
- BODY bodyRest = getMessageBodyPart(folder, uid, count - n, n);
-
- // Creating and parsing message from 2 parts
- MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
- new BufferedInputStream(bodyRest.getByteArrayInputStream())));
-
- MimeMultipart content = (MimeMultipart) message.getContent();
- // Reading first part - should be successful
- assertNotNull(content.getBodyPart(0).getContent());
- // Reading second part - should be successful
- assertNotNull(content.getBodyPart(1).getContent());
- }
- }
-
- public void testEncodedFromToAddresses() throws Exception
- {
- // RFC1342
- String addressString = "ars.kov@gmail.com";
- String personalString = "�?р�?ений Ковальчук";
- InternetAddress address = new InternetAddress(addressString, personalString, "UTF-8");
-
- // Following method returns the address with quoted personal aka <["�?р�?ений Ковальчук"] >
- // NOTE! This should be coincided with RFC822MetadataExtracter. Would 'addresses' be quoted or not?
- // String decodedAddress = address.toUnicodeString();
- // Starting from javax.mail 1.5.6 the address is folded at linear whitespace so that each line is no longer than 76 characters, if possible.
- String decodedAddress = MimeUtility.decodeText(MimeUtility.fold(6, address.toString()));
-
- // InternetAddress.toString(new Address[] {address}) - is used in the RFC822MetadataExtracter
- // So, compare with that
- assertFalse("Non ASCII characters in the address should be encoded", decodedAddress.equals(InternetAddress.toString(new Address[] {address})));
-
- MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
-
- MimeMessageHelper messageHelper = new MimeMessageHelper(message, false, "UTF-8");
-
- messageHelper.setText("This is a sample message for ALF-5647");
- messageHelper.setSubject("This is a sample message for ALF-5647");
- messageHelper.setFrom(address);
- messageHelper.addTo(address);
- messageHelper.addCc(address);
-
- // Creating the message node in the repository
- UserTransaction txn = transactionService.getUserTransaction();
- txn.begin();
- String name = AlfrescoImapConst.MESSAGE_PREFIX + GUID.generate();
- FileInfo messageFile = fileFolderService.create(testImapFolderNodeRef, name, ContentModel.TYPE_CONTENT);
- // Writing a content.
- NodeRef nodeRef = messageFile.getNodeRef();
- Serializable origModified = getModified(nodeRef);
- new IncomingImapMessage(messageFile, serviceRegistry, message);
- txn.commit();
-
- // Calls to new IncomingImapMessage(...) only takes place when a new nodeRef is being created.
- // No other code will be changing the nodeRef. An ImapModel.ASPECT_IMAP_CONTENT is added, which
- // triggers a metadata extract to take place in a post commit method. Previously this would have been a
- // synchronous process. This is no longer true as it may now take place in a T-Engine. So, we need to wait
- // for the extract to take place. There does not
- long end = System.currentTimeMillis()+10000;
- while (System.currentTimeMillis() <= end && origModified.equals(getModified(nodeRef)))
- {
- Thread.currentThread().sleep(1000);
- }
-
- // Getting the transformed properties from the repository
- // cm:originator, cm:addressee, cm:addressees, imap:messageFrom, imap:messageTo, imap:messageCc
- Map properties = nodeService.getProperties(nodeRef);
- String cmOriginator = (String) properties.get(ContentModel.PROP_ORIGINATOR);
- String cmAddressee = (String) properties.get(ContentModel.PROP_ADDRESSEE);
- @SuppressWarnings("unchecked")
- List cmAddressees = (List) properties.get(ContentModel.PROP_ADDRESSEES);
- String imapMessageFrom = (String) properties.get(ImapModel.PROP_MESSAGE_FROM);
- String imapMessageTo = (String) properties.get(ImapModel.PROP_MESSAGE_TO);
- String imapMessageCc = (String) properties.get(ImapModel.PROP_MESSAGE_CC);
-
- assertNotNull(cmOriginator);
- assertEquals(decodedAddress, cmOriginator);
- assertNotNull(cmAddressee);
- assertEquals(decodedAddress, cmAddressee);
- assertNotNull(cmAddressees);
- assertEquals(1, cmAddressees.size());
- assertEquals(decodedAddress, cmAddressees.get(0));
- assertNotNull(imapMessageFrom);
- assertEquals(decodedAddress, imapMessageFrom);
- assertNotNull(imapMessageTo);
- assertEquals(decodedAddress, imapMessageTo);
- assertNotNull(imapMessageCc);
- assertEquals(decodedAddress, imapMessageCc);
- }
-
- private Serializable getModified(NodeRef nodeRef)
- {
- Map origProperties = nodeService.getProperties(nodeRef);
- return origProperties.get(PROP_MODIFIED);
- }
-
- @Category(RedundantTests.class)
- public void testEightBitMessage() throws Exception
- {
-
- Store lstore = session.getStore(PROTOCOL);
- lstore.connect(imapServer.getHost(), imapServer.getPort(), ADMIN_USER_NAME, ADMIN_USER_PASSWORD);
-
- String folderName = "Alfresco IMAP/" + IMAP_FOLDER_NAME;
-
- IMAPFolder lfolder = (IMAPFolder) lstore.getFolder(folderName);
- lfolder.open(Folder.READ_WRITE);
-
- InputStream messageFileInputStream1 = null;
- InputStream messageFileInputStream2 = null;
- try
- {
- ClassPathResource fileResource = new ClassPathResource("imap/test-8bit-message.eml");
- messageFileInputStream1 = new FileInputStream(fileResource.getFile());
- Message message = new MimeMessage(Session.getDefaultInstance(new Properties()), messageFileInputStream1);
- String subject = message.getSubject();
-
- // get original bytes for further comparation
- messageFileInputStream2 = new FileInputStream(fileResource.getFile());
- byte[] original = ASCIIUtility.getBytes(messageFileInputStream2);
-
- Message[] messages = {message};
-
- lfolder.appendMessages(messages);
-
-
-
- // The search is not implemented.
- // SearchTerm term = new HeaderTerm("X-Alfresco-Unique", "test8bit");
- // messages = folder.search(term);
-
- // So wee need to get our test message's UID from the repo
-
- String messageXPath = companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME + "/*[like(@cm:title, $cm:title, true)]";
-
- QueryParameterDefinition[] params = new QueryParameterDefinition[1];
- params[0] = new QueryParameterDefImpl(
- ContentModel.PROP_TITLE,
- serviceRegistry.getDictionaryService().getDataType(DataTypeDefinition.TEXT),
- true,
- subject);
-
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, messageXPath, params, namespaceService, true);
-
-
- // does the message exist
- assertEquals(1, nodeRefs.size());
-
- NodeRef messageNodeRef = nodeRefs.get(0);
-
- // get message UID
- Long dbid = (Long) nodeService.getProperty(messageNodeRef, ContentModel.PROP_NODE_DBID);
-
- // fetch the massage
- RFC822DATA data = getRFC822Message(lfolder, dbid);
-
- assertNotNull("Can't fetch a message from the repositiry", data);
-
- byte[] processed = ASCIIUtility.getBytes(data.getByteArrayInputStream());
-
- assertTrue("Original message doesn't coincide to the message processed by the repository", Arrays.equals(original, processed));
- }
- finally
- {
- if (messageFileInputStream1 != null) messageFileInputStream1.close();
- if (messageFileInputStream2 != null) messageFileInputStream2.close();
- }
-
- // close connection
- lfolder.close(true);
- lstore.close();
-
- }
-
-
- private static RFC822DATA getRFC822Message(final IMAPFolder folder, final long uid) throws MessagingException
- {
- return (RFC822DATA) folder.doCommand(new IMAPFolder.ProtocolCommand()
- {
- public Object doCommand(IMAPProtocol p) throws ProtocolException
- {
- Response[] r = p.command("UID FETCH " + uid + " (RFC822)", null);
- logResponse(r);
- Response response = r[r.length - 1];
- if (!response.isOK())
- {
- throw new ProtocolException("Unable to retrieve message in RFC822 format");
- }
-
- FetchResponse fetchResponse = (FetchResponse) r[0];
- return fetchResponse.getItem(RFC822DATA.class);
- }
- });
-
- }
-
- /**
- * Returns BODY object containing desired message fragment
- *
- * @param folder Folder containing the message
- * @param uid Message UID
- * @param from starting byte
- * @param count bytes to read
- * @return BODY containing desired message fragment
- * @throws MessagingException
- */
- private static BODY getMessageBodyPart(IMAPFolder folder, final Long uid, final Integer from, final Integer count) throws MessagingException
- {
- return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand()
- {
- public Object doCommand(IMAPProtocol p) throws ProtocolException
- {
- Response[] r = p.command("UID FETCH " + uid + " (FLAGS BODY.PEEK[]<" + from + "." + count + ">)", null);
- logResponse(r);
- Response response = r[r.length - 1];
-
- // Grab response
- if (!response.isOK())
- {
- throw new ProtocolException("Unable to retrieve message part <" + from + "." + count + ">");
- }
-
- FetchResponse fetchResponse = (FetchResponse) r[0];
- BODY body = (BODY) fetchResponse.getItem(com.sun.mail.imap.protocol.BODY.class);
- return body;
- }
- });
-
- }
-
- /**
- * Finds node by its path
- *
- * @param path String
- * @return NodeRef
- */
- private NodeRef findNode(String path)
- {
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, path, null, namespaceService, false);
- return nodeRefs.size() > 0 ? nodeRefs.get(0) : null;
- }
-
- /**
- * Returns the UID of the first message in folder
- *
- * @param folder Folder containing the message
- * @param msn message sequence number
- * @return UID of the first message
- * @throws MessagingException
- */
- private static Long getMessageUid(IMAPFolder folder, final int msn) throws MessagingException
- {
- return (Long) folder.doCommand(new IMAPFolder.ProtocolCommand()
- {
- public Object doCommand(IMAPProtocol p) throws ProtocolException
- {
- String command = "FETCH " + msn + " (UID)";
- Response[] r = p.command(command, null);
- logResponse(r);
- Response response = r[r.length - 1];
-
- // Grab response
- if (!response.isOK())
- {
- throw new ProtocolException("Unable to retrieve message UID");
- }
-
- for(int i = 0 ; i < r.length; i++)
- {
- if(r[i] instanceof FetchResponse)
- {
- FetchResponse fetchResponse = (FetchResponse) r[0];
- UID uid = (UID) fetchResponse.getItem(UID.class);
- logger.debug("SECNUM=" + uid.seqnum + ", UID="+uid.uid);
- return uid.uid;
- }
- }
-
- /**
- * Uh-oh - this is where we would intermittently fall over with a class cast exception.
- * The following code probes why we don't have a FetchResponse
- */
- StringBuffer sb = new StringBuffer();
- sb.append("command="+command);
- sb.append('\n');
- sb.append("resp length=" + r.length);
- sb.append('\n');
- for(int i = 0 ; i < r.length; i++)
- {
- logger.error(r[i]);
- sb.append("class=" + r[i].getClass().getName());
- IMAPResponse unexpected = (IMAPResponse)r[i];
- sb.append("key=" + unexpected.getKey());
- sb.append("number=" + unexpected.getNumber());
- sb.append("rest=" + unexpected.getRest());
-
- sb.append("r[" + i + "]=" + r[i] + '\n');
- }
- throw new ProtocolException("getMessageUid: "+ sb.toString());
- }
- });
- }
-
- /**
- * Returns size of the message
- *
- * @param folder Folder containing the message
- * @param uid Message UID
- * @return Returns size of the message
- * @throws MessagingException
- */
- private static Integer getMessageSize(IMAPFolder folder, final Long uid) throws MessagingException
- {
- return getMessageBody(folder, uid).getByteArray().getCount();
- }
-
- /**
- * Returns a full message body
- *
- * @param folder Folder containing the message
- * @param uid Message UID
- * @return Returns size of the message
- * @throws MessagingException
- */
- private static BODY getMessageBody(IMAPFolder folder, final Long uid) throws MessagingException
- {
- return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand()
- {
- public Object doCommand(IMAPProtocol p) throws ProtocolException
- {
- Response[] r = p.command("UID FETCH " + uid + " (FLAGS BODY.PEEK[])", null);
- logResponse(r);
- Response response = r[r.length - 1];
-
- // Grab response
- if (!response.isOK())
- {
- throw new ProtocolException("Unable to retrieve message size");
- }
- FetchResponse fetchResponse = (FetchResponse) r[0];
- BODY body = (BODY) fetchResponse.getItem(BODY.class);
- return body;
- }
- });
- }
-
- /**
- * Simple util for logging response
- *
- * @param r response
- */
- private static void logResponse(Response[] r)
- {
- for (int i = 0; i < r.length; i++)
- {
- logger.debug(r[i]);
- }
- }
-
- @Override
- public void tearDown() throws Exception
- {
- // Deleting created test environment
- logger.debug("tearDown ");
-
- UserTransaction txn = transactionService.getUserTransaction();
- txn.begin();
-
- List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
- namespaceService, false);
- if (nodeRefs != null && nodeRefs.size() > 0)
- {
- fileFolderService.delete(nodeRefs.get(0));
- }
-
- authenticationService.deleteAuthentication(anotherUserName);
- personService.deletePerson(anotherUserName);
-
- txn.commit();
-
- // Closing client connection
- folder.forceClose();
- store.close();
- logger.debug("tearDown end");
- }
-
-}
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2005 - 2025 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.repo.imap;
+
+import static org.alfresco.model.ContentModel.PROP_MODIFIED;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import jakarta.mail.Address;
+import jakarta.mail.Folder;
+import jakarta.mail.Message;
+import jakarta.mail.MessagingException;
+import jakarta.mail.Session;
+import jakarta.mail.Store;
+import jakarta.mail.internet.InternetAddress;
+import jakarta.mail.internet.MimeMessage;
+import jakarta.mail.internet.MimeMultipart;
+import jakarta.mail.internet.MimeUtility;
+import jakarta.transaction.UserTransaction;
+
+import junit.framework.TestCase;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.angus.mail.iap.ProtocolException;
+import org.eclipse.angus.mail.iap.Response;
+import org.eclipse.angus.mail.imap.IMAPFolder;
+import org.eclipse.angus.mail.imap.protocol.BODY;
+import org.eclipse.angus.mail.imap.protocol.FetchResponse;
+import org.eclipse.angus.mail.imap.protocol.IMAPProtocol;
+import org.eclipse.angus.mail.imap.protocol.IMAPResponse;
+import org.eclipse.angus.mail.imap.protocol.RFC822DATA;
+import org.eclipse.angus.mail.imap.protocol.UID;
+import org.eclipse.angus.mail.util.ASCIIUtility;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.mail.javamail.MimeMessageHelper;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.model.ImapModel;
+import org.alfresco.repo.importer.ACPImportPackageHandler;
+import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
+import org.alfresco.repo.node.integrity.IntegrityChecker;
+import org.alfresco.repo.search.QueryParameterDefImpl;
+import org.alfresco.service.ServiceRegistry;
+import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
+import org.alfresco.service.cmr.model.FileFolderService;
+import org.alfresco.service.cmr.model.FileFolderUtil;
+import org.alfresco.service.cmr.model.FileInfo;
+import org.alfresco.service.cmr.repository.ContentWriter;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.search.QueryParameterDefinition;
+import org.alfresco.service.cmr.search.SearchService;
+import org.alfresco.service.cmr.security.MutableAuthenticationService;
+import org.alfresco.service.cmr.security.PersonService;
+import org.alfresco.service.cmr.view.ImporterService;
+import org.alfresco.service.cmr.view.Location;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.transaction.TransactionService;
+import org.alfresco.test_category.OwnJVMTestsCategory;
+import org.alfresco.util.ApplicationContextHelper;
+import org.alfresco.util.GUID;
+import org.alfresco.util.PropertyMap;
+import org.alfresco.util.config.RepositoryFolderConfigBean;
+import org.alfresco.util.testing.category.LuceneTests;
+import org.alfresco.util.testing.category.RedundantTests;
+
+@Category({OwnJVMTestsCategory.class, LuceneTests.class})
+public class ImapMessageTest extends TestCase
+{
+ private static Log logger = LogFactory.getLog(ImapMessageTest.class);
+
+ // IMAP client settings
+ private static final String PROTOCOL = "imap";
+ private static final String HOST = "localhost";
+ private static final int PORT = 7143;
+
+ private static final String ADMIN_USER_NAME = "admin";
+ private static final String ADMIN_USER_PASSWORD = "admin";
+ private static final String IMAP_FOLDER_NAME = "test";
+
+ private Session session = null;
+ private Store store = null;
+ private IMAPFolder folder = null;
+
+ private ApplicationContext ctx;
+ private ServiceRegistry serviceRegistry;
+ private TransactionService transactionService;
+ private NodeService nodeService;
+ private ImporterService importerService;
+ private PersonService personService;
+ private SearchService searchService;
+ private NamespaceService namespaceService;
+ private FileFolderService fileFolderService;
+ private MutableAuthenticationService authenticationService;
+ private AlfrescoImapServer imapServer;
+
+ String anotherUserName;
+ private NodeRef testImapFolderNodeRef;
+ private NodeRef storeRootNodeRef;
+ private final String storePath = "workspace://SpacesStore";
+ private final String companyHomePathInStore = "/app:company_home";
+
+ private static final String TEST_FOLDER = "Alfresco IMAP/" + IMAP_FOLDER_NAME + "/___-___folder_a/" + "___-___folder_a_a";
+ private static final String TEST_FILE = "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME + "/" + NamespaceService.CONTENT_MODEL_PREFIX
+ + ":___-___folder_a/" + NamespaceService.CONTENT_MODEL_PREFIX + ":___-___folder_a_a/" + NamespaceService.CONTENT_MODEL_PREFIX + ":___-___file_a_a";
+
+ @Override
+ public void setUp() throws Exception
+ {
+ ctx = ApplicationContextHelper.getApplicationContext();
+ logger.debug("In SetUp");
+ serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
+ transactionService = serviceRegistry.getTransactionService();
+ nodeService = serviceRegistry.getNodeService();
+ importerService = serviceRegistry.getImporterService();
+ personService = serviceRegistry.getPersonService();
+ authenticationService = serviceRegistry.getAuthenticationService();
+ searchService = serviceRegistry.getSearchService();
+ namespaceService = serviceRegistry.getNamespaceService();
+ fileFolderService = serviceRegistry.getFileFolderService();
+
+ // start the transaction
+ UserTransaction txn = transactionService.getUserTransaction();
+ txn.begin();
+ authenticationService.authenticate(ADMIN_USER_NAME, ADMIN_USER_PASSWORD.toCharArray());
+
+ // downgrade integrity
+ IntegrityChecker.setWarnInTransaction();
+
+ anotherUserName = "user" + System.currentTimeMillis();
+
+ PropertyMap testUser = new PropertyMap();
+ testUser.put(ContentModel.PROP_USERNAME, anotherUserName);
+ testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName);
+ testUser.put(ContentModel.PROP_LASTNAME, anotherUserName);
+ testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com");
+ testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle");
+
+ personService.createPerson(testUser);
+
+ // create the ACEGI Authentication instance for the new user
+ authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray());
+
+ StoreRef storeRef = new StoreRef(storePath);
+ storeRootNodeRef = nodeService.getRootNode(storeRef);
+
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
+ NodeRef companyHomeNodeRef = nodeRefs.get(0);
+
+ nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
+ namespaceService, false);
+ if (nodeRefs != null && nodeRefs.size() > 0)
+ {
+ fileFolderService.delete(nodeRefs.get(0));
+ }
+
+ ChildApplicationContextFactory imap = (ChildApplicationContextFactory) ctx.getBean("imap");
+ ApplicationContext imapCtx = imap.getApplicationContext();
+ ImapServiceImpl imapServiceImpl = (ImapServiceImpl) imapCtx.getBean("imapService");
+ imapServer = (AlfrescoImapServer) imapCtx.getBean("imapServer");
+
+ if (!imapServer.isImapServerEnabled())
+ {
+ imapServer.setImapServerEnabled(true);
+ imapServer.setHost(HOST);
+ imapServer.setPort(PORT);
+ imapServer.startup();
+ }
+
+ // Creating IMAP test folder for IMAP root
+ LinkedList folders = new LinkedList();
+ folders.add(IMAP_FOLDER_NAME);
+ FileFolderUtil.makeFolders(fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);
+
+ // Setting IMAP root
+ RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
+ imapHome.setStore(storePath);
+ imapHome.setRootPath(companyHomePathInStore);
+ imapHome.setFolderPath(NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME);
+ imapServiceImpl.setImapHome(imapHome);
+
+ // Starting IMAP
+ imapServiceImpl.startupInTxn(true);
+
+ nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
+ namespaceService, false);
+ testImapFolderNodeRef = nodeRefs.get(0);
+
+ /* Importing test folders: Test folder contains: "___-___folder_a" "___-___folder_a" contains: "___-___folder_a_a", "___-___file_a", "Message_485.eml" (this is IMAP Message) "___-___folder_a_a" contains: "____-____file_a_a" */
+ importInternal("imap/imapservice_test_folder_a.acp", testImapFolderNodeRef);
+
+ txn.commit();
+
+ // Init mail client session
+ Properties props = new Properties();
+ props.setProperty("mail.imap.partialfetch", "false");
+ this.session = Session.getDefaultInstance(props, null);
+
+ // Get the store
+ this.store = session.getStore(PROTOCOL);
+ // this.store.connect(HOST, PORT, anotherUserName, anotherUserName);
+ this.store.connect(imapServer.getHost(), imapServer.getPort(), anotherUserName, anotherUserName);
+
+ // Get folder
+ folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
+ folder.open(Folder.READ_ONLY);
+
+ logger.debug("End SetUp");
+
+ }
+
+ private void importInternal(String acpName, NodeRef space) throws IOException
+ {
+ // Importing IMAP test acp
+ ClassPathResource acpResource = new ClassPathResource(acpName);
+ ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
+ Location importLocation = new Location(space);
+ importerService.importView(acpHandler, importLocation, null, null);
+ }
+
+ public void testMessageModifiedBetweenReads() throws Exception
+ {
+ // Get test message UID
+ final Long uid = getMessageUid(folder, 1);
+
+ // Get unmodified message
+ BODY body = getMessageBody(folder, uid);
+
+ // Parse the multipart MIME message
+ MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new BufferedInputStream(body.getByteArrayInputStream()));
+
+ // Reading first part - should be successful
+ MimeMultipart content = (MimeMultipart) message.getContent();
+ assertNotNull(content.getBodyPart(0).getContent());
+ // Reading second part - should be successful
+ assertNotNull(content.getBodyPart(1).getContent());
+
+ // Modify message. The size of letter describing the node may change
+ // These changes should be committed because it should be visible from client
+ NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
+ UserTransaction txn = transactionService.getUserTransaction();
+ txn.begin();
+ ContentWriter writer = fileFolderService.getWriter(contentNode);
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < 2000; i++)
+ {
+ sb.append("test string");
+ }
+ writer.putContent(sb.toString());
+ txn.commit();
+
+ // Read updated message part
+ BODY bodyNew = getMessageBody(folder, uid);
+
+ // The body should be updated
+ assertFalse(Arrays.equals(bodyNew.getByteArray().getBytes(), body.getByteArray().getBytes()));
+
+ // Parse the multipart MIME message
+ message = new MimeMessage(Session.getDefaultInstance(new Properties()), new BufferedInputStream(bodyNew.getByteArrayInputStream()));
+
+ // Reading first part - should be successful
+ content = (MimeMultipart) message.getContent();
+ assertNotNull(content.getBodyPart(0).getContent());
+ // Reading second part - should be successful
+ assertNotNull(content.getBodyPart(1).getContent());
+ }
+
+ public void testMessageRenamedBetweenReads() throws Exception
+ {
+ // Get test message UID
+ final Long uid = getMessageUid(folder, 1);
+ // Get Message size
+ final int count = getMessageSize(folder, uid);
+
+ // Get first part
+ // Split the message into 2 part using a non multiple of 4 - 103 is a prime number
+ // as the BASE64Decoder may not throw the IOException
+ // see MNT-12995
+ BODY body = getMessageBodyPart(folder, uid, 0, count - 103);
+
+ // Rename message. The size of letter describing the node will change
+ // These changes should be committed because it should be visible from client
+ NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
+ UserTransaction txn = transactionService.getUserTransaction();
+ txn.begin();
+ fileFolderService.rename(contentNode, "testtesttesttesttesttesttesttesttesttest");
+ txn.commit();
+
+ // Read second message part
+ BODY bodyRest = getMessageBodyPart(folder, uid, count - 103, 103);
+
+ // Creating and parsing message from 2 parts
+ MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
+ new BufferedInputStream(bodyRest.getByteArrayInputStream())));
+
+ // Reading first part - should be successful
+ MimeMultipart content = (MimeMultipart) message.getContent();
+ assertNotNull(content.getBodyPart(0).getContent());
+
+ try
+ {
+ // Reading second part cause error
+ content.getBodyPart(1).getContent();
+ fail("Should raise an IOException");
+ }
+ catch (IOException e)
+ {}
+ }
+
+ public void dontTestMessageCache() throws Exception
+ {
+
+ // Create messages
+ NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
+ UserTransaction txn = transactionService.getUserTransaction();
+ txn.begin();
+
+ // Create messages more than cache capacity
+ for (int i = 0; i < 51; i++)
+ {
+ FileInfo fi = fileFolderService.create(nodeService.getParentAssocs(contentNode).get(0).getParentRef(), "test" + i, ContentModel.TYPE_CONTENT);
+ ContentWriter writer = fileFolderService.getWriter(fi.getNodeRef());
+ writer.putContent("test");
+ }
+
+ txn.commit();
+
+ // Reload folder
+ folder.close(false);
+ folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
+ folder.open(Folder.READ_ONLY);
+
+ // Read all messages
+ for (int i = 1; i < 51; i++)
+ {
+ // Get test message UID
+ final Long uid = getMessageUid(folder, i);
+ // Get Message size
+ final int count = getMessageSize(folder, uid);
+
+ // Get first part
+ BODY body = getMessageBodyPart(folder, uid, 0, count - 100);
+ // Read second message part
+ BODY bodyRest = getMessageBodyPart(folder, uid, count - 100, 100);
+
+ // Creating and parsing message from 2 parts
+ MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
+ new BufferedInputStream(bodyRest.getByteArrayInputStream())));
+
+ // Reading first part - should be successful
+ MimeMultipart content = (MimeMultipart) message.getContent();
+ assertNotNull(content.getBodyPart(0).getContent());
+ assertNotNull(content.getBodyPart(1).getContent());
+ }
+ }
+
+ @Test
+ public void testSearchTermWithNonEnglishLocale() throws Exception
+ {
+ folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
+ folder.open(Folder.READ_ONLY);
+
+ Locale defaultLocale = Locale.getDefault();
+ try
+ {
+ Locale.setDefault(Locale.FRENCH);
+ String dateStr = "12-Jul-2020";
+ final IMAPFolder.ProtocolCommand uid_search_since = new IMAPFolder.ProtocolCommand() {
+ @Override
+ public Object doCommand(IMAPProtocol protocol)
+ {
+ return protocol.command("UID SEARCH SINCE " + dateStr, null);
+ }
+ };
+ // UID SEARCH SINCE
+ Response[] ret = (Response[]) folder.doCommand(uid_search_since);
+ IMAPResponse response = (IMAPResponse) ret[0];
+ assertEquals("* SEARCH ", response.toString());
+ }
+ catch (MessagingException e)
+ {
+ fail("Date cannot be parsed");
+ }
+ finally
+ {
+ Locale.setDefault(defaultLocale);
+ }
+ }
+
+ @Test
+ public void testSearchTermWithNonEnglishLocaleFalsePositive() throws Exception
+ {
+ Locale defaultLocale = Locale.getDefault();
+ try
+ {
+ folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
+ folder.open(Folder.READ_ONLY);
+
+ Locale.setDefault(Locale.FRENCH);
+ String dateStr = "12-juil.-2020";
+ final IMAPFolder.ProtocolCommand uid_search_since = new IMAPFolder.ProtocolCommand() {
+ @Override
+ public Object doCommand(IMAPProtocol protocol)
+ {
+ return protocol.command("UID SEARCH SINCE " + dateStr, null);
+ }
+ };
+ // UID SEARCH SINCE
+ Response[] ret = (Response[]) folder.doCommand(uid_search_since);
+ assertEquals("java.io.IOException: Connection dropped by server?", ret[0].getException().toString());
+ }
+ catch (MessagingException e)
+ {
+ // expected
+ }
+ finally
+ {
+ Locale.setDefault(defaultLocale);
+ }
+ }
+
+ public void testUnmodifiedMessage() throws Exception
+ {
+ // Get test message UID
+ final Long uid = getMessageUid(folder, 1);
+ // Get Message size
+ final int count = getMessageSize(folder, uid);
+
+ // Make multiple message reading
+ for (int i = 0; i < 100; i++)
+ {
+ // Get random offset
+ int n = (int) ((int) 100 * Math.random());
+
+ // Get first part
+ BODY body = getMessageBodyPart(folder, uid, 0, count - n);
+ // Read second message part
+ BODY bodyRest = getMessageBodyPart(folder, uid, count - n, n);
+
+ // Creating and parsing message from 2 parts
+ MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
+ new BufferedInputStream(bodyRest.getByteArrayInputStream())));
+
+ MimeMultipart content = (MimeMultipart) message.getContent();
+ // Reading first part - should be successful
+ assertNotNull(content.getBodyPart(0).getContent());
+ // Reading second part - should be successful
+ assertNotNull(content.getBodyPart(1).getContent());
+ }
+ }
+
+ public void testEncodedFromToAddresses() throws Exception
+ {
+ // RFC1342
+ String addressString = "ars.kov@gmail.com";
+ String personalString = "�?р�?ений Ковальчук";
+ InternetAddress address = new InternetAddress(addressString, personalString, "UTF-8");
+
+ // Following method returns the address with quoted personal aka <["�?р�?ений Ковальчук"] >
+ // NOTE! This should be coincided with RFC822MetadataExtracter. Would 'addresses' be quoted or not?
+ // String decodedAddress = address.toUnicodeString();
+ // Starting from javax.mail 1.5.6 the address is folded at linear whitespace so that each line is no longer than 76 characters, if possible.
+ String decodedAddress = MimeUtility.decodeText(MimeUtility.fold(6, address.toString()));
+
+ // InternetAddress.toString(new Address[] {address}) - is used in the RFC822MetadataExtracter
+ // So, compare with that
+ assertFalse("Non ASCII characters in the address should be encoded", decodedAddress.equals(InternetAddress.toString(new Address[]{address})));
+
+ MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
+
+ MimeMessageHelper messageHelper = new MimeMessageHelper(message, false, "UTF-8");
+
+ messageHelper.setText("This is a sample message for ALF-5647");
+ messageHelper.setSubject("This is a sample message for ALF-5647");
+ messageHelper.setFrom(address);
+ messageHelper.addTo(address);
+ messageHelper.addCc(address);
+
+ // Creating the message node in the repository
+ UserTransaction txn = transactionService.getUserTransaction();
+ txn.begin();
+ String name = AlfrescoImapConst.MESSAGE_PREFIX + GUID.generate();
+ FileInfo messageFile = fileFolderService.create(testImapFolderNodeRef, name, ContentModel.TYPE_CONTENT);
+ // Writing a content.
+ NodeRef nodeRef = messageFile.getNodeRef();
+ Serializable origModified = getModified(nodeRef);
+ new IncomingImapMessage(messageFile, serviceRegistry, message);
+ txn.commit();
+
+ // Calls to new IncomingImapMessage(...) only takes place when a new nodeRef is being created.
+ // No other code will be changing the nodeRef. An ImapModel.ASPECT_IMAP_CONTENT is added, which
+ // triggers a metadata extract to take place in a post commit method. Previously this would have been a
+ // synchronous process. This is no longer true as it may now take place in a T-Engine. So, we need to wait
+ // for the extract to take place. There does not
+ long end = System.currentTimeMillis() + 10000;
+ while (System.currentTimeMillis() <= end && origModified.equals(getModified(nodeRef)))
+ {
+ Thread.currentThread().sleep(1000);
+ }
+
+ // Getting the transformed properties from the repository
+ // cm:originator, cm:addressee, cm:addressees, imap:messageFrom, imap:messageTo, imap:messageCc
+ Map properties = nodeService.getProperties(nodeRef);
+ String cmOriginator = (String) properties.get(ContentModel.PROP_ORIGINATOR);
+ String cmAddressee = (String) properties.get(ContentModel.PROP_ADDRESSEE);
+ @SuppressWarnings("unchecked")
+ List cmAddressees = (List) properties.get(ContentModel.PROP_ADDRESSEES);
+ String imapMessageFrom = (String) properties.get(ImapModel.PROP_MESSAGE_FROM);
+ String imapMessageTo = (String) properties.get(ImapModel.PROP_MESSAGE_TO);
+ String imapMessageCc = (String) properties.get(ImapModel.PROP_MESSAGE_CC);
+
+ assertNotNull(cmOriginator);
+ assertEquals(decodedAddress, cmOriginator);
+ assertNotNull(cmAddressee);
+ assertEquals(decodedAddress, cmAddressee);
+ assertNotNull(cmAddressees);
+ assertEquals(1, cmAddressees.size());
+ assertEquals(decodedAddress, cmAddressees.get(0));
+ assertNotNull(imapMessageFrom);
+ assertEquals(decodedAddress, imapMessageFrom);
+ assertNotNull(imapMessageTo);
+ assertEquals(decodedAddress, imapMessageTo);
+ assertNotNull(imapMessageCc);
+ assertEquals(decodedAddress, imapMessageCc);
+ }
+
+ private Serializable getModified(NodeRef nodeRef)
+ {
+ Map origProperties = nodeService.getProperties(nodeRef);
+ return origProperties.get(PROP_MODIFIED);
+ }
+
+ @Category(RedundantTests.class)
+ public void testEightBitMessage() throws Exception
+ {
+
+ Store lstore = session.getStore(PROTOCOL);
+ lstore.connect(imapServer.getHost(), imapServer.getPort(), ADMIN_USER_NAME, ADMIN_USER_PASSWORD);
+
+ String folderName = "Alfresco IMAP/" + IMAP_FOLDER_NAME;
+
+ IMAPFolder lfolder = (IMAPFolder) lstore.getFolder(folderName);
+ lfolder.open(Folder.READ_WRITE);
+
+ InputStream messageFileInputStream1 = null;
+ InputStream messageFileInputStream2 = null;
+ try
+ {
+ ClassPathResource fileResource = new ClassPathResource("imap/test-8bit-message.eml");
+ messageFileInputStream1 = new FileInputStream(fileResource.getFile());
+ Message message = new MimeMessage(Session.getDefaultInstance(new Properties()), messageFileInputStream1);
+ String subject = message.getSubject();
+
+ // get original bytes for further comparation
+ messageFileInputStream2 = new FileInputStream(fileResource.getFile());
+ byte[] original = ASCIIUtility.getBytes(messageFileInputStream2);
+
+ Message[] messages = {message};
+
+ lfolder.appendMessages(messages);
+
+ // The search is not implemented.
+ // SearchTerm term = new HeaderTerm("X-Alfresco-Unique", "test8bit");
+ // messages = folder.search(term);
+
+ // So wee need to get our test message's UID from the repo
+
+ String messageXPath = companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME + "/*[like(@cm:title, $cm:title, true)]";
+
+ QueryParameterDefinition[] params = new QueryParameterDefinition[1];
+ params[0] = new QueryParameterDefImpl(
+ ContentModel.PROP_TITLE,
+ serviceRegistry.getDictionaryService().getDataType(DataTypeDefinition.TEXT),
+ true,
+ subject);
+
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, messageXPath, params, namespaceService, true);
+
+ // does the message exist
+ assertEquals(1, nodeRefs.size());
+
+ NodeRef messageNodeRef = nodeRefs.get(0);
+
+ // get message UID
+ Long dbid = (Long) nodeService.getProperty(messageNodeRef, ContentModel.PROP_NODE_DBID);
+
+ // fetch the massage
+ RFC822DATA data = getRFC822Message(lfolder, dbid);
+
+ assertNotNull("Can't fetch a message from the repositiry", data);
+
+ byte[] processed = ASCIIUtility.getBytes(data.getByteArrayInputStream());
+
+ assertTrue("Original message doesn't coincide to the message processed by the repository", Arrays.equals(original, processed));
+ }
+ finally
+ {
+ if (messageFileInputStream1 != null)
+ messageFileInputStream1.close();
+ if (messageFileInputStream2 != null)
+ messageFileInputStream2.close();
+ }
+
+ // close connection
+ lfolder.close(true);
+ lstore.close();
+
+ }
+
+ private static RFC822DATA getRFC822Message(final IMAPFolder folder, final long uid) throws MessagingException
+ {
+ return (RFC822DATA) folder.doCommand(new IMAPFolder.ProtocolCommand() {
+ public Object doCommand(IMAPProtocol p) throws ProtocolException
+ {
+ Response[] r = p.command("UID FETCH " + uid + " (RFC822)", null);
+ logResponse(r);
+ Response response = r[r.length - 1];
+ if (!response.isOK())
+ {
+ throw new ProtocolException("Unable to retrieve message in RFC822 format");
+ }
+
+ FetchResponse fetchResponse = (FetchResponse) r[0];
+ return fetchResponse.getItem(RFC822DATA.class);
+ }
+ });
+
+ }
+
+ /**
+ * Returns BODY object containing desired message fragment
+ *
+ * @param folder
+ * Folder containing the message
+ * @param uid
+ * Message UID
+ * @param from
+ * starting byte
+ * @param count
+ * bytes to read
+ * @return BODY containing desired message fragment
+ * @throws MessagingException
+ */
+ private static BODY getMessageBodyPart(IMAPFolder folder, final Long uid, final Integer from, final Integer count) throws MessagingException
+ {
+ return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand() {
+ public Object doCommand(IMAPProtocol p) throws ProtocolException
+ {
+ Response[] r = p.command("UID FETCH " + uid + " (FLAGS BODY.PEEK[]<" + from + "." + count + ">)", null);
+ logResponse(r);
+ Response response = r[r.length - 1];
+
+ // Grab response
+ if (!response.isOK())
+ {
+ throw new ProtocolException("Unable to retrieve message part <" + from + "." + count + ">");
+ }
+
+ FetchResponse fetchResponse = (FetchResponse) r[0];
+ BODY body = (BODY) fetchResponse.getItem(BODY.class);
+ return body;
+ }
+ });
+
+ }
+
+ /**
+ * Finds node by its path
+ *
+ * @param path
+ * String
+ * @return NodeRef
+ */
+ private NodeRef findNode(String path)
+ {
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, path, null, namespaceService, false);
+ return nodeRefs.size() > 0 ? nodeRefs.get(0) : null;
+ }
+
+ /**
+ * Returns the UID of the first message in folder
+ *
+ * @param folder
+ * Folder containing the message
+ * @param msn
+ * message sequence number
+ * @return UID of the first message
+ * @throws MessagingException
+ */
+ private static Long getMessageUid(IMAPFolder folder, final int msn) throws MessagingException
+ {
+ return (Long) folder.doCommand(new IMAPFolder.ProtocolCommand() {
+ public Object doCommand(IMAPProtocol p) throws ProtocolException
+ {
+ String command = "FETCH " + msn + " (UID)";
+ Response[] r = p.command(command, null);
+ logResponse(r);
+ Response response = r[r.length - 1];
+
+ // Grab response
+ if (!response.isOK())
+ {
+ throw new ProtocolException("Unable to retrieve message UID");
+ }
+
+ for (int i = 0; i < r.length; i++)
+ {
+ if (r[i] instanceof FetchResponse)
+ {
+ FetchResponse fetchResponse = (FetchResponse) r[0];
+ UID uid = (UID) fetchResponse.getItem(UID.class);
+ logger.debug("SECNUM=" + uid.seqnum + ", UID=" + uid.uid);
+ return uid.uid;
+ }
+ }
+
+ /**
+ * Uh-oh - this is where we would intermittently fall over with a class cast exception. The following code probes why we don't have a FetchResponse
+ */
+ StringBuffer sb = new StringBuffer();
+ sb.append("command=" + command);
+ sb.append('\n');
+ sb.append("resp length=" + r.length);
+ sb.append('\n');
+ for (int i = 0; i < r.length; i++)
+ {
+ logger.error(r[i]);
+ sb.append("class=" + r[i].getClass().getName());
+ IMAPResponse unexpected = (IMAPResponse) r[i];
+ sb.append("key=" + unexpected.getKey());
+ sb.append("number=" + unexpected.getNumber());
+ sb.append("rest=" + unexpected.getRest());
+
+ sb.append("r[" + i + "]=" + r[i] + '\n');
+ }
+ throw new ProtocolException("getMessageUid: " + sb.toString());
+ }
+ });
+ }
+
+ /**
+ * Returns size of the message
+ *
+ * @param folder
+ * Folder containing the message
+ * @param uid
+ * Message UID
+ * @return Returns size of the message
+ * @throws MessagingException
+ */
+ private static Integer getMessageSize(IMAPFolder folder, final Long uid) throws MessagingException
+ {
+ return getMessageBody(folder, uid).getByteArray().getCount();
+ }
+
+ /**
+ * Returns a full message body
+ *
+ * @param folder
+ * Folder containing the message
+ * @param uid
+ * Message UID
+ * @return Returns size of the message
+ * @throws MessagingException
+ */
+ private static BODY getMessageBody(IMAPFolder folder, final Long uid) throws MessagingException
+ {
+ return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand() {
+ public Object doCommand(IMAPProtocol p) throws ProtocolException
+ {
+ Response[] r = p.command("UID FETCH " + uid + " (FLAGS BODY.PEEK[])", null);
+ logResponse(r);
+ Response response = r[r.length - 1];
+
+ // Grab response
+ if (!response.isOK())
+ {
+ throw new ProtocolException("Unable to retrieve message size");
+ }
+ FetchResponse fetchResponse = (FetchResponse) r[0];
+ BODY body = (BODY) fetchResponse.getItem(BODY.class);
+ return body;
+ }
+ });
+ }
+
+ /**
+ * Simple util for logging response
+ *
+ * @param r
+ * response
+ */
+ private static void logResponse(Response[] r)
+ {
+ for (int i = 0; i < r.length; i++)
+ {
+ logger.debug(r[i]);
+ }
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ // Deleting created test environment
+ logger.debug("tearDown ");
+
+ UserTransaction txn = transactionService.getUserTransaction();
+ txn.begin();
+
+ List nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
+ namespaceService, false);
+ if (nodeRefs != null && nodeRefs.size() > 0)
+ {
+ fileFolderService.delete(nodeRefs.get(0));
+ }
+
+ authenticationService.deleteAuthentication(anotherUserName);
+ personService.deletePerson(anotherUserName);
+
+ txn.commit();
+
+ // Closing client connection
+ folder.forceClose();
+ store.close();
+ logger.debug("tearDown end");
+ }
+
+}