Update profile controller to S3 AWSv2.

This commit is contained in:
Graeme Connell 2021-06-11 15:37:27 -06:00 committed by gram-signal
parent 42ff3f8432
commit 5d5c63e6d4
3 changed files with 31 additions and 14 deletions

View File

@ -10,8 +10,6 @@ import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.codahale.metrics.SharedMetricRegistries; import com.codahale.metrics.SharedMetricRegistries;
import com.codahale.metrics.jdbi3.strategies.DefaultNameStrategy; import com.codahale.metrics.jdbi3.strategies.DefaultNameStrategy;
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect;
@ -205,8 +203,14 @@ import org.whispersystems.textsecuregcm.workers.VacuumCommand;
import org.whispersystems.textsecuregcm.workers.ZkParamsCommand; import org.whispersystems.textsecuregcm.workers.ZkParamsCommand;
import org.whispersystems.websocket.WebSocketResourceProviderFactory; import org.whispersystems.websocket.WebSocketResourceProviderFactory;
import org.whispersystems.websocket.setup.WebSocketEnvironment; import org.whispersystems.websocket.setup.WebSocketEnvironment;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient; import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.s3.S3Client;
public class WhisperServerService extends Application<WhisperServerConfiguration> { public class WhisperServerService extends Application<WhisperServerConfiguration> {
@ -504,9 +508,14 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
environment.lifecycle().manage(torExitNodeManager); environment.lifecycle().manage(torExitNodeManager);
environment.lifecycle().manage(asnManager); environment.lifecycle().manage(asnManager);
AWSCredentials credentials = new BasicAWSCredentials(config.getCdnConfiguration().getAccessKey(), config.getCdnConfiguration().getAccessSecret()); StaticCredentialsProvider cdnCredentialsProvider = StaticCredentialsProvider
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials); .create(AwsBasicCredentials.create(
AmazonS3 cdnS3Client = AmazonS3Client.builder().withCredentials(credentialsProvider).withRegion(config.getCdnConfiguration().getRegion()).build(); config.getCdnConfiguration().getAccessKey(),
config.getCdnConfiguration().getAccessSecret()));
S3Client cdnS3Client = S3Client.builder()
.credentialsProvider(cdnCredentialsProvider)
.region(Region.of(config.getCdnConfiguration().getRegion()))
.build();
PostPolicyGenerator profileCdnPolicyGenerator = new PostPolicyGenerator(config.getCdnConfiguration().getRegion(), config.getCdnConfiguration().getBucket(), config.getCdnConfiguration().getAccessKey()); PostPolicyGenerator profileCdnPolicyGenerator = new PostPolicyGenerator(config.getCdnConfiguration().getRegion(), config.getCdnConfiguration().getBucket(), config.getCdnConfiguration().getAccessKey());
PolicySigner profileCdnPolicySigner = new PolicySigner(config.getCdnConfiguration().getAccessSecret(), config.getCdnConfiguration().getRegion()); PolicySigner profileCdnPolicySigner = new PolicySigner(config.getCdnConfiguration().getAccessSecret(), config.getCdnConfiguration().getRegion());

View File

@ -5,7 +5,6 @@
package org.whispersystems.textsecuregcm.controllers; package org.whispersystems.textsecuregcm.controllers;
import com.amazonaws.services.s3.AmazonS3;
import com.codahale.metrics.annotation.Timed; import com.codahale.metrics.annotation.Timed;
import io.dropwizard.auth.Auth; import io.dropwizard.auth.Auth;
import java.security.SecureRandom; import java.security.SecureRandom;
@ -60,6 +59,8 @@ import org.whispersystems.textsecuregcm.storage.VersionedProfile;
import org.whispersystems.textsecuregcm.util.ExactlySize; import org.whispersystems.textsecuregcm.util.ExactlySize;
import org.whispersystems.textsecuregcm.util.Pair; import org.whispersystems.textsecuregcm.util.Pair;
import org.whispersystems.textsecuregcm.util.Util; import org.whispersystems.textsecuregcm.util.Util;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType") @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Path("/v1/profile") @Path("/v1/profile")
@ -78,7 +79,7 @@ public class ProfileController {
private final ServerZkProfileOperations zkProfileOperations; private final ServerZkProfileOperations zkProfileOperations;
private final boolean isZkEnabled; private final boolean isZkEnabled;
private final AmazonS3 s3client; private final S3Client s3client;
private final String bucket; private final String bucket;
public ProfileController(RateLimiters rateLimiters, public ProfileController(RateLimiters rateLimiters,
@ -86,7 +87,7 @@ public class ProfileController {
ProfilesManager profilesManager, ProfilesManager profilesManager,
UsernamesManager usernamesManager, UsernamesManager usernamesManager,
DynamicConfigurationManager dynamicConfigurationManager, DynamicConfigurationManager dynamicConfigurationManager,
AmazonS3 s3client, S3Client s3client,
PostPolicyGenerator policyGenerator, PostPolicyGenerator policyGenerator,
PolicySigner policySigner, PolicySigner policySigner,
String bucket, String bucket,
@ -147,7 +148,10 @@ public class ProfileController {
currentAvatar = Optional.of(account.getAvatar()); currentAvatar = Optional.of(account.getAvatar());
} }
currentAvatar.ifPresent(s -> s3client.deleteObject(bucket, s)); currentAvatar.ifPresent(s -> s3client.deleteObject(DeleteObjectRequest.builder()
.bucket(bucket)
.key(s)
.build()));
response = Optional.of(generateAvatarUploadForm(avatar)); response = Optional.of(generateAvatarUploadForm(avatar));
} }
@ -372,7 +376,10 @@ public class ProfileController {
ProfileAvatarUploadAttributes profileAvatarUploadAttributes = generateAvatarUploadForm(objectName); ProfileAvatarUploadAttributes profileAvatarUploadAttributes = generateAvatarUploadForm(objectName);
if (previousAvatar != null && previousAvatar.startsWith("profiles/")) { if (previousAvatar != null && previousAvatar.startsWith("profiles/")) {
s3client.deleteObject(bucket, previousAvatar); s3client.deleteObject(DeleteObjectRequest.builder()
.bucket(bucket)
.key(previousAvatar)
.build());
} }
account.setAvatar(objectName); account.setAvatar(objectName);

View File

@ -18,7 +18,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import com.amazonaws.services.s3.AmazonS3;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule; import io.dropwizard.testing.junit.ResourceTestRule;
@ -61,6 +60,8 @@ import org.whispersystems.textsecuregcm.storage.VersionedProfile;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper; import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import org.whispersystems.textsecuregcm.util.SystemMapper; import org.whispersystems.textsecuregcm.util.SystemMapper;
import org.whispersystems.textsecuregcm.util.Util; import org.whispersystems.textsecuregcm.util.Util;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
public class ProfileControllerTest { public class ProfileControllerTest {
@ -71,7 +72,7 @@ public class ProfileControllerTest {
private static RateLimiter rateLimiter = mock(RateLimiter.class ); private static RateLimiter rateLimiter = mock(RateLimiter.class );
private static RateLimiter usernameRateLimiter = mock(RateLimiter.class ); private static RateLimiter usernameRateLimiter = mock(RateLimiter.class );
private static AmazonS3 s3client = mock(AmazonS3.class); private static S3Client s3client = mock(S3Client.class);
private static PostPolicyGenerator postPolicyGenerator = new PostPolicyGenerator("us-west-1", "profile-bucket", "accessKey"); private static PostPolicyGenerator postPolicyGenerator = new PostPolicyGenerator("us-west-1", "profile-bucket", "accessKey");
private static PolicySigner policySigner = new PolicySigner("accessSecret", "us-west-1"); private static PolicySigner policySigner = new PolicySigner("accessSecret", "us-west-1");
private static ServerZkProfileOperations zkProfileOperations = mock(ServerZkProfileOperations.class); private static ServerZkProfileOperations zkProfileOperations = mock(ServerZkProfileOperations.class);
@ -419,7 +420,7 @@ public class ProfileControllerTest {
verify(profilesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO), eq("validversion")); verify(profilesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO), eq("validversion"));
verify(profilesManager, times(1)).set(eq(AuthHelper.VALID_UUID_TWO), profileArgumentCaptor.capture()); verify(profilesManager, times(1)).set(eq(AuthHelper.VALID_UUID_TWO), profileArgumentCaptor.capture());
verify(s3client, times(1)).deleteObject(eq("profilesBucket"), eq("profiles/validavatar")); verify(s3client, times(1)).deleteObject(eq(DeleteObjectRequest.builder().bucket("profilesBucket").key("profiles/validavatar").build()));
assertThat(profileArgumentCaptor.getValue().getCommitment()).isEqualTo(commitment.serialize()); assertThat(profileArgumentCaptor.getValue().getCommitment()).isEqualTo(commitment.serialize());
assertThat(profileArgumentCaptor.getValue().getAvatar()).startsWith("profiles/"); assertThat(profileArgumentCaptor.getValue().getAvatar()).startsWith("profiles/");
@ -444,7 +445,7 @@ public class ProfileControllerTest {
verify(profilesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO), eq("validversion")); verify(profilesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO), eq("validversion"));
verify(profilesManager, times(1)).set(eq(AuthHelper.VALID_UUID_TWO), profileArgumentCaptor.capture()); verify(profilesManager, times(1)).set(eq(AuthHelper.VALID_UUID_TWO), profileArgumentCaptor.capture());
verify(s3client, times(1)).deleteObject(eq("profilesBucket"), eq("profiles/validavatar")); verify(s3client, times(1)).deleteObject(eq(DeleteObjectRequest.builder().bucket("profilesBucket").key("profiles/validavatar").build()));
assertThat(profileArgumentCaptor.getValue().getCommitment()).isEqualTo(commitment.serialize()); assertThat(profileArgumentCaptor.getValue().getCommitment()).isEqualTo(commitment.serialize());
assertThat(profileArgumentCaptor.getValue().getAvatar()).startsWith("profiles/"); assertThat(profileArgumentCaptor.getValue().getAvatar()).startsWith("profiles/");