This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit d31b8bfc0ec68b19b58acd14eb0e9690b8ef80a7 Author: Gautier DI FOLCO <gdifo...@linagora.com> AuthorDate: Tue Feb 18 11:58:02 2020 +0100 JAMES-3067 Recursively find allowed From headers --- .../data/CassandraRecipientRewriteTableModule.java | 4 + .../data/JPARecipientRewriteTableModule.java | 4 + .../james/modules/data/MemoryDataModule.java | 5 + .../META-INF/org/apache/james/spring-server.xml | 1 + .../java/org/apache/james/util/StreamUtils.java | 68 +++++++++ .../org/apache/james/util/StreamUtilsTest.java | 70 +++++++++ .../james/rrt/api/RecipientRewriteTable.java | 2 + .../rrt/api/ReverseRecipientRewriteTable.java} | 42 +----- .../apache/james/rrt/lib/CanSendFromContract.java | 147 +++++++++++++++--- .../lib/ReverseRecipientRewriteTableContract.java | 167 +++++++++++++++++++++ .../rrt/lib/AbstractRecipientRewriteTable.java | 9 ++ .../org/apache/james/rrt/lib/CanSendFromImpl.java | 48 ++---- .../rrt/lib/ReverseRecipientRewriteTableImpl.java | 105 +++++++++++++ .../apache/james/rrt/lib/CanSendFromImplTest.java | 4 +- ...a => ReverseRecipientRewriteTableImplTest.java} | 17 ++- .../methods/SetMessagesCreationProcessorTest.java | 5 +- .../methods/SetMessagesUpdateProcessorTest.java | 5 +- .../apache/james/smtpserver/SMTPServerTest.java | 6 +- .../james/webadmin/routes/UserRoutesTest.java | 6 +- 19 files changed, 609 insertions(+), 106 deletions(-) diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java index 5a1836f..4eaccfc 100644 --- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java +++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java @@ -21,11 +21,13 @@ package org.apache.james.modules.data; import org.apache.james.backends.cassandra.components.CassandraModule; import org.apache.james.rrt.api.CanSendFrom; import org.apache.james.rrt.api.RecipientRewriteTable; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.cassandra.CassandraMappingsSourcesDAO; import org.apache.james.rrt.cassandra.CassandraRRTModule; import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTable; import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTableDAO; import org.apache.james.rrt.lib.CanSendFromImpl; +import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl; import org.apache.james.server.core.configuration.ConfigurationProvider; import org.apache.james.utils.InitializationOperation; import org.apache.james.utils.InitilizationOperationBuilder; @@ -42,6 +44,8 @@ public class CassandraRecipientRewriteTableModule extends AbstractModule { bind(CassandraRecipientRewriteTableDAO.class).in(Scopes.SINGLETON); bind(CassandraMappingsSourcesDAO.class).in(Scopes.SINGLETON); bind(RecipientRewriteTable.class).to(CassandraRecipientRewriteTable.class); + bind(ReverseRecipientRewriteTableImpl.class).in(Scopes.SINGLETON); + bind(ReverseRecipientRewriteTable.class).to(ReverseRecipientRewriteTableImpl.class); bind(CanSendFromImpl.class).in(Scopes.SINGLETON); bind(CanSendFrom.class).to(CanSendFromImpl.class); Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class); diff --git a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java index f22eb63..a608538 100644 --- a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java +++ b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java @@ -20,8 +20,10 @@ package org.apache.james.modules.data; import org.apache.james.rrt.api.CanSendFrom; import org.apache.james.rrt.api.RecipientRewriteTable; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.jpa.JPARecipientRewriteTable; import org.apache.james.rrt.lib.CanSendFromImpl; +import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl; import org.apache.james.server.core.configuration.ConfigurationProvider; import org.apache.james.utils.InitializationOperation; import org.apache.james.utils.InitilizationOperationBuilder; @@ -35,6 +37,8 @@ public class JPARecipientRewriteTableModule extends AbstractModule { public void configure() { bind(JPARecipientRewriteTable.class).in(Scopes.SINGLETON); bind(RecipientRewriteTable.class).to(JPARecipientRewriteTable.class); + bind(ReverseRecipientRewriteTableImpl.class).in(Scopes.SINGLETON); + bind(ReverseRecipientRewriteTable.class).to(ReverseRecipientRewriteTableImpl.class); bind(CanSendFromImpl.class).in(Scopes.SINGLETON); bind(CanSendFrom.class).to(CanSendFromImpl.class); } diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java index d78baca..d33c1ea 100644 --- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java +++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java @@ -34,7 +34,9 @@ import org.apache.james.mailrepository.memory.MemoryMailRepositoryUrlStore; import org.apache.james.modules.server.MailStoreRepositoryModule; import org.apache.james.rrt.api.CanSendFrom; import org.apache.james.rrt.api.RecipientRewriteTable; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.lib.CanSendFromImpl; +import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.apache.james.server.core.configuration.ConfigurationProvider; import org.apache.james.user.api.UsersRepository; @@ -68,6 +70,9 @@ public class MemoryDataModule extends AbstractModule { bind(MemoryRecipientRewriteTable.class).in(Scopes.SINGLETON); bind(RecipientRewriteTable.class).to(MemoryRecipientRewriteTable.class); + bind(ReverseRecipientRewriteTableImpl.class).in(Scopes.SINGLETON); + bind(ReverseRecipientRewriteTable.class).to(ReverseRecipientRewriteTableImpl.class); + bind(CanSendFromImpl.class).in(Scopes.SINGLETON); bind(CanSendFrom.class).to(CanSendFromImpl.class); diff --git a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml index 46b1f29..8a37ab5 100644 --- a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml +++ b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml @@ -326,5 +326,6 @@ <bean id="jspfLogger" class="org.apache.james.smtpserver.fastfail.SPFHandler.SPFLogger"/> + <bean id="reverserecipientrewritetable" class="org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl" /> <bean id="cansendfrom" class="org.apache.james.rrt.lib.CanSendFromImpl" /> </beans> diff --git a/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java b/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java index ccdffd2..aea59a1 100644 --- a/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java +++ b/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java @@ -21,12 +21,21 @@ package org.apache.james.util; import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.Optional; +import java.util.Spliterator; +import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import com.github.steveash.guavate.Guavate; +import com.google.common.base.Preconditions; public class StreamUtils { + private static final boolean PARALLEL = true; + @SafeVarargs public static <T> Stream<T> ofNullables(T... array) { return ofNullable(array); @@ -54,4 +63,63 @@ public class StreamUtils { public static <T> Stream<T> flatten(Stream<T>... streams) { return flatten(Arrays.stream(streams)); } + + public static <T> Stream<T> unfold(T seed, Function<T, Optional<T>> generator) { + return StreamSupport.stream(new UnfoldSpliterator(seed, generator), !PARALLEL); + } + + public static <T> Stream<T> iterate(T seed, Long limit, Function<T, Stream<T>> generator) { + Preconditions.checkArgument(limit >= 0, "StreamUtils.iterate have a given limit ok '{}', while it should not be negative", limit); + return StreamUtils.unfold(Arrays.asList(seed), conservativeGenerator(generator)) + .limit(limit + 1) + .flatMap(List::stream); + } + + private static <T> Function<List<T>, Optional<List<T>>> conservativeGenerator(Function<T, Stream<T>> generator) { + return previous -> { + List<T> generated = previous.stream() + .flatMap(generator) + .collect(Guavate.toImmutableList()); + + if (generated.isEmpty()) { + return Optional.empty(); + } else { + return Optional.of(generated); + } + }; + } + + private static class UnfoldSpliterator<T> implements Spliterator<T> { + + private static final Spliterator<?> NOT_ABLE_TO_SPLIT_SPLITERATOR = null; + private Optional<T> current; + private final Function<T, Optional<T>> generator; + + private UnfoldSpliterator(T seed, Function<T, Optional<T>> generator) { + this.current = Optional.of(seed); + this.generator = generator; + } + + @Override + public boolean tryAdvance(Consumer<? super T> action) { + current.ifPresent(action); + current = current.flatMap(generator); + return current.isPresent(); + } + + @Override + public Spliterator<T> trySplit() { + return (Spliterator<T>) NOT_ABLE_TO_SPLIT_SPLITERATOR; + } + + @Override + public long estimateSize() { + return Long.MAX_VALUE; + } + + @Override + public int characteristics() { + return Spliterator.IMMUTABLE & Spliterator.NONNULL & Spliterator.ORDERED; + } + } } diff --git a/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java index e08ebea..67f8527 100644 --- a/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java +++ b/server/container/util/src/test/java/org/apache/james/util/StreamUtilsTest.java @@ -20,8 +20,11 @@ package org.apache.james.util; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; import org.junit.jupiter.api.Test; @@ -112,4 +115,71 @@ class StreamUtilsTest { .collect(Guavate.toImmutableList())) .containsExactly(1, 2); } + + @Test + void unfoldShouldGenerateAnFiniteStream() { + Stream<Integer> unfolded = StreamUtils.unfold(1, i -> { + if (i < 10) { + return Optional.of(i + 1); + } else { + return Optional.empty(); + } + }); + + assertThat(unfolded.collect(Guavate.toImmutableList())) + .contains(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + void unfoldShouldGenerateALazyInfiniteStream() { + AtomicInteger counter = new AtomicInteger(0); + Stream<Integer> unfolded = StreamUtils.unfold(1, i -> { + counter.incrementAndGet(); + return Optional.of(i + 1); + }); + + assertThat(unfolded.limit(10).collect(Guavate.toImmutableList())) + .contains(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + assertThat(counter.get()) + .isEqualTo(10); + } + + @Test + void unfoldShouldHaveAtLeastTheSeed() { + Stream<Integer> unfolded = StreamUtils.unfold(1, i -> Optional.empty()); + + assertThat(unfolded.collect(Guavate.toImmutableList())) + .contains(1); + } + + @Test + void iterateWithANegativeLimitShouldThrow() { + assertThatCode(() -> StreamUtils.iterate(1, (long) -1, Stream::of)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void iterateWithZeroLimitShouldHaveOnlyTheSeed() { + Stream<Integer> generated = StreamUtils.iterate(1, (long) 0, Stream::of); + + assertThat(generated.collect(Guavate.toImmutableList())) + .containsOnly(1); + } + + @Test + void iterateWithEmptyGeneratorShouldHaveOnlyTheSeed() { + Stream<Integer> generated = StreamUtils.iterate(1, (long) 10, i -> Stream.of()); + + assertThat(generated.collect(Guavate.toImmutableList())) + .containsOnly(1); + } + + @Test + void iterateWithGeneratorShouldHaveOnlyTheLimitedElements() { + Stream<Integer> generated = StreamUtils.iterate(1, (long) 5, i -> Stream.of(i + 1)); + + assertThat(generated.collect(Guavate.toImmutableList())) + .containsOnly(1, 2, 3, 4, 5, 6); + } } diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java index e3ea519..ece8f55 100644 --- a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java +++ b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java @@ -122,6 +122,8 @@ public interface RecipientRewriteTable { */ Map<MappingSource, Mappings> getAllMappings() throws RecipientRewriteTableException; + int getMappingLimit(); + default Stream<MappingSource> listSources(Mapping mapping) throws RecipientRewriteTableException { Preconditions.checkArgument(listSourcesSupportedType.contains(mapping.getType()), "Not supported mapping of type %s", mapping.getType()); diff --git a/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java b/server/data/data-api/src/main/java/org/apache/james/rrt/api/ReverseRecipientRewriteTable.java similarity index 53% copy from server/container/util/src/main/java/org/apache/james/util/StreamUtils.java copy to server/data/data-api/src/main/java/org/apache/james/rrt/api/ReverseRecipientRewriteTable.java index ccdffd2..3f17aff 100644 --- a/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java +++ b/server/data/data-api/src/main/java/org/apache/james/rrt/api/ReverseRecipientRewriteTable.java @@ -7,7 +7,7 @@ * "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 * + * 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 * @@ -15,43 +15,15 @@ * KIND, either express or implied. See the License for the * * specific language governing permissions and limitations * * under the License. * - ****************************************************************/ + ***************************************************************/ -package org.apache.james.util; +package org.apache.james.rrt.api; -import java.util.Arrays; -import java.util.Collection; -import java.util.Optional; -import java.util.function.Function; import java.util.stream.Stream; -public class StreamUtils { +import org.apache.james.core.MailAddress; +import org.apache.james.core.Username; - @SafeVarargs - public static <T> Stream<T> ofNullables(T... array) { - return ofNullable(array); - } - - public static <T> Stream<T> ofNullable(T[] array) { - return ofOptional(Optional.ofNullable(array)); - } - - public static <T> Stream<T> ofOptional(Optional<T[]> array) { - return array - .map(Arrays::stream) - .orElse(Stream.empty()); - } - - public static <T> Stream<T> flatten(Collection<Stream<T>> streams) { - return flatten(streams.stream()); - } - - public static <T> Stream<T> flatten(Stream<Stream<T>> streams) { - return streams.flatMap(Function.identity()); - } - - @SafeVarargs - public static <T> Stream<T> flatten(Stream<T>... streams) { - return flatten(Arrays.stream(streams)); - } +public interface ReverseRecipientRewriteTable { + Stream<MailAddress> listAddresses(Username user) throws RecipientRewriteTable.ErrorMappingException, RecipientRewriteTableException; } diff --git a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/CanSendFromContract.java b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/CanSendFromContract.java index 13df95e..0a0201d 100644 --- a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/CanSendFromContract.java +++ b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/CanSendFromContract.java @@ -20,13 +20,17 @@ package org.apache.james.rrt.lib; import static org.assertj.core.api.Assertions.assertThat; +import java.util.Optional; +import java.util.stream.IntStream; + import org.apache.james.core.Domain; import org.apache.james.core.Username; import org.apache.james.rrt.api.CanSendFrom; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import com.github.fge.lambdas.Throwing; + public interface CanSendFromContract { Domain DOMAIN = Domain.of("example.com"); @@ -43,6 +47,28 @@ public interface CanSendFromContract { void addGroupMapping(String group, Username user) throws Exception; + @FunctionalInterface + interface RequireUserName { + void to(Username user) throws Exception; + } + + @FunctionalInterface + interface RequireDomain { + void to(Domain domain) throws Exception; + } + + default RequireUserName redirectUser(Username alias) { + return user -> addAliasMapping(alias, user); + } + + default RequireDomain redirectDomain(Domain alias) { + return domain -> addDomainMapping(alias, domain); + } + + default RequireUserName redirectGroup(String group) { + return user -> addGroupMapping(group, user); + } + @Test default void userCanSendFromShouldBeFalseWhenSenderIsNotTheUser() { assertThat(canSendFrom().userCanSendFrom(USER, OTHER_USER)).isFalse(); @@ -55,14 +81,14 @@ public interface CanSendFromContract { @Test default void userCanSendFromShouldBeFalseWhenSenderIsAnAliasOfAnotherUser() throws Exception { - addAliasMapping(USER_ALIAS, OTHER_USER); + redirectUser(USER_ALIAS).to(OTHER_USER); assertThat(canSendFrom().userCanSendFrom(USER, USER_ALIAS)).isFalse(); } @Test default void userCanSendFromShouldBeTrueWhenSenderIsAnAliasOfTheUser() throws Exception { - addAliasMapping(USER_ALIAS, USER); + redirectUser(USER_ALIAS).to(USER); assertThat(canSendFrom().userCanSendFrom(USER, USER_ALIAS)).isTrue(); } @@ -70,17 +96,47 @@ public interface CanSendFromContract { @Test default void userCanSendFromShouldBeTrueWhenSenderIsAnAliasOfAnAliasOfTheUser() throws Exception { Username userAliasBis = Username.of("aliasbis@" + DOMAIN.asString()); - addAliasMapping(userAliasBis, USER_ALIAS); - addAliasMapping(USER_ALIAS, USER); + redirectUser(userAliasBis).to(USER_ALIAS); + redirectUser(USER_ALIAS).to(USER); + + assertThat(canSendFrom().userCanSendFrom(USER, userAliasBis)).isTrue(); + } + + @Test + default void userCanSendFromShouldBeFalseWhenSenderIsAnAliasOfAnAliasOfAnAliasOfTheUser() throws Exception { + Username userAliasBis = Username.of("aliasbis@" + DOMAIN.asString()); + Username userAliasTer = Username.of("aliaster@" + DOMAIN.asString()); + redirectUser(userAliasTer).to(userAliasBis); + redirectUser(userAliasBis).to(USER_ALIAS); + redirectUser(USER_ALIAS).to(USER); + + assertThat(canSendFrom().userCanSendFrom(USER, userAliasTer)).isTrue(); + } + + @Test + default void userCanSendFromShouldBeTrueWhenSenderIsAnAliasOfAnAliasInAnotherDomainOfTheUser() throws Exception { + Username userAlias = Username.of("aliasbis@" + OTHER_DOMAIN.asString()); + Username userAliasBis = Username.of("aliaster@" + OTHER_DOMAIN.asString()); + redirectUser(userAliasBis).to(userAlias); + redirectUser(userAlias).to(USER); + + assertThat(canSendFrom().userCanSendFrom(USER, userAliasBis)).isTrue(); + } + + @Test + default void userCanSendFromShouldBeTrueWhenSenderIsAnAliasInAnotherDomainOfAnAliasOfTheUser() throws Exception { + Username userAliasBis = Username.of("aliasbis@" + OTHER_DOMAIN.asString()); + redirectUser(userAliasBis).to(USER_ALIAS); + redirectUser(USER_ALIAS).to(USER); assertThat(canSendFrom().userCanSendFrom(USER, userAliasBis)).isTrue(); } @Test default void userCanSendFromShouldBeTrueWhenSenderIsAnAliasOfTheDomainUser() throws Exception { - Username fromUser = Username.of(USER.getLocalPart() + "@" + OTHER_DOMAIN.asString()); + Username fromUser = USER.withOtherDomain(Optional.of(OTHER_DOMAIN)); - addDomainMapping(OTHER_DOMAIN, DOMAIN); + redirectDomain(OTHER_DOMAIN).to(DOMAIN); assertThat(canSendFrom().userCanSendFrom(USER, fromUser)).isTrue(); } @@ -89,7 +145,7 @@ public interface CanSendFromContract { default void userCanSendFromShouldBeFalseWhenWhenSenderIsAnAliasOfTheUserFromAGroupAlias() throws Exception { Username fromGroup = Username.of("gr...@example.com"); - addGroupMapping("gr...@example.com", USER); + redirectGroup("gr...@example.com").to(USER); assertThat(canSendFrom().userCanSendFrom(USER, fromGroup)).isFalse(); @@ -103,25 +159,24 @@ public interface CanSendFromContract { @Test default void allValidFromAddressesShouldContainOnlyUserAddressWhenUserHasNoAliasAndAnotherUserHasOne() throws Exception { - addAliasMapping(USER_ALIAS, OTHER_USER); + redirectUser(USER_ALIAS).to(OTHER_USER); assertThat(canSendFrom().allValidFromAddressesForUser(USER)) .containsExactly(USER.asMailAddress()); } @Test default void allValidFromAddressesShouldContainUserAddressAndAnAliasOfTheUser() throws Exception { - addAliasMapping(USER_ALIAS, USER); + redirectUser(USER_ALIAS).to(USER); assertThat(canSendFrom().allValidFromAddressesForUser(USER)) .containsExactlyInAnyOrder(USER.asMailAddress(), USER_ALIAS.asMailAddress()); } @Test - @Disabled("Recursive aliases are not supported yet") default void allValidFromAddressesFromShouldBeTrueWhenSenderIsAnAliasOfAnAliasOfTheUser() throws Exception { Username userAliasBis = Username.of("aliasbis@" + DOMAIN.asString()); - addAliasMapping(userAliasBis, USER_ALIAS); - addAliasMapping(USER_ALIAS, USER); + redirectUser(userAliasBis).to(USER_ALIAS); + redirectUser(USER_ALIAS).to(USER); assertThat(canSendFrom().allValidFromAddressesForUser(USER)) .containsExactlyInAnyOrder(USER.asMailAddress(), USER_ALIAS.asMailAddress(), userAliasBis.asMailAddress()); @@ -129,9 +184,9 @@ public interface CanSendFromContract { @Test default void allValidFromAddressesShouldContainUserAddressAndAnAliasOfTheDomainUser() throws Exception { - Username fromUser = Username.of(USER.getLocalPart() + "@" + OTHER_DOMAIN.asString()); + Username fromUser = USER.withOtherDomain(Optional.of(OTHER_DOMAIN)); - addDomainMapping(OTHER_DOMAIN, DOMAIN); + redirectDomain(OTHER_DOMAIN).to(DOMAIN); assertThat(canSendFrom().allValidFromAddressesForUser(USER)) .containsExactlyInAnyOrder(USER.asMailAddress(), fromUser.asMailAddress()); @@ -139,14 +194,66 @@ public interface CanSendFromContract { @Test default void allValidFromAddressesShouldContainUserAddressAndAnAliasOfTheDomainUserFromAnotherDomain() throws Exception { - Username userAliasOtherDomain = Username.of(USER_ALIAS.getLocalPart() + "@" + OTHER_DOMAIN.asString()); + Username userAliasOtherDomain = USER_ALIAS.withOtherDomain(Optional.of(OTHER_DOMAIN)); - addDomainMapping(OTHER_DOMAIN, DOMAIN); - addAliasMapping(userAliasOtherDomain, USER); + redirectDomain(OTHER_DOMAIN).to(DOMAIN); + redirectUser(userAliasOtherDomain).to(USER); - Username userAliasMainDomain = Username.of(USER_ALIAS.getLocalPart() + "@" + DOMAIN.asString()); - Username userOtherDomain = Username.of(USER.getLocalPart() + "@" + OTHER_DOMAIN.asString()); + Username userAliasMainDomain = USER_ALIAS.withOtherDomain(Optional.of(DOMAIN)); + Username userOtherDomain = USER.withOtherDomain(Optional.of(OTHER_DOMAIN)); assertThat(canSendFrom().allValidFromAddressesForUser(USER)) .containsExactlyInAnyOrder(USER.asMailAddress(), userAliasOtherDomain.asMailAddress(), userAliasMainDomain.asMailAddress(), userOtherDomain.asMailAddress()); } + + @Test + default void allValidFromAddressesShouldContainASendersAliasOfAnAliasOfTheUser() throws Exception { + Username userAliasBis = Username.of("aliasbis@" + DOMAIN.asString()); + redirectUser(userAliasBis).to(USER_ALIAS); + redirectUser(USER_ALIAS).to(USER); + + assertThat(canSendFrom().userCanSendFrom(USER, userAliasBis)).isTrue(); + } + + @Test + default void allValidFromAddressesShouldNotContainAliasesRequiringMoreThanTenRecursionSteps() throws Exception { + int recursionLevel = 10; + IntStream.range(0, recursionLevel) + .forEach(Throwing.intConsumer(aliasNumber -> { + Username userAliasFrom = Username.of("alias" + aliasNumber + "@" + DOMAIN.asString()); + Username userAliasTo; + if (aliasNumber == 0) { + userAliasTo = USER_ALIAS; + } else { + userAliasTo = Username.of("alias" + (aliasNumber - 1) + "@" + DOMAIN.asString()); + } + redirectUser(userAliasFrom).to(userAliasTo); + }).sneakyThrow()); + + Username userAliasExcluded = Username.of("alias" + (recursionLevel - 1) + "@" + DOMAIN.asString()); + redirectUser(USER_ALIAS).to(USER); + + assertThat(canSendFrom().allValidFromAddressesForUser(USER)) + .doesNotContain(userAliasExcluded.asMailAddress()); + } + + @Test + default void allValidFromAddressesShouldContainASendersAliasOfAnAliasInAnotherDomainOfTheUser() throws Exception { + Username userAlias = Username.of("aliasbis@" + OTHER_DOMAIN.asString()); + Username userAliasBis = Username.of("aliaster@" + OTHER_DOMAIN.asString()); + redirectUser(userAliasBis).to(userAlias); + redirectUser(userAlias).to(USER); + + assertThat(canSendFrom().allValidFromAddressesForUser(USER)) + .contains(userAliasBis.asMailAddress()); + } + + @Test + default void allValidFromAddressesShouldContainAnUserAliasFollowingADomainAliasResolution() throws Exception { + Username userAliasBis = Username.of("aliasbis@" + OTHER_DOMAIN.asString()); + redirectUser(userAliasBis).to(USER_ALIAS); + redirectUser(USER_ALIAS).to(USER); + + assertThat(canSendFrom().allValidFromAddressesForUser(USER)) + .contains(userAliasBis.asMailAddress()); + } } diff --git a/server/data/data-api/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableContract.java b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableContract.java new file mode 100644 index 0000000..edf4372 --- /dev/null +++ b/server/data/data-api/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableContract.java @@ -0,0 +1,167 @@ +/** ************************************************************* + * 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.rrt.lib; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; +import java.util.stream.IntStream; + +import org.apache.james.core.Domain; +import org.apache.james.core.Username; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; +import org.junit.jupiter.api.Test; + +import com.github.fge.lambdas.Throwing; + +public interface ReverseRecipientRewriteTableContract { + + Domain DOMAIN = Domain.of("example.com"); + Domain OTHER_DOMAIN = Domain.of("other.org"); + Username USER = Username.of("u...@example.com"); + Username USER_ALIAS = Username.of("al...@example.com"); + Username OTHER_USER = Username.of("ot...@example.com"); + + ReverseRecipientRewriteTable reverseRecipientRewriteTable(); + + void addAliasMapping(Username alias, Username user) throws Exception; + + void addDomainMapping(Domain alias, Domain domain) throws Exception; + + void addGroupMapping(String group, Username user) throws Exception; + + @FunctionalInterface + interface RequireUserName { + void to(Username user) throws Exception; + } + + @FunctionalInterface + interface RequireDomain { + void to(Domain domain) throws Exception; + } + + default CanSendFromContract.RequireUserName redirectUser(Username alias) { + return user -> addAliasMapping(alias, user); + } + + default CanSendFromContract.RequireDomain redirectDomain(Domain alias) { + return domain -> addDomainMapping(alias, domain); + } + + default CanSendFromContract.RequireUserName redirectGroup(String group) { + return user -> addGroupMapping(group, user); + } + @Test + default void listAddressesShouldContainOnlyUserAddressWhenUserHasNoAlias() throws Exception { + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .containsExactly(USER.asMailAddress()); + } + + @Test + default void listAddressesShouldContainOnlyUserAddressWhenUserHasNoAliasAndAnotherUserHasOne() throws Exception { + redirectUser(USER_ALIAS).to(OTHER_USER); + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .containsExactly(USER.asMailAddress()); + } + + @Test + default void listAddressesShouldContainUserAddressAndAnAliasOfTheUser() throws Exception { + redirectUser(USER_ALIAS).to(USER); + + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .containsExactlyInAnyOrder(USER.asMailAddress(), USER_ALIAS.asMailAddress()); + } + + @Test + default void listAddressesFromShouldBeTrueWhenSenderIsAnAliasOfAnAliasOfTheUser() throws Exception { + Username userAliasBis = Username.of("aliasbis@" + DOMAIN.asString()); + redirectUser(userAliasBis).to(USER_ALIAS); + redirectUser(USER_ALIAS).to(USER); + + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .containsExactlyInAnyOrder(USER.asMailAddress(), USER_ALIAS.asMailAddress(), userAliasBis.asMailAddress()); + } + + @Test + default void listAddressesShouldContainUserAddressAndAnAliasOfTheDomainUser() throws Exception { + Username fromUser = USER.withOtherDomain(Optional.of(OTHER_DOMAIN)); + + redirectDomain(OTHER_DOMAIN).to(DOMAIN); + + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .containsExactlyInAnyOrder(USER.asMailAddress(), fromUser.asMailAddress()); + } + + @Test + default void listAddressesShouldContainUserAddressAndAnAliasOfTheDomainUserFromAnotherDomain() throws Exception { + Username userAliasOtherDomain = USER_ALIAS.withOtherDomain(Optional.of(OTHER_DOMAIN)); + + redirectDomain(OTHER_DOMAIN).to(DOMAIN); + redirectUser(userAliasOtherDomain).to(USER); + + Username userAliasMainDomain = USER_ALIAS.withOtherDomain(Optional.of(DOMAIN)); + Username userOtherDomain = USER.withOtherDomain(Optional.of(OTHER_DOMAIN)); + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .containsExactlyInAnyOrder(USER.asMailAddress(), userAliasOtherDomain.asMailAddress(), userAliasMainDomain.asMailAddress(), userOtherDomain.asMailAddress()); + } + + @Test + default void listAddressesShouldNotContainAliasesRequiringMoreThanTenRecursionSteps() throws Exception { + int recursionLevel = 10; + IntStream.range(0, recursionLevel) + .forEach(Throwing.intConsumer(aliasNumber -> { + Username userAliasFrom = Username.of("alias" + aliasNumber + "@" + DOMAIN.asString()); + Username userAliasTo; + if (aliasNumber == 0) { + userAliasTo = USER_ALIAS; + } else { + userAliasTo = Username.of("alias" + (aliasNumber - 1) + "@" + DOMAIN.asString()); + } + redirectUser(userAliasFrom).to(userAliasTo); + }).sneakyThrow()); + + Username userAliasExcluded = Username.of("alias" + (recursionLevel - 1) + "@" + DOMAIN.asString()); + redirectUser(USER_ALIAS).to(USER); + + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .doesNotContain(userAliasExcluded.asMailAddress()); + } + + @Test + default void listAddressesShouldContainASendersAliasOfAnAliasInAnotherDomainOfTheUser() throws Exception { + Username userAlias = Username.of("aliasbis@" + OTHER_DOMAIN.asString()); + Username userAliasBis = Username.of("aliaster@" + OTHER_DOMAIN.asString()); + redirectUser(userAliasBis).to(userAlias); + redirectUser(userAlias).to(USER); + + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .contains(userAliasBis.asMailAddress()); + } + + @Test + default void listAddressesShouldContainAnUserAliasFollowingADomainAliasResolution() throws Exception { + Username userAliasBis = Username.of("aliasbis@" + OTHER_DOMAIN.asString()); + redirectUser(userAliasBis).to(USER_ALIAS); + redirectUser(USER_ALIAS).to(USER); + + assertThat(reverseRecipientRewriteTable().listAddresses(USER)) + .contains(userAliasBis.asMailAddress()); + } +} diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java index 260d5f6..cafc427 100644 --- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java +++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java @@ -60,6 +60,15 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT private DomainList domainList; + @Override + public int getMappingLimit() { + if (recursive) { + return mappingLimit; + } else { + return 0; + } + } + @Inject public void setDomainList(DomainList domainList) { this.domainList = domainList; diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/CanSendFromImpl.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/CanSendFromImpl.java index 930cc58..b2bedc8 100644 --- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/CanSendFromImpl.java +++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/CanSendFromImpl.java @@ -23,7 +23,6 @@ import static org.apache.james.rrt.lib.Mapping.Type.Domain; import java.util.EnumSet; import java.util.List; -import java.util.Optional; import java.util.stream.Stream; import javax.inject.Inject; @@ -34,19 +33,24 @@ import org.apache.james.core.Username; import org.apache.james.rrt.api.CanSendFrom; import org.apache.james.rrt.api.RecipientRewriteTable; import org.apache.james.rrt.api.RecipientRewriteTableException; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.util.OptionalUtils; -import com.github.fge.lambdas.Throwing; -import com.github.steveash.guavate.Guavate; - public class CanSendFromImpl implements CanSendFrom { + @FunctionalInterface + interface DomainFetcher { + List<Domain> fetch(Username user); + } + public static final EnumSet<Mapping.Type> ALIAS_TYPES_ACCEPTED_IN_FROM = EnumSet.of(Alias, Domain); private final RecipientRewriteTable recipientRewriteTable; + private final ReverseRecipientRewriteTable reverseRecipientRewriteTable; @Inject - public CanSendFromImpl(RecipientRewriteTable recipientRewriteTable) { + public CanSendFromImpl(RecipientRewriteTable recipientRewriteTable, ReverseRecipientRewriteTable reverseRecipientRewriteTable) { this.recipientRewriteTable = recipientRewriteTable; + this.reverseRecipientRewriteTable = reverseRecipientRewriteTable; } @Override @@ -60,13 +64,7 @@ public class CanSendFromImpl implements CanSendFrom { @Override public Stream<MailAddress> allValidFromAddressesForUser(Username user) throws RecipientRewriteTable.ErrorMappingException, RecipientRewriteTableException { - List<Domain> domains = relatedDomains(user).collect(Guavate.toImmutableList()); - - return relatedAliases(user) - .flatMap(allowedUser -> domains.stream() - .map(Optional::of) - .map(allowedUser::withOtherDomain) - .map(Throwing.function(Username::asMailAddress).sneakyThrow())); + return reverseRecipientRewriteTable.listAddresses(user); } private boolean emailIsAnAliasOfTheConnectedUser(Username connectedUser, Username fromUser) throws RecipientRewriteTable.ErrorMappingException, RecipientRewriteTableException { @@ -78,30 +76,4 @@ public class CanSendFromImpl implements CanSendFrom { .map(Username::fromMailAddress) .anyMatch(alias -> alias.equals(connectedUser)); } - - private Stream<Username> relatedAliases(Username user) throws RecipientRewriteTableException { - return Stream.concat( - Stream.of(user), - recipientRewriteTable - .listSources(Mapping.alias(user.asString())) - .map(MappingSource::asUsername) - .flatMap(OptionalUtils::toStream) - ); - } - - private Stream<Domain> relatedDomains(Username user) { - return user.getDomainPart() - .map(Throwing.function(this::fetchDomains).sneakyThrow()) - .orElseGet(Stream::empty); - } - - private Stream<Domain> fetchDomains(Domain domain) throws RecipientRewriteTableException { - return Stream.concat( - Stream.of(domain), - recipientRewriteTable - .listSources(Mapping.domain(domain)) - .map(MappingSource::asDomain) - .flatMap(OptionalUtils::toStream) - ); - } } diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImpl.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImpl.java new file mode 100644 index 0000000..419a69b --- /dev/null +++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImpl.java @@ -0,0 +1,105 @@ +/**************************************************************** + * 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.rrt.lib; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; + +import javax.inject.Inject; + +import org.apache.james.core.Domain; +import org.apache.james.core.MailAddress; +import org.apache.james.core.Username; +import org.apache.james.rrt.api.RecipientRewriteTable; +import org.apache.james.rrt.api.RecipientRewriteTableException; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; +import org.apache.james.util.OptionalUtils; +import org.apache.james.util.StreamUtils; + +import com.github.fge.lambdas.Throwing; +import com.github.steveash.guavate.Guavate; + +public class ReverseRecipientRewriteTableImpl implements ReverseRecipientRewriteTable { + private final RecipientRewriteTable recipientRewriteTable; + + @Inject + public ReverseRecipientRewriteTableImpl(RecipientRewriteTable recipientRewriteTable) { + this.recipientRewriteTable = recipientRewriteTable; + } + + @Override + public Stream<MailAddress> listAddresses(Username user) throws RecipientRewriteTable.ErrorMappingException, RecipientRewriteTableException { + CanSendFromImpl.DomainFetcher domains = domainFetcher(user); + + return relatedAliases(user) + .flatMap(allowedUser -> domains.fetch(allowedUser) + .stream() + .map(Optional::of) + .map(allowedUser::withOtherDomain) + .map(Throwing.function(Username::asMailAddress).sneakyThrow())) + .distinct(); + } + + private Stream<Username> relatedAliases(Username user) { + return StreamUtils.iterate( + user, + (long) recipientRewriteTable.getMappingLimit(), + Throwing.<Username, Stream<Username>>function(targetUser -> + recipientRewriteTable + .listSources(Mapping.alias(targetUser.asString())) + .map(MappingSource::asUsername) + .flatMap(OptionalUtils::toStream)).sneakyThrow() + ); + } + + private CanSendFromImpl.DomainFetcher domainFetcher(Username user) { + HashMap<Domain, List<Domain>> fetchedDomains = new HashMap<>(); + List<Domain> userDomains = relatedDomains(user).collect(Guavate.toImmutableList()); + user.getDomainPart().ifPresent(domain -> fetchedDomains.put(domain, userDomains)); + Function<Domain, List<Domain>> computeDomain = givenDomain -> Stream.concat(userDomains.stream(), fetchDomains(givenDomain)).collect(Guavate.toImmutableList()); + return givenUsername -> + givenUsername + .getDomainPart() + .map(domain -> fetchedDomains.computeIfAbsent(domain, computeDomain)) + .orElseGet(Arrays::asList); + } + + private Stream<Domain> relatedDomains(Username user) { + return user.getDomainPart() + .map(this::fetchDomains) + .orElseGet(Stream::empty); + } + + private Stream<Domain> fetchDomains(Domain domain) { + return StreamUtils.iterate( + domain, + (long) recipientRewriteTable.getMappingLimit(), + Throwing.<Domain, Stream<Domain>>function(targetDomain -> + recipientRewriteTable + .listSources(Mapping.domain(targetDomain)) + .map(MappingSource::asDomain) + .flatMap(OptionalUtils::toStream)).sneakyThrow() + ); + } +} diff --git a/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java b/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java index a38467a..47863a1 100644 --- a/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java +++ b/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java @@ -26,6 +26,7 @@ import org.apache.james.dnsservice.api.DNSService; import org.apache.james.domainlist.lib.DomainListConfiguration; import org.apache.james.domainlist.memory.MemoryDomainList; import org.apache.james.rrt.api.CanSendFrom; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.junit.jupiter.api.BeforeEach; @@ -47,7 +48,8 @@ public class CanSendFromImplTest implements CanSendFromContract { domainList.addDomain(OTHER_DOMAIN); recipientRewriteTable.setDomainList(domainList); - canSendFrom = new CanSendFromImpl(recipientRewriteTable); + ReverseRecipientRewriteTable reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable); + canSendFrom = new CanSendFromImpl(recipientRewriteTable, reverseRecipientRewriteTable); } @Override diff --git a/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java b/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImplTest.java similarity index 84% copy from server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java copy to server/data/data-memory/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImplTest.java index a38467a..fe0d17b 100644 --- a/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/CanSendFromImplTest.java +++ b/server/data/data-memory/src/test/java/org/apache/james/rrt/lib/ReverseRecipientRewriteTableImplTest.java @@ -7,7 +7,7 @@ * "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 * + * 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 * @@ -15,7 +15,8 @@ * KIND, either express or implied. See the License for the * * specific language governing permissions and limitations * * under the License. * - ****************************************************************/ + ***************************************************************/ + package org.apache.james.rrt.lib; import static org.mockito.Mockito.mock; @@ -25,14 +26,14 @@ import org.apache.james.core.Username; import org.apache.james.dnsservice.api.DNSService; import org.apache.james.domainlist.lib.DomainListConfiguration; import org.apache.james.domainlist.memory.MemoryDomainList; -import org.apache.james.rrt.api.CanSendFrom; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.junit.jupiter.api.BeforeEach; -public class CanSendFromImplTest implements CanSendFromContract { +public class ReverseRecipientRewriteTableImplTest implements ReverseRecipientRewriteTableContract { AbstractRecipientRewriteTable recipientRewriteTable; - CanSendFrom canSendFrom; + ReverseRecipientRewriteTableImpl reverseRecipientRewriteTable; @BeforeEach void setup() throws Exception { @@ -47,12 +48,12 @@ public class CanSendFromImplTest implements CanSendFromContract { domainList.addDomain(OTHER_DOMAIN); recipientRewriteTable.setDomainList(domainList); - canSendFrom = new CanSendFromImpl(recipientRewriteTable); + this.reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable); } @Override - public CanSendFrom canSendFrom() { - return canSendFrom; + public ReverseRecipientRewriteTable reverseRecipientRewriteTable() { + return reverseRecipientRewriteTable; } @Override diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java index ade1101..6740ff1 100644 --- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java +++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java @@ -74,9 +74,11 @@ import org.apache.james.mailbox.model.TestMessageId; import org.apache.james.metrics.tests.RecordingMetricFactory; import org.apache.james.rrt.api.CanSendFrom; import org.apache.james.rrt.api.RecipientRewriteTableException; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.lib.Mapping; import org.apache.james.rrt.lib.MappingSource; import org.apache.james.rrt.lib.CanSendFromImpl; +import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.apache.james.util.OptionalUtils; import org.apache.james.util.html.HtmlTextExtractor; @@ -154,7 +156,8 @@ public class SetMessagesCreationProcessorTest { domainList.addDomain(Domain.of("example.com")); domainList.addDomain(Domain.of("other.org")); recipientRewriteTable.setDomainList(domainList); - canSendFrom = new CanSendFromImpl(recipientRewriteTable); + ReverseRecipientRewriteTable reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable); + canSendFrom = new CanSendFromImpl(recipientRewriteTable, reverseRecipientRewriteTable); messageFullViewFactory = new MessageFullViewFactory(blobManager, messageContentExtractor, htmlTextExtractor, messageIdManager, new MemoryMessageFastViewProjection(new RecordingMetricFactory())); diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java index 9b6f88a..4b8f472 100644 --- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java +++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java @@ -67,8 +67,10 @@ import org.apache.james.mailbox.model.TestMessageId; import org.apache.james.metrics.tests.RecordingMetricFactory; import org.apache.james.rrt.api.CanSendFrom; import org.apache.james.rrt.api.RecipientRewriteTableException; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.lib.CanSendFromImpl; import org.apache.james.rrt.lib.MappingSource; +import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.apache.james.util.OptionalUtils; import org.apache.james.util.html.HtmlTextExtractor; @@ -167,7 +169,8 @@ public class SetMessagesUpdateProcessorTest { domainList.addDomain(Domain.of("example.com")); domainList.addDomain(Domain.of("other.org")); recipientRewriteTable.setDomainList(domainList); - canSendFrom = new CanSendFromImpl(recipientRewriteTable); + ReverseRecipientRewriteTable reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable); + canSendFrom = new CanSendFromImpl(recipientRewriteTable, reverseRecipientRewriteTable); mockedMailSpool = mock(MailSpool.class); mockedMailboxManager = mock(MailboxManager.class); mockedMailboxIdFactory = mock(MailboxId.Factory.class); diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java index 9e5278a..c471f72 100644 --- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java +++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java @@ -72,8 +72,10 @@ import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory; import org.apache.james.queue.memory.MemoryMailQueueFactory; import org.apache.james.rrt.api.CanSendFrom; import org.apache.james.rrt.api.RecipientRewriteTable; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.lib.CanSendFromImpl; import org.apache.james.rrt.lib.MappingSource; +import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.apache.james.server.core.configuration.Configuration; import org.apache.james.server.core.filesystem.FileSystemImpl; @@ -198,6 +200,7 @@ public class SMTPServerTest { protected MemoryMailQueueFactory queueFactory; protected MemoryMailQueueFactory.MemoryMailQueue queue; protected MemoryRecipientRewriteTable rewriteTable; + private ReverseRecipientRewriteTable reverseRewriteTable; protected CanSendFrom canSendFrom; private SMTPServer smtpServer; @@ -276,7 +279,8 @@ public class SMTPServerTest { dnsServer = new AlterableDNSServer(); rewriteTable = new MemoryRecipientRewriteTable(); - canSendFrom = new CanSendFromImpl(rewriteTable); + reverseRewriteTable = new ReverseRecipientRewriteTableImpl(rewriteTable); + canSendFrom = new CanSendFromImpl(rewriteTable, reverseRewriteTable); queueFactory = new MemoryMailQueueFactory(new RawMailQueueItemDecoratorFactory()); queue = queueFactory.createQueue(MailQueueFactory.SPOOL); diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UserRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UserRoutesTest.java index 7936d4f..d45f79e 100644 --- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UserRoutesTest.java +++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/UserRoutesTest.java @@ -43,8 +43,10 @@ import org.apache.james.domainlist.api.mock.SimpleDomainList; import org.apache.james.rrt.api.CanSendFrom; import org.apache.james.rrt.api.RecipientRewriteTable; import org.apache.james.rrt.api.RecipientRewriteTableException; +import org.apache.james.rrt.api.ReverseRecipientRewriteTable; import org.apache.james.rrt.lib.CanSendFromImpl; import org.apache.james.rrt.lib.MappingSource; +import org.apache.james.rrt.lib.ReverseRecipientRewriteTableImpl; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.apache.james.user.api.UsersRepository; import org.apache.james.user.api.UsersRepositoryException; @@ -98,6 +100,7 @@ class UserRoutesTest { final MemoryUsersRepository usersRepository; final SimpleDomainList domainList; final MemoryRecipientRewriteTable recipientRewriteTable; + final ReverseRecipientRewriteTable reverseRecipientRewriteTable; final CanSendFrom canSendFrom; WebAdminServer webAdminServer; @@ -107,7 +110,8 @@ class UserRoutesTest { this.domainList = domainList; this.recipientRewriteTable = new MemoryRecipientRewriteTable(); this.recipientRewriteTable.setDomainList(domainList); - this.canSendFrom = new CanSendFromImpl(recipientRewriteTable); + this.reverseRecipientRewriteTable = new ReverseRecipientRewriteTableImpl(recipientRewriteTable); + this.canSendFrom = new CanSendFromImpl(recipientRewriteTable, reverseRecipientRewriteTable); } @Override --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org