JAMES-4025 Drop AccessToken authentication strategy and related classes
diff --git a/server/container/guice/cassandra/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java b/server/container/guice/cassandra/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
index c651368..cebbbb5 100644
--- a/server/container/guice/cassandra/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
+++ b/server/container/guice/cassandra/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java
@@ -28,7 +28,6 @@
import org.apache.james.eventsourcing.eventstore.EventStore;
import org.apache.james.eventsourcing.eventstore.dto.EventDTO;
import org.apache.james.eventsourcing.eventstore.dto.EventDTOModule;
-import org.apache.james.jmap.api.access.AccessTokenRepository;
import org.apache.james.jmap.api.filtering.FilteringManagement;
import org.apache.james.jmap.api.filtering.FilteringRuleSetDefineDTOModules;
import org.apache.james.jmap.api.filtering.FiltersDeleteUserDataTaskStep;
@@ -43,8 +42,6 @@
import org.apache.james.jmap.api.pushsubscription.PushSubscriptionRepository;
import org.apache.james.jmap.api.upload.UploadRepository;
import org.apache.james.jmap.api.upload.UploadUsageRepository;
-import org.apache.james.jmap.cassandra.access.CassandraAccessModule;
-import org.apache.james.jmap.cassandra.access.CassandraAccessTokenRepository;
import org.apache.james.jmap.cassandra.change.CassandraEmailChangeModule;
import org.apache.james.jmap.cassandra.change.CassandraMailboxChangeModule;
import org.apache.james.jmap.cassandra.filtering.CassandraFilteringProjection;
@@ -75,9 +72,6 @@
public class CassandraJmapModule extends AbstractModule {
@Override
protected void configure() {
- bind(CassandraAccessTokenRepository.class).in(Scopes.SINGLETON);
- bind(AccessTokenRepository.class).to(CassandraAccessTokenRepository.class);
-
bind(CassandraUploadRepository.class).in(Scopes.SINGLETON);
bind(UploadDAO.class).in(Scopes.SINGLETON);
bind(UploadRepository.class).to(CassandraUploadRepository.class);
@@ -103,7 +97,6 @@
bind(EmailQueryView.class).to(CassandraEmailQueryView.class);
Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class);
- cassandraDataDefinitions.addBinding().toInstance(CassandraAccessModule.MODULE);
cassandraDataDefinitions.addBinding().toInstance(CassandraMessageFastViewProjectionModule.MODULE);
cassandraDataDefinitions.addBinding().toInstance(CassandraEmailQueryViewModule.MODULE);
cassandraDataDefinitions.addBinding().toInstance(CassandraMailboxChangeModule.MODULE);
diff --git a/server/container/guice/memory/src/main/java/org/apache/james/modules/data/MemoryDataJmapModule.java b/server/container/guice/memory/src/main/java/org/apache/james/modules/data/MemoryDataJmapModule.java
index 09a8666..cea7c2d 100644
--- a/server/container/guice/memory/src/main/java/org/apache/james/modules/data/MemoryDataJmapModule.java
+++ b/server/container/guice/memory/src/main/java/org/apache/james/modules/data/MemoryDataJmapModule.java
@@ -20,7 +20,6 @@
package org.apache.james.modules.data;
import org.apache.james.core.healthcheck.HealthCheck;
-import org.apache.james.jmap.api.access.AccessTokenRepository;
import org.apache.james.jmap.api.filtering.FilteringManagement;
import org.apache.james.jmap.api.filtering.FiltersDeleteUserDataTaskStep;
import org.apache.james.jmap.api.filtering.impl.EventSourcingFilteringManagement;
@@ -32,7 +31,6 @@
import org.apache.james.jmap.api.projections.MessageFastViewProjectionHealthCheck;
import org.apache.james.jmap.api.pushsubscription.PushDeleteUserDataTaskStep;
import org.apache.james.jmap.api.upload.UploadRepository;
-import org.apache.james.jmap.memory.access.MemoryAccessTokenRepository;
import org.apache.james.jmap.memory.identity.MemoryCustomIdentityDAO;
import org.apache.james.jmap.memory.projections.MemoryEmailQueryView;
import org.apache.james.jmap.memory.projections.MemoryMessageFastViewProjection;
@@ -51,9 +49,6 @@
@Override
protected void configure() {
- bind(MemoryAccessTokenRepository.class).in(Scopes.SINGLETON);
- bind(AccessTokenRepository.class).to(MemoryAccessTokenRepository.class);
-
bind(InMemoryUploadRepository.class).in(Scopes.SINGLETON);
bind(UploadRepository.class).to(InMemoryUploadRepository.class);
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPWithoutDraftCommonModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPWithoutDraftCommonModule.java
index 3e645f7..d2746a8 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPWithoutDraftCommonModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPWithoutDraftCommonModule.java
@@ -19,9 +19,6 @@
package org.apache.james.jmap;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.james.jmap.api.access.AccessTokenRepository;
import org.apache.james.jmap.json.ObjectMapperFactory;
import org.apache.james.jmap.methods.BlobManager;
import org.apache.james.jmap.methods.BlobManagerImpl;
@@ -37,10 +34,8 @@
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
-import com.google.inject.name.Names;
public class JMAPWithoutDraftCommonModule extends AbstractModule {
- private static final long DEFAULT_TOKEN_EXPIRATION_IN_MS = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES);
@Override
protected void configure() {
@@ -59,6 +54,5 @@
bind(JmapResponseWriterImpl.class).in(Scopes.SINGLETON);
bind(JmapResponseWriter.class).to(JmapResponseWriterImpl.class);
- bindConstant().annotatedWith(Names.named(AccessTokenRepository.TOKEN_EXPIRATION_IN_MS)).to(DEFAULT_TOKEN_EXPIRATION_IN_MS);
}
}
diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java
deleted file mode 100644
index f0109da..0000000
--- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************
- * 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.oss.driver.api.querybuilder.SchemaBuilder.RowsPerPartition.rows;
-
-import org.apache.james.backends.cassandra.components.CassandraModule;
-import org.apache.james.backends.cassandra.utils.CassandraConstants;
-import org.apache.james.jmap.cassandra.access.table.CassandraAccessTokenTable;
-
-import com.datastax.oss.driver.api.core.type.DataTypes;
-
-public interface CassandraAccessModule {
- CassandraModule MODULE = CassandraModule.table(CassandraAccessTokenTable.TABLE_NAME)
- .comment("Holds JMAP access token required to process to authentication.")
- .options(options -> options
- .withCaching(true, rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION)))
- .statement(statement -> types -> statement
- .withPartitionKey(CassandraAccessTokenTable.TOKEN, DataTypes.UUID)
- .withColumn(CassandraAccessTokenTable.USERNAME, DataTypes.TEXT))
- .build();
-}
diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenDAO.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenDAO.java
deleted file mode 100644
index 1f31aa4..0000000
--- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenDAO.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************
- * 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.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
-import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.deleteFrom;
-import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto;
-import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;
-import static org.apache.james.jmap.api.access.AccessTokenRepository.TOKEN_EXPIRATION_IN_MS;
-
-import java.util.concurrent.TimeUnit;
-
-import jakarta.inject.Inject;
-import jakarta.inject.Named;
-
-import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.core.Username;
-import org.apache.james.jmap.api.access.AccessToken;
-import org.apache.james.jmap.cassandra.access.table.CassandraAccessTokenTable;
-
-import com.datastax.oss.driver.api.core.CqlSession;
-import com.datastax.oss.driver.api.core.cql.PreparedStatement;
-import com.datastax.oss.driver.api.core.type.codec.TypeCodecs;
-import com.google.common.primitives.Ints;
-
-import reactor.core.publisher.Mono;
-
-public class CassandraAccessTokenDAO {
-
- private static final String TTL = "ttl";
-
- private final CassandraAsyncExecutor cassandraAsyncExecutor;
- private final PreparedStatement removeStatement;
- private final PreparedStatement insertStatement;
- private final PreparedStatement selectStatement;
- private final int durationInSeconds;
-
- @Inject
- public CassandraAccessTokenDAO(CqlSession session, @Named(TOKEN_EXPIRATION_IN_MS) long durationInMilliseconds) {
- this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
- this.durationInSeconds = Ints.checkedCast(TimeUnit.MILLISECONDS.toSeconds(durationInMilliseconds));
-
- this.removeStatement = session.prepare(deleteFrom(CassandraAccessTokenTable.TABLE_NAME)
- .whereColumn(CassandraAccessTokenTable.TOKEN).isEqualTo(bindMarker(CassandraAccessTokenTable.TOKEN))
- .build());
-
- this.insertStatement = session.prepare(insertInto(CassandraAccessTokenTable.TABLE_NAME)
- .value(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN))
- .value(CassandraAccessTokenTable.USERNAME, bindMarker(CassandraAccessTokenTable.USERNAME))
- .usingTtl(bindMarker(TTL))
- .build());
-
- this.selectStatement = session.prepare(selectFrom(CassandraAccessTokenTable.TABLE_NAME)
- .column(CassandraAccessTokenTable.USERNAME)
- .whereColumn(CassandraAccessTokenTable.TOKEN)
- .isEqualTo(bindMarker(CassandraAccessTokenTable.TOKEN))
- .build());
- }
-
- public Mono<Void> addToken(Username username, AccessToken accessToken) {
- return cassandraAsyncExecutor.executeVoid(insertStatement.bind()
- .setUuid(CassandraAccessTokenTable.TOKEN, accessToken.asUUID())
- .setString(CassandraAccessTokenTable.USERNAME, username.asString())
- .setInt(TTL, durationInSeconds));
- }
-
- public Mono<Void> removeToken(AccessToken accessToken) {
- return cassandraAsyncExecutor.executeVoid(removeStatement.bind()
- .setUuid(CassandraAccessTokenTable.TOKEN, accessToken.asUUID()));
- }
-
- public Mono<Username> getUsernameFromToken(AccessToken accessToken) {
- return cassandraAsyncExecutor.executeSingleRow(selectStatement.bind()
- .set(CassandraAccessTokenTable.TOKEN, accessToken.asUUID(), TypeCodecs.UUID))
- .map(row -> row.get(0, TypeCodecs.TEXT))
- .map(Username::of);
- }
-}
diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java
deleted file mode 100644
index 0f10886..0000000
--- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/****************************************************************
- * 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 jakarta.inject.Inject;
-
-import org.apache.james.core.Username;
-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;
-
-import reactor.core.publisher.Mono;
-
-public class CassandraAccessTokenRepository implements AccessTokenRepository {
-
- private final CassandraAccessTokenDAO cassandraAccessTokenDAO;
-
- @Inject
- CassandraAccessTokenRepository(CassandraAccessTokenDAO cassandraAccessTokenDAO) {
- this.cassandraAccessTokenDAO = cassandraAccessTokenDAO;
- }
-
- @Override
- public Mono<Void> addToken(Username username, AccessToken accessToken) {
- Preconditions.checkNotNull(username);
- Preconditions.checkNotNull(accessToken);
-
- return cassandraAccessTokenDAO.addToken(username, accessToken);
- }
-
- @Override
- public Mono<Void> removeToken(AccessToken accessToken) {
- Preconditions.checkNotNull(accessToken);
-
- return cassandraAccessTokenDAO.removeToken(accessToken);
- }
-
- @Override
- public Mono<Username> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken {
- Preconditions.checkNotNull(accessToken);
-
- return cassandraAccessTokenDAO.getUsernameFromToken(accessToken)
- .switchIfEmpty(Mono.error(() -> new InvalidAccessToken(accessToken)));
- }
-}
diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java
deleted file mode 100644
index 026f80e..0000000
--- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/****************************************************************
- * 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;
-
-import com.datastax.oss.driver.api.core.CqlIdentifier;
-
-public interface CassandraAccessTokenTable {
-
- String TABLE_NAME = "access_token";
-
- CqlIdentifier TOKEN = CqlIdentifier.fromCql("access_token");
- CqlIdentifier USERNAME = CqlIdentifier.fromCql("username");
-
-}
diff --git a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java
deleted file mode 100644
index 66640e9..0000000
--- a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/****************************************************************
- * 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.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.jmap.api.access.AccessTokenRepository;
-import org.apache.james.jmap.api.access.AccessTokenRepositoryContract;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class CassandraAccessTokenRepositoryTest implements AccessTokenRepositoryContract {
- @RegisterExtension
- static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraAccessModule.MODULE);
-
- AccessTokenRepository accessTokenRepository;
-
- @BeforeEach
- void setUp(CassandraCluster cassandra) {
- accessTokenRepository = new CassandraAccessTokenRepository(
- new CassandraAccessTokenDAO(cassandra.getConf(), AccessTokenRepositoryContract.TTL_IN_MS));
- }
-
- @Override
- public AccessTokenRepository accessTokenRepository() {
- return accessTokenRepository;
- }
-
-}
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
deleted file mode 100644
index aeb699b..0000000
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/AccessToken.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************
- * 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 java.util.Objects;
-import java.util.UUID;
-
-import org.apache.james.jmap.api.access.exceptions.NotAnAccessTokenException;
-
-public class AccessToken {
-
- public static AccessToken fromString(String tokenString) throws NotAnAccessTokenException {
- try {
- return new AccessToken(UUID.fromString(tokenString));
- } catch (IllegalArgumentException e) {
- throw new NotAnAccessTokenException(e);
- }
- }
-
- private final UUID token;
-
- private AccessToken(UUID token) {
- this.token = token;
- }
-
- public static AccessToken generate() {
- return new AccessToken(UUID.randomUUID());
- }
-
- public String serialize() {
- return token.toString();
- }
-
- public UUID asUUID() {
- return token;
- }
-
- @Override
- public boolean equals(Object o) {
- return o instanceof AccessToken
- && Objects.equals(this.token, ((AccessToken)o).token);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(token);
- }
-}
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/AccessTokenRepository.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/AccessTokenRepository.java
deleted file mode 100644
index 3682a73..0000000
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/AccessTokenRepository.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/****************************************************************
- * 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 org.apache.james.core.Username;
-import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken;
-
-import reactor.core.publisher.Mono;
-
-public interface AccessTokenRepository {
-
- String TOKEN_EXPIRATION_IN_MS = "tokenExpirationInMs";
-
- Mono<Void> addToken(Username username, AccessToken accessToken);
-
- Mono<Void> removeToken(AccessToken accessToken);
-
- Mono<Username> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken;
-
-}
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/exceptions/InvalidAccessToken.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/exceptions/InvalidAccessToken.java
deleted file mode 100644
index c5ee869..0000000
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/exceptions/InvalidAccessToken.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/****************************************************************
- * 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.exceptions;
-
-import org.apache.james.jmap.api.access.AccessToken;
-
-public class InvalidAccessToken extends RuntimeException {
-
- public InvalidAccessToken(AccessToken token) {
- super(token.serialize() + " is missing");
- }
-}
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/exceptions/NotAnAccessTokenException.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/exceptions/NotAnAccessTokenException.java
deleted file mode 100644
index ca8940f..0000000
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/access/exceptions/NotAnAccessTokenException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/****************************************************************
- * 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.exceptions;
-
-public class NotAnAccessTokenException extends RuntimeException {
-
- public NotAnAccessTokenException(Exception e) {
- super(e);
- }
-}
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/access/MemoryAccessTokenRepository.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/access/MemoryAccessTokenRepository.java
deleted file mode 100644
index 3745d54..0000000
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/access/MemoryAccessTokenRepository.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************
- * 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.memory.access;
-
-import java.util.Optional;
-
-import jakarta.inject.Inject;
-import jakarta.inject.Named;
-
-import org.apache.commons.collections4.map.PassiveExpiringMap;
-import org.apache.james.core.Username;
-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;
-
-import reactor.core.publisher.Mono;
-
-public class MemoryAccessTokenRepository implements AccessTokenRepository {
- private final PassiveExpiringMap<AccessToken, Username> tokensExpirationDates;
-
- @Inject
- public MemoryAccessTokenRepository(@Named(TOKEN_EXPIRATION_IN_MS) long durationInMilliseconds) {
- tokensExpirationDates = new PassiveExpiringMap<>(durationInMilliseconds);
- }
-
- @Override
- public Mono<Void> addToken(Username username, AccessToken accessToken) {
- Preconditions.checkNotNull(username);
- Preconditions.checkNotNull(accessToken);
- synchronized (tokensExpirationDates) {
- tokensExpirationDates.put(accessToken, username);
- }
- return Mono.empty();
- }
-
- @Override
- public Mono<Void> removeToken(AccessToken accessToken) {
- Preconditions.checkNotNull(accessToken);
- synchronized (tokensExpirationDates) {
- tokensExpirationDates.remove(accessToken);
- }
- return Mono.empty();
- }
-
- @Override
- public Mono<Username> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken {
- Preconditions.checkNotNull(accessToken);
- synchronized (tokensExpirationDates) {
- return Mono.just(
- Optional.ofNullable(tokensExpirationDates.get(accessToken))
- .orElseThrow(() -> new InvalidAccessToken(accessToken)));
- }
- }
-
-}
diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AccessTokenRepositoryContract.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AccessTokenRepositoryContract.java
deleted file mode 100644
index 87e11cf..0000000
--- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AccessTokenRepositoryContract.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************
- * 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.assertThatThrownBy;
-
-import org.apache.james.core.Username;
-import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken;
-import org.junit.jupiter.api.Test;
-
-public interface AccessTokenRepositoryContract {
- AccessToken TOKEN = AccessToken.generate();
- Username USERNAME = Username.of("username");
- long TTL_IN_MS = 1000;
-
- AccessTokenRepository accessTokenRepository();
-
- @Test
- default void validTokenMustBeRetrieved() {
- accessTokenRepository().addToken(USERNAME, TOKEN).block();
- assertThat(accessTokenRepository().getUsernameFromToken(TOKEN).block()).isEqualTo(USERNAME);
- }
-
- @Test
- default void absentTokensMustBeInvalid() {
- assertThatThrownBy(() -> accessTokenRepository().getUsernameFromToken(TOKEN).block()).isExactlyInstanceOf(InvalidAccessToken.class);
- }
-
- @Test
- default void removedTokensMustBeInvalid() {
- accessTokenRepository().addToken(USERNAME, TOKEN).block();
- accessTokenRepository().removeToken(TOKEN).block();
- assertThatThrownBy(() -> accessTokenRepository().getUsernameFromToken(TOKEN).block()).isExactlyInstanceOf(InvalidAccessToken.class);
- }
-
- @Test
- default void outDatedTokenMustBeInvalid() throws Exception {
- accessTokenRepository().addToken(USERNAME, TOKEN).block();
- Thread.sleep(2 * TTL_IN_MS);
- assertThatThrownBy(() -> accessTokenRepository().getUsernameFromToken(TOKEN).block()).isExactlyInstanceOf(InvalidAccessToken.class);
- }
-
- @Test
- default void addTokenMustThrowWhenUsernameIsNull() {
- assertThatThrownBy(() -> accessTokenRepository().addToken(null, TOKEN))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- default void addTokenMustThrowWhenTokenIsNull() {
- assertThatThrownBy(() -> accessTokenRepository().addToken(USERNAME, null))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- default void removeTokenTokenMustThrowWhenTokenIsNull() {
- assertThatThrownBy(() -> accessTokenRepository().removeToken(null))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- default void getUsernameFromTokenMustThrowWhenTokenIsNull() {
- assertThatThrownBy(() -> accessTokenRepository().getUsernameFromToken(null))
- .isInstanceOf(NullPointerException.class);
- }
-
-}
diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AccessTokenTest.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AccessTokenTest.java
deleted file mode 100644
index 9693af9..0000000
--- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/access/AccessTokenTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/****************************************************************
- * 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.assertThatThrownBy;
-
-import org.apache.james.jmap.api.access.exceptions.NotAnAccessTokenException;
-import org.junit.jupiter.api.Test;
-
-class AccessTokenTest {
-
- @Test
- void fromStringShouldThrowWhenNotAnUUID() {
- assertThatThrownBy(() -> AccessToken.fromString("bad"))
- .isInstanceOf(NotAnAccessTokenException.class);
- }
-
- @Test
- void fromStringShouldWork() throws NotAnAccessTokenException {
- String expectedToken = "dab315ad-a59a-4107-8d00-0fef9a0745b8";
-
- AccessToken accessToken = AccessToken.fromString(expectedToken);
- assertThat(accessToken.serialize()).isEqualTo(expectedToken);
- }
-}
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
deleted file mode 100644
index 4c868f1..0000000
--- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/memory/access/MemoryAccessTokenRepositoryTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/****************************************************************
- * 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.memory.access;
-
-import org.apache.james.jmap.api.access.AccessTokenRepository;
-import org.apache.james.jmap.api.access.AccessTokenRepositoryContract;
-import org.junit.jupiter.api.BeforeEach;
-
-class MemoryAccessTokenRepositoryTest implements AccessTokenRepositoryContract {
- AccessTokenRepository accessTokenRepository;
-
- @BeforeEach
- void setUp() {
- accessTokenRepository = new MemoryAccessTokenRepository(AccessTokenRepositoryContract.TTL_IN_MS);
- }
-
- @Override
- public AccessTokenRepository accessTokenRepository() {
- return accessTokenRepository;
- }
-}
diff --git a/server/testing/src/main/java/org/apache/james/jmap/AccessToken.java b/server/testing/src/main/java/org/apache/james/jmap/AccessToken.java
deleted file mode 100644
index 0e9969d..0000000
--- a/server/testing/src/main/java/org/apache/james/jmap/AccessToken.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/****************************************************************
- * 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 com.google.common.annotations.VisibleForTesting;
-
-@VisibleForTesting
-public class AccessToken {
-
- public static AccessToken of(String tokenString) {
- return new AccessToken(tokenString);
- }
-
- private final String token;
-
- private AccessToken(String token) {
- this.token = token;
- }
-
- public String asString() {
- return token;
- }
-}
diff --git a/server/testing/src/main/java/org/apache/james/jmap/HttpJmapAuthentication.java b/server/testing/src/main/java/org/apache/james/jmap/HttpJmapAuthentication.java
deleted file mode 100644
index 00fbc34..0000000
--- a/server/testing/src/main/java/org/apache/james/jmap/HttpJmapAuthentication.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.jmap;
-
-import static org.apache.james.jmap.JMAPTestingConstants.calmlyAwait;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.time.Duration;
-
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.fluent.Request;
-import org.apache.http.client.fluent.Response;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.entity.ContentType;
-import org.apache.james.core.Username;
-import org.hamcrest.core.IsAnything;
-
-import com.jayway.jsonpath.JsonPath;
-
-public class HttpJmapAuthentication {
-
- public static AccessToken authenticateJamesUser(URIBuilder uriBuilder, Username username, String password) {
- return calmlyAwait
- .atMost(Duration.ofMinutes(2))
- .until(
- () -> doAuthenticate(uriBuilder, username, password), IsAnything.anything());
- }
-
- public static AccessToken doAuthenticate(URIBuilder uriBuilder, Username username, String password) throws ClientProtocolException, IOException, URISyntaxException {
- String continuationToken = getContinuationToken(uriBuilder, username);
-
- Response response = postAuthenticate(uriBuilder, password, continuationToken);
-
- return AccessToken.of(
- JsonPath.parse(response.returnContent().asString())
- .read("accessToken"));
- }
-
- private static Response postAuthenticate(URIBuilder uriBuilder, String password, String continuationToken) throws ClientProtocolException, IOException, URISyntaxException {
- return Request.Post(uriBuilder.setPath("/authentication").build())
- .bodyString("{\"token\": \"" + continuationToken + "\", \"method\": \"password\", \"password\": \"" + password + "\"}",
- ContentType.APPLICATION_JSON)
- .setHeader("Accept", ContentType.APPLICATION_JSON.getMimeType())
- .execute();
- }
-
- private static String getContinuationToken(URIBuilder uriBuilder, Username username) throws ClientProtocolException, IOException, URISyntaxException {
- Response response = Request.Post(uriBuilder.setPath("/authentication").build())
- .bodyString("{\"username\": \"" + username.asString() + "\", \"clientName\": \"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", \"deviceName\": \"Joe Blogg’s iPhone\"}",
- ContentType.APPLICATION_JSON)
- .setHeader("Accept", ContentType.APPLICATION_JSON.getMimeType())
- .execute();
-
- return JsonPath.parse(response.returnContent().asString())
- .read("continuationToken");
- }
-
-}
diff --git a/server/testing/src/main/java/org/apache/james/jmap/JmapCommonRequests.java b/server/testing/src/main/java/org/apache/james/jmap/JmapCommonRequests.java
deleted file mode 100644
index 981e549..0000000
--- a/server/testing/src/main/java/org/apache/james/jmap/JmapCommonRequests.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.jmap;
-
-import static io.restassured.RestAssured.with;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasKey;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.text.IsEmptyString.emptyOrNullString;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import org.apache.james.mailbox.Role;
-import org.apache.james.mailbox.model.MailboxId;
-
-import io.restassured.builder.ResponseSpecBuilder;
-import io.restassured.path.json.JsonPath;
-import io.restassured.specification.ResponseSpecification;
-
-public class JmapCommonRequests {
- private static final String NAME = "[0][0]";
- private static final String ARGUMENTS = "[0][1]";
- private static final String NOT_UPDATED = ARGUMENTS + ".notUpdated";
-
- public static String getOutboxId(AccessToken accessToken) {
- return getMailboxId(accessToken, Role.OUTBOX);
- }
-
- public static String getSentId(AccessToken accessToken) {
- return getMailboxId(accessToken, Role.SENT);
- }
-
- public static String getDraftId(AccessToken accessToken) {
- return getMailboxId(accessToken, Role.DRAFTS);
- }
-
- public static String getMailboxId(AccessToken accessToken, Role role) {
- return getAllMailboxesIds(accessToken).stream()
- .filter(mailbox -> mailbox.get("role").equals(role.serialize()))
- .map(mailbox -> mailbox.get("id"))
- .findFirst().get();
- }
-
- public static List<Map<String, String>> getAllMailboxesIds(AccessToken accessToken) {
- return with()
- .header("Authorization", accessToken.asString())
- .body("[[\"getMailboxes\", {\"properties\": [\"role\", \"name\", \"id\"]}, \"#0\"]]")
- .post("/jmap")
- .andReturn()
- .body()
- .jsonPath()
- .getList(ARGUMENTS + ".list");
- }
-
- public static boolean isAnyMessageFoundInRecipientsMailboxes(AccessToken recipientToken) {
- try {
- with()
- .header("Authorization", recipientToken.asString())
- .body("[[\"getMessageList\", {}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1));
- return true;
-
- } catch (AssertionError e) {
- return false;
- }
- }
-
- public static boolean isAnyMessageFoundInRecipientsMailbox(AccessToken recipientToken, MailboxId mailboxId) {
- return isAnyMessageFoundInRecipientsMailbox(recipientToken, mailboxId.serialize());
- }
-
- public static boolean isAnyMessageFoundInRecipientsMailbox(AccessToken recipientToken, String serialize) {
- try {
- with()
- .header("Authorization", recipientToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + serialize + "\"]}}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1));
- return true;
-
- } catch (AssertionError e) {
- return false;
- }
- }
-
- public static String getInboxId(AccessToken accessToken) {
- return getMailboxId(accessToken, Role.INBOX);
- }
-
- public static List<String> listMessageIdsForAccount(AccessToken accessToken) {
- return with()
- .header("Authorization", accessToken.asString())
- .body("[[\"getMessageList\", {}, \"#0\"]]")
- .post("/jmap")
- .then()
- .extract()
- .body()
- .path(ARGUMENTS + ".messageIds");
- }
-
- public static String getLastMessageId(AccessToken accessToken) {
- return with()
- .header("Authorization", accessToken.asString())
- .body("[[\"getMessageList\", {\"sort\":[\"date desc\"]}, \"#0\"]]")
- .post("/jmap")
- .then()
- .extract()
- .body()
- .path(ARGUMENTS + ".messageIds[0]");
- }
-
- public static String getLatestMessageId(AccessToken accessToken, Role mailbox) {
- String mailboxId = getMailboxId(accessToken, mailbox);
- return with()
- .header("Authorization", accessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + mailboxId + "\"]}, \"sort\":[\"date desc\"]}, \"#0\"]]")
- .post("/jmap")
- .then()
- .extract()
- .path(ARGUMENTS + ".messageIds[0]");
- }
-
- public static String bodyOfMessage(AccessToken accessToken, String messageId) {
- return getMessageContent(accessToken, messageId)
- .get(ARGUMENTS + ".list[0].textBody");
- }
-
- public static List<String> receiversOfMessage(AccessToken accessToken, String messageId) {
- return getMessageContent(accessToken, messageId)
- .getList(ARGUMENTS + ".list[0].to.email");
- }
-
- private static JsonPath getMessageContent(AccessToken accessToken, String messageId) {
- return with()
- .header("Authorization", accessToken.asString())
- .body("[[\"getMessages\", {\"ids\": [\"" + messageId + "\"]}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messages"))
- .body(ARGUMENTS + ".list", hasSize(1))
- .extract()
- .jsonPath();
- }
-
- public static List<String> listMessageIdsInMailbox(AccessToken accessToken, String mailboxId) {
- return with()
- .header("Authorization", accessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + mailboxId + "\"]}}, \"#0\"]]")
- .post("/jmap")
- .then()
- .extract()
- .body()
- .path(ARGUMENTS + ".messageIds");
- }
-
- public static ResponseSpecification getSetMessagesUpdateOKResponseAssertions(String messageId) {
- ResponseSpecBuilder builder = new ResponseSpecBuilder()
- .expectStatusCode(200)
- .expectBody(NAME, equalTo("messagesSet"))
- .expectBody(ARGUMENTS + ".updated", hasSize(1))
- .expectBody(ARGUMENTS + ".updated", contains(messageId))
- .expectBody(ARGUMENTS + ".error", is(emptyOrNullString()))
- .expectBody(NOT_UPDATED, not(hasKey(messageId)));
- return builder.build();
- }
-
- public static void deleteMessages(AccessToken accessToken, List<String> idsToDestroy) {
- String idString = concatMessageIds(idsToDestroy);
-
- with()
- .header("Authorization", accessToken.asString())
- .body("[[\"setMessages\", {\"destroy\": [" + idString + "]}, \"#0\"]]")
- .post("/jmap");
- }
-
- public static String concatMessageIds(List<String> ids) {
- return ids.stream()
- .map(id -> "\"" + id + "\"")
- .collect(Collectors.joining(","));
- }
-}