diff --git a/service/pom.xml b/service/pom.xml
index 9b28b4f9e..c9d7eb1be 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -289,10 +289,6 @@
com.amazonaws
aws-java-sdk-core
-
- com.amazonaws
- aws-java-sdk-s3
-
com.amazonaws
dynamodb-lock-client
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
index 000c32f7f..f7c671ada 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
@@ -80,7 +80,6 @@ import org.whispersystems.textsecuregcm.badges.ResourceBundleLevelTranslator;
import org.whispersystems.textsecuregcm.configuration.DirectoryServerConfiguration;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import org.whispersystems.textsecuregcm.controllers.AccountController;
-import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV1;
import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV2;
import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV3;
import org.whispersystems.textsecuregcm.controllers.CertificateController;
@@ -136,7 +135,6 @@ import org.whispersystems.textsecuregcm.metrics.MicrometerRegistryManager;
import org.whispersystems.textsecuregcm.metrics.NetworkReceivedGauge;
import org.whispersystems.textsecuregcm.metrics.NetworkSentGauge;
import org.whispersystems.textsecuregcm.metrics.OperatingSystemMemoryGauge;
-import org.whispersystems.textsecuregcm.push.PushLatencyManager;
import org.whispersystems.textsecuregcm.metrics.ReportedMessageMetricsListener;
import org.whispersystems.textsecuregcm.metrics.TrafficSource;
import org.whispersystems.textsecuregcm.providers.MultiRecipientMessageProvider;
@@ -148,6 +146,7 @@ import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
import org.whispersystems.textsecuregcm.push.FcmSender;
import org.whispersystems.textsecuregcm.push.MessageSender;
import org.whispersystems.textsecuregcm.push.ProvisioningManager;
+import org.whispersystems.textsecuregcm.push.PushLatencyManager;
import org.whispersystems.textsecuregcm.push.PushNotificationManager;
import org.whispersystems.textsecuregcm.push.ReceiptSender;
import org.whispersystems.textsecuregcm.recaptcha.RecaptchaClient;
@@ -632,7 +631,6 @@ public class WhisperServerService extends Application commonControllers = Lists.newArrayList(
- new AttachmentControllerV1(rateLimiters, config.getAwsAttachmentsConfiguration().getAccessKey(), config.getAwsAttachmentsConfiguration().getAccessSecret(), config.getAwsAttachmentsConfiguration().getBucket()),
new AttachmentControllerV2(rateLimiters, config.getAwsAttachmentsConfiguration().getAccessKey(), config.getAwsAttachmentsConfiguration().getAccessSecret(), config.getAwsAttachmentsConfiguration().getRegion(), config.getAwsAttachmentsConfiguration().getBucket()),
new AttachmentControllerV3(rateLimiters, config.getGcpAttachmentsConfiguration().getDomain(), config.getGcpAttachmentsConfiguration().getEmail(), config.getGcpAttachmentsConfiguration().getMaxSizeInBytes(), config.getGcpAttachmentsConfiguration().getPathPrefix(), config.getGcpAttachmentsConfiguration().getRsaSigningKey()),
new CertificateController(new CertificateGenerator(config.getDeliveryCertificate().getCertificate(), config.getDeliveryCertificate().getPrivateKey(), config.getDeliveryCertificate().getExpiresDays()), zkAuthOperations, clock),
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerBase.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerBase.java
deleted file mode 100644
index 81286e624..000000000
--- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerBase.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2013-2020 Signal Messenger, LLC
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-
-package org.whispersystems.textsecuregcm.controllers;
-
-import org.whispersystems.textsecuregcm.util.Conversions;
-
-import java.security.SecureRandom;
-
-public class AttachmentControllerBase {
-
- protected long generateAttachmentId() {
- byte[] attachmentBytes = new byte[8];
- new SecureRandom().nextBytes(attachmentBytes);
-
- attachmentBytes[0] = (byte)(attachmentBytes[0] & 0x7F);
- return Conversions.byteArrayToLong(attachmentBytes);
- }
-
-}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV1.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV1.java
deleted file mode 100644
index 4ffc65cd0..000000000
--- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV1.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2013-2021 Signal Messenger, LLC
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-package org.whispersystems.textsecuregcm.controllers;
-
-import com.amazonaws.HttpMethod;
-import com.codahale.metrics.annotation.Timed;
-import io.dropwizard.auth.Auth;
-import java.net.URL;
-import java.util.stream.Stream;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
-import org.whispersystems.textsecuregcm.entities.AttachmentDescriptorV1;
-import org.whispersystems.textsecuregcm.entities.AttachmentUri;
-import org.whispersystems.textsecuregcm.limits.RateLimiters;
-import org.whispersystems.textsecuregcm.s3.UrlSigner;
-
-
-@Path("/v1/attachments")
-public class AttachmentControllerV1 extends AttachmentControllerBase {
-
- @SuppressWarnings("unused")
- private final Logger logger = LoggerFactory.getLogger(AttachmentControllerV1.class);
-
- private static final String[] UNACCELERATED_REGIONS = {"+20", "+971", "+968", "+974"};
-
- private final RateLimiters rateLimiters;
- private final UrlSigner urlSigner;
-
- public AttachmentControllerV1(RateLimiters rateLimiters, String accessKey, String accessSecret, String bucket) {
- this.rateLimiters = rateLimiters;
- this.urlSigner = new UrlSigner(accessKey, accessSecret, bucket);
- }
-
- @Timed
- @GET
- @Produces(MediaType.APPLICATION_JSON)
- public AttachmentDescriptorV1 allocateAttachment(@Auth AuthenticatedAccount auth) throws RateLimitExceededException {
-
- rateLimiters.getAttachmentLimiter().validate(auth.getAccount().getUuid());
-
- long attachmentId = generateAttachmentId();
- URL url = urlSigner.getPreSignedUrl(attachmentId, HttpMethod.PUT,
- Stream.of(UNACCELERATED_REGIONS).anyMatch(region -> auth.getAccount().getNumber().startsWith(region)));
-
- return new AttachmentDescriptorV1(attachmentId, url.toExternalForm());
- }
-
- @Timed
- @GET
- @Produces(MediaType.APPLICATION_JSON)
- @Path("/{attachmentId}")
- public AttachmentUri redirectToAttachment(@Auth AuthenticatedAccount auth,
- @PathParam("attachmentId") long attachmentId) {
- return new AttachmentUri(urlSigner.getPreSignedUrl(attachmentId, HttpMethod.GET,
- Stream.of(UNACCELERATED_REGIONS).anyMatch(region -> auth.getAccount().getNumber().startsWith(region))));
- }
-
-}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV2.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV2.java
index 09dd37be9..b0d5021af 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV2.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV2.java
@@ -7,6 +7,7 @@ package org.whispersystems.textsecuregcm.controllers;
import com.codahale.metrics.annotation.Timed;
import io.dropwizard.auth.Auth;
+import java.security.SecureRandom;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import javax.ws.rs.GET;
@@ -19,19 +20,21 @@ import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.s3.PolicySigner;
import org.whispersystems.textsecuregcm.s3.PostPolicyGenerator;
+import org.whispersystems.textsecuregcm.util.Conversions;
import org.whispersystems.textsecuregcm.util.Pair;
@Path("/v2/attachments")
-public class AttachmentControllerV2 extends AttachmentControllerBase {
+public class AttachmentControllerV2 {
private final PostPolicyGenerator policyGenerator;
- private final PolicySigner policySigner;
- private final RateLimiter rateLimiter;
+ private final PolicySigner policySigner;
+ private final RateLimiter rateLimiter;
- public AttachmentControllerV2(RateLimiters rateLimiters, String accessKey, String accessSecret, String region, String bucket) {
- this.rateLimiter = rateLimiters.getAttachmentLimiter();
- this.policyGenerator = new PostPolicyGenerator(region, bucket, accessKey);
- this.policySigner = new PolicySigner(accessSecret, region);
+ public AttachmentControllerV2(RateLimiters rateLimiters, String accessKey, String accessSecret, String region,
+ String bucket) {
+ this.rateLimiter = rateLimiters.getAttachmentLimiter();
+ this.policyGenerator = new PostPolicyGenerator(region, bucket, accessKey);
+ this.policySigner = new PolicySigner(accessSecret, region);
}
@Timed
@@ -54,5 +57,12 @@ public class AttachmentControllerV2 extends AttachmentControllerBase {
policy.second(), signature);
}
+ private long generateAttachmentId() {
+ byte[] attachmentBytes = new byte[8];
+ new SecureRandom().nextBytes(attachmentBytes);
+
+ attachmentBytes[0] = (byte) (attachmentBytes[0] & 0x7F);
+ return Conversions.byteArrayToLong(attachmentBytes);
+ }
}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV3.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV3.java
index 631730420..cb54b22dc 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV3.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AttachmentControllerV3.java
@@ -29,7 +29,7 @@ import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
@Path("/v3/attachments")
-public class AttachmentControllerV3 extends AttachmentControllerBase {
+public class AttachmentControllerV3 {
@Nonnull
private final RateLimiter rateLimiter;
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/entities/AttachmentDescriptorV1.java b/service/src/main/java/org/whispersystems/textsecuregcm/entities/AttachmentDescriptorV1.java
deleted file mode 100644
index b014e2071..000000000
--- a/service/src/main/java/org/whispersystems/textsecuregcm/entities/AttachmentDescriptorV1.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2013-2020 Signal Messenger, LLC
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-package org.whispersystems.textsecuregcm.entities;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class AttachmentDescriptorV1 {
-
- @JsonProperty
- private long id;
-
- @JsonProperty
- private String idString;
-
- @JsonProperty
- private String location;
-
- public AttachmentDescriptorV1(long id, String location) {
- this.id = id;
- this.idString = String.valueOf(id);
- this.location = location;
- }
-
- public AttachmentDescriptorV1() {}
-
- public long getId() {
- return id;
- }
-
- public String getLocation() {
- return location;
- }
-
- public String getIdString() {
- return idString;
- }
-}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/s3/UrlSigner.java b/service/src/main/java/org/whispersystems/textsecuregcm/s3/UrlSigner.java
deleted file mode 100644
index 34c6fd1b5..000000000
--- a/service/src/main/java/org/whispersystems/textsecuregcm/s3/UrlSigner.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2013-2020 Signal Messenger, LLC
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-package org.whispersystems.textsecuregcm.s3;
-
-import com.amazonaws.HttpMethod;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.BasicAWSCredentials;
-import com.amazonaws.services.s3.AmazonS3;
-import com.amazonaws.services.s3.AmazonS3Client;
-import com.amazonaws.services.s3.S3ClientOptions;
-import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
-
-import java.net.URL;
-import java.util.Date;
-
-public class UrlSigner {
-
- private static final long DURATION = 60 * 60 * 1000;
-
- private final AWSCredentials credentials;
- private final String bucket;
-
- public UrlSigner(String accessKey, String accessSecret, String bucket) {
- this.credentials = new BasicAWSCredentials(accessKey, accessSecret);
- this.bucket = bucket;
- }
-
- public URL getPreSignedUrl(long attachmentId, HttpMethod method, boolean unaccelerated) {
- AmazonS3 client = new AmazonS3Client(credentials);
- GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, String.valueOf(attachmentId), method);
-
- request.setExpiration(new Date(System.currentTimeMillis() + DURATION));
- request.setContentType("application/octet-stream");
-
- if (unaccelerated) {
- client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build());
- } else {
- client.setS3ClientOptions(S3ClientOptions.builder().setAccelerateModeEnabled(true).build());
- }
-
- return client.generatePresignedUrl(request);
- }
-
-}
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AttachmentControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AttachmentControllerTest.java
index c52740eb8..5e7ecb85c 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AttachmentControllerTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AttachmentControllerTest.java
@@ -35,13 +35,10 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
-import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV1;
import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV2;
import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV3;
-import org.whispersystems.textsecuregcm.entities.AttachmentDescriptorV1;
import org.whispersystems.textsecuregcm.entities.AttachmentDescriptorV2;
import org.whispersystems.textsecuregcm.entities.AttachmentDescriptorV3;
-import org.whispersystems.textsecuregcm.entities.AttachmentUri;
import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
@@ -83,7 +80,6 @@ class AttachmentControllerTest {
ImmutableSet.of(AuthenticatedAccount.class, DisabledPermittedAuthenticatedAccount.class)))
.setMapper(SystemMapper.getMapper())
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
- .addResource(new AttachmentControllerV1(rateLimiters, "accessKey", "accessSecret", "attachment-bucket"))
.addResource(new AttachmentControllerV2(rateLimiters, "accessKey", "accessSecret", "us-east-1", "attachmentv2-bucket"))
.addResource(new AttachmentControllerV3(rateLimiters, "some-cdn.signal.org", "signal@example.com", 1000, "/attach-here", RSA_PRIVATE_KEY_PEM))
.build();
@@ -198,53 +194,4 @@ class AttachmentControllerTest {
assertThat(response.getStatus()).isEqualTo(401);
}
-
- @Test
- void testAcceleratedPut() {
- AttachmentDescriptorV1 descriptor = resources.getJerseyTest()
- .target("/v1/attachments/")
- .request()
- .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
- .get(AttachmentDescriptorV1.class);
-
- assertThat(descriptor.getLocation()).startsWith("https://attachment-bucket.s3-accelerate.amazonaws.com");
- assertThat(descriptor.getId()).isGreaterThan(0);
- assertThat(descriptor.getIdString()).isNotBlank();
- }
-
- @Test
- void testUnacceleratedPut() {
- AttachmentDescriptorV1 descriptor = resources.getJerseyTest()
- .target("/v1/attachments/")
- .request()
- .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
- .get(AttachmentDescriptorV1.class);
-
- assertThat(descriptor.getLocation()).startsWith("https://s3.amazonaws.com");
- assertThat(descriptor.getId()).isGreaterThan(0);
- assertThat(descriptor.getIdString()).isNotBlank();
- }
-
- @Test
- void testAcceleratedGet() throws MalformedURLException {
- AttachmentUri uri = resources.getJerseyTest()
- .target("/v1/attachments/1234")
- .request()
- .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
- .get(AttachmentUri.class);
-
- assertThat(uri.getLocation().getHost()).isEqualTo("attachment-bucket.s3-accelerate.amazonaws.com");
- }
-
- @Test
- void testUnacceleratedGet() throws MalformedURLException {
- AttachmentUri uri = resources.getJerseyTest()
- .target("/v1/attachments/1234")
- .request()
- .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
- .get(AttachmentUri.class);
-
- assertThat(uri.getLocation().getHost()).isEqualTo("s3.amazonaws.com");
- }
-
}
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/UrlSignerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/UrlSignerTest.java
deleted file mode 100644
index 51e28b716..000000000
--- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/UrlSignerTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2013-2020 Signal Messenger, LLC
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-
-package org.whispersystems.textsecuregcm.tests.util;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import com.amazonaws.HttpMethod;
-import java.net.URL;
-import org.junit.jupiter.api.Test;
-import org.whispersystems.textsecuregcm.s3.UrlSigner;
-
-class UrlSignerTest {
-
- @Test
- void testTransferAcceleration() {
- UrlSigner signer = new UrlSigner("foo", "bar", "attachments-test");
- URL url = signer.getPreSignedUrl(1234, HttpMethod.GET, false);
-
- assertThat(url).hasHost("attachments-test.s3-accelerate.amazonaws.com");
- }
-
- @Test
- void testTransferUnaccelerated() {
- UrlSigner signer = new UrlSigner("foo", "bar", "attachments-test");
- URL url = signer.getPreSignedUrl(1234, HttpMethod.GET, true);
-
- assertThat(url).hasHost("s3.amazonaws.com");
- }
-
-}