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 bt...@apache.org on 2017/04/03 08:34:26 UTC
[3/7] james-project git commit: JAMES-1983 Split WebAdmin to match
orthogonal Guice architecture
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/pom.xml b/server/protocols/webadmin/webadmin-core/pom.xml
new file mode 100644
index 0000000..151bbca
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/pom.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>james-server</artifactId>
+ <groupId>org.apache.james</groupId>
+ <version>3.0.0-beta6-SNAPSHOT</version>
+ <relativePath>../../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>james-server-webadmin-core</artifactId>
+ <packaging>jar</packaging>
+
+ <name>Apache James :: Server :: Web Admin :: Core</name>
+
+ <profiles>
+ <profile>
+ <id>noTest</id>
+ <activation>
+ <os>
+ <family>windows</family>
+ </os>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>disable-build-for-older-jdk</id>
+ <activation>
+ <jdk>(,1.8)</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-jar</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>jar</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>test-jar</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-compile</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>default-testCompile</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-test</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-install</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-resources</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>default-testResources</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-site-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-descriptor</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>build-for-jdk-8</id>
+ <activation>
+ <jdk>[1.8,)</jdk>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>james-server-util-java8</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>james-server-lifecycle-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>james-server-jwt</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>metrics-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>metrics-logger</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.github.fge</groupId>
+ <artifactId>throwing-lambdas</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sparkjava</groupId>
+ <artifactId>spark-core</artifactId>
+ <version>2.5.5</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>${assertj-3.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>nl.jqno.equalsverifier</groupId>
+ <artifactId>equalsverifier</artifactId>
+ <version>1.7.6</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>fully.qualified.MainClass</mainClass>
+ </manifest>
+ </archive>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>animal-sniffer-java-8</id>
+ <activation>
+ <jdk>[1.8,)</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ <configuration>
+ <signature>
+ <groupId>org.codehaus.mojo.signature</groupId>
+ <artifactId>java18</artifactId>
+ <version>1.0</version>
+ </signature>
+ </configuration>
+ <executions>
+ <execution>
+ <id>check_java_8</id>
+ <phase>test</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/CORSFilter.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/CORSFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/CORSFilter.java
new file mode 100644
index 0000000..c4cfb29
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/CORSFilter.java
@@ -0,0 +1,40 @@
+/****************************************************************
+ * 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.webadmin;
+
+import spark.Filter;
+import spark.Request;
+import spark.Response;
+
+
+public class CORSFilter implements Filter {
+ private final String urlCORSOrigin;
+
+ public CORSFilter(String urlCORSOrigin) {
+ this.urlCORSOrigin = urlCORSOrigin;
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ response.header("Access-Control-Allow-Origin", urlCORSOrigin);
+ response.header("Access-Control-Request-Method", "DELETE, GET, POST, PUT");
+ response.header("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept");
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Constants.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Constants.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Constants.java
new file mode 100644
index 0000000..1031a86
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Constants.java
@@ -0,0 +1,27 @@
+/****************************************************************
+ * 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.webadmin;
+
+public interface Constants {
+
+ String SEPARATOR = "/";
+ String EMPTY_BODY = "";
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/FixedPort.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/FixedPort.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/FixedPort.java
new file mode 100644
index 0000000..7ada8a1
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/FixedPort.java
@@ -0,0 +1,54 @@
+/****************************************************************
+ * 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.webadmin;
+
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+
+public class FixedPort implements Port {
+
+ private final int port;
+
+ public FixedPort(int port) {
+ Preconditions.checkArgument(port > 0 && port < 65536, "Port should be strictly contained between 0 and 65536");
+ this.port = port;
+ }
+
+ @Override
+ public int toInt() {
+ return port;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof FixedPort) {
+ FixedPort that = (FixedPort) o;
+
+ return Objects.equals(this.port, that.port);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(port);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Port.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Port.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Port.java
new file mode 100644
index 0000000..ff7a50b
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Port.java
@@ -0,0 +1,26 @@
+/****************************************************************
+ * 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.webadmin;
+
+public interface Port {
+
+ int toInt();
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/RandomPort.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/RandomPort.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/RandomPort.java
new file mode 100644
index 0000000..2b3ab5d
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/RandomPort.java
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.webadmin;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.base.Throwables;
+
+public class RandomPort implements Port {
+
+ public static int findFreePort() {
+ try (ServerSocket socket = new ServerSocket(0)) {
+ return socket.getLocalPort();
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ private final Supplier<Integer> portSupplier;
+
+ public RandomPort() {
+ portSupplier = Suppliers.memoize(RandomPort::findFreePort);
+ }
+
+ @Override
+ public int toInt() {
+ return portSupplier.get();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Routes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Routes.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Routes.java
new file mode 100644
index 0000000..bc8554a
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/Routes.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.webadmin;
+
+import spark.Service;
+
+public interface Routes {
+
+ void define(Service service);
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/TlsConfiguration.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/TlsConfiguration.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/TlsConfiguration.java
new file mode 100644
index 0000000..d549ea3
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/TlsConfiguration.java
@@ -0,0 +1,124 @@
+/****************************************************************
+ * 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.webadmin;
+
+import java.util.Objects;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+public class TlsConfiguration {
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String keystoreFilePath;
+ private String keystorePassword;
+ private String truststoreFilePath;
+ private String truststorePassword;
+
+ public Builder raw(String keystoreFilePath,
+ String keystorePassword,
+ String truststoreFilePath,
+ String truststorePassword){
+ Preconditions.checkNotNull(keystoreFilePath);
+ Preconditions.checkNotNull(keystorePassword);
+
+ this.keystoreFilePath = keystoreFilePath;
+ this.keystorePassword = keystorePassword;
+ this.truststoreFilePath = truststoreFilePath;
+ this.truststorePassword = truststorePassword;
+ return this;
+ }
+
+ public Builder selfSigned(String keystoreFilePath, String keystorePassword){
+ Preconditions.checkNotNull(keystoreFilePath);
+ Preconditions.checkNotNull(keystorePassword);
+
+ this.keystoreFilePath = keystoreFilePath;
+ this.keystorePassword = keystorePassword;
+ return this;
+ }
+
+ public TlsConfiguration build() {
+ Preconditions.checkState(hasKeystoreInformation(), "If enabled, you need to provide keystore information");
+ Preconditions.checkState(optionalHasTrustStoreInformation(), "You need to provide both information about trustStore");
+ return new TlsConfiguration(keystoreFilePath, keystorePassword, truststoreFilePath, truststorePassword);
+ }
+
+ private boolean optionalHasTrustStoreInformation() {
+ return (truststoreFilePath == null) == (truststorePassword == null);
+ }
+
+ private boolean hasKeystoreInformation() {
+ return keystorePassword != null && keystoreFilePath != null;
+ }
+
+ }
+
+ private final String keystoreFilePath;
+ private final String keystorePassword;
+ private final String truststoreFilePath;
+ private final String truststorePassword;
+
+ @VisibleForTesting
+ TlsConfiguration(String keystoreFilePath, String keystorePassword, String truststoreFilePath, String truststorePassword) {
+ this.keystoreFilePath = keystoreFilePath;
+ this.keystorePassword = keystorePassword;
+ this.truststoreFilePath = truststoreFilePath;
+ this.truststorePassword = truststorePassword;
+ }
+
+ public String getKeystoreFilePath() {
+ return keystoreFilePath;
+ }
+
+ public String getKeystorePassword() {
+ return keystorePassword;
+ }
+
+ public String getTruststoreFilePath() {
+ return truststoreFilePath;
+ }
+
+ public String getTruststorePassword() {
+ return truststorePassword;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof TlsConfiguration) {
+ TlsConfiguration that = (TlsConfiguration) o;
+
+ return Objects.equals(this.keystoreFilePath, that.keystoreFilePath)
+ && Objects.equals(this.keystorePassword, that.keystorePassword)
+ && Objects.equals(this.truststoreFilePath, that.truststoreFilePath)
+ && Objects.equals(this.truststorePassword, that.truststorePassword);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(keystoreFilePath, keystorePassword, truststoreFilePath, truststorePassword);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
new file mode 100644
index 0000000..716645c
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
@@ -0,0 +1,169 @@
+/****************************************************************
+ * 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.webadmin;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+public class WebAdminConfiguration {
+
+ public static final boolean DEFAULT_CORS_DISABLED = false;
+ public static final String CORS_ALL_ORIGINS = "*";
+
+ public static WebAdminConfiguration testingConfiguration() {
+ return WebAdminConfiguration.builder()
+ .enabled()
+ .port(new RandomPort())
+ .build();
+ }
+
+ public static final WebAdminConfiguration DISABLED_CONFIGURATION = WebAdminConfiguration.builder()
+ .disabled()
+ .build();
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private Optional<Boolean> enabled = Optional.empty();
+ private Optional<Port> port = Optional.empty();
+ private Optional<Boolean> enableCORS = Optional.empty();
+ private Optional<TlsConfiguration> tlsConfiguration = Optional.empty();
+ private Optional<String> urlCORSOrigin = Optional.empty();
+
+ public Builder tls(TlsConfiguration tlsConfiguration) {
+ this.tlsConfiguration = Optional.of(tlsConfiguration);
+ return this;
+ }
+
+ public Builder tls(Optional<TlsConfiguration> tlsConfiguration) {
+ this.tlsConfiguration = tlsConfiguration;
+ return this;
+ }
+
+ public Builder port(Port port) {
+ this.port = Optional.of(port);
+ return this;
+ }
+
+ public Builder enable(boolean isEnabled) {
+ this.enabled = Optional.of(isEnabled);
+ return this;
+ }
+ public Builder enabled() {
+ return enable(true);
+ }
+
+ public Builder disabled() {
+ return enable(false);
+ }
+
+ public Builder urlCORSOrigin(String origin) {
+ this.urlCORSOrigin = Optional.ofNullable(origin);
+ return this;
+ }
+
+ public Builder enableCORS(boolean isEnabled) {
+ this.enableCORS = Optional.of(isEnabled);
+ return this;
+ }
+
+ public Builder CORSenabled() {
+ return enableCORS(true);
+ }
+
+ public Builder CORSdisabled() {
+ return enableCORS(false);
+ }
+
+ public WebAdminConfiguration build() {
+ Preconditions.checkState(enabled.isPresent(), "You need to explicitly enable or disable WebAdmin server");
+ Preconditions.checkState(!enabled.get() || port.isPresent(), "You need to specify a port for WebAdminConfiguration");
+ return new WebAdminConfiguration(enabled.get(),
+ port,
+ tlsConfiguration,
+ enableCORS.orElse(DEFAULT_CORS_DISABLED),
+ urlCORSOrigin.orElse(CORS_ALL_ORIGINS));
+ }
+ }
+
+ private final boolean enabled;
+ private final Optional<Port> port;
+ private final Optional<TlsConfiguration> tlsConfiguration;
+ private final boolean enableCORS;
+ private final String urlCORSOrigin;
+
+ @VisibleForTesting
+ WebAdminConfiguration(boolean enabled, Optional<Port> port, Optional<TlsConfiguration> tlsConfiguration, boolean enableCORS, String urlCORSOrigin) {
+ this.enabled = enabled;
+ this.port = port;
+ this.tlsConfiguration = tlsConfiguration;
+ this.enableCORS = enableCORS;
+ this.urlCORSOrigin = urlCORSOrigin;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public String getUrlCORSOrigin() {
+ return urlCORSOrigin;
+ }
+
+ public Port getPort() {
+ return port.orElseThrow(() -> new IllegalStateException("No port was specified"));
+ }
+
+ public TlsConfiguration getTlsConfiguration() {
+ return tlsConfiguration.orElseThrow(() -> new IllegalStateException("No tls configuration"));
+ }
+
+ public boolean isEnableCORS() {
+ return enableCORS;
+ }
+
+ public boolean isTlsEnabled() {
+ return tlsConfiguration.isPresent();
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof WebAdminConfiguration) {
+ WebAdminConfiguration that = (WebAdminConfiguration) o;
+
+ return Objects.equals(this.enabled, that.enabled)
+ && Objects.equals(this.port, that.port)
+ && Objects.equals(this.tlsConfiguration, that.tlsConfiguration)
+ && Objects.equals(this.enableCORS, that.enableCORS)
+ && Objects.equals(this.urlCORSOrigin, that.urlCORSOrigin);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(enabled, port, tlsConfiguration, enableCORS, urlCORSOrigin);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
new file mode 100644
index 0000000..abce524
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
@@ -0,0 +1,129 @@
+/****************************************************************
+ * 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.webadmin;
+
+import java.io.IOException;
+import java.util.Set;
+
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.lifecycle.api.Configurable;
+import org.apache.james.metrics.api.MetricFactory;
+import org.apache.james.webadmin.authentication.AuthenticationFilter;
+import org.apache.james.webadmin.authentication.NoAuthenticationFilter;
+import org.apache.james.webadmin.metric.MetricPostFilter;
+import org.apache.james.webadmin.metric.MetricPreFilter;
+import org.apache.james.webadmin.routes.CORSRoute;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableSet;
+
+import spark.Service;
+
+public class WebAdminServer implements Configurable {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(WebAdminServer.class);
+ public static final HierarchicalConfiguration NO_CONFIGURATION = null;
+ public static final int DEFAULT_PORT = 8080;
+
+ private final WebAdminConfiguration configuration;
+ private final Set<Routes> routesList;
+ private final Service service;
+ private final AuthenticationFilter authenticationFilter;
+ private final MetricFactory metricFactory;
+
+ // Spark do not allow to retrieve allocated port when using a random port. Thus we generate the port.
+ @Inject
+ private WebAdminServer(WebAdminConfiguration configuration, Set<Routes> routesList, AuthenticationFilter authenticationFilter,
+ MetricFactory metricFactory) {
+ this.configuration = configuration;
+ this.routesList = routesList;
+ this.authenticationFilter = authenticationFilter;
+ this.metricFactory = metricFactory;
+ this.service = Service.ignite();
+ }
+
+ @VisibleForTesting
+ public WebAdminServer(MetricFactory metricFactory, Routes... routes) throws IOException {
+ this(WebAdminConfiguration.testingConfiguration(),
+ ImmutableSet.copyOf(routes),
+ new NoAuthenticationFilter(),
+ metricFactory);
+ }
+
+ @Override
+ public void configure(HierarchicalConfiguration config) throws ConfigurationException {
+ if (configuration.isEnabled()) {
+ service.port(configuration.getPort().toInt());
+ configureHTTPS();
+ configureCORS();
+ configureMetrics();
+ service.before(authenticationFilter);
+ routesList.forEach(routes -> routes.define(service));
+ service.awaitInitialization();
+ LOGGER.info("Web admin server started");
+ }
+ }
+
+ private void configureMetrics() {
+ service.before(new MetricPreFilter(metricFactory));
+ service.after(new MetricPostFilter());
+ }
+
+ private void configureHTTPS() {
+ if (configuration.isTlsEnabled()) {
+ TlsConfiguration tlsConfiguration = configuration.getTlsConfiguration();
+ service.secure(tlsConfiguration.getKeystoreFilePath(),
+ tlsConfiguration.getKeystorePassword(),
+ tlsConfiguration.getTruststoreFilePath(),
+ tlsConfiguration.getTruststorePassword());
+ LOGGER.info("Web admin set up to use HTTPS");
+ }
+ }
+
+ private void configureCORS() {
+ if (configuration.isEnabled()) {
+ service.before(new CORSFilter(configuration.getUrlCORSOrigin()));
+ new CORSRoute().define(service);
+ LOGGER.info("Web admin set up to enable CORS from " + configuration.getUrlCORSOrigin());
+ }
+ }
+
+ @PreDestroy
+ public void destroy() {
+ if (configuration.isEnabled()) {
+ service.stop();
+ LOGGER.info("Web admin server stopped");
+ }
+ }
+
+ public void await() {
+ service.awaitInitialization();
+ }
+
+ public Port getPort() {
+ return configuration.getPort();
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/AuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/AuthenticationFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/AuthenticationFilter.java
new file mode 100644
index 0000000..f73b818
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/AuthenticationFilter.java
@@ -0,0 +1,25 @@
+/****************************************************************
+ * 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.webadmin.authentication;
+
+import spark.Filter;
+
+public interface AuthenticationFilter extends Filter {
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/JwtFilter.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/JwtFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/JwtFilter.java
new file mode 100644
index 0000000..4832d6f
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/JwtFilter.java
@@ -0,0 +1,76 @@
+/****************************************************************
+ * 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.webadmin.authentication;
+
+import static spark.Spark.halt;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+import org.apache.james.jwt.JwtTokenVerifier;
+
+import spark.Request;
+import spark.Response;
+
+public class JwtFilter implements AuthenticationFilter {
+ public static final String AUTHORIZATION_HEADER_PREFIX = "Bearer ";
+ public static final String AUTHORIZATION_HEADER_NAME = "Authorization";
+ public static final String OPTIONS = "OPTIONS";
+
+ private final JwtTokenVerifier jwtTokenVerifier;
+
+ @Inject
+ public JwtFilter(JwtTokenVerifier jwtTokenVerifier) {
+ this.jwtTokenVerifier = jwtTokenVerifier;
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ if (request.requestMethod() != OPTIONS) {
+ Optional<String> bearer = Optional.ofNullable(request.headers(AUTHORIZATION_HEADER_NAME))
+ .filter(value -> value.startsWith(AUTHORIZATION_HEADER_PREFIX))
+ .map(value -> value.substring(AUTHORIZATION_HEADER_PREFIX.length()));
+
+ checkHeaderPresent(bearer);
+ checkValidSignature(bearer);
+ checkIsAdmin(bearer);
+ }
+ }
+
+ private void checkHeaderPresent(Optional<String> bearer) {
+ if (!bearer.isPresent()) {
+ halt(401, "No Bearer header.");
+ }
+ }
+
+ private void checkValidSignature(Optional<String> bearer) {
+ if (!jwtTokenVerifier.verify(bearer.get())) {
+ halt(401, "Invalid Bearer header.");
+ }
+ }
+
+ private void checkIsAdmin(Optional<String> bearer) {
+ if (!jwtTokenVerifier.hasAttribute("admin", true, bearer.get())) {
+ halt(401, "Non authorized user.");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/NoAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/NoAuthenticationFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/NoAuthenticationFilter.java
new file mode 100644
index 0000000..45a2f5b
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/authentication/NoAuthenticationFilter.java
@@ -0,0 +1,31 @@
+/****************************************************************
+ * 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.webadmin.authentication;
+
+import spark.Request;
+import spark.Response;
+
+public class NoAuthenticationFilter implements AuthenticationFilter {
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/metric/MetricPostFilter.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/metric/MetricPostFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/metric/MetricPostFilter.java
new file mode 100644
index 0000000..4d9b8b7
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/metric/MetricPostFilter.java
@@ -0,0 +1,37 @@
+/****************************************************************
+ * 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.webadmin.metric;
+
+import org.apache.james.metrics.api.TimeMetric;
+
+import spark.Filter;
+import spark.Request;
+import spark.Response;
+
+public class MetricPostFilter implements Filter {
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ if (request.attribute(MetricPreFilter.METRICS) instanceof TimeMetric) {
+ TimeMetric timeMetric = request.attribute(MetricPreFilter.METRICS);
+ timeMetric.stopAndPublish();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/metric/MetricPreFilter.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/metric/MetricPreFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/metric/MetricPreFilter.java
new file mode 100644
index 0000000..1ed9d76
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/metric/MetricPreFilter.java
@@ -0,0 +1,41 @@
+/****************************************************************
+ * 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.webadmin.metric;
+
+import org.apache.james.metrics.api.MetricFactory;
+
+import spark.Filter;
+import spark.Request;
+import spark.Response;
+
+public class MetricPreFilter implements Filter {
+ public static final String METRICS = "metrics";
+ private final MetricFactory metricFactory;
+
+ public MetricPreFilter(MetricFactory metricFactory) {
+ this.metricFactory = metricFactory;
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ request.attribute(METRICS, metricFactory.timer("webAdmin"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/routes/CORSRoute.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/routes/CORSRoute.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/routes/CORSRoute.java
new file mode 100644
index 0000000..39e9bd7
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/routes/CORSRoute.java
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.webadmin.routes;
+
+import org.apache.james.webadmin.Routes;
+
+import spark.Service;
+
+public class CORSRoute implements Routes {
+
+ @Override
+ public void define(Service service) {
+ service.options("/*", (request, response) -> {
+ String accessControlRequestHeaders = request.headers("Access-Control-Request-Headers");
+ if (accessControlRequestHeaders != null) {
+ response.header("Access-Control-Allow-Headers", accessControlRequestHeaders);
+ }
+ String accessControlRequestMethod = request.headers("Access-Control-Request-Method");
+ if (accessControlRequestMethod != null) {
+ response.header("Access-Control-Allow-Methods", accessControlRequestMethod);
+ }
+ return "";
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractException.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractException.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractException.java
new file mode 100644
index 0000000..dc6b578
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractException.java
@@ -0,0 +1,27 @@
+/****************************************************************
+ * 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.webadmin.utils;
+
+public class JsonExtractException extends Exception {
+
+ public JsonExtractException(Throwable throwable) {
+ super(throwable);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
new file mode 100644
index 0000000..f4eb420
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.webadmin.utils;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class JsonExtractor<Request> {
+
+ private final ObjectMapper objectMapper;
+ private final Class<Request> type;
+
+ public JsonExtractor(Class<Request> type) {
+ this.objectMapper = new ObjectMapper();
+ this.type = type;
+ }
+
+ public Request parse(String text) throws JsonExtractException {
+ try {
+ return objectMapper.readValue(text, type);
+ } catch (IOException e) {
+ throw new JsonExtractException(e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonTransformer.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonTransformer.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonTransformer.java
new file mode 100644
index 0000000..3c32f0c
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonTransformer.java
@@ -0,0 +1,41 @@
+/****************************************************************
+ * 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.webadmin.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+import spark.ResponseTransformer;
+
+public class JsonTransformer implements ResponseTransformer {
+
+ private final ObjectMapper objectMapper;
+
+ public JsonTransformer() {
+ objectMapper = new ObjectMapper();
+ objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+ }
+
+ @Override
+ public String render(Object o) throws JsonProcessingException {
+ return objectMapper.writeValueAsString(o);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/FixedPortTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/FixedPortTest.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/FixedPortTest.java
new file mode 100644
index 0000000..2712daa
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/FixedPortTest.java
@@ -0,0 +1,57 @@
+/****************************************************************
+ * 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.webadmin;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.junit.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class FixedPortTest {
+
+ @Test
+ public void toIntShouldThrowOnNegativePort() {
+ assertThatThrownBy(() -> new FixedPort(-1)).isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ public void toIntShouldThrowOnNullPort() {
+ assertThatThrownBy(() -> new FixedPort(0)).isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ public void toIntShouldThrowOnTooBigNumbers() {
+ assertThatThrownBy(() -> new FixedPort(65536)).isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ public void toIntShouldReturnedDesiredPort() {
+ int expectedPort = 452;
+ assertThat(new FixedPort(expectedPort).toInt()).isEqualTo(expectedPort);
+ }
+
+ @Test
+ public void shouldMatchBeanContract() {
+ EqualsVerifier.forClass(FixedPort.class).verify();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/RandomPortTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/RandomPortTest.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/RandomPortTest.java
new file mode 100644
index 0000000..07d1996
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/RandomPortTest.java
@@ -0,0 +1,34 @@
+/****************************************************************
+ * 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.webadmin;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class RandomPortTest {
+
+ @Test
+ public void toIntShouldReturnTwoTimeTheSameResult() {
+ RandomPort testee = new RandomPort();
+ assertThat(testee.toInt()).isEqualTo(testee.toInt());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/TlsConfigurationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/TlsConfigurationTest.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/TlsConfigurationTest.java
new file mode 100644
index 0000000..2d93282
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/TlsConfigurationTest.java
@@ -0,0 +1,88 @@
+/****************************************************************
+ * 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.webadmin;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class TlsConfigurationTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void buildShouldThrowWhenNotEnabled() {
+ expectedException.expect(IllegalStateException.class);
+
+ TlsConfiguration.builder().build();
+ }
+
+ @Test
+ public void buildShouldThrowWhenEnableWithoutKeystore() {
+ expectedException.expect(IllegalStateException.class);
+
+ TlsConfiguration.builder().build();
+ }
+
+ @Test
+ public void selfSignedShouldThrowOnNullKeyStorePath() {
+ expectedException.expect(NullPointerException.class);
+
+ TlsConfiguration.builder()
+ .selfSigned(null, "abc");
+ }
+
+ @Test
+ public void selfSignedShouldThrowOnNullKeyStorePassword() {
+ expectedException.expect(NullPointerException.class);
+
+ TlsConfiguration.builder()
+ .selfSigned("abc", null);
+ }
+
+ @Test
+ public void buildShouldWorkOnSelfSignedHttps() {
+ assertThat(
+ TlsConfiguration.builder()
+ .selfSigned("abcd", "efgh")
+ .build())
+ .isEqualTo(new TlsConfiguration("abcd", "efgh", null, null));
+ }
+
+ @Test
+ public void buildShouldWorkOnTrustedHttps() {
+ assertThat(
+ TlsConfiguration.builder()
+ .raw("a", "b", "c", "d")
+ .build())
+ .isEqualTo(new TlsConfiguration("a", "b", "c", "d"));
+ }
+
+ @Test
+ public void shouldRespectBeanContract() {
+ EqualsVerifier.forClass(TlsConfiguration.class).verify();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java
new file mode 100644
index 0000000..1030dcf
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java
@@ -0,0 +1,181 @@
+/****************************************************************
+ * 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.webadmin;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class WebAdminConfigurationTest {
+
+ public static final FixedPort PORT = new FixedPort(80);
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void buildShouldThrowWhenNoPortButEnabled() {
+ expectedException.expect(IllegalStateException.class);
+
+ WebAdminConfiguration.builder().enabled().build();
+ }
+
+ @Test
+ public void buildShouldWorkWithoutPortWhenDisabled() {
+ assertThat(WebAdminConfiguration.builder()
+ .disabled()
+ .build())
+ .extracting(WebAdminConfiguration::isEnabled)
+ .containsExactly(false);
+ }
+
+ @Test
+ public void buildShouldFailOnNoEnable() {
+ expectedException.expect(IllegalStateException.class);
+
+ WebAdminConfiguration.builder().port(PORT).build();
+ }
+
+ @Test
+ public void builderShouldBuildWithRightPort() {
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .port(PORT)
+ .build())
+ .extracting(WebAdminConfiguration::getPort)
+ .containsExactly(PORT);
+ }
+
+
+ @Test
+ public void builderShouldBuildWithEnable() {
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .port(PORT)
+ .build())
+ .extracting(WebAdminConfiguration::isEnabled)
+ .containsExactly(true);
+ }
+
+ @Test
+ public void builderShouldAcceptHttps() {
+ TlsConfiguration tlsConfiguration = TlsConfiguration.builder()
+ .selfSigned("abcd", "efgh")
+ .build();
+
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .tls(tlsConfiguration)
+ .port(PORT)
+ .build())
+ .extracting(WebAdminConfiguration::getTlsConfiguration)
+ .containsExactly(tlsConfiguration);
+ }
+
+ @Test
+ public void builderShouldReturnTlsEnableWhenTlsConfiguration() {
+ TlsConfiguration tlsConfiguration = TlsConfiguration.builder()
+ .selfSigned("abcd", "efgh")
+ .build();
+
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .tls(tlsConfiguration)
+ .port(PORT)
+ .build())
+ .extracting(WebAdminConfiguration::getTlsConfiguration)
+ .containsExactly(tlsConfiguration);
+ }
+
+ @Test
+ public void builderShouldReturnTlsDisableWhenNoTlsConfiguration() {
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .port(PORT)
+ .build())
+ .extracting(WebAdminConfiguration::isTlsEnabled)
+ .containsExactly(false);
+ }
+
+ @Test
+ public void builderShouldCORSEnabled() {
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .port(PORT)
+ .CORSenabled()
+ .build())
+ .extracting(WebAdminConfiguration::isEnableCORS)
+ .containsExactly(true);
+ }
+
+ @Test
+ public void builderShouldAcceptAllOriginsByDefault() {
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .port(PORT)
+ .CORSenabled()
+ .build())
+ .extracting(WebAdminConfiguration::getUrlCORSOrigin)
+ .containsExactly("*");
+ }
+
+ @Test
+ public void builderShouldCORSDisabled() {
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .port(PORT)
+ .CORSdisabled()
+ .build())
+ .extracting(WebAdminConfiguration::isEnableCORS)
+ .containsExactly(false);
+ }
+
+ @Test
+ public void builderShouldCORSWithOrigin() {
+ String origin = "linagora.com";
+ assertThat(
+ WebAdminConfiguration.builder()
+ .enabled()
+ .port(PORT)
+ .CORSenabled()
+ .urlCORSOrigin(origin)
+ .build())
+ .extracting(WebAdminConfiguration::getUrlCORSOrigin)
+ .containsExactly(origin);
+ }
+
+ @Test
+ public void shouldMatchBeanContract() {
+ EqualsVerifier.forClass(WebAdminConfiguration.class).verify();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/cca0f398/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/authentication/JwtFilterTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/authentication/JwtFilterTest.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/authentication/JwtFilterTest.java
new file mode 100644
index 0000000..6512ddb
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/authentication/JwtFilterTest.java
@@ -0,0 +1,124 @@
+/****************************************************************
+ * 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.webadmin.authentication;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.james.jwt.JwtTokenVerifier;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import com.google.common.collect.ImmutableSet;
+
+import spark.HaltException;
+import spark.Request;
+import spark.Response;
+
+public class JwtFilterTest {
+
+ public static final Matcher<HaltException> STATUS_CODE_MATCHER_401 = new BaseMatcher<HaltException>() {
+ @Override
+ public boolean matches(Object o) {
+ if (o instanceof HaltException) {
+ HaltException haltException = (HaltException) o;
+ return haltException.statusCode() == 401;
+ }
+ return false;
+ }
+
+ @Override
+ public void describeTo(Description description) {}
+ };
+
+ private JwtTokenVerifier jwtTokenVerifier;
+ private JwtFilter jwtFilter;
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ jwtTokenVerifier = mock(JwtTokenVerifier.class);
+ jwtFilter = new JwtFilter(jwtTokenVerifier);
+ }
+
+ @Test
+ public void handleShouldRejectRequestWithHeaders() throws Exception {
+ Request request = mock(Request.class);
+ when(request.headers()).thenReturn(ImmutableSet.of());
+
+ expectedException.expect(HaltException.class);
+ expectedException.expect(STATUS_CODE_MATCHER_401);
+
+ jwtFilter.handle(request, mock(Response.class));
+ }
+
+ @Test
+ public void handleShouldRejectRequestWithBearersHeaders() throws Exception {
+ Request request = mock(Request.class);
+ when(request.headers(JwtFilter.AUTHORIZATION_HEADER_NAME)).thenReturn("Invalid value");
+
+ expectedException.expect(HaltException.class);
+ expectedException.expect(STATUS_CODE_MATCHER_401);
+
+ jwtFilter.handle(request, mock(Response.class));
+ }
+
+ @Test
+ public void handleShouldRejectRequestWithInvalidBearerHeaders() throws Exception {
+ Request request = mock(Request.class);
+ when(request.headers(JwtFilter.AUTHORIZATION_HEADER_NAME)).thenReturn("Bearer value");
+ when(jwtTokenVerifier.verify("value")).thenReturn(false);
+
+ expectedException.expect(HaltException.class);
+ expectedException.expect(STATUS_CODE_MATCHER_401);
+
+ jwtFilter.handle(request, mock(Response.class));
+ }
+
+ @Test
+ public void handleShouldRejectRequestWithoutAdminClaim() throws Exception {
+ Request request = mock(Request.class);
+ when(request.headers(JwtFilter.AUTHORIZATION_HEADER_NAME)).thenReturn("Bearer value");
+ when(jwtTokenVerifier.verify("value")).thenReturn(true);
+ when(jwtTokenVerifier.hasAttribute("admin", true, "value")).thenReturn(false);
+
+ expectedException.expect(HaltException.class);
+ expectedException.expect(STATUS_CODE_MATCHER_401);
+
+ jwtFilter.handle(request, mock(Response.class));
+ }
+
+ @Test
+ public void handleShouldAcceptValidJwt() throws Exception {
+ Request request = mock(Request.class);
+ when(request.headers(JwtFilter.AUTHORIZATION_HEADER_NAME)).thenReturn("Bearer value");
+ when(jwtTokenVerifier.verify("value")).thenReturn(true);
+ when(jwtTokenVerifier.hasAttribute("admin", true, "value")).thenReturn(true);
+
+ jwtFilter.handle(request, mock(Response.class));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org