From f5f29bb287f1e673c09dc6fedfc30878b76dabcc Mon Sep 17 00:00:00 2001 From: JesseLovelace <43148100+JesseLovelace@users.noreply.github.com> Date: Wed, 6 Feb 2019 13:04:14 -0800 Subject: [PATCH] Implement BucketPolicyOnly (#4404) * implement BucketPolicyOnly * [Storage] Bucket Policy Only samples (#4408) * Humble beginnings for BPO samples with tests * Update samples per client changes * Fix format issue * Lint fix --- .../java/com/google/cloud/storage/Bucket.java | 6 + .../com/google/cloud/storage/BucketInfo.java | 143 ++++++++++++++++++ .../com/google/cloud/storage/Storage.java | 15 +- .../cloud/storage/spi/v1/HttpStorageRpc.java | 17 ++- .../cloud/storage/spi/v1/StorageRpc.java | 1 + .../google/cloud/storage/BucketInfoTest.java | 23 +++ .../cloud/storage/it/ITStorageTest.java | 80 ++++++++++ google-cloud-clients/pom.xml | 2 +- .../storage/snippets/StorageSnippets.java | 65 ++++++++ .../storage/snippets/ITStorageSnippets.java | 15 ++ 10 files changed, 364 insertions(+), 3 deletions(-) diff --git a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java index b10f56194423..30f9ce61f1fc 100644 --- a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java +++ b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java @@ -655,6 +655,12 @@ public Builder setRetentionPeriod(Long retentionPeriod) { return this; } + @Override + public Builder setIamConfiguration(IamConfiguration iamConfiguration) { + infoBuilder.setIamConfiguration(iamConfiguration); + return this; + } + @Override public Bucket build() { return new Bucket(storage, infoBuilder); diff --git a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java index caceb2f19d2a..c8d1d07a274b 100644 --- a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java +++ b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java @@ -95,6 +95,118 @@ public com.google.api.services.storage.model.Bucket apply(BucketInfo bucketInfo) private final Long retentionEffectiveTime; private final Boolean retentionPolicyIsLocked; private final Long retentionPeriod; + private final IamConfiguration iamConfiguration; + + /** + * The Bucket's IAM Configuration. + * + * @see Bucket Policy Only + */ + public static class IamConfiguration implements Serializable { + private static final long serialVersionUID = -8671736104909424616L; + + private Boolean isBucketPolicyOnlyEnabled; + private Long bucketPolicyOnlyLockedTime; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) { + return false; + } + IamConfiguration other = (IamConfiguration) o; + return Objects.equals(toPb(), other.toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(isBucketPolicyOnlyEnabled, bucketPolicyOnlyLockedTime); + } + + private IamConfiguration(Builder builder) { + this.isBucketPolicyOnlyEnabled = builder.isBucketPolicyOnlyEnabled; + this.bucketPolicyOnlyLockedTime = builder.bucketPolicyOnlyLockedTime; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public Builder toBuilder() { + Builder builder = new Builder(); + builder.isBucketPolicyOnlyEnabled = isBucketPolicyOnlyEnabled; + builder.bucketPolicyOnlyLockedTime = bucketPolicyOnlyLockedTime; + return builder; + } + + public Boolean isBucketPolicyOnlyEnabled() { + return isBucketPolicyOnlyEnabled; + } + + public Long getBucketPolicyOnlyLockedTime() { + return bucketPolicyOnlyLockedTime; + } + + Bucket.IamConfiguration toPb() { + Bucket.IamConfiguration iamConfiguration = new Bucket.IamConfiguration(); + + Bucket.IamConfiguration.BucketPolicyOnly bucketPolicyOnly = + new Bucket.IamConfiguration.BucketPolicyOnly(); + bucketPolicyOnly.setEnabled(isBucketPolicyOnlyEnabled); + bucketPolicyOnly.setLockedTime( + bucketPolicyOnlyLockedTime == null ? null : new DateTime(bucketPolicyOnlyLockedTime)); + + iamConfiguration.setBucketPolicyOnly(bucketPolicyOnly); + + return iamConfiguration; + } + + static IamConfiguration fromPb(Bucket.IamConfiguration iamConfiguration) { + Bucket.IamConfiguration.BucketPolicyOnly bucketPolicyOnly = + iamConfiguration.getBucketPolicyOnly(); + DateTime lockedTime = bucketPolicyOnly.getLockedTime(); + + return newBuilder() + .setIsBucketPolicyOnlyEnabled(bucketPolicyOnly.getEnabled()) + .setBucketPolicyOnlyLockedTime(lockedTime == null ? null : lockedTime.getValue()) + .build(); + } + + /** Builder for {@code IamConfiguration} */ + public static class Builder { + private Boolean isBucketPolicyOnlyEnabled; + private Long bucketPolicyOnlyLockedTime; + + /** + * Sets whether BucketPolicyOnly is enabled for this bucket. When this is enabled, access to + * the bucket will be configured through IAM, and legacy ACL policies will not work. When this + * is first enabled, {@code bucketPolicyOnly.lockedTime} will be set by the API automatically. + * This field can then be disabled until the time specified, after which it will become + * immutable and calls to change it will fail. If this is enabled, calls to access legacy ACL + * information will fail. + */ + public Builder setIsBucketPolicyOnlyEnabled(Boolean isBucketPolicyOnlyEnabled) { + this.isBucketPolicyOnlyEnabled = isBucketPolicyOnlyEnabled; + return this; + } + + /** + * Sets the deadline for switching {@code bucketPolicyOnly.enabled} back to false. After this + * time passes, calls to do so will fail. This is package-private, since in general this field + * should never be set by a user--it's automatically set by the backend when {@code enabled} + * is set to true. + */ + Builder setBucketPolicyOnlyLockedTime(Long bucketPolicyOnlyLockedTime) { + this.bucketPolicyOnlyLockedTime = bucketPolicyOnlyLockedTime; + return this; + } + + /** Builds an {@code IamConfiguration} object */ + public IamConfiguration build() { + return new IamConfiguration(this); + } + } + } /** * Lifecycle rule for a bucket. Allows supported Actions, such as deleting and changing storage @@ -786,6 +898,15 @@ public abstract static class Builder { @BetaApi public abstract Builder setRetentionPeriod(Long retentionPeriod); + /** + * Sets the IamConfiguration to specify whether IAM access should be enabled. + * + * @see Bucket Policy + * Only + */ + @BetaApi + public abstract Builder setIamConfiguration(IamConfiguration iamConfiguration); + /** Creates a {@code BucketInfo} object. */ public abstract BucketInfo build(); } @@ -816,6 +937,7 @@ static final class BuilderImpl extends Builder { private Long retentionEffectiveTime; private Boolean retentionPolicyIsLocked; private Long retentionPeriod; + private IamConfiguration iamConfiguration; BuilderImpl(String name) { this.name = name; @@ -846,6 +968,7 @@ static final class BuilderImpl extends Builder { retentionEffectiveTime = bucketInfo.retentionEffectiveTime; retentionPolicyIsLocked = bucketInfo.retentionPolicyIsLocked; retentionPeriod = bucketInfo.retentionPeriod; + iamConfiguration = bucketInfo.iamConfiguration; } @Override @@ -998,6 +1121,12 @@ public Builder setRetentionPeriod(Long retentionPeriod) { return this; } + @Override + public Builder setIamConfiguration(IamConfiguration iamConfiguration) { + this.iamConfiguration = iamConfiguration; + return this; + } + @Override public BucketInfo build() { checkNotNull(name); @@ -1030,6 +1159,7 @@ public BucketInfo build() { retentionEffectiveTime = builder.retentionEffectiveTime; retentionPolicyIsLocked = builder.retentionPolicyIsLocked; retentionPeriod = builder.retentionPeriod; + iamConfiguration = builder.iamConfiguration; } /** Returns the service-generated id for the bucket. */ @@ -1268,6 +1398,12 @@ public Long getRetentionPeriod() { return retentionPeriod; } + /** Returns the IAM configuration */ + @BetaApi + public IamConfiguration getIamConfiguration() { + return iamConfiguration; + } + /** Returns a builder for the current bucket. */ public Builder toBuilder() { return new BuilderImpl(this); @@ -1405,6 +1541,9 @@ public Rule apply(LifecycleRule lifecycleRule) { bucketPb.setRetentionPolicy(retentionPolicy); } } + if (iamConfiguration != null) { + bucketPb.setIamConfiguration(iamConfiguration.toPb()); + } return bucketPb; } @@ -1526,6 +1665,10 @@ public DeleteRule apply(Rule rule) { builder.setRetentionPeriod(retentionPolicy.getRetentionPeriod()); } } + Bucket.IamConfiguration iamConfiguration = bucketPb.getIamConfiguration(); + if (iamConfiguration != null) { + builder.setIamConfiguration(IamConfiguration.fromPb(iamConfiguration)); + } return builder.build(); } } diff --git a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java index 6ce9ca8c6e2a..534b1e0810aa 100644 --- a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java +++ b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java @@ -96,7 +96,8 @@ enum BucketField implements FieldSelector { ENCRYPTION("encryption"), BILLING("billing"), DEFAULT_EVENT_BASED_HOLD("defaultEventBasedHold"), - RETENTION_POLICY("retentionPolicy"); + RETENTION_POLICY("retentionPolicy"), + IAMCONFIGURATION("iamConfiguration"); static final List REQUIRED_FIELDS = ImmutableList.of(NAME); @@ -204,6 +205,18 @@ public static BucketTargetOption metagenerationNotMatch() { public static BucketTargetOption userProject(String userProject) { return new BucketTargetOption(StorageRpc.Option.USER_PROJECT, userProject); } + + /** + * Returns an option to define the projection in the API request. In some cases this option may + * be needed to be set to `noAcl` to omit ACL data from the response. The default value is + * `full` + * + * @see Buckets: + * patch + */ + public static BucketTargetOption projection(String projection) { + return new BucketTargetOption(StorageRpc.Option.PROJECTION, projection); + } } /** Class for specifying bucket source options. */ diff --git a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java index a10b4ef8a973..072b65227be8 100644 --- a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java +++ b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java @@ -85,6 +85,7 @@ public class HttpStorageRpc implements StorageRpc { public static final String DEFAULT_PROJECTION = "full"; + public static final String NO_ACL_PROJECTION = "noAcl"; private static final String ENCRYPTION_KEY_PREFIX = "x-goog-encryption-"; private static final String SOURCE_ENCRYPTION_KEY_PREFIX = "x-goog-copy-source-encryption-"; @@ -450,10 +451,24 @@ public Bucket patch(Bucket bucket, Map options) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_PATCH_BUCKET); Scope scope = tracer.withSpan(span); try { + String projection = Option.PROJECTION.getString(options); + + if (bucket.getIamConfiguration() != null + && bucket.getIamConfiguration().getBucketPolicyOnly() != null + && bucket.getIamConfiguration().getBucketPolicyOnly().getEnabled()) { + // If BucketPolicyOnly is enabled, patch calls will fail if ACL information is included in + // the request + bucket.setDefaultObjectAcl(null); + bucket.setAcl(null); + + if (projection == null) { + projection = NO_ACL_PROJECTION; + } + } return storage .buckets() .patch(bucket.getName(), bucket) - .setProjection(DEFAULT_PROJECTION) + .setProjection(projection == null ? DEFAULT_PROJECTION : projection) .setPredefinedAcl(Option.PREDEFINED_ACL.getString(options)) .setPredefinedDefaultObjectAcl(Option.PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) diff --git a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/StorageRpc.java b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/StorageRpc.java index 447643283d94..eecf311a7033 100644 --- a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/StorageRpc.java +++ b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/StorageRpc.java @@ -50,6 +50,7 @@ enum Option { IF_SOURCE_GENERATION_NOT_MATCH("ifSourceGenerationNotMatch"), IF_DISABLE_GZIP_CONTENT("disableGzipContent"), PREFIX("prefix"), + PROJECTION("projection"), MAX_RESULTS("maxResults"), PAGE_TOKEN("pageToken"), DELIMITER("delimiter"), diff --git a/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java b/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java index d5bc87550385..919afeb0adea 100644 --- a/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java +++ b/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java @@ -18,8 +18,10 @@ import static com.google.cloud.storage.Acl.Project.ProjectRole.VIEWERS; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import com.google.api.services.storage.model.Bucket; import com.google.api.services.storage.model.Bucket.Lifecycle.Rule; import com.google.cloud.storage.Acl.Project; import com.google.cloud.storage.Acl.Role; @@ -64,6 +66,11 @@ public class BucketInfoTest { LifecycleAction.newDeleteAction(), LifecycleCondition.newBuilder().setAge(5).build())); private static final String INDEX_PAGE = "index.html"; + private static final BucketInfo.IamConfiguration IAM_CONFIGURATION = + BucketInfo.IamConfiguration.newBuilder() + .setIsBucketPolicyOnlyEnabled(true) + .setBucketPolicyOnlyLockedTime(System.currentTimeMillis()) + .build(); private static final String NOT_FOUND_PAGE = "error.html"; private static final String LOCATION = "ASIA"; private static final StorageClass STORAGE_CLASS = StorageClass.STANDARD; @@ -90,6 +97,7 @@ public class BucketInfoTest { .setDeleteRules(DELETE_RULES) .setLifecycleRules(LIFECYCLE_RULES) .setIndexPage(INDEX_PAGE) + .setIamConfiguration(IAM_CONFIGURATION) .setNotFoundPage(NOT_FOUND_PAGE) .setLocation(LOCATION) .setStorageClass(STORAGE_CLASS) @@ -139,6 +147,7 @@ public void testBuilder() { assertEquals(DEFAULT_ACL, BUCKET_INFO.getDefaultAcl()); assertEquals(DELETE_RULES, BUCKET_INFO.getDeleteRules()); assertEquals(INDEX_PAGE, BUCKET_INFO.getIndexPage()); + assertEquals(IAM_CONFIGURATION, BUCKET_INFO.getIamConfiguration()); assertEquals(NOT_FOUND_PAGE, BUCKET_INFO.getNotFoundPage()); assertEquals(LOCATION, BUCKET_INFO.getLocation()); assertEquals(STORAGE_CLASS, BUCKET_INFO.getStorageClass()); @@ -174,6 +183,7 @@ private void compareBuckets(BucketInfo expected, BucketInfo value) { assertEquals(expected.getDeleteRules(), value.getDeleteRules()); assertEquals(expected.getLifecycleRules(), value.getLifecycleRules()); assertEquals(expected.getIndexPage(), value.getIndexPage()); + assertEquals(expected.getIamConfiguration(), value.getIamConfiguration()); assertEquals(expected.getNotFoundPage(), value.getNotFoundPage()); assertEquals(expected.getLocation(), value.getLocation()); assertEquals(expected.getStorageClass(), value.getStorageClass()); @@ -244,4 +254,17 @@ public void testLifecycleRules() { assertTrue(setStorageClassLifecycleRule.getCondition().getIsLive()); assertEquals(10, setStorageClassLifecycleRule.getCondition().getNumNewerVersions().intValue()); } + + @Test + public void testIamConfiguration() { + Bucket.IamConfiguration iamConfiguration = + BucketInfo.IamConfiguration.newBuilder() + .setIsBucketPolicyOnlyEnabled(true) + .setBucketPolicyOnlyLockedTime(System.currentTimeMillis()) + .build() + .toPb(); + + assertEquals(Boolean.TRUE, iamConfiguration.getBucketPolicyOnly().getEnabled()); + assertNotNull(iamConfiguration.getBucketPolicyOnly().getLockedTime()); + } } diff --git a/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java b/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java index 3a97dab2800d..114954d396b3 100644 --- a/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java +++ b/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java @@ -2442,4 +2442,84 @@ public void testGetServiceAccount() { assertNotNull(serviceAccount); assertTrue(serviceAccount.getEmail().endsWith(SERVICE_ACCOUNT_EMAIL_SUFFIX)); } + + @Test + public void testBucketWithBucketPolicyOnlyEnabled() throws Exception { + String bpoBucket = RemoteStorageHelper.generateBucketName(); + try { + storage.create( + Bucket.newBuilder(bpoBucket) + .setIamConfiguration( + BucketInfo.IamConfiguration.newBuilder() + .setIsBucketPolicyOnlyEnabled(true) + .build()) + .build()); + + Bucket remoteBucket = + storage.get(bpoBucket, Storage.BucketGetOption.fields(BucketField.IAMCONFIGURATION)); + + assertTrue(remoteBucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); + assertNotNull(remoteBucket.getIamConfiguration().getBucketPolicyOnlyLockedTime()); + try { + remoteBucket.listAcls(); + fail("StorageException was expected."); + } catch (StorageException e) { + // Expected: Listing legacy ACLs should fail on a BPO enabled bucket + } + try { + remoteBucket.listDefaultAcls(); + fail("StorageException was expected"); + } catch (StorageException e) { + // Expected: Listing legacy ACLs should fail on a BPO enabled bucket + } + } finally { + RemoteStorageHelper.forceDelete(storage, bpoBucket, 1, TimeUnit.MINUTES); + } + } + + @Test + public void testEnableAndDisableBucketPolicyOnlyOnExistingBucket() throws Exception { + String bpoBucket = RemoteStorageHelper.generateBucketName(); + try { + BucketInfo.IamConfiguration bpoDisabledIamConfiguration = + BucketInfo.IamConfiguration.newBuilder().setIsBucketPolicyOnlyEnabled(false).build(); + Bucket bucket = + storage.create( + Bucket.newBuilder(bpoBucket) + .setIamConfiguration(bpoDisabledIamConfiguration) + .setAcl(ImmutableList.of(Acl.of(User.ofAllAuthenticatedUsers(), Role.READER))) + .setDefaultAcl( + ImmutableList.of(Acl.of(User.ofAllAuthenticatedUsers(), Role.READER))) + .build()); + + bucket + .toBuilder() + .setIamConfiguration( + bpoDisabledIamConfiguration.toBuilder().setIsBucketPolicyOnlyEnabled(true).build()) + .build() + .update(); + + Bucket remoteBucket = + storage.get(bpoBucket, Storage.BucketGetOption.fields(BucketField.IAMCONFIGURATION)); + + assertTrue(remoteBucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); + assertNotNull(remoteBucket.getIamConfiguration().getBucketPolicyOnlyLockedTime()); + + bucket.toBuilder().setIamConfiguration(bpoDisabledIamConfiguration).build().update(); + + remoteBucket = + storage.get( + bpoBucket, + Storage.BucketGetOption.fields( + BucketField.IAMCONFIGURATION, BucketField.ACL, BucketField.DEFAULT_OBJECT_ACL)); + + assertFalse(remoteBucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); + assertEquals(User.ofAllAuthenticatedUsers(), remoteBucket.getDefaultAcl().get(0).getEntity()); + assertEquals(Role.READER, remoteBucket.getDefaultAcl().get(0).getRole()); + assertEquals(User.ofAllAuthenticatedUsers(), remoteBucket.getAcl().get(0).getEntity()); + assertEquals(Role.READER, remoteBucket.getAcl().get(0).getRole()); + } finally { + RemoteStorageHelper.forceDelete(storage, bpoBucket, 1, TimeUnit.MINUTES); + } + } } diff --git a/google-cloud-clients/pom.xml b/google-cloud-clients/pom.xml index ba7a0816b9fa..65bf89456454 100644 --- a/google-cloud-clients/pom.xml +++ b/google-cloud-clients/pom.xml @@ -230,7 +230,7 @@ com.google.apis google-api-services-storage - v1-rev20181013-1.27.0 + v1-rev20181109-1.27.0 com.google.apis diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/storage/snippets/StorageSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/storage/snippets/StorageSnippets.java index ab2ec4df8edf..ccec623a1812 100644 --- a/google-cloud-examples/src/main/java/com/google/cloud/examples/storage/snippets/StorageSnippets.java +++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/storage/snippets/StorageSnippets.java @@ -1393,4 +1393,69 @@ public Blob releaseTemporaryHold(String bucketName, String blobName) throws Stor // [END storage_release_temporary_hold] return blob; } + + /** Example of how to enable Bucket Policy Only for a bucket */ + public Bucket enableBucketPolicyOnly(String bucketName) throws StorageException { + // [START storage_enable_bucket_policy_only] + // Instantiate a Google Cloud Storage client + Storage storage = StorageOptions.getDefaultInstance().getService(); + + // The name of a bucket, e.g. "my-bucket" + // String bucketName = "my-bucket"; + + BucketInfo.IamConfiguration iamConfiguration = + BucketInfo.IamConfiguration.newBuilder().setIsBucketPolicyOnlyEnabled(true).build(); + Bucket bucket = + storage.update( + BucketInfo.newBuilder(bucketName).setIamConfiguration(iamConfiguration).build()); + + System.out.println("Bucket Policy Only was enabled for " + bucketName); + // [END storage_enable_bucket_policy_only] + return bucket; + } + + /** Example of how to disable Bucket Policy Only for a bucket */ + public Bucket disableBucketPolicyOnly(String bucketName) throws StorageException { + // [START storage_disable_bucket_policy_only] + // Instantiate a Google Cloud Storage client + Storage storage = StorageOptions.getDefaultInstance().getService(); + + // The name of a bucket, e.g. "my-bucket" + // String bucketName = "my-bucket"; + + BucketInfo.IamConfiguration iamConfiguration = + BucketInfo.IamConfiguration.newBuilder().setIsBucketPolicyOnlyEnabled(false).build(); + Bucket bucket = + storage.update( + BucketInfo.newBuilder(bucketName).setIamConfiguration(iamConfiguration).build()); + + System.out.println("Bucket Policy Only was disabled for " + bucketName); + // [END storage_disable_bucket_policy_only] + return bucket; + } + + /** Example of how to get Bucket Policy Only metadata for a bucket */ + public Bucket getBucketPolicyOnly(String bucketName) throws StorageException { + // [START storage_get_bucket_policy_only] + // Instantiate a Google Cloud Storage client + Storage storage = StorageOptions.getDefaultInstance().getService(); + + // The name of a bucket, e.g. "my-bucket" + // String bucketName = "my-bucket"; + + Bucket bucket = storage.get(bucketName, BucketGetOption.fields(BucketField.IAMCONFIGURATION)); + BucketInfo.IamConfiguration iamConfiguration = bucket.getIamConfiguration(); + + Boolean enabled = iamConfiguration.isBucketPolicyOnlyEnabled(); + Date lockedTime = new Date(iamConfiguration.getBucketPolicyOnlyLockedTime()); + + if (enabled != null && enabled) { + System.out.println("Bucket Policy Only is enabled for " + bucketName); + System.out.println("Bucket will be locked on " + lockedTime); + } else { + System.out.println("Bucket Policy Only is disabled for " + bucketName); + } + // [END storage_get_bucket_policy_only] + return bucket; + } } diff --git a/google-cloud-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITStorageSnippets.java b/google-cloud-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITStorageSnippets.java index 19db91dcf44b..fe618755d5cd 100644 --- a/google-cloud-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITStorageSnippets.java +++ b/google-cloud-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITStorageSnippets.java @@ -546,4 +546,19 @@ public void testLockRetentionPolicy() { bucket = storageSnippets.lockRetentionPolicy(tempBucket); assertTrue(bucket.retentionPolicyIsLocked()); } + + @Test + public void testBucketPolicyOnly() { + String tempBucket = RemoteStorageHelper.generateBucketName(); + Bucket bucket = storageSnippets.createBucket(tempBucket); + assertNotNull(bucket); + bucket = storageSnippets.enableBucketPolicyOnly(tempBucket); + assertTrue(bucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); + assertNotNull(bucket.getIamConfiguration().getBucketPolicyOnlyLockedTime()); + bucket = storageSnippets.getBucketPolicyOnly(tempBucket); + assertTrue(bucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); + assertNotNull(bucket.getIamConfiguration().getBucketPolicyOnlyLockedTime()); + bucket = storageSnippets.disableBucketPolicyOnly(tempBucket); + assertFalse(bucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); + } }