From 1c779e6ff3d123f29f369628b1afbfa5656d55d2 Mon Sep 17 00:00:00 2001 From: Mark Rogers Date: Mon, 3 Oct 2011 13:51:54 +0000 Subject: [PATCH] Merge V3.4 TO HEAD 30844 : ALF-9544 Inbound email restricts file name to 86 characters or less. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30920 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../email/server/EmailServiceImplTest.java | 324 ++++++++++++++++++ .../handler/AbstractEmailMessageHandler.java | 7 +- .../handler/FolderEmailMessageHandler.java | 4 +- 3 files changed, 331 insertions(+), 4 deletions(-) create mode 100644 source/java/org/alfresco/email/server/EmailServiceImplTest.java diff --git a/source/java/org/alfresco/email/server/EmailServiceImplTest.java b/source/java/org/alfresco/email/server/EmailServiceImplTest.java new file mode 100644 index 0000000000..39ef252d9c --- /dev/null +++ b/source/java/org/alfresco/email/server/EmailServiceImplTest.java @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * 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 . + */ +package org.alfresco.email.server; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; +import java.util.Set; +import java.io.Serializable; + +import javax.mail.Address; +import javax.mail.Message; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; + +import org.alfresco.email.server.impl.subetha.SubethaEmailMessage; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.imap.ImapServiceImpl; +import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.person.PersonServiceImpl; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.admin.AdminService; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; +import org.alfresco.service.cmr.email.EmailMessage; +import org.alfresco.service.cmr.email.EmailMessageException; +import org.alfresco.service.cmr.email.EmailService; +import org.alfresco.service.cmr.lock.LockService; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.CopyService; +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.MutableAuthenticationService; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.cmr.version.VersionService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.transaction.TransactionService; +import org.alfresco.util.ApplicationContextHelper; +import org.alfresco.util.BaseSpringTest; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.filters.StringInputStream; +import org.springframework.context.ApplicationContext; + +import com.sun.mail.smtp.SMTPMessage; + +import junit.framework.TestCase; + +/** + * Unit test of EmailServiceImplTest + * @author mrogers + * + */ +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; + + 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); + searchService = (SearchService)emailCtx.getBean("SearchService"); + assertNotNull("searchService", searchService); + namespaceService = (NamespaceService)emailCtx.getBean("NamespaceService"); + assertNotNull("namespaceService", namespaceService); + } + + 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 + { + + 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 = new StringInputStream(bos.toString()); + assertNotNull("is is null", is); + + SubethaEmailMessage m = new SubethaEmailMessage(from, to, is); + + emailService.importMessage(m); + fail("anonymous user not rejected"); + } + catch (EmailMessageException e) + { + // Check the exception is for the anonymous user. + assertTrue(e.getMessage().contains("anonymous")); + } + + /** + * Step 2 + * + * 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("JavaMail APIs transport.java Test"); + msg.setContent(content, "text/plain"); + + StringBuffer sb = new StringBuffer(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + msg.writeTo(bos); + InputStream is = new StringInputStream(bos.toString()); + assertNotNull("is is null", is); + + SubethaEmailMessage m = new SubethaEmailMessage(from, to, is); + + emailService.importMessage(m); + } + + + /** + * ALF-9544 + * + * Inbound email to a folder restricts file name to 86 characters or less. + */ + public void testFolderSubject() throws Exception + { + 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"; + + /** + * 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 = new StringInputStream(bos.toString()); + assertNotNull("is is null", is); + + SubethaEmailMessage m = new SubethaEmailMessage(from, to, is); + + emailService.importMessage(m); + + } + + + +} diff --git a/source/java/org/alfresco/email/server/handler/AbstractEmailMessageHandler.java b/source/java/org/alfresco/email/server/handler/AbstractEmailMessageHandler.java index 9075505bad..ddc9b4cfba 100644 --- a/source/java/org/alfresco/email/server/handler/AbstractEmailMessageHandler.java +++ b/source/java/org/alfresco/email/server/handler/AbstractEmailMessageHandler.java @@ -274,17 +274,20 @@ public abstract class AbstractEmailMessageHandler implements EmailMessageHandler NodeRef childNodeRef = nodeService.getChildByName(parent, assocType, name); if (childNodeRef != null) { - // The node is present already. Make sure the name csae is correct + // The node is present already. Make sure the name case is correct nodeService.setProperty(childNodeRef, ContentModel.PROP_NAME, name); } else { Map contentProps = new HashMap(); contentProps.put(ContentModel.PROP_NAME, name); + + QName assocName = QName.createQNameWithValidLocalName(NamespaceService.CONTENT_MODEL_1_0_URI, name); + ChildAssociationRef associationRef = nodeService.createNode( parent, assocType, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), + assocName, ContentModel.TYPE_CONTENT, contentProps); childNodeRef = associationRef.getChildRef(); diff --git a/source/java/org/alfresco/email/server/handler/FolderEmailMessageHandler.java b/source/java/org/alfresco/email/server/handler/FolderEmailMessageHandler.java index fc636e1cc4..2c27dcce41 100644 --- a/source/java/org/alfresco/email/server/handler/FolderEmailMessageHandler.java +++ b/source/java/org/alfresco/email/server/handler/FolderEmailMessageHandler.java @@ -63,11 +63,11 @@ public class FolderEmailMessageHandler extends AbstractEmailMessageHandler { if (log.isDebugEnabled()) { - log.debug("Message is psocessing by SpaceMailMessageHandler"); + log.debug("Message is processing by FolderMailMessageHandler"); } try { - // Check type of the node. It must be a SPACE + // Check type of the node. It must be a FOLDER QName nodeTypeQName = getNodeService().getType(nodeRef); if (getDictionaryService().isSubClass(nodeTypeQName, ContentModel.TYPE_FOLDER))