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
The following commit(s) were added to refs/heads/master by this push:
new 11b2d18cb7 JAMES-4113 RSpamD record details of Virus scan decision
11b2d18cb7 is described below
commit 11b2d18cb75adc59a3f15215023a4b5893387e9a
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Feb 7 22:33:07 2025 +0100
JAMES-4113 RSpamD record details of Virus scan decision
---
.../org/apache/james/rspamd/RspamdScanner.java | 17 +++++------
.../apache/james/rspamd/model/AnalysisResult.java | 33 ++++++++++++++--------
.../rspamd/model/AnalysisResultDeserializer.java | 14 ++++-----
.../james/rspamd/client/RspamdHttpClientTest.java | 6 ++--
.../model/AnalysisResultDeserializationTest.java | 2 +-
5 files changed, 40 insertions(+), 32 deletions(-)
diff --git
a/third-party/rspamd/src/main/java/org/apache/james/rspamd/RspamdScanner.java
b/third-party/rspamd/src/main/java/org/apache/james/rspamd/RspamdScanner.java
index bb81a51410..19a5ce13e1 100644
---
a/third-party/rspamd/src/main/java/org/apache/james/rspamd/RspamdScanner.java
+++
b/third-party/rspamd/src/main/java/org/apache/james/rspamd/RspamdScanner.java
@@ -111,23 +111,24 @@ public class RspamdScanner extends GenericMailet {
"sender", mail.getMaybeSender().asString(),
"recipient", rcptAndResult.getKey().asString(),
"rspamDAction", rcptAndResult.getValue().getAction().name(),
+ "virus", rcptAndResult.getValue().getVirusNote().orElse(""),
"rspamDRequiredScore",
Float.toString(rcptAndResult.getValue().getRequiredScore()),
"rspamRewrittenSubject",
rcptAndResult.getValue().getDesiredRewriteSubject().orElse(""),
"rspamDScore",
Float.toString(rcptAndResult.getValue().getScore()))))
.log("Mail scanned with RSpamD.");
if (AnalysisResult.Action.REJECT ==
rcptAndResult.getValue().getAction()) {
- rejectSpamProcessor.ifPresent(processor -> processorPerUser(mail,
rcptAndResult.getKey(), processor));
+ rejectSpamProcessor.ifPresent(processor -> processorPerUser(mail,
rcptAndResult.getKey(), processor, "Rejected due to high spam score"));
}
appendRspamdResultHeader(mail, rcptAndResult.getKey(),
rcptAndResult.getRight());
- if (rcptAndResult.getRight().hasVirus()) {
- virusProcessor.ifPresent(processor -> processorPerUser(mail,
rcptAndResult.getKey(), processor));
+ if (rcptAndResult.getRight().getVirusNote().isPresent()) {
+ virusProcessor.ifPresent(processor -> processorPerUser(mail,
rcptAndResult.getKey(), processor,
rcptAndResult.getRight().getVirusNote().get()));
}
}
- private void processorPerUser(Mail mail, MailAddress rcpt, String
processor) {
+ private void processorPerUser(Mail mail, MailAddress rcpt, String
processor, String error) {
Mail copy = null;
try {
copy = mail.duplicate();
@@ -165,12 +166,12 @@ public class RspamdScanner extends GenericMailet {
.ifPresent(Throwing.consumer(desiredRewriteSubject ->
mail.getMessage().setSubject(desiredRewriteSubject)));
}
- if (rspamdResult.hasVirus()) {
- virusProcessor.ifPresent(state -> {
+ rspamdResult.getVirusNote()
+ .ifPresent(virusNote -> {
LOGGER.info("Detected a mail containing virus. Sending mail {}
to {}", mail, virusProcessor);
- mail.setState(state);
+ mail.setErrorMessage(virusNote);
+ virusProcessor.ifPresent(mail::setState);
});
- }
}
private void appendRspamdResultHeader(Mail mail, MailAddress recipient,
AnalysisResult rspamdResult) {
diff --git
a/third-party/rspamd/src/main/java/org/apache/james/rspamd/model/AnalysisResult.java
b/third-party/rspamd/src/main/java/org/apache/james/rspamd/model/AnalysisResult.java
index 2091207bae..3ded63ca0d 100644
---
a/third-party/rspamd/src/main/java/org/apache/james/rspamd/model/AnalysisResult.java
+++
b/third-party/rspamd/src/main/java/org/apache/james/rspamd/model/AnalysisResult.java
@@ -23,6 +23,7 @@ import java.util.Objects;
import java.util.Optional;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
@@ -38,10 +39,11 @@ public class AnalysisResult {
private float score;
private float requiredScore;
private Optional<String> desiredRewriteSubject;
- private boolean hasVirus;
+ private Optional<String> virusNote;
public Builder() {
desiredRewriteSubject = Optional.empty();
+ virusNote = Optional.empty();
}
public Builder action(Action action) {
@@ -64,15 +66,24 @@ public class AnalysisResult {
return this;
}
+ @VisibleForTesting
public Builder hasVirus(boolean hasVirus) {
- this.hasVirus = hasVirus;
+ if (hasVirus) {
+ this.virusNote = Optional.of("A notice describing the virus");
+ }
+ return this;
+ }
+
+ @VisibleForTesting
+ public Builder virusNote(String value) {
+ this.virusNote = Optional.of(value);
return this;
}
public AnalysisResult build() {
Preconditions.checkNotNull(action);
- return new AnalysisResult(action, score, requiredScore,
desiredRewriteSubject, hasVirus);
+ return new AnalysisResult(action, score, requiredScore,
desiredRewriteSubject, virusNote);
}
}
@@ -99,14 +110,14 @@ public class AnalysisResult {
private final float score;
private final float requiredScore;
private final Optional<String> desiredRewriteSubject;
- private final boolean hasVirus;
+ private final Optional<String> virusNote;
- public AnalysisResult(Action action, float score, float requiredScore,
Optional<String> desiredRewriteSubject, boolean hasVirus) {
+ public AnalysisResult(Action action, float score, float requiredScore,
Optional<String> desiredRewriteSubject, Optional<String> virusNote) {
this.action = action;
this.score = score;
this.requiredScore = requiredScore;
this.desiredRewriteSubject = desiredRewriteSubject;
- this.hasVirus = hasVirus;
+ this.virusNote = virusNote;
}
public Action getAction() {
@@ -125,8 +136,8 @@ public class AnalysisResult {
return desiredRewriteSubject;
}
- public boolean hasVirus() {
- return hasVirus;
+ public Optional<String> getVirusNote() {
+ return virusNote;
}
@Override
@@ -138,14 +149,14 @@ public class AnalysisResult {
&& Objects.equals(this.requiredScore, that.requiredScore)
&& Objects.equals(this.action, that.action)
&& Objects.equals(this.desiredRewriteSubject,
that.desiredRewriteSubject)
- && Objects.equals(this.hasVirus, that.hasVirus);
+ && Objects.equals(this.virusNote, that.virusNote);
}
return false;
}
@Override
public final int hashCode() {
- return Objects.hash(action, score, requiredScore,
desiredRewriteSubject, hasVirus);
+ return Objects.hash(action, score, requiredScore,
desiredRewriteSubject, virusNote);
}
@Override
@@ -155,7 +166,7 @@ public class AnalysisResult {
.add("score", score)
.add("requiredScore", requiredScore)
.add("desiredRewriteSubject", desiredRewriteSubject)
- .add("hasVirus", hasVirus)
+ .add("virusNote", virusNote)
.toString();
}
}
diff --git
a/third-party/rspamd/src/main/java/org/apache/james/rspamd/model/AnalysisResultDeserializer.java
b/third-party/rspamd/src/main/java/org/apache/james/rspamd/model/AnalysisResultDeserializer.java
index 25b992826c..a490c90f9e 100644
---
a/third-party/rspamd/src/main/java/org/apache/james/rspamd/model/AnalysisResultDeserializer.java
+++
b/third-party/rspamd/src/main/java/org/apache/james/rspamd/model/AnalysisResultDeserializer.java
@@ -44,9 +44,9 @@ public class AnalysisResultDeserializer extends
StdDeserializer<AnalysisResult>
float score = node.get("score").floatValue();
float requiredScore = node.get("required_score").floatValue();
Optional<String> desiredRewriteSubject =
deserializeRewriteSubject(node);
- boolean hasVirus = deserializeClamVirus(node);
+ Optional<String> virusNote = deserializeClamVirus(node);
- return new AnalysisResult(action,score, requiredScore,
desiredRewriteSubject, hasVirus);
+ return new AnalysisResult(action,score, requiredScore,
desiredRewriteSubject, virusNote);
}
private AnalysisResult.Action deserializeAction(String actionAsString) {
@@ -59,16 +59,12 @@ public class AnalysisResultDeserializer extends
StdDeserializer<AnalysisResult>
}
private Optional<String> deserializeRewriteSubject(JsonNode node) {
- JsonNode rewriteSubjectJsonNode = node.get("subject");
- if (rewriteSubjectJsonNode == null) {
- return Optional.empty();
- }
- return Optional.of(rewriteSubjectJsonNode.asText());
+ return Optional.ofNullable(node.get("subject")).map(JsonNode::asText);
}
- private boolean deserializeClamVirus(JsonNode node) {
+ private Optional<String> deserializeClamVirus(JsonNode node) {
JsonNode clamVirusJsonNode = node.get("symbols").get("CLAM_VIRUS");
- return clamVirusJsonNode != null;
+ return Optional.ofNullable(clamVirusJsonNode).map(JsonNode::toString);
}
}
diff --git
a/third-party/rspamd/src/test/java/org/apache/james/rspamd/client/RspamdHttpClientTest.java
b/third-party/rspamd/src/test/java/org/apache/james/rspamd/client/RspamdHttpClientTest.java
index 964b783e5c..ab63385125 100644
---
a/third-party/rspamd/src/test/java/org/apache/james/rspamd/client/RspamdHttpClientTest.java
+++
b/third-party/rspamd/src/test/java/org/apache/james/rspamd/client/RspamdHttpClientTest.java
@@ -158,7 +158,7 @@ class RspamdHttpClientTest {
softly.assertThat(analysisResult.getAction()).isEqualTo(AnalysisResult.Action.NO_ACTION);
softly.assertThat(analysisResult.getRequiredScore()).isEqualTo(13.5F);
softly.assertThat(analysisResult.getDesiredRewriteSubject()).isEqualTo(Optional.empty());
- softly.assertThat(analysisResult.hasVirus()).isEqualTo(false);
+ softly.assertThat(analysisResult.getVirusNote()).isEmpty();
});
RequestSpecification rspamdApi =
WebAdminUtils.spec(Port.of(rspamdExtension.rspamdPort()));
@@ -217,7 +217,7 @@ class RspamdHttpClientTest {
RspamdHttpClient client = new RspamdHttpClient(configuration);
AnalysisResult analysisResult = client.checkV2(virusMessage).block();
- assertThat(analysisResult.hasVirus()).isTrue();
+ assertThat(analysisResult.getVirusNote()).isPresent();
}
@Test
@@ -226,7 +226,7 @@ class RspamdHttpClientTest {
RspamdHttpClient client = new RspamdHttpClient(configuration);
AnalysisResult analysisResult =
client.checkV2(nonVirusMessage).block();
- assertThat(analysisResult.hasVirus()).isFalse();
+ assertThat(analysisResult.getVirusNote()).isEmpty();
}
@Test
diff --git
a/third-party/rspamd/src/test/java/org/apache/james/rspamd/model/AnalysisResultDeserializationTest.java
b/third-party/rspamd/src/test/java/org/apache/james/rspamd/model/AnalysisResultDeserializationTest.java
index 52f3abc7f0..3c0b8c63aa 100644
---
a/third-party/rspamd/src/test/java/org/apache/james/rspamd/model/AnalysisResultDeserializationTest.java
+++
b/third-party/rspamd/src/test/java/org/apache/james/rspamd/model/AnalysisResultDeserializationTest.java
@@ -227,7 +227,7 @@ public class AnalysisResultDeserializationTest {
.action(AnalysisResult.Action.NO_ACTION)
.score(3.5F)
.requiredScore(14.0F)
- .hasVirus(true)
+
.virusNote("{\"name\":\"CLAM_VIRUS\",\"score\":0.0,\"metric_score\":0.0,\"options\":[\"Eicar-Signature\"]}")
.build());
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]