package org.activityinfo.service.blob;
import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import com.google.common.base.Charsets;
import com.google.common.collect.Maps;
import com.google.common.io.BaseEncoding;
import org.joda.time.Period;
import java.util.Map;
/**
* @see <a href="https://developers.google.com/storage/docs/reference-methods?csw=1#postobject">GCS Docs</a>
*/
public class GcsUploadCredentialBuilder {
private static final String STATUS_CODE = "201";
private static final String END_POINT_URL_FORMAT = "https://%s.storage.googleapis.com";
public static final int BYTES_IN_MEGA_BYTE = 1024 * 1024;
private final GcsPolicyBuilder policyDocument;
private final Map<String, String> formFields;
private final AppIdentityService identityService;
public GcsUploadCredentialBuilder() {
this(AppIdentityServiceFactory.getAppIdentityService());
}
public GcsUploadCredentialBuilder(AppIdentityService identityService) {
this.policyDocument = new GcsPolicyBuilder();
this.formFields = Maps.newHashMap();
this.identityService = identityService;
policyDocument.successActionStatusMustBe(STATUS_CODE);
}
/**
*
* @param bucketName The name of the bucket that you want to upload to.
*/
public GcsUploadCredentialBuilder setBucket(String bucketName) {
policyDocument.bucketNameMustEqual(bucketName);
formFields.put("bucket", bucketName);
return this;
}
public GcsUploadCredentialBuilder setKey(String objectKey) {
policyDocument.keyMustEqual(objectKey);
formFields.put("key", objectKey);
return this;
}
public GcsUploadCredentialBuilder setMaxContentLength(long maxBytes) {
policyDocument.contentLengthMustBeBetween(0, maxBytes);
return this;
}
public GcsUploadCredentialBuilder setMaxContentLengthInMegabytes(int megabytes) {
return setMaxContentLength(megabytes * BYTES_IN_MEGA_BYTE);
}
public GcsUploadCredentialBuilder expireAfter(Period period) {
policyDocument.expiresAfter(period.toStandardDuration());
return this;
}
public UploadCredentials build() {
byte[] policy = policyDocument.toJsonBytes();
String encodedPolicy = BaseEncoding.base64().encode(policy);
AppIdentityService.SigningResult signature = identityService.signForApp(encodedPolicy.getBytes(Charsets.UTF_8));
formFields.put("GoogleAccessId", identityService.getServiceAccountName());
formFields.put("policy", encodedPolicy);
formFields.put("signature", BaseEncoding.base64().encode(signature.getSignature()));
formFields.put("success_action_status", STATUS_CODE);
return new UploadCredentials(String.format(END_POINT_URL_FORMAT, formFields.get("bucket")), "POST", formFields);
}
}