diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java index e5f3bd2b21d..4b7d1cdf93a 100644 --- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java +++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java @@ -21,6 +21,7 @@ import org.apache.james.mailbox.cassandra.CassandraId; import org.apache.james.modules.data.CassandraDomainListModule; +import org.apache.james.modules.data.CassandraJmapModule; import org.apache.james.modules.data.CassandraRecipientRewriteTableModule; import org.apache.james.modules.data.CassandraSieveRepositoryModule; import org.apache.james.modules.data.CassandraUsersRepositoryModule; @@ -43,6 +44,7 @@ public class CassandraJamesServerMain { new CassandraDomainListModule(), new CassandraRecipientRewriteTableModule(), new CassandraSieveRepositoryModule(), + new CassandraJmapModule(), new CassandraMailboxModule(), new CassandraSessionModule(), new ElasticSearchMailboxModule(), diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java new file mode 100644 index 00000000000..23f3d2af8f0 --- /dev/null +++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java @@ -0,0 +1,39 @@ +/**************************************************************** + * 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.modules.data; + +import org.apache.james.backends.cassandra.components.CassandraModule; +import org.apache.james.jmap.api.access.AccessTokenRepository; +import org.apache.james.jmap.cassandra.access.CassandraAccessModule; +import org.apache.james.jmap.cassandra.access.CassandraAccessTokenRepository; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; + +public class CassandraJmapModule extends AbstractModule { + + @Override + protected void configure() { + bind(AccessTokenRepository.class).to(CassandraAccessTokenRepository.class); + + Multibinder cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class); + cassandraDataDefinitions.addBinding().to(CassandraAccessModule.class); + } +} diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java index d2ad4b0dc18..405e0d78e56 100644 --- a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java +++ b/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java @@ -28,7 +28,6 @@ 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.send.MailFactory; import org.apache.james.jmap.send.MailSpool; import org.apache.james.jmap.utils.DefaultZonedDateTimeProvider; @@ -51,7 +50,6 @@ protected void configure() { 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); bind(MailSpool.class).in(Singleton.class); diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java index 96632551c37..7af047806a4 100644 --- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java +++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java @@ -21,6 +21,8 @@ import org.apache.james.domainlist.api.DomainList; import org.apache.james.domainlist.memory.MemoryDomainList; +import org.apache.james.jmap.api.access.AccessTokenRepository; +import org.apache.james.jmap.memory.access.MemoryAccessTokenRepository; import org.apache.james.rrt.api.RecipientRewriteTable; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.apache.james.sieverepository.api.SieveRepository; @@ -56,6 +58,9 @@ protected void configure() { bind(SieveFileRepository.class).in(Scopes.SINGLETON); bind(SieveRepository.class).to(SieveFileRepository.class); + bind(MemoryAccessTokenRepository.class).in(Scopes.SINGLETON); + bind(AccessTokenRepository.class).to(MemoryAccessTokenRepository.class); + Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(MemoryDataConfigurationPerformer.class); } diff --git a/server/data/data-cassandra/pom.xml b/server/data/data-cassandra/pom.xml index f37e5200d00..d10118ee022 100644 --- a/server/data/data-cassandra/pom.xml +++ b/server/data/data-cassandra/pom.xml @@ -177,6 +177,16 @@ ${project.groupId} james-server-data-api + + org.apache.james + james-server-data-jmap + + + org.apache.james + james-server-data-jmap + test + test-jar + ${project.groupId} james-server-data-library diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java new file mode 100644 index 00000000000..8125ef27ab2 --- /dev/null +++ b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java @@ -0,0 +1,67 @@ +/**************************************************************** + * 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.cassandra.access; + +import static com.datastax.driver.core.DataType.text; +import static com.datastax.driver.core.DataType.uuid; + +import java.util.List; + +import org.apache.james.backends.cassandra.components.CassandraIndex; +import org.apache.james.backends.cassandra.components.CassandraModule; +import org.apache.james.backends.cassandra.components.CassandraTable; +import org.apache.james.backends.cassandra.components.CassandraType; +import org.apache.james.jmap.cassandra.access.table.CassandraAccessTokenTable; + +import com.datastax.driver.core.schemabuilder.SchemaBuilder; +import com.google.common.collect.ImmutableList; + +public class CassandraAccessModule implements CassandraModule { + + private final List tables; + private final List index; + private final List types; + + public CassandraAccessModule() { + tables = ImmutableList.of( + new CassandraTable(CassandraAccessTokenTable.TABLE_NAME, + SchemaBuilder.createTable(CassandraAccessTokenTable.TABLE_NAME) + .ifNotExists() + .addPartitionKey(CassandraAccessTokenTable.TOKEN, uuid()) + .addColumn(CassandraAccessTokenTable.USERNAME, text()))); + index = ImmutableList.of(); + types = ImmutableList.of(); + } + + @Override + public List moduleTables() { + return tables; + } + + @Override + public List moduleIndex() { + return index; + } + + @Override + public List moduleTypes() { + return types; + } +} diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java new file mode 100644 index 00000000000..b1b1b23ce6f --- /dev/null +++ b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java @@ -0,0 +1,113 @@ +/**************************************************************** + * 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.cassandra.access; + +import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker; +import static com.datastax.driver.core.querybuilder.QueryBuilder.delete; +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; +import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto; +import static com.datastax.driver.core.querybuilder.QueryBuilder.select; +import static com.datastax.driver.core.querybuilder.QueryBuilder.ttl; + +import java.util.Optional; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.james.backends.cassandra.utils.CassandraConstants; +import org.apache.james.jmap.api.access.AccessToken; +import org.apache.james.jmap.api.access.AccessTokenRepository; +import org.apache.james.jmap.api.access.exceptions.AccessTokenAlreadyStored; +import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; +import org.apache.james.jmap.cassandra.access.table.CassandraAccessTokenTable; + +import com.datastax.driver.core.PreparedStatement; +import com.datastax.driver.core.Session; +import com.google.common.base.Preconditions; + +public class CassandraAccessTokenRepository implements AccessTokenRepository { + + private static final String TTL = "ttl"; + + private final Session session; + private final PreparedStatement removeStatement; + private final PreparedStatement insertStatement; + private final PreparedStatement selectStatement; + private final int durationInSeconds; + + @Inject + public CassandraAccessTokenRepository(Session session, @Named(TOKEN_EXPIRATION_IN_MS) long durationInMilliseconds) { + this.session = session; + this.durationInSeconds = (int) (durationInMilliseconds / 1000); + + this.removeStatement = this.session.prepare(delete() + .from(CassandraAccessTokenTable.TABLE_NAME) + .where(eq(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)))); + + this.insertStatement = this.session.prepare(insertInto(CassandraAccessTokenTable.TABLE_NAME) + .ifNotExists() + .value(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)) + .value(CassandraAccessTokenTable.USERNAME, bindMarker(CassandraAccessTokenTable.USERNAME)) + .using(ttl(bindMarker(TTL)))); + + this.selectStatement = this.session.prepare(select() + .from(CassandraAccessTokenTable.TABLE_NAME) + .where(eq(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)))); + } + + @Override + public void addToken(String username, AccessToken accessToken) throws AccessTokenAlreadyStored { + Preconditions.checkNotNull(username); + Preconditions.checkArgument(! username.isEmpty(), "Username should not be empty"); + Preconditions.checkNotNull(accessToken); + + boolean applied = session.execute(insertStatement.bind() + .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken()) + .setString(CassandraAccessTokenTable.USERNAME, username) + .setInt(TTL, durationInSeconds)) + .one() + .getBool(CassandraConstants.LIGHTWEIGHT_TRANSACTION_APPLIED); + + if (!applied) { + throw new AccessTokenAlreadyStored(accessToken); + } + } + + @Override + public void removeToken(AccessToken accessToken) { + Preconditions.checkNotNull(accessToken); + + session.execute(removeStatement.bind() + .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken())); + } + + @Override + public String getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken { + Preconditions.checkNotNull(accessToken); + + return Optional.ofNullable( + session.execute( + selectStatement.bind() + .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken())) + .one()) + .map(row -> row.getString(CassandraAccessTokenTable.USERNAME)) + .orElseThrow(() -> new InvalidAccessToken(accessToken)); + } +} diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java new file mode 100644 index 00000000000..482e4ef62ff --- /dev/null +++ b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java @@ -0,0 +1,29 @@ +/**************************************************************** + * 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.cassandra.access.table; + +public interface CassandraAccessTokenTable { + + String TABLE_NAME = "access_token"; + + String TOKEN = "access_token"; + String USERNAME = "username"; + +} diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java new file mode 100644 index 00000000000..355e45d40ba --- /dev/null +++ b/server/data/data-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.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.jmap.cassandra.access; + +import org.apache.james.backends.cassandra.CassandraCluster; +import org.apache.james.jmap.api.access.AbstractAccessTokenRepositoryTest; +import org.apache.james.jmap.api.access.AccessTokenRepository; +import org.junit.After; + +public class CassandraAccessTokenRepositoryTest extends AbstractAccessTokenRepositoryTest { + + private CassandraCluster cassandra; + + @Override + protected AccessTokenRepository createAccessTokenRepository() { + cassandra = CassandraCluster.create(new CassandraAccessModule()); + return new CassandraAccessTokenRepository(cassandra.getConf(), TTL_IN_MS); + } + + @After + public void tearDown() { + cassandra.clearAllTables(); + } +} diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/AccessToken.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/AccessToken.java index ddf9b217760..ea864536bd1 100644 --- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/AccessToken.java +++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/AccessToken.java @@ -48,6 +48,10 @@ public String serialize() { return token.toString(); } + public UUID getToken() { + return token; + } + @Override public boolean equals(Object o) { return o != null diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AbstractAccessTokenRepositoryTest.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AbstractAccessTokenRepositoryTest.java new file mode 100644 index 00000000000..0209af3473b --- /dev/null +++ b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AbstractAccessTokenRepositoryTest.java @@ -0,0 +1,105 @@ +/**************************************************************** + * 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.api.access; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import org.apache.james.jmap.api.access.exceptions.AccessTokenAlreadyStored; +import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; +import org.junit.Before; +import org.junit.Test; + +public abstract class AbstractAccessTokenRepositoryTest { + + private static final AccessToken TOKEN = AccessToken.generate(); + private static final String USERNAME = "username"; + public static final long TTL_IN_MS = 1000; + + private AccessTokenRepository accessTokenRepository; + + @Before + public void setUp() { + accessTokenRepository = createAccessTokenRepository(); + } + + abstract protected AccessTokenRepository createAccessTokenRepository(); + + @Test + public void validTokenMustWork() throws Exception { + accessTokenRepository.addToken(USERNAME, TOKEN); + assertThat(accessTokenRepository.getUsernameFromToken(TOKEN)).isEqualTo(USERNAME); + } + + @Test(expected=InvalidAccessToken.class) + public void nonStoredTokensMustBeInvalid() throws Exception { + accessTokenRepository.getUsernameFromToken(TOKEN); + } + + @Test(expected=InvalidAccessToken.class) + public void removedTokensMustBeInvalid() throws Exception { + accessTokenRepository.addToken(USERNAME, TOKEN); + accessTokenRepository.removeToken(TOKEN); + accessTokenRepository.getUsernameFromToken(TOKEN); + } + + @Test(expected = AccessTokenAlreadyStored.class) + public void addTokenMustThrowWhenTokenIsAlreadyStored() throws Exception { + try { + accessTokenRepository.addToken(USERNAME, TOKEN); + } catch(Exception e) { + fail("Exception caught", e); + } + accessTokenRepository.addToken(USERNAME, TOKEN); + } + + @Test(expected=InvalidAccessToken.class) + public void outDatedTokenMustBeInvalid() throws Exception { + accessTokenRepository.addToken(USERNAME, TOKEN); + Thread.sleep(2 * TTL_IN_MS); + accessTokenRepository.getUsernameFromToken(TOKEN); + } + + @Test(expected = NullPointerException.class) + public void addTokenMustThrowWhenUsernameIsNull() throws Exception { + accessTokenRepository.addToken(null, TOKEN); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenMustThrowWhenUsernameIsEmpty() throws Exception { + accessTokenRepository.addToken("", TOKEN); + } + + @Test(expected = NullPointerException.class) + public void addTokenMustThrowWhenTokenIsNull() throws Exception { + accessTokenRepository.addToken(USERNAME, null); + } + + @Test(expected = NullPointerException.class) + public void removeTokenTokenMustThrowWhenTokenIsNull() throws Exception { + accessTokenRepository.removeToken(null); + } + + @Test(expected = NullPointerException.class) + public void getUsernameFromTokenMustThrowWhenTokenIsNull() throws Exception { + accessTokenRepository.getUsernameFromToken(null); + } + +} diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/memory/access/MemoryAccessTokenRepositoryTest.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/memory/access/MemoryAccessTokenRepositoryTest.java index 9130239d958..cc01ff72c12 100644 --- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/memory/access/MemoryAccessTokenRepositoryTest.java +++ b/server/data/data-jmap/src/test/java/org/apache/james/jmap/memory/access/MemoryAccessTokenRepositoryTest.java @@ -19,86 +19,12 @@ package org.apache.james.jmap.memory.access; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import org.apache.james.jmap.api.access.AbstractAccessTokenRepositoryTest; -import org.apache.james.jmap.api.access.AccessToken; -import org.apache.james.jmap.api.access.exceptions.AccessTokenAlreadyStored; -import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; -import org.junit.Before; -import org.junit.Test; +public class MemoryAccessTokenRepositoryTest extends AbstractAccessTokenRepositoryTest { -public class MemoryAccessTokenRepositoryTest { - - private static final AccessToken TOKEN = AccessToken.generate(); - private static final String USERNAME = "username"; - private static final long TTL_IN_MS = 100; - - private MemoryAccessTokenRepository accessTokenRepository; - - @Before - public void setUp() { - accessTokenRepository = new MemoryAccessTokenRepository(TTL_IN_MS); - } - - @Test - public void validTokenMustWork() throws Exception { - accessTokenRepository.addToken(USERNAME, TOKEN); - assertThat(accessTokenRepository.getUsernameFromToken(TOKEN)).isEqualTo(USERNAME); - } - - @Test(expected=InvalidAccessToken.class) - public void nonStoredTokensMustBeInvalid() throws Exception { - accessTokenRepository.getUsernameFromToken(TOKEN); - } - - @Test(expected=InvalidAccessToken.class) - public void removedTokensMustBeInvalid() throws Exception { - accessTokenRepository.addToken(USERNAME, TOKEN); - accessTokenRepository.removeToken(TOKEN); - accessTokenRepository.getUsernameFromToken(TOKEN); - } - - @Test(expected = AccessTokenAlreadyStored.class) - public void addTokenMustThrowWhenTokenIsAlreadyStored() throws Exception { - try { - accessTokenRepository.addToken(USERNAME, TOKEN); - } catch(Exception e) { - fail("Exception caught", e); - } - accessTokenRepository.addToken(USERNAME, TOKEN); - } - - @Test(expected=InvalidAccessToken.class) - public void outDatedTokenMustBeInvalid() throws Exception { - accessTokenRepository.addToken(USERNAME, TOKEN); - Thread.sleep(200); - accessTokenRepository.getUsernameFromToken(TOKEN); - } - - @Test(expected = NullPointerException.class) - public void addTokenMustThrowWhenUsernameIsNull() throws Exception { - accessTokenRepository.addToken(null, TOKEN); - } - - @Test(expected = IllegalArgumentException.class) - public void addTokenMustThrowWhenUsernameIsEmpty() throws Exception { - accessTokenRepository.addToken("", TOKEN); - } - - @Test(expected = NullPointerException.class) - public void addTokenMustThrowWhenTokenIsNull() throws Exception { - accessTokenRepository.addToken(USERNAME, null); - } - - @Test(expected = NullPointerException.class) - public void removeTokenTokenMustThrowWhenTokenIsNull() throws Exception { - accessTokenRepository.removeToken(null); - } - - @Test(expected = NullPointerException.class) - public void getUsernameFromTokenMustThrowWhenTokenIsNull() throws Exception { - accessTokenRepository.getUsernameFromToken(null); + protected MemoryAccessTokenRepository createAccessTokenRepository() { + return new MemoryAccessTokenRepository(TTL_IN_MS); } } diff --git a/server/pom.xml b/server/pom.xml index 884c734abd9..074b93bc96c 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -535,6 +535,13 @@ james-server-data-jmap ${project.version} + + org.apache.james + james-server-data-jmap + test + test-jar + ${project.version} + org.apache.james james-server-data-jcr