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 e3025a8  JAMES-3078 Allow to disable user provisioning for JMAP (#708)
e3025a8 is described below

commit e3025a8892a9c7fa4f5a47bc271381632ed79272
Author: Benoit TELLIER <[email protected]>
AuthorDate: Mon Oct 25 10:07:00 2021 +0700

    JAMES-3078 Allow to disable user provisioning for JMAP (#708)
---
 .../docs/modules/ROOT/pages/configure/jmap.adoc    |  4 +++
 .../org/apache/james/jmap/draft/JMAPModule.java    |  1 +
 .../apache/james/jmap/http/UserProvisioner.java    |  7 ++++--
 .../james/jmap/http/UserProvisionerTest.java       |  5 ++--
 .../james/jmap/http/UserProvisionerThreadTest.java |  3 ++-
 .../apache/james/jmap/http/UserProvisioning.scala  |  5 ++--
 .../org/apache/james/jmap/JMAPConfiguration.java   | 29 ++++++++++++++++++++--
 .../apache/james/jmap/JMAPConfigurationTest.java   |  8 +++---
 src/site/xdoc/server/config-jmap.xml               |  5 ++++
 9 files changed, 55 insertions(+), 12 deletions(-)

diff --git 
a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/jmap.adoc 
b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/jmap.adoc
index 60032d9..b3e29fd 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/jmap.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/jmap.adoc
@@ -51,6 +51,10 @@ Defaults to an empty list.
 | Should simple Email/query be resolved against a Cassandra projection, or 
should we resolve them against ElasticSearch?
 This enables a higher resilience, but the projection needs to be correctly 
populated.
 
+| user.provisioning.enabled
+| Optional boolean. Defaults to true.
+| Governs whether authenticated users that do not exist locally should be 
created in the users repository.
+
 | jmap.version.default
 | Optional string. Defaults to draft. Allowed values: draft, rfc-8621.
 | Which version of the JMAP protocol should be served when none supplied in 
the Accept header.
diff --git 
a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
 
b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
index e61541b..b1f9e56 100644
--- 
a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
+++ 
b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
@@ -178,6 +178,7 @@ public class JMAPModule extends AbstractModule {
                 .enabled(configuration.getBoolean("enabled", true))
                 .port(Port.of(configuration.getInt("jmap.port", 
DEFAULT_JMAP_PORT)))
                 
.enableEmailQueryView(Optional.ofNullable(configuration.getBoolean("view.email.query.enabled",
 null)))
+                
.userProvisioningEnabled(Optional.ofNullable(configuration.getBoolean("user.provisioning.enabled",
 null)))
                 
.defaultVersion(Optional.ofNullable(configuration.getString("jmap.version.default",
 null))
                     .map(Version::of))
                 
.maximumSendSize(Optional.ofNullable(configuration.getString("email.send.max.size",
 null))
diff --git 
a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UserProvisioner.java
 
b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UserProvisioner.java
index a841145..bd774b2 100644
--- 
a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UserProvisioner.java
+++ 
b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UserProvisioner.java
@@ -23,6 +23,7 @@ import java.util.UUID;
 import javax.inject.Inject;
 
 import org.apache.james.core.Username;
+import org.apache.james.jmap.JMAPConfiguration;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.user.api.AlreadyExistInUsersRepositoryException;
@@ -36,18 +37,20 @@ import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
 
 public class UserProvisioner {
+    private final JMAPConfiguration jmapConfiguration;
     private final UsersRepository usersRepository;
     private final MetricFactory metricFactory;
 
     @Inject
     @VisibleForTesting
-    UserProvisioner(UsersRepository usersRepository, MetricFactory 
metricFactory) {
+    UserProvisioner(JMAPConfiguration jmapConfiguration, UsersRepository 
usersRepository, MetricFactory metricFactory) {
+        this.jmapConfiguration = jmapConfiguration;
         this.usersRepository = usersRepository;
         this.metricFactory = metricFactory;
     }
 
     public Mono<Void> provisionUser(MailboxSession session) {
-        if (session != null && !usersRepository.isReadOnly()) {
+        if (session != null && !usersRepository.isReadOnly() && 
jmapConfiguration.isUserProvisioningEnabled()) {
             return createAccountIfNeeded(session);
         }
         return Mono.empty();
diff --git 
a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/http/UserProvisionerTest.java
 
b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/http/UserProvisionerTest.java
index c043160..876dfad 100644
--- 
a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/http/UserProvisionerTest.java
+++ 
b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/http/UserProvisionerTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
 
 import org.apache.james.core.Username;
 import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.jmap.JMAPConfiguration;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
@@ -47,7 +48,7 @@ public class UserProvisionerTest {
     @Before
     public void setup() throws Exception {
         usersRepository = 
MemoryUsersRepository.withoutVirtualHosting(NO_DOMAIN_LIST);
-        testee = new UserProvisioner(usersRepository, new 
RecordingMetricFactory());
+        testee = new UserProvisioner(JMAPConfiguration.DEFAULT, 
usersRepository, new RecordingMetricFactory());
     }
 
     @Test
@@ -82,7 +83,7 @@ public class UserProvisionerTest {
     public void filterShouldNotTryToAddUserWhenReadOnlyUsersRepository() {
         UsersRepository usersRepository = mock(UsersRepository.class);
         when(usersRepository.isReadOnly()).thenReturn(true);
-        testee = new UserProvisioner(usersRepository, new 
RecordingMetricFactory());
+        testee = new UserProvisioner(JMAPConfiguration.DEFAULT, 
usersRepository, new RecordingMetricFactory());
 
         MailboxSession mailboxSession = 
MailboxSessionUtil.create(USERNAME_WITH_DOMAIN);
 
diff --git 
a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/http/UserProvisionerThreadTest.java
 
b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/http/UserProvisionerThreadTest.java
index 621af5b..4d3c257 100644
--- 
a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/http/UserProvisionerThreadTest.java
+++ 
b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/http/UserProvisionerThreadTest.java
@@ -23,6 +23,7 @@ import java.util.concurrent.ExecutionException;
 
 import org.apache.james.core.Username;
 import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.jmap.JMAPConfiguration;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
@@ -42,7 +43,7 @@ public class UserProvisionerThreadTest {
     public void before() {
         usersRepository = 
MemoryUsersRepository.withoutVirtualHosting(NO_DOMAIN_LIST);
         session = MailboxSessionUtil.create(Username.of("username"));
-        testee = new UserProvisioner(usersRepository, new 
RecordingMetricFactory());
+        testee = new UserProvisioner(JMAPConfiguration.DEFAULT, 
usersRepository, new RecordingMetricFactory());
     }
 
     @Test
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/UserProvisioning.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/UserProvisioning.scala
index 8ec20d1..3fbd94e 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/UserProvisioning.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/UserProvisioning.scala
@@ -23,15 +23,16 @@ import java.util.UUID
 
 import javax.inject.Inject
 import org.apache.james.core.Username
+import org.apache.james.jmap.JMAPConfiguration
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import org.apache.james.user.api.{AlreadyExistInUsersRepositoryException, 
UsersRepository}
 import reactor.core.scala.publisher.SMono
 import reactor.core.scheduler.Schedulers
 
-class UserProvisioning @Inject() (usersRepository: UsersRepository, 
metricFactory: MetricFactory) {
+class UserProvisioning @Inject() (usersRepository: UsersRepository, 
metricFactory: MetricFactory, jmapConfiguration: JMAPConfiguration = 
JMAPConfiguration.DEFAULT) {
   def provisionUser(session: MailboxSession): SMono[Unit] =
-    if (session != null && !usersRepository.isReadOnly) {
+    if (session != null && !usersRepository.isReadOnly && 
jmapConfiguration.isUserProvisioningEnabled) {
       createAccountIfNeeded(session)
     } else {
       SMono.empty
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
index 18e53d6..4ca7b96 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
@@ -34,6 +34,7 @@ public class JMAPConfiguration {
     public static class Builder {
         private Optional<Boolean> enabled = Optional.empty();
         private Optional<Boolean> emailQueryViewEnabled = Optional.empty();
+        private Optional<Boolean> userProvisioningEnabled = Optional.empty();
         private Optional<Port> port = Optional.empty();
         private Optional<Version> defaultVersion = Optional.empty();
         private Optional<Long> maximumSendSize = Optional.empty();
@@ -64,6 +65,15 @@ public class JMAPConfiguration {
             return this;
         }
 
+        public Builder userProvisioningEnabled(boolean enabled) {
+            return userProvisioningEnabled(Optional.of(enabled));
+        }
+
+        public Builder userProvisioningEnabled(Optional<Boolean> enabled) {
+            this.userProvisioningEnabled = enabled;
+            return this;
+        }
+
         public Builder enableEmailQueryView() {
             return enableEmailQueryView(true);
         }
@@ -72,6 +82,14 @@ public class JMAPConfiguration {
             return enableEmailQueryView(false);
         }
 
+        public Builder enableUserProvisioning() {
+            return userProvisioningEnabled(true);
+        }
+
+        public Builder disableUserProvisioning() {
+            return userProvisioningEnabled(false);
+        }
+
         public Builder port(Port port) {
             this.port = Optional.of(port);
             return this;
@@ -99,7 +117,8 @@ public class JMAPConfiguration {
         public JMAPConfiguration build() {
             Preconditions.checkState(enabled.isPresent(), "You should specify 
if JMAP server should be started");
             return new JMAPConfiguration(enabled.get(), port, 
emailQueryViewEnabled.orElse(false),
-                    defaultVersion.orElse(Version.DRAFT), maximumSendSize);
+                userProvisioningEnabled.orElse(true),
+                defaultVersion.orElse(Version.DRAFT), maximumSendSize);
         }
     }
 
@@ -108,14 +127,16 @@ public class JMAPConfiguration {
     private final boolean enabled;
     private final Optional<Port> port;
     private final boolean emailQueryViewEnabled;
+    private final boolean userProvisioningEnabled;
     private final Version defaultVersion;
     private final Optional<Long> maximumSendSize;
 
     @VisibleForTesting
-    JMAPConfiguration(boolean enabled, Optional<Port> port, boolean 
emailQueryViewEnabled, Version defaultVersion, Optional<Long> maximumSendSize) {
+    JMAPConfiguration(boolean enabled, Optional<Port> port, boolean 
emailQueryViewEnabled, boolean userProvisioningEnabled, Version defaultVersion, 
Optional<Long> maximumSendSize) {
         this.enabled = enabled;
         this.port = port;
         this.emailQueryViewEnabled = emailQueryViewEnabled;
+        this.userProvisioningEnabled = userProvisioningEnabled;
         this.defaultVersion = defaultVersion;
         this.maximumSendSize = maximumSendSize;
     }
@@ -132,6 +153,10 @@ public class JMAPConfiguration {
         return emailQueryViewEnabled;
     }
 
+    public boolean isUserProvisioningEnabled() {
+        return userProvisioningEnabled;
+    }
+
     public Version getDefaultVersion() {
         return defaultVersion;
     }
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
index 85ffe47..4a17270 100644
--- 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
@@ -41,7 +41,7 @@ class JMAPConfigurationTest {
 
     @Test
     void buildShouldWorkWhenRandomPort() {
-        JMAPConfiguration expectedJMAPConfiguration = new 
JMAPConfiguration(ENABLED, Optional.empty(), ENABLED, Version.DRAFT, 
Optional.empty());
+        JMAPConfiguration expectedJMAPConfiguration = new 
JMAPConfiguration(ENABLED, Optional.empty(), ENABLED, ENABLED, Version.DRAFT, 
Optional.empty());
 
         JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
             .enable()
@@ -53,12 +53,13 @@ class JMAPConfigurationTest {
 
     @Test
     void buildShouldWorkWhenFixedPort() {
-        JMAPConfiguration expectedJMAPConfiguration = new 
JMAPConfiguration(ENABLED, Optional.of(Port.of(80)), ENABLED, Version.DRAFT, 
Optional.empty());
+        JMAPConfiguration expectedJMAPConfiguration = new 
JMAPConfiguration(ENABLED, Optional.of(Port.of(80)), ENABLED, ENABLED, 
Version.DRAFT, Optional.empty());
 
         JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
             .enable()
             .port(Port.of(80))
             .enableEmailQueryView()
+            .enableUserProvisioning()
             .build();
 
         
assertThat(jmapConfiguration).isEqualToComparingFieldByField(expectedJMAPConfiguration);
@@ -66,11 +67,12 @@ class JMAPConfigurationTest {
 
     @Test
     void buildShouldWorkWhenDisabled() {
-        JMAPConfiguration expectedJMAPConfiguration = new 
JMAPConfiguration(DISABLED, Optional.empty(), DISABLED, Version.DRAFT, 
Optional.empty());
+        JMAPConfiguration expectedJMAPConfiguration = new 
JMAPConfiguration(DISABLED, Optional.empty(), DISABLED, DISABLED, 
Version.DRAFT, Optional.empty());
 
         JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
             .disable()
             .disableEmailQueryView()
+            .disableUserProvisioning()
             .build();
         
assertThat(jmapConfiguration).isEqualToComparingFieldByField(expectedJMAPConfiguration);
     }
diff --git a/src/site/xdoc/server/config-jmap.xml 
b/src/site/xdoc/server/config-jmap.xml
index 33ba3a7..df5d11d 100644
--- a/src/site/xdoc/server/config-jmap.xml
+++ b/src/site/xdoc/server/config-jmap.xml
@@ -79,6 +79,11 @@
                     <dd>Should simple Email/query be resolved against a 
Cassandra projection, or should we resolve them against ElasticSearch?
                         This enables a higher resilience, but the projection 
needs to be correctly populated.</dd>
 
+                    <dt><strong>user.provisioning.enabled</strong></dt>
+                    <dd>Optional boolean. Defaults to true.</dd>
+                    <dd>Governs whether authenticated users that do not exist 
locally should be created in the users repository.
+                    </dd>
+
                     <dt><strong>jmap.version.default</strong></dt>
                     <dd>Optional string. Defaults to draft. Allowed values: 
draft, rfc-8621.</dd>
                     <dd>Which version of the JMAP protocol should be served 
when none supplied in the Accept header.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to