You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ad...@apache.org on 2016/01/13 10:38:41 UTC

svn commit: r1724377 - in /james/project/trunk: dockerfiles/run/guice/destination/conf/ server/ server/container/cassandra-guice/sample-configuration/ server/container/cassandra-guice/src/main/java/org/apache/james/jmap/ server/container/cassandra-guic...

Author: aduprat
Date: Wed Jan 13 09:38:41 2016
New Revision: 1724377

URL: http://svn.apache.org/viewvc?rev=1724377&view=rev
Log:
JAMES-1654 Add JWT PublicKey in JMAP configuration. Contributed by Duprat <an...@gmail.com>

Added:
    james/project/trunk/dockerfiles/run/guice/destination/conf/jwt_publickey
    james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
Modified:
    james/project/trunk/dockerfiles/run/guice/destination/conf/jmap.properties
    james/project/trunk/server/container/cassandra-guice/sample-configuration/jmap.properties
    james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/JMAPModule.java
    james/project/trunk/server/container/cassandra-guice/src/test/java/org/apache/james/modules/TestJMAPServerModule.java
    james/project/trunk/server/container/jetty/pom.xml
    james/project/trunk/server/pom.xml
    james/project/trunk/server/protocols/jmap/pom.xml
    james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
    james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java

Modified: james/project/trunk/dockerfiles/run/guice/destination/conf/jmap.properties
URL: http://svn.apache.org/viewvc/james/project/trunk/dockerfiles/run/guice/destination/conf/jmap.properties?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/dockerfiles/run/guice/destination/conf/jmap.properties (original)
+++ james/project/trunk/dockerfiles/run/guice/destination/conf/jmap.properties Wed Jan 13 09:38:41 2016
@@ -1,4 +1,11 @@
 # Configuration file for JMAP
 
 tls.keystoreURL=file://conf/keystore
-tls.secret=james72laBalle
\ No newline at end of file
+tls.secret=james72laBalle
+
+#
+# If you wish to use OAuth authentication, you should provide a valid JWT public key.
+# The following entry specify the link to the URL of the public key file,
+# which should be a PEM format file.
+#
+jwt.publickeypem.url=file://conf/jwt_publickey

Added: james/project/trunk/dockerfiles/run/guice/destination/conf/jwt_publickey
URL: http://svn.apache.org/viewvc/james/project/trunk/dockerfiles/run/guice/destination/conf/jwt_publickey?rev=1724377&view=auto
==============================================================================
--- james/project/trunk/dockerfiles/run/guice/destination/conf/jwt_publickey (added)
+++ james/project/trunk/dockerfiles/run/guice/destination/conf/jwt_publickey Wed Jan 13 09:38:41 2016
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtlChO/nlVP27MpdkG0Bh
+16XrMRf6M4NeyGa7j5+1UKm42IKUf3lM28oe82MqIIRyvskPc11NuzSor8HmvH8H
+lhDs5DyJtx2qp35AT0zCqfwlaDnlDc/QDlZv1CoRZGpQk1Inyh6SbZwYpxxwh0fi
++d/4RpE3LBVo8wgOaXPylOlHxsDizfkL8QwXItyakBfMO6jWQRrj7/9WDhGf4Hi+
+GQur1tPGZDl9mvCoRHjFrD5M/yypIPlfMGWFVEvV5jClNMLAQ9bYFuOc7H1fEWw6
+U1LZUUbJW9/CH45YXz82CYqkrfbnQxqRb2iVbVjs/sHopHd1NTiCfUtwvcYJiBVj
+kwIDAQAB
+-----END PUBLIC KEY-----

Modified: james/project/trunk/server/container/cassandra-guice/sample-configuration/jmap.properties
URL: http://svn.apache.org/viewvc/james/project/trunk/server/container/cassandra-guice/sample-configuration/jmap.properties?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/server/container/cassandra-guice/sample-configuration/jmap.properties (original)
+++ james/project/trunk/server/container/cassandra-guice/sample-configuration/jmap.properties Wed Jan 13 09:38:41 2016
@@ -1,4 +1,11 @@
 # Configuration file for JMAP
 
 tls.keystoreURL=file://conf/keystore
-tls.secret=james72laBalle
\ No newline at end of file
+tls.secret=james72laBalle
+
+#
+# If you wish to use OAuth authentication, you should provide a valid JWT public key.
+# The following entry specify the link to the URL of the public key file,
+# which should be a PEM format file.
+#
+jwt.publickeypem.url=
\ No newline at end of file

Modified: james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/JMAPModule.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/JMAPModule.java?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/JMAPModule.java (original)
+++ james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/JMAPModule.java Wed Jan 13 09:38:41 2016
@@ -19,12 +19,16 @@
 package org.apache.james.jmap;
 
 import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Optional;
 
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.io.FileUtils;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.jmap.methods.RequestHandler;
 
+import com.github.fge.lambdas.Throwing;
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
@@ -42,14 +46,20 @@ public class JMAPModule extends Abstract
 
     @Provides
     @Singleton
-    JMAPConfiguration provideConfiguration(FileSystem fileSystem) throws FileNotFoundException, ConfigurationException{
+    JMAPConfiguration provideConfiguration(FileSystem fileSystem) throws ConfigurationException, IOException{
         PropertiesConfiguration configuration = getConfiguration(fileSystem);
-        String keystore = configuration.getString("tls.keystoreURL");
-        String secret = configuration.getString("tls.secret");
-        return new JMAPConfiguration(keystore, secret);
+        return JMAPConfiguration.builder()
+                .keystore(configuration.getString("tls.keystoreURL"))
+                .secret(configuration.getString("tls.secret"))
+                .jwtPublicKeyPem(loadPublicKey(fileSystem, Optional.ofNullable(configuration.getString("jwt.publickeypem.url"))))
+                .build();
     }
 
     private PropertiesConfiguration getConfiguration(FileSystem fileSystem) throws FileNotFoundException, ConfigurationException {
         return new PropertiesConfiguration(fileSystem.getFile(FileSystem.FILE_PROTOCOL_AND_CONF + "jmap.properties"));
     }
+
+    private Optional<String> loadPublicKey(FileSystem fileSystem, Optional<String> jwtPublickeyPemUrl) {
+        return jwtPublickeyPemUrl.map(Throwing.function(url -> FileUtils.readFileToString(fileSystem.getFile(url))));
+    }
 }

Modified: james/project/trunk/server/container/cassandra-guice/src/test/java/org/apache/james/modules/TestJMAPServerModule.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/container/cassandra-guice/src/test/java/org/apache/james/modules/TestJMAPServerModule.java?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/server/container/cassandra-guice/src/test/java/org/apache/james/modules/TestJMAPServerModule.java (original)
+++ james/project/trunk/server/container/cassandra-guice/src/test/java/org/apache/james/modules/TestJMAPServerModule.java Wed Jan 13 09:38:41 2016
@@ -50,7 +50,10 @@ public class TestJMAPServerModule extend
     @Provides
     @Singleton
     JMAPConfiguration provideConfiguration() throws FileNotFoundException, ConfigurationException{
-        return new JMAPConfiguration("keystore", "james72laBalle");
+        return JMAPConfiguration.builder()
+                .keystore("keystore")
+                .secret("james72laBalle")
+                .build();
     }
     
     private static class RandomPortConfiguration implements PortConfiguration {

Modified: james/project/trunk/server/container/jetty/pom.xml
URL: http://svn.apache.org/viewvc/james/project/trunk/server/container/jetty/pom.xml?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/server/container/jetty/pom.xml (original)
+++ james/project/trunk/server/container/jetty/pom.xml Wed Jan 13 09:38:41 2016
@@ -129,6 +129,10 @@
             </activation>
             <dependencies>
                 <dependency>
+                    <groupId>com.github.fge</groupId>
+                    <artifactId>throwing-lambdas</artifactId>
+                </dependency>
+                <dependency>
                     <groupId>com.google.guava</groupId>
                     <artifactId>guava</artifactId>
                 </dependency>

Modified: james/project/trunk/server/pom.xml
URL: http://svn.apache.org/viewvc/james/project/trunk/server/pom.xml?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/server/pom.xml (original)
+++ james/project/trunk/server/pom.xml Wed Jan 13 09:38:41 2016
@@ -193,6 +193,7 @@
         <cassandra-unit.version>2.1.9.2</cassandra-unit.version>
         <assertj-1.version>1.7.1</assertj-1.version>
         <assertj-3.version>3.2.0</assertj-3.version>
+        <throwing-lambdas.version>0.5.0</throwing-lambdas.version>
     </properties>
 
     <dependencyManagement>
@@ -1413,6 +1414,11 @@
                 <artifactId>jetty-servlet</artifactId>
                 <version>${jetty.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.github.fge</groupId>
+                <artifactId>throwing-lambdas</artifactId>
+                <version>${throwing-lambdas.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

Modified: james/project/trunk/server/protocols/jmap/pom.xml
URL: http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/pom.xml?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/server/protocols/jmap/pom.xml (original)
+++ james/project/trunk/server/protocols/jmap/pom.xml Wed Jan 13 09:38:41 2016
@@ -215,7 +215,6 @@
                 <dependency>
                     <groupId>com.github.fge</groupId>
                     <artifactId>throwing-lambdas</artifactId>
-                    <version>0.5.0</version>
                 </dependency>
                 <dependency>
                     <groupId>com.jayway.restassured</groupId>

Modified: james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java (original)
+++ james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java Wed Jan 13 09:38:41 2016
@@ -18,14 +18,58 @@
  ****************************************************************/
 package org.apache.james.jmap;
 
+import java.util.Optional;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
 public class JMAPConfiguration {
 
-    public final String keystore;
-    public final String secret;
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+        public String keystore;
+        public String secret;
+        public Optional<String> jwtPublicKeyPem;
+
+        private Builder() {
+            jwtPublicKeyPem = Optional.empty();
+        }
+
+        public Builder keystore(String keystore) {
+            this.keystore = keystore;
+            return this;
+        }
+
+        public Builder secret(String secret) {
+            this.secret = secret;
+            return this;
+        }
 
-    public JMAPConfiguration(String keystore, String secret) {
+        public Builder jwtPublicKeyPem(Optional<String> jwtPublicKeyPem) {
+            Preconditions.checkNotNull(jwtPublicKeyPem);
+            this.jwtPublicKeyPem = jwtPublicKeyPem;
+            return this;
+        }
+
+        public JMAPConfiguration build() {
+            Preconditions.checkState(!Strings.isNullOrEmpty(keystore), "'keystore' is mandatory");
+            Preconditions.checkState(!Strings.isNullOrEmpty(secret), "'secret' is mandatory");
+            return new JMAPConfiguration(keystore, secret, jwtPublicKeyPem);
+        }
+    }
+
+    private final String keystore;
+    private final String secret;
+    private final Optional<String> jwtPublicKeyPem;
+
+    @VisibleForTesting JMAPConfiguration(String keystore, String secret, Optional<String> jwtPublicKeyPem) {
         this.keystore = keystore;
         this.secret = secret;
+        this.jwtPublicKeyPem = jwtPublicKeyPem;
     }
 
     public String getKeystore() {
@@ -35,4 +79,8 @@ public class JMAPConfiguration {
     public String getSecret() {
         return secret;
     }
+
+    public Optional<String> getJwtPublicKeyPem() {
+        return jwtPublicKeyPem;
+    }
 }

Added: james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java?rev=1724377&view=auto
==============================================================================
--- james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java (added)
+++ james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java Wed Jan 13 09:38:41 2016
@@ -0,0 +1,90 @@
+/****************************************************************
+ * 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.jmap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.Optional;
+
+import org.junit.Test;
+
+public class JMAPConfigurationTest {
+
+    @Test
+    public void buildShouldThrowWhenKeystoreIsNull() {
+        assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .keystore(null)
+                .build())
+            .isInstanceOf(IllegalStateException.class)
+            .hasMessage("'keystore' is mandatory");
+    }
+
+    @Test
+    public void buildShouldThrowWhenKeystoreIsEmpty() {
+        assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .keystore("")
+                .build())
+            .isInstanceOf(IllegalStateException.class)
+            .hasMessage("'keystore' is mandatory");
+    }
+
+    @Test
+    public void buildShouldThrowWhenSecretIsNull() {
+        assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .keystore("keystore")
+                .secret(null)
+                .build())
+            .isInstanceOf(IllegalStateException.class)
+            .hasMessage("'secret' is mandatory");
+    }
+
+    @Test
+    public void buildShouldThrowWhenSecretIsEmpty() {
+        assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .keystore("keystore")
+                .secret("")
+                .build())
+            .isInstanceOf(IllegalStateException.class)
+            .hasMessage("'secret' is mandatory");
+    }
+
+    @Test
+    public void buildShouldThrowWhenJwtPublicKeyPemIsNull() {
+        assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .keystore("keystore")
+                .secret("secret")
+                .jwtPublicKeyPem(null)
+                .build())
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void buildShouldWork() {
+        JMAPConfiguration expectedJMAPConfiguration = new JMAPConfiguration("keystore", "secret", Optional.of("file://conf/jwt_publickey"));
+
+        JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
+            .keystore("keystore")
+            .secret("secret")
+            .jwtPublicKeyPem(Optional.of("file://conf/jwt_publickey"))
+            .build();
+        assertThat(jmapConfiguration).isEqualToComparingFieldByField(expectedJMAPConfiguration);
+    }
+}

Modified: james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java?rev=1724377&r1=1724376&r2=1724377&view=diff
==============================================================================
--- james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java (original)
+++ james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java Wed Jan 13 09:38:41 2016
@@ -46,7 +46,11 @@ public class JamesSignatureHandlerProvid
                 return null;
             }
         };
-        JamesSignatureHandler signatureHandler = new JamesSignatureHandler(fileSystem, new JMAPConfiguration("keystore", "james72laBalle"));
+        JamesSignatureHandler signatureHandler = new JamesSignatureHandler(fileSystem, 
+                JMAPConfiguration.builder()
+                    .keystore("keystore")
+                    .secret("james72laBalle")
+                    .build());
         signatureHandler.init();
         return signatureHandler;
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org