This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new 164afea5dc [ENHANCEMENT] MailetContainer should record loggedIn user
in MDC (#2950)
164afea5dc is described below
commit 164afea5dc89587d737dff2febbb2ef30328bc76
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Feb 27 13:42:48 2026 +0100
[ENHANCEMENT] MailetContainer should record loggedIn user in MDC (#2950)
---
.../api/src/main/java/org/apache/mailet/Mail.java | 11 ++++++
.../mailetcontainer/impl/MatcherSplitter.java | 16 ++------
.../james/mailetcontainer/impl/ProcessorImpl.java | 46 ++++++++++++----------
.../org/apache/james/jmap/mailet/SentByJmap.java | 3 +-
.../james/jmap/send/PostDequeueDecorator.java | 2 +-
.../jmap/method/EmailSubmissionSetMethod.scala | 5 +--
.../apache/james/jmap/method/MDNSendMethod.scala | 6 +--
.../apache/james/jmap/mailet/SentByJmapTest.java | 6 +--
.../james/jmap/send/PostDequeueDecoratorTest.java | 2 +-
9 files changed, 50 insertions(+), 47 deletions(-)
diff --git a/mailet/api/src/main/java/org/apache/mailet/Mail.java
b/mailet/api/src/main/java/org/apache/mailet/Mail.java
index bd869ab901..f7a7b5183f 100644
--- a/mailet/api/src/main/java/org/apache/mailet/Mail.java
+++ b/mailet/api/src/main/java/org/apache/mailet/Mail.java
@@ -34,6 +34,7 @@ import jakarta.mail.internet.MimeMessage;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.james.core.MailAddress;
import org.apache.james.core.MaybeSender;
+import org.apache.james.core.Username;
import org.apache.mailet.PerRecipientHeaders.Header;
import com.google.common.collect.ImmutableMap;
@@ -102,6 +103,7 @@ public interface Mail extends Serializable, Cloneable {
String LOCAL_DELIVERY = "local-delivery";
AttributeName SMTP_AUTH_USER =
AttributeName.of("org.apache.james.SMTPAuthUser");
+ AttributeName JMAP_AUTH_USER =
AttributeName.of("org.apache.james.jmap.send.MailMetaData.username");
AttributeName SMTP_HELO = AttributeName.of("org.apache.james.HELO");
AttributeName SSL_PROTOCOL =
AttributeName.of("org.apache.james.ssl.protocol");
AttributeName SSL_CIPHER = AttributeName.of("org.apache.james.ssl.cipher");
@@ -453,4 +455,13 @@ public interface Mail extends Serializable, Cloneable {
.asAttributes()
.forEach(this::setAttribute);
}
+
+ default Optional<Username> loggedInUser() {
+ return getAttribute(Mail.SMTP_AUTH_USER)
+ .or(() -> getAttribute(Mail.JMAP_AUTH_USER))
+ .map(attribute -> attribute.getValue().value())
+ .filter(String.class::isInstance)
+ .map(String.class::cast)
+ .map(Username::of);
+ }
}
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
index 9e872bd675..284c7387f3 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java
@@ -19,6 +19,8 @@
package org.apache.james.mailetcontainer.impl;
+import static org.apache.james.mailetcontainer.impl.ProcessorImpl.mdcBase;
+
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collection;
@@ -32,7 +34,6 @@ import
org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor.MailetP
import org.apache.james.metrics.api.MetricFactory;
import org.apache.james.metrics.api.TimeMetric;
import org.apache.james.server.core.MailImpl;
-import org.apache.james.util.MDCBuilder;
import org.apache.mailet.Attribute;
import org.apache.mailet.AttributeName;
import org.apache.mailet.AttributeValue;
@@ -41,8 +42,6 @@ import org.apache.mailet.Matcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.ImmutableList;
-
/**
* A Splitter for use with Camel to split the MailMessage into many pieces if
* needed. This is done by use a Matcher.
@@ -87,17 +86,8 @@ public class MatcherSplitter {
List<Mail> mails = new ArrayList<>();
boolean fullMatch = false;
- try (Closeable closeable =
- MDCBuilder.create()
- .addToContext(MDCBuilder.PROTOCOL, "MAILET")
- .addToContext(MDCBuilder.ACTION, "MATCHER")
- .addToContext(MDCBuilder.IP, mail.getRemoteAddr())
- .addToContext(MDCBuilder.HOST, mail.getRemoteHost())
+ try (Closeable closeable = mdcBase(mail)
.addToContext("matcher", matcher.getMatcherInfo())
- .addToContext("state", mail.getState())
- .addToContext("mail", mail.getName())
- .addToContext("recipients",
ImmutableList.copyOf(mail.getRecipients()).toString())
- .addToContext("sender",
mail.getMaybeSender().asString())
.build()) {
// call the matcher
matchedRcpts = matcher.match(mail);
diff --git
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
index 416f284e5a..98506fb6eb 100644
---
a/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
+++
b/server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/ProcessorImpl.java
@@ -21,7 +21,9 @@ package org.apache.james.mailetcontainer.impl;
import java.io.Closeable;
import java.util.List;
import java.util.Locale;
+import java.util.Optional;
+import org.apache.james.core.Username;
import
org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor.MailetProcessorListener;
import
org.apache.james.mailetcontainer.lib.MailProcessingErrorHandlingConfiguration;
import org.apache.james.metrics.api.MetricFactory;
@@ -48,12 +50,10 @@ public class ProcessorImpl {
private final List<MailetProcessorListener> listeners;
private final Mailet mailet;
- public ProcessorImpl(
- MetricFactory metricFactory,
- Mailet mailet,
- MailProcessingErrorHandlingConfiguration
processingErrorHandlingConfiguration,
- List<MailetProcessorListener> listeners
- ) {
+ public ProcessorImpl(MetricFactory metricFactory,
+ Mailet mailet,
+ MailProcessingErrorHandlingConfiguration
processingErrorHandlingConfiguration,
+ List<MailetProcessorListener> listeners) {
this.metricFactory = metricFactory;
this.processingErrorHandlingConfiguration =
processingErrorHandlingConfiguration;
this.listeners = listeners;
@@ -67,22 +67,8 @@ public class ProcessorImpl {
long start = System.currentTimeMillis();
TimeMetric timeMetric =
metricFactory.timer(mailet.getClass().getSimpleName());
Throwable ex = null;
- String smtpSessionID = mail.getAttribute(Mail.SMTP_SESSION_ID)
- .map(Attribute::getValue)
- .map(AttributeValue::value)
- .map(String.class::cast)
- .orElse(null);
- try (Closeable closeable =
- MDCBuilder.create()
- .addToContext(MDCBuilder.PROTOCOL, "MAILET")
- .addToContext(MDCBuilder.ACTION, "MAILET")
- .addToContext(MDCBuilder.HOST, mail.getRemoteHost())
- .addToContext(MDCBuilder.SESSION_ID, smtpSessionID)
- .addToContext("state", mail.getState())
+ try (Closeable closeable = mdcBase(mail)
.addToContext("mailet", mailet.getClass().getSimpleName())
- .addToContext("mail", mail.getName())
- .addToContext("recipients",
ImmutableList.copyOf(mail.getRecipients()).toString())
- .addToContext("sender", mail.getMaybeSender().asString())
.build()) {
MailetPipelineLogging.logBeginOfMailetProcess(mailet, mail);
mailet.service(mail);
@@ -115,6 +101,24 @@ public class ProcessorImpl {
}
}
+ static MDCBuilder mdcBase(Mail mail) {
+ Optional<String> smtpSessionID =
mail.getAttribute(Mail.SMTP_SESSION_ID)
+ .map(Attribute::getValue)
+ .map(AttributeValue::value)
+ .map(String.class::cast);
+
+ return MDCBuilder.create()
+ .addToContext(MDCBuilder.PROTOCOL, "MAILET")
+ .addToContext(MDCBuilder.ACTION, "MAILET")
+ .addToContext(MDCBuilder.HOST, mail.getRemoteHost())
+ .addToContextIfPresent(MDCBuilder.SESSION_ID, smtpSessionID)
+ .addToContext("state", mail.getState())
+ .addToContext("mail", mail.getName())
+ .addToContext("recipients",
ImmutableList.copyOf(mail.getRecipients()).toString())
+ .addToContext("sender", mail.getMaybeSender().asString())
+ .addToContextIfPresent("loggedInUser",
mail.loggedInUser().map(Username::asString));
+ }
+
public String mailetName() {
return mailet.getMailetInfo();
}
diff --git
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/SentByJmap.java
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/SentByJmap.java
index 1163c5bd69..97cd75066f 100644
---
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/SentByJmap.java
+++
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/SentByJmap.java
@@ -24,7 +24,6 @@ package org.apache.james.jmap.mailet;
import java.util.Collection;
import org.apache.james.core.MailAddress;
-import org.apache.james.jmap.send.MailMetadata;
import org.apache.mailet.AttributeUtils;
import org.apache.mailet.Mail;
import org.apache.mailet.base.GenericMatcher;
@@ -34,7 +33,7 @@ import com.google.common.collect.ImmutableList;
public class SentByJmap extends GenericMatcher {
@Override
public Collection<MailAddress> match(Mail mail) {
- return AttributeUtils.getAttributeValueFromMail(mail,
MailMetadata.MAIL_METADATA_USERNAME_ATTRIBUTE)
+ return AttributeUtils.getAttributeValueFromMail(mail,
Mail.JMAP_AUTH_USER)
.map(ignored -> mail.getRecipients())
.orElse(ImmutableList.of());
}
diff --git
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/send/PostDequeueDecorator.java
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/send/PostDequeueDecorator.java
index f03931ca5e..fa0304e88d 100644
---
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/send/PostDequeueDecorator.java
+++
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/send/PostDequeueDecorator.java
@@ -101,7 +101,7 @@ public class PostDequeueDecorator extends
MailQueueItemDecorator {
}
private Optional<String> retrieveUsername() {
- return AttributeUtils.getValueAndCastFromMail(getMail(),
MailMetadata.MAIL_METADATA_USERNAME_ATTRIBUTE, String.class);
+ return AttributeUtils.getValueAndCastFromMail(getMail(),
Mail.JMAP_AUTH_USER, String.class);
}
private boolean mandatoryJmapMetaDataIsPresent() {
diff --git
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
index 55c76d6449..adf5866e19 100644
---
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
+++
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
@@ -41,7 +41,7 @@ import
org.apache.james.jmap.core.SetError.{SetErrorDescription, SetErrorType}
import org.apache.james.jmap.core.{ClientId, Invocation,
JmapRfc8621Configuration, Properties, ServerId, SessionTranslator, SetError,
SubmissionCapabilityFactory, UTCDate, UuidState}
import org.apache.james.jmap.json.EmailSubmissionSetSerializer
import org.apache.james.jmap.mail.{EmailSubmissionAddress,
EmailSubmissionCreationId, EmailSubmissionCreationRequest,
EmailSubmissionCreationResponse, EmailSubmissionId, EmailSubmissionSetRequest,
EmailSubmissionSetResponse, Envelope, ParameterName, ParameterValue}
-import org.apache.james.jmap.method.EmailSubmissionSetMethod.{CreationFailure,
CreationResult, CreationResults, CreationSuccess, LOGGER,
MAIL_METADATA_USERNAME_ATTRIBUTE, NO_DELAY, VALID_PARAMETER_NAME_SET, formatter}
+import org.apache.james.jmap.method.EmailSubmissionSetMethod.{CreationFailure,
CreationResult, CreationResults, CreationSuccess, LOGGER, NO_DELAY,
VALID_PARAMETER_NAME_SET, formatter}
import org.apache.james.jmap.routes.{ProcessingContext, SessionSupplier}
import org.apache.james.lifecycle.api.{LifecycleUtil, Startable}
import org.apache.james.mailbox.model.{FetchGroup, MessageId, MessageResult}
@@ -65,7 +65,6 @@ import scala.language.postfixOps
import scala.util.{Failure, Success, Try}
object EmailSubmissionSetMethod {
- val MAIL_METADATA_USERNAME_ATTRIBUTE: AttributeName =
AttributeName.of("org.apache.james.jmap.send.MailMetaData.username")
val LOGGER: Logger =
LoggerFactory.getLogger(classOf[EmailSubmissionSetMethod])
val noRecipients: SetErrorType = "noRecipients"
val forbiddenFrom: SetErrorType = "forbiddenFrom"
@@ -288,7 +287,7 @@ class EmailSubmissionSetMethod @Inject()(serializer:
EmailSubmissionSetSerialize
.name(submissionId.value)
.addRecipients(envelope.rcptTo.map(_.email).asJava)
.sender(envelope.mailFrom.email)
- .addAttribute(new Attribute(MAIL_METADATA_USERNAME_ATTRIBUTE,
AttributeValue.of(mailboxSession.getUser.asString())))
+ .addAttribute(new Attribute(Mail.JMAP_AUTH_USER,
AttributeValue.of(mailboxSession.getUser.asString())))
.build()
mailImpl.setMessageNoCopy(message)
mailImpl
diff --git
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
index a6a541cb99..cb0a6243c8 100644
---
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
+++
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
@@ -32,7 +32,7 @@ import org.apache.james.jmap.json.MDNSerializer
import org.apache.james.jmap.mail.MDN._
import org.apache.james.jmap.mail.MDNSend.MDN_ALREADY_SENT_FLAG
import org.apache.james.jmap.mail._
-import org.apache.james.jmap.method.EmailSubmissionSetMethod.{LOGGER,
MAIL_METADATA_USERNAME_ATTRIBUTE}
+import org.apache.james.jmap.method.EmailSubmissionSetMethod.LOGGER
import org.apache.james.jmap.routes.{ProcessingContext, SessionSupplier}
import org.apache.james.lifecycle.api.{LifecycleUtil, Startable}
import org.apache.james.mailbox.model.{FetchGroup, MessageResult}
@@ -48,7 +48,7 @@ import org.apache.james.mime4j.stream.MimeConfig
import org.apache.james.queue.api.MailQueueFactory.SPOOL
import org.apache.james.queue.api.{MailQueue, MailQueueFactory}
import org.apache.james.server.core.MailImpl
-import org.apache.mailet.{Attribute, AttributeValue}
+import org.apache.mailet.{Attribute, AttributeValue, Mail}
import play.api.libs.json.{JsError, JsObject, JsSuccess}
import reactor.core.scala.publisher.{SFlux, SMono}
@@ -209,7 +209,7 @@ class MDNSendMethod @Inject()(serializer: MDNSerializer,
.sender(sender)
.addRecipient(recipient)
.mimeMessage(mimeMessage)
- .addAttribute(new Attribute(MAIL_METADATA_USERNAME_ATTRIBUTE,
AttributeValue.of(mailboxSession.getUser.asString())))
+ .addAttribute(new Attribute(Mail.JMAP_AUTH_USER,
AttributeValue.of(mailboxSession.getUser.asString())))
.build()
mailImpl -> mimeMessage
}
diff --git
a/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/mailet/SentByJmapTest.java
b/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/mailet/SentByJmapTest.java
index 20e570c885..362409eed7 100644
---
a/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/mailet/SentByJmapTest.java
+++
b/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/mailet/SentByJmapTest.java
@@ -24,9 +24,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.Collection;
import org.apache.james.core.MailAddress;
-import org.apache.james.jmap.send.MailMetadata;
import org.apache.mailet.Attribute;
import org.apache.mailet.AttributeValue;
+import org.apache.mailet.Mail;
import org.apache.mailet.base.MailAddressFixture;
import org.apache.mailet.base.test.FakeMail;
import org.apache.mailet.base.test.FakeMailContext;
@@ -52,7 +52,7 @@ public class SentByJmapTest {
FakeMail fakeMail = FakeMail.builder()
.name("name")
.recipient(recipient)
- .attribute(new
Attribute(MailMetadata.MAIL_METADATA_USERNAME_ATTRIBUTE,
AttributeValue.of("true")))
+ .attribute(new Attribute(Mail.JMAP_AUTH_USER,
AttributeValue.of("true")))
.build();
Collection<MailAddress> results = testee.match(fakeMail);
@@ -89,7 +89,7 @@ public class SentByJmapTest {
FakeMail fakeMail = FakeMail.builder()
.name("name")
.recipients()
- .attribute(new
Attribute(MailMetadata.MAIL_METADATA_USERNAME_ATTRIBUTE,
AttributeValue.of("true")))
+ .attribute(new Attribute(Mail.JMAP_AUTH_USER,
AttributeValue.of("true")))
.build();
Collection<MailAddress> results = testee.match(fakeMail);
diff --git
a/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/send/PostDequeueDecoratorTest.java
b/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/send/PostDequeueDecoratorTest.java
index 6d7d3bc04d..b2de29a6ce 100644
---
a/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/send/PostDequeueDecoratorTest.java
+++
b/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/send/PostDequeueDecoratorTest.java
@@ -76,7 +76,7 @@ public class PostDequeueDecoratorTest {
private static final MessageUid UID = MessageUid.of(1);
private static final MailboxPath OUTBOX_MAILBOX_PATH =
MailboxPath.forUser(USERNAME, OUTBOX);
private static final MailboxPath SENT_MAILBOX_PATH =
MailboxPath.forUser(USERNAME, SENT);
- private static final Attribute USERNAME_ATTRIBUTE = new
Attribute(MailMetadata.MAIL_METADATA_USERNAME_ATTRIBUTE,
AttributeValue.of(RAW_USERNAME));
+ private static final Attribute USERNAME_ATTRIBUTE = new
Attribute(Mail.JMAP_AUTH_USER, AttributeValue.of(RAW_USERNAME));
private StoreMailboxManager mailboxManager;
private MailQueueItem mockedMailQueueItem;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]