Skip to content

Commit

Permalink
JAMES-1644 Add guice injection in JMAP module
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/james/project/trunk@1719323 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
mbaechler committed Dec 11, 2015
1 parent c95449c commit af23766
Show file tree
Hide file tree
Showing 18 changed files with 136 additions and 50 deletions.
4 changes: 4 additions & 0 deletions server/container/cassandra-guice/pom.xml
Expand Up @@ -265,6 +265,10 @@
<groupId>${project.groupId}</groupId>
<artifactId>james-server-filesystem-api</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>james-server-jmap</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>james-server-lifecycle-api</artifactId>
Expand Down
@@ -0,0 +1,52 @@
/****************************************************************
* 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 java.util.concurrent.TimeUnit;

import org.apache.james.jmap.api.AccessTokenManager;
import org.apache.james.jmap.api.ContinuationTokenManager;
import org.apache.james.jmap.api.access.AccessTokenRepository;
import org.apache.james.jmap.crypto.AccessTokenManagerImpl;
import org.apache.james.jmap.crypto.JamesSignatureHandler;
import org.apache.james.jmap.crypto.SignatureHandler;
import org.apache.james.jmap.crypto.SignedContinuationTokenManager;
import org.apache.james.jmap.memory.access.MemoryAccessTokenRepository;
import org.apache.james.jmap.utils.DefaultZonedDateTimeProvider;
import org.apache.james.jmap.utils.ZonedDateTimeProvider;

import com.google.inject.AbstractModule;
import com.google.inject.name.Names;

public class JMAPCommonModule extends AbstractModule {

private static final long DEFAULT_TOKEN_EXPIRATION_IN_MS = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES);

@Override
protected void configure() {
bind(SignatureHandler.class).to(JamesSignatureHandler.class);
bind(ZonedDateTimeProvider.class).to(DefaultZonedDateTimeProvider.class);
bind(ContinuationTokenManager.class).to(SignedContinuationTokenManager.class);

bindConstant().annotatedWith(Names.named(AccessTokenRepository.TOKEN_EXPIRATION_IN_MS)).to(DEFAULT_TOKEN_EXPIRATION_IN_MS);
bind(AccessTokenRepository.class).to(MemoryAccessTokenRepository.class);
bind(AccessTokenManager.class).to(AccessTokenManagerImpl.class);
}

}
Expand Up @@ -24,6 +24,8 @@

public interface AccessTokenRepository {

String TOKEN_EXPIRATION_IN_MS = "tokenExpirationInMs";

void addToken(String username, AccessToken accessToken) throws AccessTokenAlreadyStored;

void removeToken(AccessToken accessToken);
Expand Down
Expand Up @@ -22,6 +22,7 @@
import java.util.Optional;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.commons.collections4.map.PassiveExpiringMap;
Expand All @@ -38,7 +39,7 @@ public class MemoryAccessTokenRepository implements AccessTokenRepository {
private final PassiveExpiringMap<AccessToken, String> tokensExpirationDates;

@Inject
public MemoryAccessTokenRepository(long durationInMilliseconds) {
public MemoryAccessTokenRepository(@Named(TOKEN_EXPIRATION_IN_MS) long durationInMilliseconds) {
tokensExpirationDates = new PassiveExpiringMap<>(durationInMilliseconds);
}

Expand Down
Expand Up @@ -32,7 +32,7 @@ public class MemoryAccessTokenRepositoryTest {

private static final AccessToken TOKEN = AccessToken.generate();
private static final String USERNAME = "username";
private static final int TTL_IN_MS = 100;
private static final long TTL_IN_MS = 100;

private MemoryAccessTokenRepository accessTokenRepository;

Expand Down
5 changes: 5 additions & 0 deletions server/pom.xml
Expand Up @@ -537,6 +537,11 @@
<scope>test</scope>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>james-server-jmap</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.james.protocols</groupId>
<artifactId>protocols-smtp</artifactId>
Expand Down
Expand Up @@ -21,6 +21,7 @@
import java.io.IOException;
import java.util.Optional;

import javax.inject.Inject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
Expand All @@ -37,6 +38,7 @@ public class AuthenticationFilter implements Filter {

private AccessTokenManager accessTokenManager;

@Inject
public AuthenticationFilter(AccessTokenManager accessTokenManager) {
this.accessTokenManager = accessTokenManager;
}
Expand Down
Expand Up @@ -21,6 +21,7 @@
import java.io.IOException;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
Expand All @@ -45,6 +46,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.annotations.VisibleForTesting;

@Singleton
public class AuthenticationServlet extends HttpServlet {

public static final String JSON_CONTENT_TYPE = "application/json";
Expand Down
Expand Up @@ -19,17 +19,22 @@

package org.apache.james.jmap.crypto;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.apache.james.jmap.api.AccessTokenManager;
import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.jmap.api.access.AccessTokenRepository;
import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken;

import com.google.common.base.Preconditions;

@Singleton
public class AccessTokenManagerImpl implements AccessTokenManager {

private final AccessTokenRepository accessTokenRepository;

@Inject
public AccessTokenManagerImpl(AccessTokenRepository accessTokenRepository) {
this.accessTokenRepository = accessTokenRepository;
}
Expand Down
Expand Up @@ -29,6 +29,9 @@
import java.security.Signature;
import java.security.SignatureException;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.HierarchicalConfiguration;
Expand All @@ -37,9 +40,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;

@Singleton
public class JamesSignatureHandler implements SignatureHandler, Configurable {

private static final Logger LOGGER = LoggerFactory.getLogger(JamesSignatureHandler.class);
Expand All @@ -54,7 +59,8 @@ public class JamesSignatureHandler implements SignatureHandler, Configurable {
private PrivateKey privateKey;
private PublicKey publicKey;

public JamesSignatureHandler(FileSystem fileSystem) {
@Inject
@VisibleForTesting JamesSignatureHandler(FileSystem fileSystem) {
this.fileSystem = fileSystem;
}

Expand All @@ -63,6 +69,7 @@ public void configure(HierarchicalConfiguration configuration) throws Configurat
secret = configuration.getString("tls.secret", "");
}

@Override
public void init() throws Exception {
KeyStore keystore = KeyStore.getInstance(JKS);
InputStream fis = fileSystem.getResource(keystoreURL);
Expand Down
Expand Up @@ -20,6 +20,8 @@
package org.apache.james.jmap.crypto;

public interface SignatureHandler {

void init() throws Exception;

String sign(String source);

Expand Down
Expand Up @@ -22,17 +22,22 @@
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.apache.james.jmap.api.ContinuationTokenManager;
import org.apache.james.jmap.model.ContinuationToken;
import org.apache.james.jmap.utils.ZonedDateTimeProvider;

import com.google.common.base.Preconditions;

@Singleton
public class SignedContinuationTokenManager implements ContinuationTokenManager {

private final SignatureHandler signatureHandler;
private final ZonedDateTimeProvider zonedDateTimeProvider;

@Inject
public SignedContinuationTokenManager(SignatureHandler signatureHandler, ZonedDateTimeProvider zonedDateTimeProvider) {
this.signatureHandler = signatureHandler;
this.zonedDateTimeProvider = zonedDateTimeProvider;
Expand All @@ -41,7 +46,7 @@ public SignedContinuationTokenManager(SignatureHandler signatureHandler, ZonedDa
@Override
public ContinuationToken generateToken(String username) {
Preconditions.checkNotNull(username);
ZonedDateTime expirationTime = zonedDateTimeProvider.provide().plusMinutes(15);
ZonedDateTime expirationTime = zonedDateTimeProvider.get().plusMinutes(15);
return new ContinuationToken(username,
expirationTime,
signatureHandler.sign(username + ContinuationToken.SEPARATOR + DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(expirationTime)));
Expand Down Expand Up @@ -70,6 +75,6 @@ private boolean isCorrectlySigned(ContinuationToken token) {
}

private boolean isExpired(ContinuationToken token) {
return token.getExpirationDate().isBefore(zonedDateTimeProvider.provide());
return token.getExpirationDate().isBefore(zonedDateTimeProvider.get());
}
}
Expand Up @@ -18,11 +18,12 @@
****************************************************************/
package org.apache.james.jmap.model;

import org.apache.james.jmap.exceptions.MalformedContinuationTokenException;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import org.apache.james.jmap.exceptions.MalformedContinuationTokenException;

@JsonDeserialize(builder=AccessTokenRequest.Builder.class)
@JsonDeserialize(builder = AccessTokenRequest.Builder.class)
public class AccessTokenRequest {

public static final String UNIQUE_JSON_PATH = "/token";
Expand Down
Expand Up @@ -25,7 +25,7 @@
public class DefaultZonedDateTimeProvider implements ZonedDateTimeProvider {

@Override
public ZonedDateTime provide() {
public ZonedDateTime get() {
return ZonedDateTime.now(ZoneOffset.UTC);
}
}
Expand Up @@ -21,8 +21,8 @@

import java.time.ZonedDateTime;

public interface ZonedDateTimeProvider {
import javax.inject.Provider;

ZonedDateTime provide();
public interface ZonedDateTimeProvider extends Provider<ZonedDateTime> {

}

0 comments on commit af23766

Please sign in to comment.