|
33 | 33 | import com.google.cloud.RetryHelper.RetryHelperException;
|
34 | 34 | import com.google.cloud.http.BaseHttpServiceException;
|
35 | 35 | import com.google.cloud.storage.Acl;
|
| 36 | +import com.google.cloud.storage.Acl.Entity; |
| 37 | +import com.google.cloud.storage.Acl.Project.ProjectRole; |
36 | 38 | import com.google.cloud.storage.Acl.Role;
|
37 | 39 | import com.google.cloud.storage.Acl.User;
|
38 | 40 | import com.google.cloud.storage.Blob;
|
|
70 | 72 | import java.util.Map;
|
71 | 73 | import java.util.Set;
|
72 | 74 | import java.util.concurrent.Callable;
|
| 75 | +import java.util.function.Predicate; |
73 | 76 | import java.util.stream.Collector;
|
74 | 77 | import java.util.stream.Collectors;
|
75 | 78 | import org.junit.Ignore;
|
@@ -185,12 +188,108 @@ public void bucket_defaultAcl_list_bucket404() {
|
185 | 188 | assertThat(storageException.getCode()).isEqualTo(404);
|
186 | 189 | }
|
187 | 190 |
|
| 191 | + @Test |
| 192 | + public void bucket_defaultAcl_create() throws Exception { |
| 193 | + BucketInfo bucketInfo = BucketInfo.newBuilder(generator.randomBucketName()).build(); |
| 194 | + try (TemporaryBucket tempB = |
| 195 | + TemporaryBucket.newBuilder().setBucketInfo(bucketInfo).setStorage(storage).build()) { |
| 196 | + BucketInfo bucket = tempB.getBucket(); |
| 197 | + |
| 198 | + Acl readAll = Acl.of(User.ofAllAuthenticatedUsers(), Role.READER); |
| 199 | + Acl actual = retry429s(() -> storage.createDefaultAcl(bucket.getName(), readAll), storage); |
| 200 | + |
| 201 | + assertThat(actual.getEntity()).isEqualTo(readAll.getEntity()); |
| 202 | + assertThat(actual.getRole()).isEqualTo(readAll.getRole()); |
| 203 | + assertThat(actual.getEtag()).isNotEmpty(); |
| 204 | + |
| 205 | + Bucket bucketUpdated = |
| 206 | + storage.get(bucket.getName(), BucketGetOption.fields(BucketField.values())); |
| 207 | + assertThat(bucketUpdated.getMetageneration()).isNotEqualTo(bucket.getMetageneration()); |
| 208 | + |
| 209 | + // etags change when updates happen, drop before our comparison |
| 210 | + List<Acl> expectedAcls = dropEtags(bucket.getDefaultAcl()); |
| 211 | + List<Acl> actualAcls = dropEtags(bucketUpdated.getDefaultAcl()); |
| 212 | + assertThat(actualAcls).containsAtLeastElementsIn(expectedAcls); |
| 213 | + assertThat(actualAcls).contains(readAll); |
| 214 | + } |
| 215 | + } |
| 216 | + |
| 217 | + @Test |
| 218 | + public void bucket_defaultAcl_create_bucket404() { |
| 219 | + Acl readAll = Acl.of(User.ofAllAuthenticatedUsers(), Role.READER); |
| 220 | + StorageException storageException = |
| 221 | + assertThrows( |
| 222 | + StorageException.class, |
| 223 | + () -> |
| 224 | + retry429s( |
| 225 | + () -> storage.createDefaultAcl(bucket.getName() + "x", readAll), storage)); |
| 226 | + |
| 227 | + assertThat(storageException.getCode()).isEqualTo(404); |
| 228 | + } |
| 229 | + |
| 230 | + @Test |
| 231 | + public void bucket_defaultAcl_update() throws Exception { |
| 232 | + BucketInfo bucketInfo = BucketInfo.newBuilder(generator.randomBucketName()).build(); |
| 233 | + try (TemporaryBucket tempB = |
| 234 | + TemporaryBucket.newBuilder().setBucketInfo(bucketInfo).setStorage(storage).build()) { |
| 235 | + BucketInfo bucket = tempB.getBucket(); |
| 236 | + |
| 237 | + List<Acl> defaultAcls = bucket.getDefaultAcl(); |
| 238 | + assertThat(defaultAcls).isNotEmpty(); |
| 239 | + |
| 240 | + Predicate<Acl> isProjectEditor = hasProjectRole(ProjectRole.EDITORS); |
| 241 | + |
| 242 | + //noinspection OptionalGetWithoutIsPresent |
| 243 | + Acl projectEditorAsOwner = |
| 244 | + defaultAcls.stream().filter(hasRole(Role.OWNER).and(isProjectEditor)).findFirst().get(); |
| 245 | + |
| 246 | + // lower the privileges of project editors to writer from owner |
| 247 | + Entity entity = projectEditorAsOwner.getEntity(); |
| 248 | + Acl projectEditorAsReader = Acl.of(entity, Role.READER); |
| 249 | + |
| 250 | + Acl actual = |
| 251 | + retry429s( |
| 252 | + () -> storage.updateDefaultAcl(bucket.getName(), projectEditorAsReader), storage); |
| 253 | + |
| 254 | + assertThat(actual.getEntity()).isEqualTo(projectEditorAsReader.getEntity()); |
| 255 | + assertThat(actual.getRole()).isEqualTo(projectEditorAsReader.getRole()); |
| 256 | + assertThat(actual.getEtag()).isNotEmpty(); |
| 257 | + |
| 258 | + Bucket bucketUpdated = |
| 259 | + storage.get(bucket.getName(), BucketGetOption.fields(BucketField.values())); |
| 260 | + assertThat(bucketUpdated.getMetageneration()).isNotEqualTo(bucket.getMetageneration()); |
| 261 | + |
| 262 | + // etags change when updates happen, drop before our comparison |
| 263 | + List<Acl> expectedAcls = |
| 264 | + dropEtags( |
| 265 | + bucket.getDefaultAcl().stream() |
| 266 | + .filter(isProjectEditor.negate()) |
| 267 | + .collect(Collectors.toList())); |
| 268 | + List<Acl> actualAcls = dropEtags(bucketUpdated.getDefaultAcl()); |
| 269 | + assertThat(actualAcls).containsAtLeastElementsIn(expectedAcls); |
| 270 | + assertThat(actualAcls).doesNotContain(projectEditorAsOwner); |
| 271 | + assertThat(actualAcls).contains(projectEditorAsReader); |
| 272 | + } |
| 273 | + } |
| 274 | + |
| 275 | + @Test |
| 276 | + public void bucket_defaultAcl_update_bucket404() { |
| 277 | + Acl readAll = Acl.of(User.ofAllAuthenticatedUsers(), Role.READER); |
| 278 | + StorageException storageException = |
| 279 | + assertThrows( |
| 280 | + StorageException.class, |
| 281 | + () -> |
| 282 | + retry429s( |
| 283 | + () -> storage.updateDefaultAcl(bucket.getName() + "x", readAll), storage)); |
| 284 | + |
| 285 | + assertThat(storageException.getCode()).isEqualTo(404); |
| 286 | + } |
| 287 | + |
188 | 288 | @Test
|
189 | 289 | @CrossRun.Ignore(transports = Transport.GRPC)
|
190 | 290 | public void testBucketDefaultAcl() {
|
191 | 291 | // TODO: break this test up into each of the respective scenarios
|
192 | 292 | // 2. Delete a default ACL for a specific entity
|
193 |
| - // 3. Create a default ACL for specific entity |
194 | 293 | // 4. Update default ACL to change role of a specific entity
|
195 | 294 |
|
196 | 295 | // according to https://cloud.google.com/storage/docs/access-control/lists#default
|
@@ -1026,4 +1125,24 @@ public boolean shouldRetry(Throwable previousThrowable, Object previousResponse)
|
1026 | 1125 | }
|
1027 | 1126 | }
|
1028 | 1127 | }
|
| 1128 | + |
| 1129 | + private static ImmutableList<Acl> dropEtags(List<Acl> defaultAcls) { |
| 1130 | + return defaultAcls.stream() |
| 1131 | + .map(acl -> Acl.of(acl.getEntity(), acl.getRole())) |
| 1132 | + .collect(ImmutableList.toImmutableList()); |
| 1133 | + } |
| 1134 | + |
| 1135 | + private static Predicate<Acl> hasRole(Acl.Role expected) { |
| 1136 | + return acl -> acl.getRole().equals(expected); |
| 1137 | + } |
| 1138 | + |
| 1139 | + private static Predicate<Acl> hasProjectRole(Acl.Project.ProjectRole expected) { |
| 1140 | + return acl -> { |
| 1141 | + Entity entity = acl.getEntity(); |
| 1142 | + if (entity.getType().equals(Entity.Type.PROJECT)) { |
| 1143 | + return ((Acl.Project) entity).getProjectRole().equals(expected); |
| 1144 | + } |
| 1145 | + return false; |
| 1146 | + }; |
| 1147 | + } |
1029 | 1148 | }
|
0 commit comments