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 e13beea8c6 JAMES-4050 Allow `%` and `*` characters in mailbox names
e13beea8c6 is described below
commit e13beea8c6b42c3246b00d4427b9d7492f086f14
Author: Quan Tran <[email protected]>
AuthorDate: Tue Aug 27 14:50:34 2024 +0700
JAMES-4050 Allow `%` and `*` characters in mailbox names
---
.../servers/pages/distributed/configure/jvm.adoc | 14 ++++-
.../apache/james/mailbox/model/MailboxPath.java | 10 +++-
.../james/mailbox/model/MailboxPathTest.java | 16 ++++++
.../suite/ListingWithRelaxedMailboxName.java | 55 ++++++++++++++++++
.../ListWithPercentWildcardInMailboxName.test | 67 ++++++++++++++++++++++
mpt/impl/imap-mailbox/inmemory/pom.xml | 2 +-
.../InMemoryListingWithRelaxedMailboxNameTest.java | 45 +++++++++++++++
.../docker-configuration/jvm.properties | 6 +-
.../sample-configuration/jvm.properties | 6 +-
.../docker-configuration/jvm.properties | 4 ++
.../sample-configuration/jvm.properties | 6 +-
.../docker-configuration/jvm.properties | 4 ++
.../sample-configuration/jvm.properties | 6 +-
.../jpa-app/sample-configuration/jvm.properties | 6 +-
.../memory-app/sample-configuration/jvm.properties | 6 +-
15 files changed, 244 insertions(+), 9 deletions(-)
diff --git a/docs/modules/servers/pages/distributed/configure/jvm.adoc
b/docs/modules/servers/pages/distributed/configure/jvm.adoc
index 7aefd940bc..58aac81469 100644
--- a/docs/modules/servers/pages/distributed/configure/jvm.adoc
+++ b/docs/modules/servers/pages/distributed/configure/jvm.adoc
@@ -118,4 +118,16 @@ Ex in `jvm.properties`
----
james.mailet.container.check.enabled=false
----
-To disable the mailet container check at James startup.
\ No newline at end of file
+To disable the mailet container check at James startup.
+
+== Relax mailbox name validation
+
+The property `james.relaxed.mailbox.name.validation` allows to accept `*` and
`%` characters in mailbox name.
+
+Optional. Boolean. Default to false.
+
+Ex in `jvm.properties`
+----
+james.relaxed.mailbox.name.validation=true
+----
+To relax validating `\*` and `%` characters in the mailbox name. Be careful as
`%` and `*` are ambiguous for the LIST / LSUB commands that interpret those as
wildcard thus returning all mailboxes matching the pattern.
\ No newline at end of file
diff --git
a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
index bba81a2082..d43641de5d 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
@@ -51,6 +51,7 @@ public class MailboxPath {
private static final Joiner PARTS_JOINER = Joiner.on(':');
private static final LookupTranslator USERNAME_ESCAPER = new
LookupTranslator(Map.of(":", "/;", "/", "//"));
private static final LookupTranslator USERNAME_UNESCAPER = new
LookupTranslator(Map.of("/;", ":", "//", "/"));
+ private static final boolean RELAX_MAILBOX_NAME_VALIDATION =
Boolean.parseBoolean(System.getProperty("james.relaxed.mailbox.name.validation",
"false"));
/**
* Return a {@link MailboxPath} which represent the INBOX of the given
@@ -94,7 +95,14 @@ public class MailboxPath {
return Username.of(USERNAME_UNESCAPER.translate(parts.get(1)));
}
- private static final String INVALID_CHARS = "%*\r\n";
+ private static String evaluateInvalidChars() {
+ if (RELAX_MAILBOX_NAME_VALIDATION) {
+ return "\r\n";
+ }
+ return "%*\r\n";
+ }
+
+ private static final String INVALID_CHARS = evaluateInvalidChars();
private static final CharMatcher INVALID_CHARS_MATCHER =
CharMatcher.anyOf(INVALID_CHARS);
// This is the size that all mailbox backend should support
public static final int MAX_MAILBOX_NAME_LENGTH = 200;
diff --git
a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
index d679f1c491..676db676be 100644
---
a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
+++
b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
@@ -373,6 +373,14 @@ class MailboxPathTest {
.isInstanceOf(MailboxNameException.class);
}
+ @Test
+ void assertAcceptableShouldNotThrowOnPercentWhenRelaxMode() {
+ System.setProperty("james.relaxed.mailbox.name.validation", "true");
+
+ assertThatCode(() -> MailboxPath.forUser(USER, "a%b"))
+ .doesNotThrowAnyException();
+ }
+
@Test
void assertAcceptableShouldThrowOnWildcard() {
assertThatThrownBy(() -> MailboxPath.forUser(USER, "a*b")
@@ -380,6 +388,14 @@ class MailboxPathTest {
.isInstanceOf(MailboxNameException.class);
}
+ @Test
+ void assertAcceptableShouldNotThrowOnWildcardWhenRelaxMode() {
+ System.setProperty("james.relaxed.mailbox.name.validation", "true");
+
+ assertThatCode(() -> MailboxPath.forUser(USER, "a*b"))
+ .doesNotThrowAnyException();
+ }
+
@Test
void assertAcceptableShouldThrowOnTooLongMailboxName() {
assertThatThrownBy(() -> MailboxPath.forUser(USER, Strings.repeat("a",
201))
diff --git
a/mpt/impl/imap-mailbox/core/src/main/java/org/apache/james/mpt/imapmailbox/suite/ListingWithRelaxedMailboxName.java
b/mpt/impl/imap-mailbox/core/src/main/java/org/apache/james/mpt/imapmailbox/suite/ListingWithRelaxedMailboxName.java
new file mode 100644
index 0000000000..4fa368b3ae
--- /dev/null
+++
b/mpt/impl/imap-mailbox/core/src/main/java/org/apache/james/mpt/imapmailbox/suite/ListingWithRelaxedMailboxName.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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.mpt.imapmailbox.suite;
+
+import java.util.Locale;
+
+import org.apache.james.mpt.api.ImapHostSystem;
+import org.apache.james.mpt.imapmailbox.ImapTestConstants;
+import org.apache.james.mpt.imapmailbox.suite.base.BasicImapCommands;
+import org.apache.james.mpt.script.SimpleScriptedTestProtocol;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public abstract class ListingWithRelaxedMailboxName implements
ImapTestConstants {
+
+ protected abstract ImapHostSystem createImapHostSystem();
+
+ protected ImapHostSystem system;
+ protected SimpleScriptedTestProtocol simpleScriptedTestProtocol;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ System.setProperty("james.relaxed.mailbox.name.validation", "true");
+
+ system = createImapHostSystem();
+ simpleScriptedTestProtocol = new
SimpleScriptedTestProtocol("/org/apache/james/imap/scripts/", system)
+ .withUser(USER, PASSWORD);
+ BasicImapCommands.welcome(simpleScriptedTestProtocol);
+ BasicImapCommands.authenticate(simpleScriptedTestProtocol);
+ }
+
+ @Test
+ public void testListWithPercentWildcardInMailboxNameUS() throws Exception {
+ simpleScriptedTestProtocol
+ .withLocale(Locale.US)
+ .run("ListWithPercentWildcardInMailboxName");
+ }
+}
diff --git
a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/ListWithPercentWildcardInMailboxName.test
b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/ListWithPercentWildcardInMailboxName.test
new file mode 100644
index 0000000000..d716d2a108
--- /dev/null
+++
b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/ListWithPercentWildcardInMailboxName.test
@@ -0,0 +1,67 @@
+# Test creating and searching mailboxes with literal '*' and '%' characters in
their names
+C: B01 CREATE "star*mailbox"
+S: B01 OK \[MAILBOXID \(.+\)\] CREATE completed.
+C: B011 CREATE "starmailbox"
+S: B011 OK \[MAILBOXID \(.+\)\] CREATE completed.
+C: B02 CREATE "percent%mailbox"
+S: B02 OK \[MAILBOXID \(.+\)\] CREATE completed.
+C: B021 CREATE "percentmailbox"
+S: B021 OK \[MAILBOXID \(.+\)\] CREATE completed.
+
+C: B03 LIST "" "star*mailbox"
+SUB {
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"star\*mailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"starmailbox\"
+}
+S: B03 OK LIST completed.
+
+C: B04 LIST "" "percent%mailbox"
+SUB {
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"percent%mailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"percentmailbox\"
+}
+S: B04 OK LIST completed.
+
+C: B05 LIST "" %
+SUB {
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"star\*mailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"starmailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"percent%mailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"percentmailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"INBOX\"
+}
+S: B05 OK LIST completed.
+
+C: B06 LIST "" *
+SUB {
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"star\*mailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"starmailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"percent%mailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"percentmailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"INBOX\"
+}
+S: B06 OK LIST completed.
+
+C: B07 LIST "" "star*mail%"
+SUB {
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"star\*mailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"starmailbox\"
+}
+S: B07 OK LIST completed.
+
+C: B08 LIST "" "percent%mail*"
+SUB {
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"percent%mailbox\"
+S: \* LIST \(\\HasNoChildren\) \"\.\" \"percentmailbox\"
+}
+S: B08 OK LIST completed.
+
+# Cleanup
+C: D9 DELETE "star*mailbox"
+S: D9 OK DELETE completed.
+C: D10 DELETE "starmailbox"
+S: D10 OK DELETE completed.
+C: D11 DELETE "percent%mailbox"
+S: D11 OK DELETE completed.
+C: D12 DELETE "percentmailbox"
+S: D12 OK DELETE completed.
\ No newline at end of file
diff --git a/mpt/impl/imap-mailbox/inmemory/pom.xml
b/mpt/impl/imap-mailbox/inmemory/pom.xml
index 5ce1fd9fa5..b814ece20d 100644
--- a/mpt/impl/imap-mailbox/inmemory/pom.xml
+++ b/mpt/impl/imap-mailbox/inmemory/pom.xml
@@ -81,7 +81,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
- <reuseForks>true</reuseForks>
+ <reuseForks>false</reuseForks>
<forkCount>1C</forkCount>
</configuration>
</plugin>
diff --git
a/mpt/impl/imap-mailbox/inmemory/src/test/java/org/apache/james/mpt/imapmailbox/inmemory/InMemoryListingWithRelaxedMailboxNameTest.java
b/mpt/impl/imap-mailbox/inmemory/src/test/java/org/apache/james/mpt/imapmailbox/inmemory/InMemoryListingWithRelaxedMailboxNameTest.java
new file mode 100644
index 0000000000..e757e5322d
--- /dev/null
+++
b/mpt/impl/imap-mailbox/inmemory/src/test/java/org/apache/james/mpt/imapmailbox/inmemory/InMemoryListingWithRelaxedMailboxNameTest.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mpt.imapmailbox.inmemory;
+
+import org.apache.james.mpt.api.ImapHostSystem;
+import org.apache.james.mpt.imapmailbox.inmemory.host.InMemoryHostSystem;
+import org.apache.james.mpt.imapmailbox.suite.ListingWithRelaxedMailboxName;
+import org.junit.jupiter.api.BeforeEach;
+
+public class InMemoryListingWithRelaxedMailboxNameTest extends
ListingWithRelaxedMailboxName {
+ private ImapHostSystem system;
+
+ @Override
+ @BeforeEach
+ public void setUp() throws Exception {
+ System.setProperty("james.relaxed.mailbox.name.validation", "true");
+
+ system = new InMemoryHostSystem();
+ system.beforeTest();
+ super.setUp();
+ }
+
+ @Override
+ protected ImapHostSystem createImapHostSystem() {
+ return system;
+ }
+
+}
diff --git a/server/apps/cassandra-app/docker-configuration/jvm.properties
b/server/apps/cassandra-app/docker-configuration/jvm.properties
index 7e3e6463ef..f638855ef4 100644
--- a/server/apps/cassandra-app/docker-configuration/jvm.properties
+++ b/server/apps/cassandra-app/docker-configuration/jvm.properties
@@ -45,4 +45,8 @@ config.file=/root/conf/cassandra-driver.conf
# JMX, when enable causes RMI to plan System.gc every hour. Set this instead
to once every 1000h.
sun.rmi.dgc.server.gcInterval=3600000000
-sun.rmi.dgc.client.gcInterval=3600000000
\ No newline at end of file
+sun.rmi.dgc.client.gcInterval=3600000000
+
+# Relax validating `*` and `%` characters in the mailbox name. Defaults to
false.
+# Be careful turning on this as `%` and `*` are ambiguous for the LIST / LSUB
commands that interpret those as wildcard thus returning all mailboxes matching
the pattern.
+#james.relaxed.mailbox.name.validation=true
\ No newline at end of file
diff --git a/server/apps/cassandra-app/sample-configuration/jvm.properties
b/server/apps/cassandra-app/sample-configuration/jvm.properties
index 7cef86567a..3cc3d17386 100644
--- a/server/apps/cassandra-app/sample-configuration/jvm.properties
+++ b/server/apps/cassandra-app/sample-configuration/jvm.properties
@@ -68,4 +68,8 @@ jmx.remote.x.mlet.allow.getMBeansFromURL=false
# james.jwt.zip.allow=false
# Enable/disable mailet container check at James startup. Defaults to true.
-# james.mailet.container.check.enabled=true
\ No newline at end of file
+# james.mailet.container.check.enabled=true
+
+# Relax validating `*` and `%` characters in the mailbox name. Defaults to
false.
+# Be careful turning on this as `%` and `*` are ambiguous for the LIST / LSUB
commands that interpret those as wildcard thus returning all mailboxes matching
the pattern.
+#james.relaxed.mailbox.name.validation=true
\ No newline at end of file
diff --git a/server/apps/distributed-app/docker-configuration/jvm.properties
b/server/apps/distributed-app/docker-configuration/jvm.properties
index 93165bbf95..b7183468f0 100644
--- a/server/apps/distributed-app/docker-configuration/jvm.properties
+++ b/server/apps/distributed-app/docker-configuration/jvm.properties
@@ -46,3 +46,7 @@ config.file=/root/conf/cassandra-driver.conf
# JMX, when enable causes RMI to plan System.gc every hour. Set this instead
to once every 1000h.
sun.rmi.dgc.server.gcInterval=3600000000
sun.rmi.dgc.client.gcInterval=3600000000
+
+# Relax validating `*` and `%` characters in the mailbox name. Defaults to
false.
+# Be careful turning on this as `%` and `*` are ambiguous for the LIST / LSUB
commands that interpret those as wildcard thus returning all mailboxes matching
the pattern.
+#james.relaxed.mailbox.name.validation=true
\ No newline at end of file
diff --git a/server/apps/distributed-app/sample-configuration/jvm.properties
b/server/apps/distributed-app/sample-configuration/jvm.properties
index f55d3d20fe..9365a7fe91 100644
--- a/server/apps/distributed-app/sample-configuration/jvm.properties
+++ b/server/apps/distributed-app/sample-configuration/jvm.properties
@@ -84,4 +84,8 @@ jmx.remote.x.mlet.allow.getMBeansFromURL=false
# james.reactor.inputstream.prefetch=4
# Enable/disable mailet container check at James startup. Defaults to true.
-# james.mailet.container.check.enabled=true
\ No newline at end of file
+# james.mailet.container.check.enabled=true
+
+# Relax validating `*` and `%` characters in the mailbox name. Defaults to
false.
+# Be careful turning on this as `%` and `*` are ambiguous for the LIST / LSUB
commands that interpret those as wildcard thus returning all mailboxes matching
the pattern.
+#james.relaxed.mailbox.name.validation=true
\ No newline at end of file
diff --git
a/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
b/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
index 93dedf3ef8..f638855ef4 100644
--- a/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
+++ b/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
@@ -46,3 +46,7 @@ config.file=/root/conf/cassandra-driver.conf
# JMX, when enable causes RMI to plan System.gc every hour. Set this instead
to once every 1000h.
sun.rmi.dgc.server.gcInterval=3600000000
sun.rmi.dgc.client.gcInterval=3600000000
+
+# Relax validating `*` and `%` characters in the mailbox name. Defaults to
false.
+# Be careful turning on this as `%` and `*` are ambiguous for the LIST / LSUB
commands that interpret those as wildcard thus returning all mailboxes matching
the pattern.
+#james.relaxed.mailbox.name.validation=true
\ No newline at end of file
diff --git
a/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
b/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
index e7ece390c2..2612e150ff 100644
--- a/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
+++ b/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
@@ -58,4 +58,8 @@ jmx.remote.x.mlet.allow.getMBeansFromURL=false
# james.jwt.zip.allow=false
# Enable/disable mailet container check at James startup. Defaults to true.
-# james.mailet.container.check.enabled=true
\ No newline at end of file
+# james.mailet.container.check.enabled=true
+
+# Relax validating `*` and `%` characters in the mailbox name. Defaults to
false.
+# Be careful turning on this as `%` and `*` are ambiguous for the LIST / LSUB
commands that interpret those as wildcard thus returning all mailboxes matching
the pattern.
+#james.relaxed.mailbox.name.validation=true
\ No newline at end of file
diff --git a/server/apps/jpa-app/sample-configuration/jvm.properties
b/server/apps/jpa-app/sample-configuration/jvm.properties
index 04cfad0b6c..68859135ac 100644
--- a/server/apps/jpa-app/sample-configuration/jvm.properties
+++ b/server/apps/jpa-app/sample-configuration/jvm.properties
@@ -56,4 +56,8 @@ openjpa.Multithreaded=true
# james.jwt.zip.allow=false
# Enable/disable mailet container check at James startup. Defaults to true.
-# james.mailet.container.check.enabled=true
\ No newline at end of file
+# james.mailet.container.check.enabled=true
+
+# Relax validating `*` and `%` characters in the mailbox name. Defaults to
false.
+# Be careful turning on this as `%` and `*` are ambiguous for the LIST / LSUB
commands that interpret those as wildcard thus returning all mailboxes matching
the pattern.
+#james.relaxed.mailbox.name.validation=true
\ No newline at end of file
diff --git a/server/apps/memory-app/sample-configuration/jvm.properties
b/server/apps/memory-app/sample-configuration/jvm.properties
index 649b5fc3b1..692bc6bf46 100644
--- a/server/apps/memory-app/sample-configuration/jvm.properties
+++ b/server/apps/memory-app/sample-configuration/jvm.properties
@@ -58,4 +58,8 @@ jmx.remote.x.mlet.allow.getMBeansFromURL=false
# james.jwt.zip.allow=false
# Enable/disable mailet container check at James startup. Defaults to true.
-# james.mailet.container.check.enabled=true
\ No newline at end of file
+# james.mailet.container.check.enabled=true
+
+# Relax validating `*` and `%` characters in the mailbox name. Defaults to
false.
+# Be careful turning on this as `%` and `*` are ambiguous for the LIST / LSUB
commands that interpret those as wildcard thus returning all mailboxes matching
the pattern.
+#james.relaxed.mailbox.name.validation=true
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]