Skip to content

Commit 8256f6d

Browse files
authored
feat: add IAM Conditions support (#120)
* Add IAM Conditions support * format * wip * set version in mock policies * wip * address comments * fix pom. * revert http-client-bom * address feedback * address integration tests feedback * update core * lint * clean up ubla * format
1 parent 2627a93 commit 8256f6d

File tree

7 files changed

+280
-40
lines changed

7 files changed

+280
-40
lines changed

google-cloud-storage/src/main/java/com/google/cloud/storage/PolicyHelper.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616

1717
package com.google.cloud.storage;
1818

19+
import com.google.api.services.storage.model.Expr;
1920
import com.google.api.services.storage.model.Policy.Bindings;
20-
import com.google.cloud.Identity;
21+
import com.google.cloud.Binding;
22+
import com.google.cloud.Condition;
2123
import com.google.cloud.Policy;
22-
import com.google.cloud.Role;
24+
import com.google.common.collect.ImmutableList;
2325
import java.util.ArrayList;
2426
import java.util.List;
25-
import java.util.Map;
26-
import java.util.Set;
2727

2828
/**
2929
* Helper for converting between the Policy model provided by the API and the Policy model provided
@@ -35,29 +35,46 @@ static Policy convertFromApiPolicy(com.google.api.services.storage.model.Policy
3535
Policy.Builder policyBuilder = Policy.newBuilder();
3636
List<Bindings> bindings = apiPolicy.getBindings();
3737
if (null != bindings && !bindings.isEmpty()) {
38+
ImmutableList.Builder<Binding> coreBindings = ImmutableList.builder();
3839
for (Bindings binding : bindings) {
39-
for (String member : binding.getMembers()) {
40-
policyBuilder.addIdentity(Role.of(binding.getRole()), Identity.valueOf(member));
40+
Binding.Builder bindingBuilder = Binding.newBuilder();
41+
bindingBuilder.setRole(binding.getRole());
42+
bindingBuilder.setMembers(binding.getMembers());
43+
if (binding.getCondition() != null) {
44+
Condition.Builder conditionBuilder = Condition.newBuilder();
45+
conditionBuilder.setTitle(binding.getCondition().getTitle());
46+
conditionBuilder.setDescription(binding.getCondition().getDescription());
47+
conditionBuilder.setExpression(binding.getCondition().getExpression());
48+
bindingBuilder.setCondition(conditionBuilder.build());
4149
}
50+
coreBindings.add(bindingBuilder.build());
4251
}
52+
policyBuilder.setBindings(coreBindings.build());
4353
} else {
4454
throw new IllegalStateException("Missing required bindings.");
4555
}
46-
return policyBuilder.setEtag(apiPolicy.getEtag()).build();
56+
return policyBuilder.setEtag(apiPolicy.getEtag()).setVersion(apiPolicy.getVersion()).build();
4757
}
4858

4959
static com.google.api.services.storage.model.Policy convertToApiPolicy(Policy policy) {
50-
List<Bindings> bindings = new ArrayList<>(policy.getBindings().size());
51-
for (Map.Entry<Role, Set<Identity>> entry : policy.getBindings().entrySet()) {
52-
List<String> members = new ArrayList<>(entry.getValue().size());
53-
for (Identity identity : entry.getValue()) {
54-
members.add(identity.strValue());
60+
List<Bindings> bindings = new ArrayList<>(policy.getBindingsList().size());
61+
for (Binding binding : policy.getBindingsList()) {
62+
Bindings apiBinding = new Bindings();
63+
apiBinding.setRole(binding.getRole());
64+
apiBinding.setMembers(new ArrayList<>(binding.getMembers()));
65+
if (binding.getCondition() != null) {
66+
Expr expr = new Expr();
67+
expr.setTitle(binding.getCondition().getTitle());
68+
expr.setDescription(binding.getCondition().getDescription());
69+
expr.setExpression(binding.getCondition().getExpression());
70+
apiBinding.setCondition(expr);
5571
}
56-
bindings.add(new Bindings().setMembers(members).setRole(entry.getKey().getValue()));
72+
bindings.add(apiBinding);
5773
}
5874
return new com.google.api.services.storage.model.Policy()
5975
.setBindings(bindings)
60-
.setEtag(policy.getEtag());
76+
.setEtag(policy.getEtag())
77+
.setVersion(policy.getVersion());
6178
}
6279

6380
private PolicyHelper() {

google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ public static BucketSourceOption metagenerationNotMatch(long metageneration) {
269269
public static BucketSourceOption userProject(String userProject) {
270270
return new BucketSourceOption(StorageRpc.Option.USER_PROJECT, userProject);
271271
}
272+
273+
public static BucketSourceOption requestedPolicyVersion(long version) {
274+
return new BucketSourceOption(StorageRpc.Option.REQUESTED_POLICY_VERSION, version);
275+
}
272276
}
273277

274278
/** Class for specifying listHmacKeys options */

google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,11 +1376,16 @@ public Policy getIamPolicy(String bucket, Map<Option, ?> options) {
13761376
Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_GET_BUCKET_IAM_POLICY);
13771377
Scope scope = tracer.withSpan(span);
13781378
try {
1379-
return storage
1380-
.buckets()
1381-
.getIamPolicy(bucket)
1382-
.setUserProject(Option.USER_PROJECT.getString(options))
1383-
.execute();
1379+
Storage.Buckets.GetIamPolicy getIamPolicy =
1380+
storage
1381+
.buckets()
1382+
.getIamPolicy(bucket)
1383+
.setUserProject(Option.USER_PROJECT.getString(options));
1384+
if (null != Option.REQUESTED_POLICY_VERSION.getLong(options)) {
1385+
getIamPolicy.setOptionsRequestedPolicyVersion(
1386+
Option.REQUESTED_POLICY_VERSION.getLong(options).intValue());
1387+
}
1388+
return getIamPolicy.execute();
13841389
} catch (IOException ex) {
13851390
span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage()));
13861391
throw translate(ex);

google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/StorageRpc.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ enum Option {
6464
USER_PROJECT("userProject"),
6565
KMS_KEY_NAME("kmsKeyName"),
6666
SERVICE_ACCOUNT_EMAIL("serviceAccount"),
67-
SHOW_DELETED_KEYS("showDeletedKeys");
67+
SHOW_DELETED_KEYS("showDeletedKeys"),
68+
REQUESTED_POLICY_VERSION("optionsRequestedPolicyVersion");
6869

6970
private final String value;
7071

google-cloud-storage/src/test/java/com/google/cloud/storage/PolicyHelperTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public void testEquivalence() {
4141
Identity.user("[email protected]"),
4242
Identity.user("[email protected]"))
4343
.setEtag(ETAG)
44+
.setVersion(1)
4445
.build();
4546
com.google.api.services.storage.model.Policy apiPolicy =
4647
new com.google.api.services.storage.model.Policy()
@@ -53,7 +54,8 @@ public void testEquivalence() {
5354
.setMembers(
5455
ImmutableList.of("user:[email protected]", "user:[email protected]"))
5556
.setRole("roles/storage.objectAdmin")))
56-
.setEtag(ETAG);
57+
.setEtag(ETAG)
58+
.setVersion(1);
5759

5860
Policy actualLibPolicy = PolicyHelper.convertFromApiPolicy(apiPolicy);
5961
com.google.api.services.storage.model.Policy actualApiPolicy =

google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ public class StorageImplTest {
288288
Identity.user("[email protected]"),
289289
Identity.user("[email protected]"))
290290
.setEtag(POLICY_ETAG1)
291+
.setVersion(1)
291292
.build();
292293

293294
private static final ServiceAccount SERVICE_ACCOUNT = ServiceAccount.of("[email protected]");
@@ -302,7 +303,8 @@ public class StorageImplTest {
302303
new Bindings()
303304
.setMembers(ImmutableList.of("user:[email protected]", "user:[email protected]"))
304305
.setRole("roles/storage.objectAdmin")))
305-
.setEtag(POLICY_ETAG1);
306+
.setEtag(POLICY_ETAG1)
307+
.setVersion(1);
306308

307309
private static final String PRIVATE_KEY_STRING =
308310
"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoG"
@@ -2891,7 +2893,8 @@ public void testSetIamPolicy() {
28912893
new Bindings()
28922894
.setMembers(ImmutableList.of("group:[email protected]"))
28932895
.setRole("roles/storage.admin")))
2894-
.setEtag(POLICY_ETAG1);
2896+
.setEtag(POLICY_ETAG1)
2897+
.setVersion(1);
28952898
// postCommitApiPolicy is identical but for the etag, which has been updated.
28962899
com.google.api.services.storage.model.Policy postCommitApiPolicy =
28972900
new com.google.api.services.storage.model.Policy()
@@ -2907,7 +2910,8 @@ public void testSetIamPolicy() {
29072910
new Bindings()
29082911
.setMembers(ImmutableList.of("group:[email protected]"))
29092912
.setRole("roles/storage.admin")))
2910-
.setEtag(POLICY_ETAG2);
2913+
.setEtag(POLICY_ETAG2)
2914+
.setVersion(1);
29112915
Policy postCommitLibPolicy =
29122916
Policy.newBuilder()
29132917
.addIdentity(StorageRoles.objectViewer(), Identity.allUsers())
@@ -2917,6 +2921,7 @@ public void testSetIamPolicy() {
29172921
Identity.user("[email protected]"))
29182922
.addIdentity(StorageRoles.admin(), Identity.group("[email protected]"))
29192923
.setEtag(POLICY_ETAG2)
2924+
.setVersion(1)
29202925
.build();
29212926

29222927
EasyMock.expect(storageRpcMock.getIamPolicy(BUCKET_NAME1, EMPTY_RPC_OPTIONS))

0 commit comments

Comments
 (0)