blob: a72c2521abcedd79aeaf92a04ae356f2c4a30c41 [file] [log] [blame]
/****************************************************************
* 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.smtpserver;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.net.InetSocketAddress;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
import org.apache.commons.configuration2.HierarchicalConfiguration;
import org.apache.commons.configuration2.tree.ImmutableNode;
import org.apache.james.UserEntityValidator;
import org.apache.james.core.Domain;
import org.apache.james.core.Username;
import org.apache.james.dnsservice.api.DNSService;
import org.apache.james.dnsservice.api.InMemoryDNSService;
import org.apache.james.domainlist.api.DomainList;
import org.apache.james.domainlist.lib.DomainListConfiguration;
import org.apache.james.domainlist.memory.MemoryDomainList;
import org.apache.james.filesystem.api.FileSystem;
import org.apache.james.mailbox.Authorizator;
import org.apache.james.mailrepository.api.MailRepositoryStore;
import org.apache.james.mailrepository.api.Protocol;
import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
import org.apache.james.mailrepository.memory.MemoryMailRepository;
import org.apache.james.mailrepository.memory.MemoryMailRepositoryStore;
import org.apache.james.mailrepository.memory.MemoryMailRepositoryUrlStore;
import org.apache.james.mailrepository.memory.SimpleMailRepositoryLoader;
import org.apache.james.metrics.api.Metric;
import org.apache.james.metrics.api.MetricFactory;
import org.apache.james.metrics.tests.RecordingMetricFactory;
import org.apache.james.protocols.api.utils.ProtocolServerUtils;
import org.apache.james.protocols.lib.mock.MockProtocolHandlerLoader;
import org.apache.james.queue.api.MailQueueFactory;
import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory;
import org.apache.james.queue.memory.MemoryMailQueueFactory;
import org.apache.james.rrt.api.AliasReverseResolver;
import org.apache.james.rrt.api.CanSendFrom;
import org.apache.james.rrt.api.RecipientRewriteTable;
import org.apache.james.rrt.api.RecipientRewriteTableConfiguration;
import org.apache.james.rrt.lib.AliasReverseResolverImpl;
import org.apache.james.rrt.lib.CanSendFromImpl;
import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
import org.apache.james.server.core.configuration.FileConfigurationProvider;
import org.apache.james.server.core.filesystem.FileSystemImpl;
import org.apache.james.smtpserver.netty.SMTPServer;
import org.apache.james.smtpserver.netty.SmtpMetricsImpl;
import org.apache.james.user.api.UsersRepository;
import org.apache.james.user.memory.MemoryUsersRepository;
import com.google.common.collect.ImmutableList;
import com.google.inject.TypeLiteral;
class SMTPServerTestSystem {
public static final String LOCAL_DOMAIN = "example.local";
public static final Username BOB = Username.of("bob@localhost");
public static final String PASSWORD = "bobpwd";
public static final Instant DATE = Instant.parse("2023-04-14T10:00:00.00Z");
public static final Clock CLOCK = Clock.fixed(DATE, ZoneId.of("Z"));
MemoryDomainList domainList;
MemoryUsersRepository usersRepository;
SMTPServerTest.AlterableDNSServer dnsServer;
MemoryMailRepositoryStore mailRepositoryStore;
FileSystemImpl fileSystem;
MockProtocolHandlerLoader chain;
MemoryMailQueueFactory queueFactory;
MemoryMailQueueFactory.MemoryCacheableMailQueue queue;
SMTPServer smtpServer;
MemoryRecipientRewriteTable rewriteTable;
void setUp(String configuration) throws Exception {
setUp(FileConfigurationProvider.getConfig(
ClassLoader.getSystemResourceAsStream(configuration)),
(userId, otherUserId) -> Authorizator.AuthorizationState.ALLOWED);
}
void setUp(HierarchicalConfiguration<ImmutableNode> configuration, Authorizator authorizator) throws Exception {
preSetUp(authorizator);
smtpServer.configure(configuration);
smtpServer.init();
}
void preSetUp(Authorizator authorizator) throws Exception {
domainList = new MemoryDomainList(new InMemoryDNSService());
domainList.configure(DomainListConfiguration.DEFAULT);
domainList.addDomain(Domain.of(LOCAL_DOMAIN));
domainList.addDomain(Domain.of("examplebis.local"));
usersRepository = MemoryUsersRepository.withVirtualHosting(domainList);
usersRepository.addUser(BOB, PASSWORD);
createMailRepositoryStore();
setUpFakeLoader(authorizator);
setUpSMTPServer();
}
void preSetUp() throws Exception {
preSetUp((userId, otherUserId) -> Authorizator.AuthorizationState.ALLOWED);
}
protected void createMailRepositoryStore() throws Exception {
fileSystem = FileSystemImpl.forTestingWithConfigurationFromClasspath();
MemoryMailRepositoryUrlStore urlStore = new MemoryMailRepositoryUrlStore();
MailRepositoryStoreConfiguration configuration = MailRepositoryStoreConfiguration.forItems(
new MailRepositoryStoreConfiguration.Item(
ImmutableList.of(new Protocol("memory")),
MemoryMailRepository.class.getName(),
new BaseHierarchicalConfiguration()));
mailRepositoryStore = new MemoryMailRepositoryStore(urlStore, new SimpleMailRepositoryLoader(), configuration);
mailRepositoryStore.init();
}
protected SMTPServer createSMTPServer(SmtpMetricsImpl smtpMetrics) {
return new SMTPServer(smtpMetrics);
}
protected void setUpSMTPServer() {
SmtpMetricsImpl smtpMetrics = mock(SmtpMetricsImpl.class);
when(smtpMetrics.getCommandsMetric()).thenReturn(mock(Metric.class));
when(smtpMetrics.getConnectionMetric()).thenReturn(mock(Metric.class));
smtpServer = createSMTPServer(smtpMetrics);
smtpServer.setDnsService(dnsServer);
smtpServer.setFileSystem(fileSystem);
smtpServer.setProtocolHandlerLoader(chain);
}
protected void setUpFakeLoader(Authorizator authorizator) {
dnsServer = new SMTPServerTest.AlterableDNSServer();
rewriteTable = new MemoryRecipientRewriteTable();
rewriteTable.setConfiguration(RecipientRewriteTableConfiguration.DEFAULT_ENABLED);
AliasReverseResolver aliasReverseResolver = new AliasReverseResolverImpl(rewriteTable);
CanSendFrom canSendFrom = new CanSendFromImpl(aliasReverseResolver);
queueFactory = new MemoryMailQueueFactory(new RawMailQueueItemDecoratorFactory(), CLOCK);
queue = queueFactory.createQueue(MailQueueFactory.SPOOL);
chain = MockProtocolHandlerLoader.builder()
.put(binder -> binder.bind(DomainList.class).toInstance(domainList))
.put(binder -> binder.bind(Clock.class).toInstance(CLOCK))
.put(binder -> binder.bind(new TypeLiteral<MailQueueFactory<?>>() {}).toInstance(queueFactory))
.put(binder -> binder.bind(RecipientRewriteTable.class).toInstance(rewriteTable))
.put(binder -> binder.bind(CanSendFrom.class).toInstance(canSendFrom))
.put(binder -> binder.bind(FileSystem.class).toInstance(fileSystem))
.put(binder -> binder.bind(MailRepositoryStore.class).toInstance(mailRepositoryStore))
.put(binder -> binder.bind(DNSService.class).toInstance(dnsServer))
.put(binder -> binder.bind(UsersRepository.class).toInstance(usersRepository))
.put(binder -> binder.bind(MetricFactory.class).to(RecordingMetricFactory.class))
.put(binder -> binder.bind(UserEntityValidator.class).toInstance(UserEntityValidator.NOOP))
.put(binder -> binder.bind(Authorizator.class).toInstance(authorizator))
.build();
}
InetSocketAddress getBindedAddress() {
return new ProtocolServerUtils(smtpServer).retrieveBindedAddress();
}
}