Support for sticker pack uploads
This commit is contained in:
parent
0d46f85ead
commit
10724fee04
|
@ -51,7 +51,7 @@ public class WhisperServerConfiguration extends Configuration {
|
|||
@NotNull
|
||||
@Valid
|
||||
@JsonProperty
|
||||
private ProfilesConfiguration profiles;
|
||||
private CdnConfiguration cdn;
|
||||
|
||||
@NotNull
|
||||
@Valid
|
||||
|
@ -247,8 +247,8 @@ public class WhisperServerConfiguration extends Configuration {
|
|||
return apn;
|
||||
}
|
||||
|
||||
public ProfilesConfiguration getProfilesConfiguration() {
|
||||
return profiles;
|
||||
public CdnConfiguration getCdnConfiguration() {
|
||||
return cdn;
|
||||
}
|
||||
|
||||
public UnidentifiedDeliveryConfiguration getDeliveryCertificate() {
|
||||
|
|
|
@ -29,9 +29,9 @@ import org.jdbi.v3.core.Jdbi;
|
|||
import org.whispersystems.dispatch.DispatchManager;
|
||||
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
|
||||
import org.whispersystems.textsecuregcm.auth.CertificateGenerator;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
|
||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccountAuthenticator;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
|
||||
import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator;
|
||||
import org.whispersystems.textsecuregcm.controllers.AccountController;
|
||||
import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV1;
|
||||
|
@ -46,6 +46,7 @@ import org.whispersystems.textsecuregcm.controllers.ProfileController;
|
|||
import org.whispersystems.textsecuregcm.controllers.ProvisioningController;
|
||||
import org.whispersystems.textsecuregcm.controllers.SecureStorageController;
|
||||
import org.whispersystems.textsecuregcm.controllers.TransparentDataController;
|
||||
import org.whispersystems.textsecuregcm.controllers.StickerController;
|
||||
import org.whispersystems.textsecuregcm.controllers.VoiceVerificationController;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.liquibase.NameableMigrationsBundle;
|
||||
|
@ -244,7 +245,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
|||
AttachmentControllerV2 attachmentControllerV2 = new AttachmentControllerV2(rateLimiters, config.getAttachmentsConfiguration().getAccessKey(), config.getAttachmentsConfiguration().getAccessSecret(), config.getAttachmentsConfiguration().getRegion(), config.getAttachmentsConfiguration().getBucket());
|
||||
KeysController keysController = new KeysController(rateLimiters, keys, accountsManager, directoryQueue);
|
||||
MessageController messageController = new MessageController(rateLimiters, pushSender, receiptSender, accountsManager, messagesManager, apnFallbackManager);
|
||||
ProfileController profileController = new ProfileController(rateLimiters, accountsManager, config.getProfilesConfiguration());
|
||||
ProfileController profileController = new ProfileController(rateLimiters, accountsManager, config.getCdnConfiguration());
|
||||
StickerController stickerController = new StickerController(rateLimiters, config.getCdnConfiguration().getAccessKey(), config.getCdnConfiguration().getAccessSecret(), config.getCdnConfiguration().getRegion(), config.getCdnConfiguration().getBucket());
|
||||
|
||||
AuthFilter<BasicCredentials, Account> accountAuthFilter = new BasicCredentialAuthFilter.Builder<Account>().setAuthenticator(accountAuthenticator).buildAuthFilter ();
|
||||
AuthFilter<BasicCredentials, DisabledPermittedAccount> disabledPermittedAccountAuthFilter = new BasicCredentialAuthFilter.Builder<DisabledPermittedAccount>().setAuthenticator(disabledPermittedAccountAuthenticator).buildAuthFilter();
|
||||
|
@ -266,6 +268,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
|||
environment.jersey().register(keysController);
|
||||
environment.jersey().register(messageController);
|
||||
environment.jersey().register(profileController);
|
||||
environment.jersey().register(stickerController);
|
||||
|
||||
///
|
||||
WebSocketEnvironment webSocketEnvironment = new WebSocketEnvironment(environment, config.getWebSocketConfiguration(), 90000);
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.whispersystems.textsecuregcm.configuration;
|
|||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
|
||||
public class ProfilesConfiguration {
|
||||
public class CdnConfiguration {
|
||||
@NotEmpty
|
||||
@JsonProperty
|
||||
private String accessKey;
|
|
@ -68,6 +68,9 @@ public class RateLimitsConfiguration {
|
|||
@JsonProperty
|
||||
private RateLimitConfiguration profile = new RateLimitConfiguration(4320, 3);
|
||||
|
||||
@JsonProperty
|
||||
private RateLimitConfiguration stickerPack = new RateLimitConfiguration(50, 20 / (24.0 * 60.0));
|
||||
|
||||
public RateLimitConfiguration getAutoBlock() {
|
||||
return autoBlock;
|
||||
}
|
||||
|
@ -132,6 +135,10 @@ public class RateLimitsConfiguration {
|
|||
return profile;
|
||||
}
|
||||
|
||||
public RateLimitConfiguration getStickerPack() {
|
||||
return stickerPack;
|
||||
}
|
||||
|
||||
public static class RateLimitConfiguration {
|
||||
@JsonProperty
|
||||
private int bucketSize;
|
||||
|
|
|
@ -41,7 +41,7 @@ public class AttachmentControllerV2 extends AttachmentControllerBase {
|
|||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
long attachmentId = generateAttachmentId();
|
||||
String objectName = String.valueOf(attachmentId);
|
||||
Pair<String, String> policy = policyGenerator.createFor(now, String.valueOf(objectName));
|
||||
Pair<String, String> policy = policyGenerator.createFor(now, String.valueOf(objectName), 100 * 1024 * 1024);
|
||||
String signature = policySigner.getSignature(now, policy.second());
|
||||
|
||||
return new AttachmentDescriptorV2(attachmentId, objectName, policy.first(),
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.hibernate.validator.valuehandling.UnwrapValidatedValue;
|
|||
import org.whispersystems.textsecuregcm.auth.Anonymous;
|
||||
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
|
||||
import org.whispersystems.textsecuregcm.auth.UnidentifiedAccessChecksum;
|
||||
import org.whispersystems.textsecuregcm.configuration.ProfilesConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.CdnConfiguration;
|
||||
import org.whispersystems.textsecuregcm.entities.Profile;
|
||||
import org.whispersystems.textsecuregcm.entities.ProfileAvatarUploadAttributes;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
|
@ -55,7 +55,7 @@ public class ProfileController {
|
|||
|
||||
public ProfileController(RateLimiters rateLimiters,
|
||||
AccountsManager accountsManager,
|
||||
ProfilesConfiguration profilesConfiguration)
|
||||
CdnConfiguration profilesConfiguration)
|
||||
{
|
||||
AWSCredentials credentials = new BasicAWSCredentials(profilesConfiguration.getAccessKey(), profilesConfiguration.getAccessSecret());
|
||||
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
|
||||
|
@ -123,7 +123,7 @@ public class ProfileController {
|
|||
String previousAvatar = account.getAvatar();
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
String objectName = generateAvatarObjectName();
|
||||
Pair<String, String> policy = policyGenerator.createFor(now, objectName);
|
||||
Pair<String, String> policy = policyGenerator.createFor(now, objectName, 10 * 1024 * 1024);
|
||||
String signature = policySigner.getSignature(now, policy.second());
|
||||
|
||||
if (previousAvatar != null && previousAvatar.startsWith("profiles/")) {
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package org.whispersystems.textsecuregcm.controllers;
|
||||
|
||||
import org.whispersystems.textsecuregcm.entities.StickerPackFormUploadAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.StickerPackFormUploadAttributes.StickerPackFormUploadItem;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.s3.PolicySigner;
|
||||
import org.whispersystems.textsecuregcm.s3.PostPolicyGenerator;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.util.Hex;
|
||||
import org.whispersystems.textsecuregcm.util.Pair;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
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 java.security.SecureRandom;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import io.dropwizard.auth.Auth;
|
||||
|
||||
@Path("/v1/sticker")
|
||||
public class StickerController {
|
||||
|
||||
private final RateLimiters rateLimiters;
|
||||
private final PolicySigner policySigner;
|
||||
private final PostPolicyGenerator policyGenerator;
|
||||
|
||||
public StickerController(RateLimiters rateLimiters, String accessKey, String accessSecret, String region, String bucket) {
|
||||
this.rateLimiters = rateLimiters;
|
||||
this.policySigner = new PolicySigner(accessSecret, region);
|
||||
this.policyGenerator = new PostPolicyGenerator(region, bucket, accessKey);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/pack/form/{count}")
|
||||
public StickerPackFormUploadAttributes getStickersForm(@Auth Account account,
|
||||
@PathParam("count") @Min(1) @Max(50) int stickerCount)
|
||||
throws RateLimitExceededException
|
||||
{
|
||||
rateLimiters.getStickerPackLimiter().validate(account.getNumber());
|
||||
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
String packId = generatePackId();
|
||||
String packLocation = "stickers/" + packId;
|
||||
String manifestKey = packLocation + "/manifest.proto";
|
||||
Pair<String, String> manifestPolicy = policyGenerator.createFor(now, manifestKey, 1024);
|
||||
String manifestSignature = policySigner.getSignature(now, manifestPolicy.second());
|
||||
StickerPackFormUploadItem manifest = new StickerPackFormUploadItem(-1, manifestKey, manifestPolicy.first(), "private", "AWS4-HMAC-SHA256",
|
||||
now.format(PostPolicyGenerator.AWS_DATE_TIME), manifestPolicy.second(), manifestSignature);
|
||||
|
||||
|
||||
List<StickerPackFormUploadItem> stickers = new LinkedList<>();
|
||||
|
||||
for (int i=0;i<stickerCount;i++) {
|
||||
String stickerKey = packLocation + "/full/" + i;
|
||||
Pair<String, String> stickerPolicy = policyGenerator.createFor(now, stickerKey, 100155);
|
||||
String stickerSignature = policySigner.getSignature(now, stickerPolicy.second());
|
||||
stickers.add(new StickerPackFormUploadItem(i, stickerKey, stickerPolicy.first(), "private", "AWS4-HMAC-SHA256",
|
||||
now.format(PostPolicyGenerator.AWS_DATE_TIME), stickerPolicy.second(), stickerSignature));
|
||||
}
|
||||
|
||||
return new StickerPackFormUploadAttributes(packId, manifest, stickers);
|
||||
}
|
||||
|
||||
private String generatePackId() {
|
||||
byte[] object = new byte[16];
|
||||
new SecureRandom().nextBytes(object);
|
||||
|
||||
return Hex.toStringCondensed(object);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StickerPackFormUploadAttributes {
|
||||
|
||||
@JsonProperty
|
||||
private StickerPackFormUploadItem manifest;
|
||||
|
||||
@JsonProperty
|
||||
private List<StickerPackFormUploadItem> stickers;
|
||||
|
||||
@JsonProperty
|
||||
private String packId;
|
||||
|
||||
public StickerPackFormUploadAttributes() {}
|
||||
|
||||
public StickerPackFormUploadAttributes(String packId, StickerPackFormUploadItem manifest, List<StickerPackFormUploadItem> stickers) {
|
||||
this.packId = packId;
|
||||
this.manifest = manifest;
|
||||
this.stickers = stickers;
|
||||
}
|
||||
|
||||
public StickerPackFormUploadItem getManifest() {
|
||||
return manifest;
|
||||
}
|
||||
|
||||
public List<StickerPackFormUploadItem> getStickers() {
|
||||
return stickers;
|
||||
}
|
||||
|
||||
public String getPackId() {
|
||||
return packId;
|
||||
}
|
||||
|
||||
public static class StickerPackFormUploadItem {
|
||||
@JsonProperty
|
||||
private int id;
|
||||
|
||||
@JsonProperty
|
||||
private String key;
|
||||
|
||||
@JsonProperty
|
||||
private String credential;
|
||||
|
||||
@JsonProperty
|
||||
private String acl;
|
||||
|
||||
@JsonProperty
|
||||
private String algorithm;
|
||||
|
||||
@JsonProperty
|
||||
private String date;
|
||||
|
||||
@JsonProperty
|
||||
private String policy;
|
||||
|
||||
@JsonProperty
|
||||
private String signature;
|
||||
|
||||
public StickerPackFormUploadItem() {}
|
||||
|
||||
public StickerPackFormUploadItem(int id, String key, String credential, String acl, String algorithm, String date, String policy, String signature) {
|
||||
this.key = key;
|
||||
this.credential = credential;
|
||||
this.acl = acl;
|
||||
this.algorithm = algorithm;
|
||||
this.date = date;
|
||||
this.policy = policy;
|
||||
this.signature = signature;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getCredential() {
|
||||
return credential;
|
||||
}
|
||||
|
||||
public String getAcl() {
|
||||
return acl;
|
||||
}
|
||||
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public String getPolicy() {
|
||||
return policy;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -42,6 +42,7 @@ public class RateLimiters {
|
|||
private final RateLimiter turnLimiter;
|
||||
|
||||
private final RateLimiter profileLimiter;
|
||||
private final RateLimiter stickerPackLimiter;
|
||||
|
||||
public RateLimiters(RateLimitsConfiguration config, ReplicatedJedisPool cacheClient) {
|
||||
this.smsDestinationLimiter = new RateLimiter(cacheClient, "smsDestination",
|
||||
|
@ -107,6 +108,10 @@ public class RateLimiters {
|
|||
this.profileLimiter = new RateLimiter(cacheClient, "profile",
|
||||
config.getProfile().getBucketSize(),
|
||||
config.getProfile().getLeakRatePerMinute());
|
||||
|
||||
this.stickerPackLimiter = new RateLimiter(cacheClient, "stickerPack",
|
||||
config.getStickerPack().getBucketSize(),
|
||||
config.getStickerPack().getLeakRatePerMinute());
|
||||
}
|
||||
|
||||
public RateLimiter getAllocateDeviceLimiter() {
|
||||
|
@ -173,4 +178,8 @@ public class RateLimiters {
|
|||
return profileLimiter;
|
||||
}
|
||||
|
||||
public RateLimiter getStickerPackLimiter() {
|
||||
return stickerPackLimiter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public class PostPolicyGenerator {
|
|||
this.awsAccessId = awsAccessId;
|
||||
}
|
||||
|
||||
public Pair<String, String> createFor(ZonedDateTime now, String object) {
|
||||
public Pair<String, String> createFor(ZonedDateTime now, String object, int maxSizeInBytes) {
|
||||
try {
|
||||
String expiration = now.plusMinutes(30).format(DateTimeFormatter.ISO_INSTANT);
|
||||
String credentialDate = now.format(CREDENTIAL_DATE);
|
||||
|
@ -35,7 +35,7 @@ public class PostPolicyGenerator {
|
|||
" {\"key\": \"%s\"},\n" +
|
||||
" {\"acl\": \"private\"},\n" +
|
||||
" [\"starts-with\", \"$Content-Type\", \"\"],\n" +
|
||||
" [\"content-length-range\", 1, 104857600],\n" +
|
||||
" [\"content-length-range\", 1, " + maxSizeInBytes + "],\n" +
|
||||
"\n" +
|
||||
" {\"x-amz-credential\": \"%s\"},\n" +
|
||||
" {\"x-amz-algorithm\": \"AWS4-HMAC-SHA256\"},\n" +
|
||||
|
|
|
@ -14,9 +14,11 @@ import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
|||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
import org.whispersystems.textsecuregcm.util.SystemMapper;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
|
||||
|
@ -45,7 +47,7 @@ public class AttachmentControllerTest {
|
|||
.build();
|
||||
|
||||
@Test
|
||||
public void testV2Form() {
|
||||
public void testV2Form() throws IOException {
|
||||
AttachmentDescriptorV2 descriptor = resources.getJerseyTest()
|
||||
.target("/v2/attachments/form/upload")
|
||||
.request()
|
||||
|
@ -68,6 +70,8 @@ public class AttachmentControllerTest {
|
|||
assertThat(descriptor.getDate()).isNotBlank();
|
||||
assertThat(descriptor.getPolicy()).isNotBlank();
|
||||
assertThat(descriptor.getSignature()).isNotBlank();
|
||||
|
||||
assertThat(new String(Base64.decode(descriptor.getPolicy()))).contains("[\"content-length-range\", 1, 104857600]");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.junit.Before;
|
|||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
|
||||
import org.whispersystems.textsecuregcm.configuration.ProfilesConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.CdnConfiguration;
|
||||
import org.whispersystems.textsecuregcm.controllers.ProfileController;
|
||||
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
|
||||
import org.whispersystems.textsecuregcm.entities.Profile;
|
||||
|
@ -30,7 +30,7 @@ public class ProfileControllerTest {
|
|||
private static AccountsManager accountsManager = mock(AccountsManager.class );
|
||||
private static RateLimiters rateLimiters = mock(RateLimiters.class );
|
||||
private static RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
private static ProfilesConfiguration configuration = mock(ProfilesConfiguration.class);
|
||||
private static CdnConfiguration configuration = mock(CdnConfiguration.class);
|
||||
|
||||
static {
|
||||
when(configuration.getAccessKey()).thenReturn("accessKey");
|
||||
|
@ -80,7 +80,7 @@ public class ProfileControllerTest {
|
|||
|
||||
verify(accountsManager, times(1)).get(AuthHelper.VALID_NUMBER_TWO);
|
||||
verify(rateLimiters, times(1)).getProfileLimiter();
|
||||
verify(rateLimiter, times(1)).validate(AuthHelper.VALID_NUMBER);
|
||||
verify(rateLimiter, times(1)).validate(eq(AuthHelper.VALID_NUMBER));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
|
||||
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
|
||||
import org.whispersystems.textsecuregcm.controllers.StickerController;
|
||||
import org.whispersystems.textsecuregcm.entities.StickerPackFormUploadAttributes;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
import org.whispersystems.textsecuregcm.util.SystemMapper;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
|
||||
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class StickerControllerTest {
|
||||
|
||||
private static RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
private static RateLimiters rateLimiters = mock(RateLimiters.class);
|
||||
|
||||
@ClassRule
|
||||
public static final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
|
||||
.setMapper(SystemMapper.getMapper())
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new StickerController(rateLimiters, "foo", "bar", "us-east-1", "mybucket"))
|
||||
.build();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(rateLimiters.getStickerPackLimiter()).thenReturn(rateLimiter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatePack() throws RateLimitExceededException, IOException {
|
||||
StickerPackFormUploadAttributes attributes = resources.getJerseyTest()
|
||||
.target("/v1/sticker/pack/form/10")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
|
||||
.get(StickerPackFormUploadAttributes.class);
|
||||
|
||||
assertThat(attributes.getPackId()).isNotNull();
|
||||
assertThat(attributes.getPackId().length()).isEqualTo(32);
|
||||
|
||||
assertThat(attributes.getManifest()).isNotNull();
|
||||
assertThat(attributes.getManifest().getKey()).isEqualTo("stickers/" + attributes.getPackId() + "/manifest.proto");
|
||||
assertThat(attributes.getManifest().getAcl()).isEqualTo("private");
|
||||
assertThat(attributes.getManifest().getPolicy()).isNotEmpty();
|
||||
assertThat(new String(Base64.decode(attributes.getManifest().getPolicy()))).contains("[\"content-length-range\", 1, 1024]");
|
||||
assertThat(attributes.getManifest().getSignature()).isNotEmpty();
|
||||
assertThat(attributes.getManifest().getAlgorithm()).isEqualTo("AWS4-HMAC-SHA256");
|
||||
assertThat(attributes.getManifest().getCredential()).isNotEmpty();
|
||||
assertThat(attributes.getManifest().getId()).isEqualTo(-1);
|
||||
|
||||
assertThat(attributes.getStickers().size()).isEqualTo(10);
|
||||
|
||||
for (int i=0;i<10;i++) {
|
||||
assertThat(attributes.getStickers().get(i).getId()).isEqualTo(i);
|
||||
assertThat(attributes.getStickers().get(i).getKey()).isEqualTo("stickers/" + attributes.getPackId() + "/full/" + i);
|
||||
assertThat(attributes.getStickers().get(i).getAcl()).isEqualTo("private");
|
||||
assertThat(attributes.getStickers().get(i).getPolicy()).isNotEmpty();
|
||||
assertThat(new String(Base64.decode(attributes.getStickers().get(i).getPolicy()))).contains("[\"content-length-range\", 1, 100155]");
|
||||
assertThat(attributes.getStickers().get(i).getSignature()).isNotEmpty();
|
||||
assertThat(attributes.getStickers().get(i).getAlgorithm()).isEqualTo("AWS4-HMAC-SHA256");
|
||||
assertThat(attributes.getStickers().get(i).getCredential()).isNotEmpty();
|
||||
}
|
||||
|
||||
verify(rateLimiters, times(1)).getStickerPackLimiter();
|
||||
verify(rateLimiter, times(1)).validate(eq(AuthHelper.VALID_NUMBER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTooLargePack() throws Exception {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target("/v1/sticker/pack/form/51")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
|
||||
.get();
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(400);
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue