From c34887d6b6d3c494b316d91d04e1c8159b0ea6a6 Mon Sep 17 00:00:00 2001 From: benwa Date: Wed, 9 Dec 2015 18:53:57 +0100 Subject: [PATCH 1/5] JAMES-1619 Unit tests for LocalDelivery mailet - with no SieveScript - with and without virtual hosting --- server/mailet/mailets/pom.xml | 12 ++ .../mailets/delivery/LocalDeliveryTest.java | 187 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml index 067753ba63f..e8c4999d24c 100644 --- a/server/mailet/mailets/pom.xml +++ b/server/mailet/mailets/pom.xml @@ -164,6 +164,18 @@ test-jar test + + org.apache.james + apache-james-mailbox-api + ${mailbox.version} + test + test-jar + + + org.mockito + mockito-core + test + diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java new file mode 100644 index 00000000000..cf365026fc8 --- /dev/null +++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java @@ -0,0 +1,187 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.transport.mailets.delivery; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.collect.Lists; +import org.apache.james.domainlist.api.DomainList; +import org.apache.james.filesystem.api.FileSystem; +import org.apache.james.mailbox.MailboxManager; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageManager; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.rrt.api.RecipientRewriteTable; +import org.apache.james.transport.mailets.LocalDelivery; +import org.apache.james.user.api.UsersRepository; +import org.apache.mailet.Mail; +import org.apache.mailet.MailAddress; +import org.apache.mailet.base.test.FakeMail; +import org.apache.mailet.base.test.FakeMailetConfig; +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.slf4j.Logger; + +import javax.activation.DataHandler; +import javax.mail.Flags; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import javax.mail.util.ByteArrayDataSource; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; +import java.util.Properties; + +public class LocalDeliveryTest { + + private UsersRepository usersRepository; + private FileSystem fileSystem; + private RecipientRewriteTable recipientRewriteTable; + private MailboxManager mailboxManager; + private DomainList domainList; + private LocalDelivery localDelivery; + + @Before + public void setUp() throws Exception { + usersRepository = mock(UsersRepository.class); + fileSystem = mock(FileSystem.class); + recipientRewriteTable = mock(RecipientRewriteTable.class); + mailboxManager = mock(MailboxManager.class); + domainList = mock(DomainList.class); + + localDelivery = new LocalDelivery(); + localDelivery.setDomainList(domainList); + localDelivery.setFileSystem(fileSystem); + localDelivery.setMailboxManager(mailboxManager); + localDelivery.setRrt(recipientRewriteTable); + localDelivery.setUsersRepository(usersRepository); + } + + @Test + public void mailShouldBeWellDeliveredByDefaultToUserWhenvirtualHostingIsTurnedOn() throws Exception { + when(usersRepository.supportVirtualHosting()).thenAnswer(new Answer() { + public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable { + return true; + } + }); + when(fileSystem.getFile(any(String.class))).thenThrow(FileNotFoundException.class); + MailboxPath inbox = new MailboxPath("#private", "receiver@domain.com", "INBOX"); + final MessageManager messageManager = mock(MessageManager.class); + when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenAnswer(new Answer() { + public MessageManager answer(InvocationOnMock invocationOnMock) throws Throwable { + return messageManager; + } + }); + final MailboxSession session = mock(MailboxSession.class); + when(session.getPathDelimiter()).thenAnswer(new Answer() { + @Override + public Character answer(InvocationOnMock invocationOnMock) throws Throwable { + return '.'; + } + }); + when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenAnswer(new Answer() { + @Override + public MailboxSession answer(InvocationOnMock invocationOnMock) throws Throwable { + return session; + } + }); + + Mail mail = createMail(); + + localDelivery.init(new FakeMailetConfig()); + localDelivery.service(mail); + + verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class)); + } + + @Test + public void mailShouldBeWellDeliveredByDefaultToUserWhenvirtualHostingIsTurnedOff() throws Exception { + when(usersRepository.supportVirtualHosting()).thenAnswer(new Answer() { + public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable { + return false; + } + }); + when(fileSystem.getFile(any(String.class))).thenThrow(FileNotFoundException.class); + MailboxPath inbox = new MailboxPath("#private", "receiver", "INBOX"); + final MessageManager messageManager = mock(MessageManager.class); + when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenAnswer(new Answer() { + public MessageManager answer(InvocationOnMock invocationOnMock) throws Throwable { + return messageManager; + } + }); + final MailboxSession session = mock(MailboxSession.class); + when(session.getPathDelimiter()).thenAnswer(new Answer() { + @Override + public Character answer(InvocationOnMock invocationOnMock) throws Throwable { + return '.'; + } + }); + when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenAnswer(new Answer() { + @Override + public MailboxSession answer(InvocationOnMock invocationOnMock) throws Throwable { + return session; + } + }); + + Mail mail = createMail(); + + localDelivery.init(new FakeMailetConfig()); + localDelivery.service(mail); + + verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class)); + } + + private Mail createMail() throws MessagingException, IOException { + MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties())); + message.setSubject("Subject"); + message.setSender(new InternetAddress("sender@any.com")); + message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("receiver@domain.com")); + MimeMultipart multipart = new MimeMultipart(); + MimeBodyPart scriptPart = new MimeBodyPart(); + scriptPart.setDataHandler( + new DataHandler( + new ByteArrayDataSource( + "toto", + "application/sieve; charset=UTF-8") + )); + scriptPart.setDisposition(MimeBodyPart.ATTACHMENT); + scriptPart.setHeader("Content-Type", "application/sieve; charset=UTF-8"); + scriptPart.setFileName("file.txt"); + multipart.addBodyPart(scriptPart); + message.setContent(multipart); + message.saveChanges(); + Mail mail = new FakeMail(message); + mail.setState(Mail.DEFAULT); + mail.setRecipients(Lists.newArrayList(new MailAddress("receiver@domain.com"))); + return mail; + } + +} \ No newline at end of file From 97ee18e7ff49f1a7d9326a41bb9ce8f7b8edd634 Mon Sep 17 00:00:00 2001 From: Erwan Guyomarc'h Date: Sat, 12 Dec 2015 15:22:05 +0100 Subject: [PATCH 2/5] JAMES-1615 SieveRepository should return an InputStream --- protocols/managesieve/pom.xml | 5 +++- .../james/managesieve/core/CoreProcessor.java | 18 ++++++++++---- .../core/CoreProcessorTestCase.java | 7 +++--- .../managesieve/mock/MockSieveRepository.java | 24 ++++++++++++++----- protocols/pom.xml | 6 +++++ .../sieverepository/api/SieveRepository.java | 5 ++-- .../file/SieveFileRepository.java | 14 ++++++----- .../lib/AbstractSieveRepositoryTest.java | 23 ++++++++++++------ .../ManageSieveMailetTestCase.java | 5 ++-- 9 files changed, 75 insertions(+), 32 deletions(-) diff --git a/protocols/managesieve/pom.xml b/protocols/managesieve/pom.xml index f6cf5529617..ae11da59c70 100644 --- a/protocols/managesieve/pom.xml +++ b/protocols/managesieve/pom.xml @@ -44,7 +44,10 @@ org.apache.james james-server-data-api - + + org.apache.commons + commons-io + junit junit diff --git a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java index 96f59bbd894..8864457d6e4 100644 --- a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java +++ b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java @@ -20,6 +20,7 @@ package org.apache.james.managesieve.core; +import org.apache.commons.io.IOUtils; import org.apache.james.managesieve.api.AuthenticationRequiredException; import org.apache.james.managesieve.api.ManageSieveRuntimeException; import org.apache.james.managesieve.api.Session; @@ -37,6 +38,7 @@ import org.apache.james.sieverepository.api.exception.StorageException; import org.apache.james.sieverepository.api.exception.UserNotFoundException; +import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -136,12 +138,15 @@ public void deleteScript(String name) throws AuthenticationRequiredException, public String getScript(String name) throws AuthenticationRequiredException, ScriptNotFoundException, StorageException { authenticationCheck(); - String script = null; + String script; try { - script = _repository.getScript(getUser(), name); + script = IOUtils.toString(_repository.getScript(getUser(), name), "UTF-8"); } catch (UserNotFoundException ex) { // Should not happen as the UserListener should ensure the session user is defined in the repository throw new ManageSieveRuntimeException(ex); + } catch (IOException ex) { + // Unable to read script InputStream + throw new ManageSieveRuntimeException(ex); } return script; } @@ -165,7 +170,7 @@ public void haveSpace(String name, long size) throws AuthenticationRequiredExcep */ public List listScripts() throws AuthenticationRequiredException { authenticationCheck(); - List summaries = null; + List summaries; try { summaries = _repository.listScripts(getUser()); } catch (SieveRepositoryException ex) { @@ -260,13 +265,16 @@ protected boolean isAuthenticated() public String getActive() throws AuthenticationRequiredException, ScriptNotFoundException, StorageException { authenticationCheck(); - String script = null; + String script; try { - script = _repository.getActive(getUser()); + script = IOUtils.toString(_repository.getActive(getUser()), "UTF-8"); } catch (UserNotFoundException ex) { // Should not happen as the UserListener should ensure the session // user is defined in the repository throw new ManageSieveRuntimeException(ex); + } catch (IOException ex) { + // Unable to read script InputStream + throw new ManageSieveRuntimeException(ex); } return script; } diff --git a/protocols/managesieve/src/test/java/org/apache/james/managesieve/core/CoreProcessorTestCase.java b/protocols/managesieve/src/test/java/org/apache/james/managesieve/core/CoreProcessorTestCase.java index 49b0c660af7..acaedf92167 100644 --- a/protocols/managesieve/src/test/java/org/apache/james/managesieve/core/CoreProcessorTestCase.java +++ b/protocols/managesieve/src/test/java/org/apache/james/managesieve/core/CoreProcessorTestCase.java @@ -20,6 +20,7 @@ package org.apache.james.managesieve.core; +import org.apache.commons.io.IOUtils; import org.apache.james.managesieve.api.AuthenticationRequiredException; import org.apache.james.managesieve.api.SyntaxException; import org.apache.james.managesieve.api.commands.Capability.Capabilities; @@ -265,7 +266,7 @@ public final void testPutScript() throws Exception { session.setAuthentication(true); session.setUser("test"); core.putScript("script", "content"); - assertEquals("content", repository.getScript("test", "script")); + assertEquals("content", IOUtils.toString(repository.getScript("test", "script"))); // Syntax success = false; @@ -297,7 +298,7 @@ public final void testRenameScript() throws Exception { session.setUser("test"); repository.putScript("test", "oldName", "content"); core.renameScript("oldName", "newName"); - assertEquals("content", repository.getScript("test", "oldName")); + assertEquals("content", IOUtils.toString(repository.getScript("test", "oldName"))); } @Test @@ -318,7 +319,7 @@ public final void testSetActive() throws Exception { session.setUser("test"); repository.putScript("test", "script", "content"); core.setActive("script"); - assertEquals("content", repository.getActive("test")); + assertEquals("content", IOUtils.toString(repository.getActive("test"))); } @Test diff --git a/protocols/managesieve/src/test/java/org/apache/james/managesieve/mock/MockSieveRepository.java b/protocols/managesieve/src/test/java/org/apache/james/managesieve/mock/MockSieveRepository.java index 4a06af6ac07..cfd9920b4cd 100644 --- a/protocols/managesieve/src/test/java/org/apache/james/managesieve/mock/MockSieveRepository.java +++ b/protocols/managesieve/src/test/java/org/apache/james/managesieve/mock/MockSieveRepository.java @@ -20,6 +20,7 @@ package org.apache.james.managesieve.mock; +import org.apache.commons.io.IOUtils; import org.apache.james.sieverepository.api.ScriptSummary; import org.apache.james.sieverepository.api.SieveRepository; import org.apache.james.sieverepository.api.exception.DuplicateException; @@ -31,6 +32,8 @@ import org.apache.james.sieverepository.api.exception.StorageException; import org.apache.james.sieverepository.api.exception.UserNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -156,7 +159,7 @@ public void deleteScript(String user, String name) throws UserNotFoundException, /** * @see SieveRepository#getActive(String) */ - public String getActive(String user) throws UserNotFoundException, ScriptNotFoundException { + public InputStream getActive(String user) throws UserNotFoundException, ScriptNotFoundException, StorageException { if (!_repository.containsKey(user)) { throw new UserNotFoundException(user); @@ -175,7 +178,12 @@ public String getActive(String user) throws UserNotFoundException, ScriptNotFoun { throw new ScriptNotFoundException(); } - return content; + try { + return IOUtils.toInputStream(content, "UTF-8"); + } catch (IOException e) { + throw new StorageException(); + } + } /** @@ -197,8 +205,8 @@ public long getQuota(String user) throws UserNotFoundException, QuotaNotFoundExc /** * @see SieveRepository#getScript(String, String) */ - public String getScript(String user, String name) throws UserNotFoundException, - ScriptNotFoundException { + public InputStream getScript(String user, String name) throws UserNotFoundException, + ScriptNotFoundException, StorageException { if (!_repository.containsKey(user)) { throw new UserNotFoundException(user); @@ -208,7 +216,11 @@ public String getScript(String user, String name) throws UserNotFoundException, { throw new ScriptNotFoundException(name); } - return script.getContent(); + try { + return IOUtils.toInputStream(script.getContent(), "UTF-8"); + } catch (IOException e) { + throw new StorageException(); + } } /** @@ -316,7 +328,7 @@ public void setActive(String user, String name) throws UserNotFoundException, ScriptNotFoundException, StorageException { // Turn off currently active script, if any - Entry oldActive = null; + Entry oldActive; oldActive = getActiveEntry(user); if (null != oldActive) { oldActive.getValue().setActive(false); diff --git a/protocols/pom.xml b/protocols/pom.xml index 9a329456a3d..e8b2049dcd3 100644 --- a/protocols/pom.xml +++ b/protocols/pom.xml @@ -55,6 +55,7 @@ 2.6 1.7 3.2.1 + 1.3.2 13.0 2.5.1 1.0.0 @@ -144,6 +145,11 @@ commons-lang ${commons-lang.version} + + org.apache.commons + commons-io + ${apache-commons-io.version} + com.google.guava guava diff --git a/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java b/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java index c1ea4f3f612..4abc01ebd58 100644 --- a/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java +++ b/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java @@ -29,6 +29,7 @@ import org.apache.james.sieverepository.api.exception.StorageException; import org.apache.james.sieverepository.api.exception.UserNotFoundException; +import java.io.InputStream; import java.util.List; @@ -56,11 +57,11 @@ public interface SieveRepository { List listScripts(String user) throws UserNotFoundException, StorageException; - String getActive(String user) throws UserNotFoundException, ScriptNotFoundException, StorageException; + InputStream getActive(String user) throws UserNotFoundException, ScriptNotFoundException, StorageException; void setActive(String user, String name) throws UserNotFoundException, ScriptNotFoundException, StorageException; - String getScript(String user, String name) throws UserNotFoundException, ScriptNotFoundException, StorageException; + InputStream getScript(String user, String name) throws UserNotFoundException, ScriptNotFoundException, StorageException; void deleteScript(String user, String name) throws UserNotFoundException, ScriptNotFoundException, IsActiveException, StorageException; diff --git a/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java b/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java index af5e9286b6c..eaf5c6f2ba3 100644 --- a/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java +++ b/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java @@ -37,9 +37,11 @@ import javax.inject.Inject; import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; @@ -171,11 +173,11 @@ public void deleteScript(final String user, final String name) throws UserNotFou } @Override - public String getScript(final String user, final String name) throws UserNotFoundException, + public InputStream getScript(final String user, final String name) throws UserNotFoundException, ScriptNotFoundException, StorageException { - String script; + InputStream script; try { - script = toString(getScriptFile(user, name), UTF_8); + script = new FileInputStream(getScriptFile(user, name)); } catch (FileNotFoundException ex) { throw new ScriptNotFoundException(ex); } @@ -282,11 +284,11 @@ public void renameScript(final String user, final String oldName, final String n } @Override - public String getActive(final String user) throws UserNotFoundException, + public InputStream getActive(final String user) throws UserNotFoundException, ScriptNotFoundException, StorageException { - String script; + InputStream script; try { - script = toString(getActiveFile(user), UTF_8); + script = new FileInputStream(getActiveFile(user)); } catch (FileNotFoundException ex) { throw new ScriptNotFoundException(ex); } diff --git a/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/AbstractSieveRepositoryTest.java b/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/AbstractSieveRepositoryTest.java index cdba3cf24f0..4a4fd1364dd 100644 --- a/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/AbstractSieveRepositoryTest.java +++ b/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/AbstractSieveRepositoryTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import org.apache.commons.io.IOUtils; import org.apache.james.sieverepository.api.ScriptSummary; import org.apache.james.sieverepository.api.SieveRepository; import org.apache.james.sieverepository.api.exception.DuplicateException; @@ -32,15 +33,19 @@ import org.junit.Before; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; + public abstract class AbstractSieveRepositoryTest { private static final String USER = "test"; private static final String SCRIPT_NAME = "script"; - private static final String SCRIPT_CONTENT = "01234567"; + private static final String SCRIPT_CONTENT = "\u0048\u0065\u006C\u006C\u006F World"; // test utf-8 private static final String OTHER_SCRIPT_NAME = "other_script"; - private static final String OTHER_SCRIPT_CONTENT = "abcdef"; + private static final String OTHER_SCRIPT_CONTENT = "Other script content"; private static final long DEFAULT_QUOTA = Long.MAX_VALUE - 1L; private static final long USER_QUOTA = Long.MAX_VALUE / 2; + private static final String UTF8_ENCODING = "UTF-8"; private SieveRepository sieveRepository; @@ -69,7 +74,7 @@ public void getScriptShouldThrowIfUnableToFindScript() throws Exception { public void getScriptShouldReturnCorrectContent() throws Exception { sieveRepository.addUser(USER); sieveRepository.putScript(USER, SCRIPT_NAME, SCRIPT_CONTENT); - assertThat(sieveRepository.getScript(USER, SCRIPT_NAME)).isEqualTo(SCRIPT_CONTENT); + assertThat(getScriptContent(sieveRepository.getScript(USER, SCRIPT_NAME))).isEqualTo(SCRIPT_CONTENT); } @Test(expected = UserNotFoundException.class) @@ -225,7 +230,7 @@ public void setActiveScriptShouldWork() throws Exception { sieveRepository.addUser(USER); sieveRepository.putScript(USER, SCRIPT_NAME, SCRIPT_CONTENT); sieveRepository.setActive(USER, SCRIPT_NAME); - assertThat(sieveRepository.getActive(USER)).isEqualTo(SCRIPT_CONTENT); + assertThat(getScriptContent(sieveRepository.getActive(USER))).isEqualTo(SCRIPT_CONTENT); } @Test @@ -235,7 +240,7 @@ public void setActiveSwitchScriptShouldWork() throws Exception { sieveRepository.setActive(USER, SCRIPT_NAME); sieveRepository.putScript(USER, OTHER_SCRIPT_NAME, OTHER_SCRIPT_CONTENT); sieveRepository.setActive(USER, OTHER_SCRIPT_NAME); - assertThat(sieveRepository.getActive(USER)).isEqualTo(OTHER_SCRIPT_CONTENT); + assertThat(getScriptContent(sieveRepository.getActive(USER))).isEqualTo(OTHER_SCRIPT_CONTENT); } @Test(expected = ScriptNotFoundException.class) @@ -305,7 +310,7 @@ public void renameScriptShouldWork() throws Exception { sieveRepository.addUser(USER); sieveRepository.putScript(USER, SCRIPT_NAME, SCRIPT_CONTENT); sieveRepository.renameScript(USER, SCRIPT_NAME, OTHER_SCRIPT_NAME); - assertThat(sieveRepository.getScript(USER, OTHER_SCRIPT_NAME)).isEqualTo(SCRIPT_CONTENT); + assertThat(getScriptContent(sieveRepository.getScript(USER, OTHER_SCRIPT_NAME))).isEqualTo(SCRIPT_CONTENT); } @Test @@ -314,7 +319,7 @@ public void renameScriptShouldPropagateActiveScript() throws Exception { sieveRepository.putScript(USER, SCRIPT_NAME, SCRIPT_CONTENT); sieveRepository.setActive(USER, SCRIPT_NAME); sieveRepository.renameScript(USER, SCRIPT_NAME, OTHER_SCRIPT_NAME); - assertThat(sieveRepository.getActive(USER)).isEqualTo(SCRIPT_CONTENT); + assertThat(getScriptContent(sieveRepository.getActive(USER))).isEqualTo(SCRIPT_CONTENT); } @Test(expected = DuplicateException.class) @@ -424,6 +429,10 @@ public void setQuotaShouldWorkOnUsers() throws Exception { assertThat(sieveRepository.getQuota(USER)).isEqualTo(DEFAULT_QUOTA); } + protected String getScriptContent(InputStream inputStream) throws IOException { + return IOUtils.toString(inputStream, UTF8_ENCODING); + } + protected abstract SieveRepository createSieveRepository() throws Exception; protected abstract void cleanUp() throws Exception; diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/managesieve/ManageSieveMailetTestCase.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/managesieve/ManageSieveMailetTestCase.java index 4574db4770a..1e4033af3c2 100644 --- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/managesieve/ManageSieveMailetTestCase.java +++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/managesieve/ManageSieveMailetTestCase.java @@ -20,6 +20,7 @@ package org.apache.james.transport.mailets.managesieve; +import org.apache.commons.io.IOUtils; import org.apache.james.managesieve.mock.MockSieveParser; import org.apache.james.managesieve.mock.MockSieveRepository; import org.apache.james.sieverepository.api.exception.DuplicateUserException; @@ -213,7 +214,7 @@ public final void testPutScript() throws MessagingException, IOException, UserNo BodyPart part = content.getBodyPart(0); String response = (String) part.getContent(); assertEquals(response, "OK (WARNINGS) \"warning1\" \"warning2\""); - assertEquals(scriptContent, _repository.getScript(message.getSender().toString(), scriptName)); + assertEquals(scriptContent, IOUtils.toString(_repository.getScript(message.getSender().toString(), scriptName))); } // Extra arguments @@ -259,7 +260,7 @@ public final void testPutScript() throws MessagingException, IOException, UserNo BodyPart part = content.getBodyPart(0); String response = (String) part.getContent(); assertTrue(response.startsWith("NO \"Syntax Error: ")); - assertEquals(scriptContent, _repository.getScript(message.getSender().toString(), scriptName)); + assertEquals(scriptContent, IOUtils.toString(_repository.getScript(message.getSender().toString(), scriptName))); } // No script From 5cb839651b7fccf0cc54be03bdf185ebac73f1d4 Mon Sep 17 00:00:00 2001 From: Erwan Guyomarc'h Date: Sat, 12 Dec 2015 15:08:47 +0100 Subject: [PATCH 3/5] JAMES-1615 provide a SieveDefaultRepository that provide retro compatibility on script retrieval (Deprecated) --- .../file/SieveDefaultRepository.java | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveDefaultRepository.java diff --git a/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveDefaultRepository.java b/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveDefaultRepository.java new file mode 100644 index 00000000000..d445ee688b8 --- /dev/null +++ b/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveDefaultRepository.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.james.sieverepository.file; + +import org.apache.james.filesystem.api.FileSystem; +import org.apache.james.sieverepository.api.ScriptSummary; +import org.apache.james.sieverepository.api.SieveRepository; +import org.apache.james.sieverepository.api.exception.DuplicateException; +import org.apache.james.sieverepository.api.exception.DuplicateUserException; +import org.apache.james.sieverepository.api.exception.IsActiveException; +import org.apache.james.sieverepository.api.exception.QuotaExceededException; +import org.apache.james.sieverepository.api.exception.QuotaNotFoundException; +import org.apache.james.sieverepository.api.exception.ScriptNotFoundException; +import org.apache.james.sieverepository.api.exception.StorageException; +import org.apache.james.sieverepository.api.exception.UserNotFoundException; + +import javax.inject.Inject; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.List; + +/** + * SieveFileRepository manages sieve scripts stored on the file system. + *

The sieve root directory is a sub-directory of the application base directory named "sieve". + * Scripts are stored in sub-directories of the sieve root directory, each with the name of the + * associated user. + */ +@Deprecated +public class SieveDefaultRepository implements SieveRepository { + private FileSystem fileSystem; + + @Inject + public void setFileSystem(FileSystem fileSystem) { + this.fileSystem = fileSystem; + } + + @Override + public void haveSpace(String user, String name, long size) throws UserNotFoundException, QuotaExceededException, StorageException { + throw apologizeForQuotas(); + } + + @Override + public void putScript(String user, String name, String content) throws UserNotFoundException, StorageException, QuotaExceededException { + throw new StorageException("This implementation is deprecated and does not support script put operation. You must directly position your scripts in the .sieve folder. Please consider using a SieveFileRepository."); + } + + @Override + public List listScripts(String user) throws UserNotFoundException, StorageException { + throw new StorageException("This implementation is deprecated and does not support listScripts operation. Please consider using a SieveFileRepository."); + } + + @Override + public InputStream getActive(String user) throws UserNotFoundException, ScriptNotFoundException, StorageException { + try { + return new FileInputStream(retrieveUserFile(user)); + } catch (FileNotFoundException e) { + throw new ScriptNotFoundException(); + } + } + + public File retrieveUserFile(String user) throws FileNotFoundException { + // RFC 5228 permits extensions: .siv .sieve + String sieveFilePrefix = FileSystem.FILE_PROTOCOL + "sieve/" + user + "."; + try { + return fileSystem.getFile(sieveFilePrefix + "sieve"); + } catch (FileNotFoundException e) { + return fileSystem.getFile(sieveFilePrefix + "siv"); + } + } + + @Override + public void setActive(String user, String name) throws UserNotFoundException, ScriptNotFoundException, StorageException { + throw new StorageException("This implementation is deprecated and does not support script SetActive operation. Your uploaded script is by default the active script. Please consider using a SieveFileRepository."); + } + + @Override + public InputStream getScript(String user, String name) throws UserNotFoundException, ScriptNotFoundException, StorageException { + return getActive(user); + } + + @Override + public void deleteScript(String user, String name) throws UserNotFoundException, ScriptNotFoundException, IsActiveException, StorageException { + throw new StorageException("This implementation is deprecated and does not support delete script operation. Please consider using a SieveFileRepository."); + } + + @Override + public void renameScript(String user, String oldName, String newName) throws UserNotFoundException, ScriptNotFoundException, DuplicateException, StorageException { + throw new StorageException("This implementation is deprecated and does not support rename script operation. Please consider using a SieveFileRepository."); + } + + @Override + public boolean hasUser(String user) throws StorageException { + throw new StorageException("This implementation is deprecated and does not support user related operation. Please consider using a SieveFileRepository."); + } + + @Override + public void addUser(String user) throws DuplicateUserException, StorageException { + throw new StorageException("This implementation is deprecated and does not support user related operation. Please consider using a SieveFileRepository."); + } + + @Override + public void removeUser(String user) throws UserNotFoundException, StorageException { + throw new StorageException("This implementation is deprecated and does not support user related operation. Please consider using a SieveFileRepository."); + } + + @Override + public boolean hasQuota() throws StorageException { + throw apologizeForQuotas(); + } + + @Override + public long getQuota() throws QuotaNotFoundException, StorageException { + throw apologizeForQuotas(); + } + + @Override + public void setQuota(long quota) throws StorageException { + throw apologizeForQuotas(); + } + + @Override + public void removeQuota() throws QuotaNotFoundException, StorageException { + throw apologizeForQuotas(); + } + + @Override + public boolean hasQuota(String user) throws UserNotFoundException, StorageException { + throw apologizeForQuotas(); + } + + @Override + public long getQuota(String user) throws UserNotFoundException, QuotaNotFoundException, StorageException { + throw apologizeForQuotas(); + } + + @Override + public void setQuota(String user, long quota) throws UserNotFoundException, StorageException { + throw apologizeForQuotas(); + } + + @Override + public void removeQuota(String user) throws UserNotFoundException, QuotaNotFoundException, StorageException { + throw apologizeForQuotas(); + } + + private StorageException apologizeForQuotas() throws StorageException { + throw new StorageException("Implementation deprecated. Quota not managed by this implementation. Please consider using a SieveFileRepository."); + } +} From 559c41c0d5d74f91ae495d9ab791a1d9f77c5655 Mon Sep 17 00:00:00 2001 From: Erwan Guyomarc'h Date: Sat, 12 Dec 2015 15:09:56 +0100 Subject: [PATCH 4/5] JAMES-1615 SieveMailet should use SieveRepository to locate user script --- .../src/main/resources/sieverepository.xml | 23 ++++++++ server/mailet/mailets/pom.xml | 4 ++ .../transport/mailets/LocalDelivery.java | 35 ++++-------- .../mailets/ResourceLocatorImpl.java | 43 ++++++-------- .../james/transport/mailets/SieveMailet.java | 48 ++++------------ .../transport/mailets/ToRecipientFolder.java | 19 +++---- .../mailets/ResourceLocatorImplTest.java | 57 +++++++++++++++++++ .../mailets/delivery/LocalDeliveryTest.java | 14 ++--- 8 files changed, 137 insertions(+), 106 deletions(-) create mode 100644 server/data/data-api/src/main/resources/sieverepository.xml create mode 100644 server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResourceLocatorImplTest.java diff --git a/server/data/data-api/src/main/resources/sieverepository.xml b/server/data/data-api/src/main/resources/sieverepository.xml new file mode 100644 index 00000000000..030713f6e6b --- /dev/null +++ b/server/data/data-api/src/main/resources/sieverepository.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml index e8c4999d24c..ba2ab807e5e 100644 --- a/server/mailet/mailets/pom.xml +++ b/server/mailet/mailets/pom.xml @@ -171,6 +171,10 @@ test test-jar + + org.assertj + assertj-core + org.mockito mockito-core diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/LocalDelivery.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/LocalDelivery.java index b8803e2d389..738e5f3c904 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/LocalDelivery.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/LocalDelivery.java @@ -31,6 +31,7 @@ import org.apache.james.domainlist.api.DomainList; import org.apache.james.filesystem.api.FileSystem; import org.apache.james.mailbox.MailboxManager; +import org.apache.james.sieverepository.api.SieveRepository; import org.apache.james.user.api.UsersRepository; import org.apache.mailet.Mail; import org.apache.mailet.MailetConfig; @@ -51,7 +52,12 @@ public class LocalDelivery extends GenericMailet { private UsersRepository usersRepository; private MailboxManager mailboxManager; private DomainList domainList; - private FileSystem fileSystem; + private SieveRepository sieveRepository; + + @Inject + public void setSieveRepository(SieveRepository sieveRepository) { + this.sieveRepository = sieveRepository; + } @Inject public void setRrt(org.apache.james.rrt.api.RecipientRewriteTable rrt) { @@ -72,11 +78,6 @@ public void setMailboxManager(@Named("mailboxmanager") MailboxManager mailboxMan public void setDomainList(DomainList domainList) { this.domainList = domainList; } - - @Inject - public void setFileSystem(FileSystem fileSystem) { - this.fileSystem = fileSystem; - } private SieveMailet sieveMailet; // Mailet that actually stores the message private RecipientRewriteTable recipientRewriteTable; // Mailet that applies RecipientRewriteTable @@ -116,14 +117,8 @@ public void init() throws MessagingException { recipientRewriteTable.setRecipientRewriteTable(rrt); recipientRewriteTable.init(getMailetConfig()); - sieveMailet = new SieveMailet(); - sieveMailet.setUsersRepository(usersRepository); - sieveMailet.setMailboxManager(mailboxManager); - sieveMailet.setFileSystem(fileSystem); + sieveMailet = new SieveMailet(usersRepository, mailboxManager, sieveRepository, "INBOX"); sieveMailet.init(new MailetConfig() { - /* - * @see org.apache.mailet.MailetConfig#getInitParameter(java.lang.String) - */ public String getInitParameter(String name) { if ("addDeliveryHeader".equals(name)) { return "Delivered-To"; @@ -133,9 +128,7 @@ public String getInitParameter(String name) { return getMailetConfig().getInitParameter(name); } } - /* - * @see org.apache.mailet.MailetConfig#getInitParameterNames() - */ + public Iterator getInitParameterNames() { IteratorChain c = new IteratorChain(); Collection h = new ArrayList(); @@ -145,15 +138,11 @@ public Iterator getInitParameterNames() { c.addIterator(h.iterator()); return c; } - /* - * @see org.apache.mailet.MailetConfig#getMailetContext() - */ + public MailetContext getMailetContext() { return getMailetConfig().getMailetContext(); } - /* - * @see org.apache.mailet.MailetConfig#getMailetName() - */ + public String getMailetName() { return getMailetConfig().getMailetName(); } @@ -161,8 +150,6 @@ public String getMailetName() { }); // Override the default value of "quiet" sieveMailet.setQuiet(getInitParameter("quiet", true)); - sieveMailet.setFolder("INBOX"); - } } diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ResourceLocatorImpl.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ResourceLocatorImpl.java index 356d86ac466..e0d9d58c19b 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ResourceLocatorImpl.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ResourceLocatorImpl.java @@ -19,33 +19,31 @@ package org.apache.james.transport.mailets; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; +import org.apache.james.sieverepository.api.SieveRepository; +import org.apache.james.sieverepository.api.exception.ScriptNotFoundException; +import org.apache.james.sieverepository.api.exception.SieveRepositoryException; +import org.apache.james.sieverepository.api.exception.StorageException; +import org.apache.james.sieverepository.api.exception.UserNotFoundException; +import org.apache.jsieve.mailet.ResourceLocator; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; import java.io.IOException; import java.io.InputStream; -import org.apache.james.filesystem.api.FileSystem; -import org.apache.jsieve.mailet.ResourceLocator; - -/** - * To maintain backwards compatibility with existing installations, this uses - * the old file based scheme. - *

The scripts are stored in the sieve sub directory of the application - * installation directory. - */ public class ResourceLocatorImpl implements ResourceLocator { private final boolean virtualHosting; - - private FileSystem fileSystem = null; + private final SieveRepository sieveRepository; - public ResourceLocatorImpl(boolean virtualHosting, FileSystem fileSystem) { + public ResourceLocatorImpl(boolean virtualHosting, SieveRepository sieveRepository) { this.virtualHosting = virtualHosting; - this.fileSystem = fileSystem; + this.sieveRepository = sieveRepository; } - public InputStream get(String uri) throws IOException { + public InputStream get(String uri) throws SieveRepositoryException { + System.out.println(uri); // Use the complete email address for finding the sieve file uri = uri.substring(2); @@ -56,15 +54,6 @@ public InputStream get(String uri) throws IOException { username = uri.substring(0, uri.indexOf("@")); } - // RFC 5228 permits extensions: .siv .sieve - String sieveFilePrefix = FileSystem.FILE_PROTOCOL + "sieve/" + username + "."; - File sieveFile; - try { - sieveFile = fileSystem.getFile(sieveFilePrefix + "sieve"); - } catch (FileNotFoundException ex) { - sieveFile = fileSystem.getFile(sieveFilePrefix + "siv"); - } - return new FileInputStream(sieveFile); + return sieveRepository.getActive(username); } - } diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SieveMailet.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SieveMailet.java index dae9d85b4de..7b28b425607 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SieveMailet.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SieveMailet.java @@ -18,14 +18,7 @@ ****************************************************************/ package org.apache.james.transport.mailets; -import java.util.Date; - -import javax.inject.Inject; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; - import org.apache.james.core.MimeMessageInputStream; -import org.apache.james.filesystem.api.FileSystem; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.MessageManager; @@ -33,6 +26,7 @@ import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.MailboxConstants; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.sieverepository.api.SieveRepository; import org.apache.james.transport.util.MailetContextLog; import org.apache.james.user.api.UsersRepository; import org.apache.james.user.api.UsersRepositoryException; @@ -42,49 +36,31 @@ import org.apache.mailet.MailAddress; import org.apache.mailet.MailetConfig; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.util.Date; + /** * Contains resource bindings. */ public class SieveMailet extends SieveMailboxMailet implements Poster { - private UsersRepository usersRepos; - private MailboxManager mailboxManager; - private FileSystem fileSystem; - private String folder; + private final UsersRepository usersRepos; + private final MailboxManager mailboxManager; + private final SieveRepository sieveRepository; + private final String folder; - @Inject - public void setUsersRepository(UsersRepository usersRepos) { + public SieveMailet(UsersRepository usersRepos, MailboxManager mailboxManager, SieveRepository sieveRepository, String folder) { this.usersRepos = usersRepos; - } - - @Inject - public void setMailboxManager(MailboxManager mailboxManager) { this.mailboxManager = mailboxManager; - } - - @Inject - public void setFileSystem(FileSystem fileSystem) { - this.fileSystem = fileSystem; - } - - public void setFolder(String folder) { + this.sieveRepository = sieveRepository; this.folder = folder; } - public SieveMailet() { - super(); - } - - /* - * (non-Javadoc) - * - * @see org.apache.jsieve.mailet.SieveMailboxMailet#init(org.apache.mailet. - * MailetConfig) - */ @Override public void init(MailetConfig config) throws MessagingException { // ATM Fixed implementation try { - setLocator(new ResourceLocatorImpl(usersRepos.supportVirtualHosting(), fileSystem)); + setLocator(new ResourceLocatorImpl(usersRepos.supportVirtualHosting(), sieveRepository)); } catch (UsersRepositoryException e) { throw new MessagingException("Unable to access UsersRepository", e); } diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToRecipientFolder.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToRecipientFolder.java index 4e3eb7cc7bf..64c5dfbdfd5 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToRecipientFolder.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToRecipientFolder.java @@ -29,6 +29,7 @@ import org.apache.commons.collections.iterators.IteratorChain; import org.apache.james.filesystem.api.FileSystem; import org.apache.james.mailbox.MailboxManager; +import org.apache.james.sieverepository.api.SieveRepository; import org.apache.james.user.api.UsersRepository; import org.apache.mailet.Mail; import org.apache.mailet.MailetConfig; @@ -54,24 +55,22 @@ public class ToRecipientFolder extends GenericMailet { private MailboxManager mailboxManager; - + private SieveRepository sieveRepository; private UsersRepository usersRepository; - private FileSystem fileSystem; - @Inject public void setMailboxManager(@Named("mailboxmanager")MailboxManager mailboxManager) { this.mailboxManager = mailboxManager; } @Inject - public void setUsersRepository(UsersRepository usersRepository) { - this.usersRepository = usersRepository; + public void setSetUsersRepository(SieveRepository setUsersRepository) { + this.sieveRepository = setUsersRepository; } @Inject - public void setFileSystem(FileSystem fileSystem) { - this.fileSystem = fileSystem; + public void setUsersRepository(UsersRepository usersRepository) { + this.usersRepository = usersRepository; } private SieveMailet sieveMailet; // Mailet that actually stores the message @@ -94,10 +93,7 @@ public void service(Mail mail) throws MessagingException { @Override public void init() throws MessagingException { super.init(); - sieveMailet = new SieveMailet(); - sieveMailet.setUsersRepository(usersRepository); - sieveMailet.setMailboxManager(mailboxManager); - sieveMailet.setFileSystem(fileSystem); + sieveMailet = new SieveMailet(usersRepository, mailboxManager, sieveRepository, "INBOX"); sieveMailet.init(new MailetConfig() { /* * @see org.apache.mailet.MailetConfig#getInitParameter(java.lang.String) @@ -139,7 +135,6 @@ public String getMailetName() { }); // Override the default value of "quiet" sieveMailet.setQuiet(getInitParameter("quiet", true)); - sieveMailet.setFolder(getInitParameter("folder", "INBOX")); } /* (non-Javadoc) diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResourceLocatorImplTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResourceLocatorImplTest.java new file mode 100644 index 00000000000..93e2823ad66 --- /dev/null +++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ResourceLocatorImplTest.java @@ -0,0 +1,57 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.transport.mailets; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.james.sieverepository.api.SieveRepository; +import org.apache.james.sieverepository.api.exception.ScriptNotFoundException; +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +public class ResourceLocatorImplTest { + + private SieveRepository sieveRepository; + private ResourceLocatorImpl resourceLocator; + + @Before + public void setUp() { + sieveRepository = mock(SieveRepository.class); + resourceLocator = new ResourceLocatorImpl(true, sieveRepository); + } + + @Test(expected = ScriptNotFoundException.class) + public void resourceLocatorImplShouldPropagateScriptNotFound() throws Exception { + when(sieveRepository.getActive("receiver@localhost")).thenThrow(new ScriptNotFoundException()); + resourceLocator.get("//receiver@localhost/sieve"); + } + + @Test + public void resourceLocatorImplShouldWork() throws Exception { + InputStream inputStream = new ByteArrayInputStream(new byte[0]); + when(sieveRepository.getActive("receiver@localhost")).thenReturn(inputStream); + assertThat(resourceLocator.get("//receiver@localhost/sieve")).isEqualTo(inputStream); + } +} diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java index cf365026fc8..7104e675b4c 100644 --- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java +++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java @@ -27,12 +27,13 @@ import com.google.common.collect.Lists; import org.apache.james.domainlist.api.DomainList; -import org.apache.james.filesystem.api.FileSystem; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.MessageManager; import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.rrt.api.RecipientRewriteTable; +import org.apache.james.sieverepository.api.SieveRepository; +import org.apache.james.sieverepository.api.exception.ScriptNotFoundException; import org.apache.james.transport.mailets.LocalDelivery; import org.apache.james.user.api.UsersRepository; import org.apache.mailet.Mail; @@ -54,7 +55,6 @@ import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.util.ByteArrayDataSource; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Date; @@ -63,26 +63,26 @@ public class LocalDeliveryTest { private UsersRepository usersRepository; - private FileSystem fileSystem; private RecipientRewriteTable recipientRewriteTable; private MailboxManager mailboxManager; private DomainList domainList; + private SieveRepository sieveRepository; private LocalDelivery localDelivery; @Before public void setUp() throws Exception { + sieveRepository = mock(SieveRepository.class); usersRepository = mock(UsersRepository.class); - fileSystem = mock(FileSystem.class); recipientRewriteTable = mock(RecipientRewriteTable.class); mailboxManager = mock(MailboxManager.class); domainList = mock(DomainList.class); localDelivery = new LocalDelivery(); localDelivery.setDomainList(domainList); - localDelivery.setFileSystem(fileSystem); localDelivery.setMailboxManager(mailboxManager); localDelivery.setRrt(recipientRewriteTable); localDelivery.setUsersRepository(usersRepository); + localDelivery.setSieveRepository(sieveRepository); } @Test @@ -92,7 +92,7 @@ public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable { return true; } }); - when(fileSystem.getFile(any(String.class))).thenThrow(FileNotFoundException.class); + when(sieveRepository.getActive("receiver@domain.com")).thenThrow(new ScriptNotFoundException()); MailboxPath inbox = new MailboxPath("#private", "receiver@domain.com", "INBOX"); final MessageManager messageManager = mock(MessageManager.class); when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenAnswer(new Answer() { @@ -129,7 +129,7 @@ public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable { return false; } }); - when(fileSystem.getFile(any(String.class))).thenThrow(FileNotFoundException.class); + when(sieveRepository.getActive("receiver")).thenThrow(new ScriptNotFoundException()); MailboxPath inbox = new MailboxPath("#private", "receiver", "INBOX"); final MessageManager messageManager = mock(MessageManager.class); when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenAnswer(new Answer() { From b693bc3ac444cabdbd14d48f65fa19c902e48e1c Mon Sep 17 00:00:00 2001 From: Erwan Guyomarc'h Date: Sat, 12 Dec 2015 15:16:03 +0100 Subject: [PATCH 5/5] JAMES-1615 As a user I should be able to configure my SieveRepository --- .../destination/conf/sieverepository.xml | 23 +++++++++++++++++++ .../resources/sieverepository-template.xml | 23 +++++++++++++++++++ .../META-INF/spring/loaders-context.xml | 12 ++++++---- .../src/main/resources/sieverepository.xml | 2 +- .../file/SieveFileRepository.java | 3 +-- 5 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 dockerfiles/run/spring/destination/conf/sieverepository.xml create mode 100644 server/app/src/main/resources/sieverepository-template.xml diff --git a/dockerfiles/run/spring/destination/conf/sieverepository.xml b/dockerfiles/run/spring/destination/conf/sieverepository.xml new file mode 100644 index 00000000000..58b0537f1e4 --- /dev/null +++ b/dockerfiles/run/spring/destination/conf/sieverepository.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/server/app/src/main/resources/sieverepository-template.xml b/server/app/src/main/resources/sieverepository-template.xml new file mode 100644 index 00000000000..58b0537f1e4 --- /dev/null +++ b/server/app/src/main/resources/sieverepository-template.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml b/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml index 70565e7d6b2..5f7b8505e58 100644 --- a/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml +++ b/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml @@ -47,6 +47,14 @@ + + + + sieverepository + + + + @@ -123,10 +131,6 @@ - - - - diff --git a/server/data/data-api/src/main/resources/sieverepository.xml b/server/data/data-api/src/main/resources/sieverepository.xml index 030713f6e6b..58b0537f1e4 100644 --- a/server/data/data-api/src/main/resources/sieverepository.xml +++ b/server/data/data-api/src/main/resources/sieverepository.xml @@ -19,5 +19,5 @@ --> - + diff --git a/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java b/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java index eaf5c6f2ba3..1c0a4552747 100644 --- a/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java +++ b/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java @@ -138,7 +138,7 @@ static protected void toFile(File file, String content) throws StorageException * Creates a new instance of SieveFileRepository. */ public SieveFileRepository() { - super(); + } /** @@ -147,7 +147,6 @@ public SieveFileRepository() { * @param fileSystem */ public SieveFileRepository(FileSystem fileSystem) { - this(); setFileSystem(fileSystem); }