use of com.google.auth.ServiceAccountSigner in project java-storage by googleapis.
the class StorageImpl method generateSignedPostPolicyV4.
@Override
public PostPolicyV4 generateSignedPostPolicyV4(BlobInfo blobInfo, long duration, TimeUnit unit, PostFieldsV4 fields, PostConditionsV4 conditions, PostPolicyV4Option... options) {
EnumMap<SignUrlOption.Option, Object> optionMap = Maps.newEnumMap(SignUrlOption.Option.class);
// Convert to a map of SignUrlOptions so we can re-use some utility methods
for (PostPolicyV4Option option : options) {
optionMap.put(SignUrlOption.Option.valueOf(option.getOption().name()), option.getValue());
}
optionMap.put(SignUrlOption.Option.SIGNATURE_VERSION, SignUrlOption.SignatureVersion.V4);
ServiceAccountSigner credentials = (ServiceAccountSigner) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED);
if (credentials == null) {
checkState(this.getOptions().getCredentials() instanceof ServiceAccountSigner, "Signing key was not provided and could not be derived");
credentials = (ServiceAccountSigner) this.getOptions().getCredentials();
}
checkArgument(!(optionMap.containsKey(SignUrlOption.Option.VIRTUAL_HOSTED_STYLE) && optionMap.containsKey(SignUrlOption.Option.PATH_STYLE) && optionMap.containsKey(SignUrlOption.Option.BUCKET_BOUND_HOST_NAME)), "Only one of VIRTUAL_HOSTED_STYLE, PATH_STYLE, or BUCKET_BOUND_HOST_NAME SignUrlOptions can be" + " specified.");
String bucketName = slashlessBucketNameFromBlobInfo(blobInfo);
boolean usePathStyle = shouldUsePathStyleForSignedUrl(optionMap);
String url;
if (usePathStyle) {
url = STORAGE_XML_URI_SCHEME + "://" + STORAGE_XML_URI_HOST_NAME + "/" + bucketName + "/";
} else {
url = STORAGE_XML_URI_SCHEME + "://" + bucketName + "." + STORAGE_XML_URI_HOST_NAME + "/";
}
if (optionMap.containsKey(SignUrlOption.Option.BUCKET_BOUND_HOST_NAME)) {
url = optionMap.get(SignUrlOption.Option.BUCKET_BOUND_HOST_NAME) + "/";
}
SimpleDateFormat googDateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
SimpleDateFormat yearMonthDayFormat = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat expirationFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
googDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
yearMonthDayFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
expirationFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
long timestamp = getOptions().getClock().millisTime();
String date = googDateFormat.format(timestamp);
String signingCredential = credentials.getAccount() + "/" + yearMonthDayFormat.format(timestamp) + "/auto/storage/goog4_request";
Map<String, String> policyFields = new HashMap<>();
PostConditionsV4.Builder conditionsBuilder = conditions.toBuilder();
for (Map.Entry<String, String> entry : fields.getFieldsMap().entrySet()) {
// Every field needs a corresponding policy condition, so add them if they're missing
conditionsBuilder.addCustomCondition(ConditionV4Type.MATCHES, entry.getKey(), entry.getValue());
policyFields.put(entry.getKey(), entry.getValue());
}
PostConditionsV4 v4Conditions = conditionsBuilder.addBucketCondition(ConditionV4Type.MATCHES, blobInfo.getBucket()).addKeyCondition(ConditionV4Type.MATCHES, blobInfo.getName()).addCustomCondition(ConditionV4Type.MATCHES, "x-goog-date", date).addCustomCondition(ConditionV4Type.MATCHES, "x-goog-credential", signingCredential).addCustomCondition(ConditionV4Type.MATCHES, "x-goog-algorithm", "GOOG4-RSA-SHA256").build();
PostPolicyV4Document document = PostPolicyV4Document.of(expirationFormat.format(timestamp + unit.toMillis(duration)), v4Conditions);
String policy = BaseEncoding.base64().encode(document.toJson().getBytes());
String signature = BaseEncoding.base16().encode(credentials.sign(policy.getBytes())).toLowerCase();
for (PostPolicyV4.ConditionV4 condition : v4Conditions.getConditions()) {
if (condition.type == ConditionV4Type.MATCHES) {
policyFields.put(condition.operand1, condition.operand2);
}
}
policyFields.put("key", blobInfo.getName());
policyFields.put("x-goog-credential", signingCredential);
policyFields.put("x-goog-algorithm", "GOOG4-RSA-SHA256");
policyFields.put("x-goog-date", date);
policyFields.put("x-goog-signature", signature);
policyFields.put("policy", policy);
policyFields.remove("bucket");
return PostPolicyV4.of(url, policyFields);
}
use of com.google.auth.ServiceAccountSigner in project java-storage by googleapis.
the class ITStorageTest method testV4SignedUrl.
@Test
public void testV4SignedUrl() throws IOException {
if (storage.getOptions().getCredentials() != null) {
assumeTrue(storage.getOptions().getCredentials() instanceof ServiceAccountSigner);
}
String blobName = "test-get-signed-url-blob/with/slashes/and?special=!#$&'()*+,:;=?@[]";
BlobInfo blob = BlobInfo.newBuilder(BUCKET, blobName).build();
Blob remoteBlob = storage.create(blob, BLOB_BYTE_CONTENT);
assertNotNull(remoteBlob);
for (Storage.SignUrlOption urlStyle : Arrays.asList(Storage.SignUrlOption.withPathStyle(), Storage.SignUrlOption.withVirtualHostedStyle())) {
URL url = storage.signUrl(blob, 1, TimeUnit.HOURS, Storage.SignUrlOption.withV4Signature(), urlStyle);
URLConnection connection = url.openConnection();
byte[] readBytes = new byte[BLOB_BYTE_CONTENT.length];
try (InputStream responseStream = connection.getInputStream()) {
assertEquals(BLOB_BYTE_CONTENT.length, responseStream.read(readBytes));
assertArrayEquals(BLOB_BYTE_CONTENT, readBytes);
}
}
}
use of com.google.auth.ServiceAccountSigner in project google-cloud-java by GoogleCloudPlatform.
the class StorageImpl method signUrl.
@Override
public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options) {
EnumMap<SignUrlOption.Option, Object> optionMap = Maps.newEnumMap(SignUrlOption.Option.class);
for (SignUrlOption option : options) {
optionMap.put(option.getOption(), option.getValue());
}
ServiceAccountSigner credentials = (ServiceAccountSigner) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED);
if (credentials == null) {
checkState(this.getOptions().getCredentials() instanceof ServiceAccountSigner, "Signing key was not provided and could not be derived");
credentials = (ServiceAccountSigner) this.getOptions().getCredentials();
}
// construct signature - see https://cloud.google.com/storage/docs/access-control#Signed-URLs
StringBuilder stBuilder = new StringBuilder();
if (optionMap.containsKey(SignUrlOption.Option.HTTP_METHOD)) {
stBuilder.append(optionMap.get(SignUrlOption.Option.HTTP_METHOD));
} else {
stBuilder.append(HttpMethod.GET);
}
stBuilder.append('\n');
if (firstNonNull((Boolean) optionMap.get(SignUrlOption.Option.MD5), false)) {
checkArgument(blobInfo.getMd5() != null, "Blob is missing a value for md5");
stBuilder.append(blobInfo.getMd5());
}
stBuilder.append('\n');
if (firstNonNull((Boolean) optionMap.get(SignUrlOption.Option.CONTENT_TYPE), false)) {
checkArgument(blobInfo.getContentType() != null, "Blob is missing a value for content-type");
stBuilder.append(blobInfo.getContentType());
}
stBuilder.append('\n');
long expiration = TimeUnit.SECONDS.convert(getOptions().getClock().millisTime() + unit.toMillis(duration), TimeUnit.MILLISECONDS);
stBuilder.append(expiration).append('\n');
StringBuilder path = new StringBuilder();
if (!blobInfo.getBucket().startsWith("/")) {
path.append('/');
}
path.append(blobInfo.getBucket());
if (!blobInfo.getBucket().endsWith("/")) {
path.append('/');
}
if (blobInfo.getName().startsWith("/")) {
path.setLength(path.length() - 1);
}
String escapedName = UrlEscapers.urlFragmentEscaper().escape(blobInfo.getName());
path.append(escapedName.replace("?", "%3F"));
stBuilder.append(path);
try {
byte[] signatureBytes = credentials.sign(stBuilder.toString().getBytes(UTF_8));
stBuilder = new StringBuilder("https://storage.googleapis.com").append(path);
String signature = URLEncoder.encode(BaseEncoding.base64().encode(signatureBytes), UTF_8.name());
stBuilder.append("?GoogleAccessId=").append(credentials.getAccount());
stBuilder.append("&Expires=").append(expiration);
stBuilder.append("&Signature=").append(signature);
return new URL(stBuilder.toString());
} catch (MalformedURLException | UnsupportedEncodingException ex) {
throw new IllegalStateException(ex);
}
}
use of com.google.auth.ServiceAccountSigner in project java-storage by googleapis.
the class ITStorageTest method testGetSignedUrl.
@Test
public void testGetSignedUrl() throws IOException {
if (storage.getOptions().getCredentials() != null) {
assumeTrue(storage.getOptions().getCredentials() instanceof ServiceAccountSigner);
}
String blobName = "test-get-signed-url-blob/with/slashes/and?special=!#$&'()*+,:;=?@[]";
BlobInfo blob = BlobInfo.newBuilder(BUCKET, blobName).build();
Blob remoteBlob = storage.create(blob, BLOB_BYTE_CONTENT);
assertNotNull(remoteBlob);
for (Storage.SignUrlOption urlStyle : Arrays.asList(Storage.SignUrlOption.withPathStyle(), Storage.SignUrlOption.withVirtualHostedStyle())) {
URL url = storage.signUrl(blob, 1, TimeUnit.HOURS, urlStyle);
URLConnection connection = url.openConnection();
byte[] readBytes = new byte[BLOB_BYTE_CONTENT.length];
try (InputStream responseStream = connection.getInputStream()) {
assertEquals(BLOB_BYTE_CONTENT.length, responseStream.read(readBytes));
assertArrayEquals(BLOB_BYTE_CONTENT, readBytes);
}
}
}
use of com.google.auth.ServiceAccountSigner in project java-storage by googleapis.
the class ITStorageTest method testPostSignedUrl.
@Test
public void testPostSignedUrl() throws IOException {
if (storage.getOptions().getCredentials() != null) {
assumeTrue(storage.getOptions().getCredentials() instanceof ServiceAccountSigner);
}
String blobName = "test-post-signed-url-blob";
BlobInfo blob = BlobInfo.newBuilder(BUCKET, blobName).build();
assertNotNull(storage.create(blob));
for (Storage.SignUrlOption urlStyle : Arrays.asList(Storage.SignUrlOption.withPathStyle(), Storage.SignUrlOption.withVirtualHostedStyle())) {
URL url = storage.signUrl(blob, 1, TimeUnit.HOURS, Storage.SignUrlOption.httpMethod(HttpMethod.POST), urlStyle);
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
connection.connect();
Blob remoteBlob = storage.get(BUCKET, blobName);
assertNotNull(remoteBlob);
assertEquals(blob.getBucket(), remoteBlob.getBucket());
assertEquals(blob.getName(), remoteBlob.getName());
}
}
Aggregations