From 52562144d730bc0ecc3fe58cf6dcb1d01325cb69 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 21 Mar 2016 09:36:13 -0700 Subject: [PATCH] Add binding entries as necessary in IamPolicy.Builder --- .../java/com/google/gcloud/IamPolicy.java | 63 +++++-------------- .../java/com/google/gcloud/IamPolicyTest.java | 44 +++++++++---- .../snippets/ModifyPolicy.java | 6 +- .../gcloud/resourcemanager/Project.java | 18 +++--- .../gcloud/resourcemanager/PolicyTest.java | 16 ++--- .../gcloud/resourcemanager/ProjectTest.java | 4 +- .../ResourceManagerImplTest.java | 4 +- .../resourcemanager/SerializationTest.java | 6 +- 8 files changed, 73 insertions(+), 88 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java index 748eaba2ab4c..3d7c1422e6fa 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java @@ -83,39 +83,8 @@ public final B bindings(Map> bindings) { return self(); } - /** - * Adds a binding to the policy. - * - * @throws IllegalArgumentException if the policy already contains a binding with the same role - * or if the role or any identities are null - */ - public final B addBinding(R role, Set identities) { - verifyBinding(role, identities); - checkArgument(!bindings.containsKey(role), - "The policy already contains a binding with the role " + role.toString() + "."); - bindings.put(role, new HashSet(identities)); - return self(); - } - - /** - * Adds a binding to the policy. - * - * @throws IllegalArgumentException if the policy already contains a binding with the same role - * or if the role or any identities are null - */ - public final B addBinding(R role, Identity first, Identity... others) { - HashSet identities = new HashSet<>(); - identities.add(first); - identities.addAll(Arrays.asList(others)); - return addBinding(role, identities); - } - private void verifyBinding(R role, Collection identities) { checkArgument(role != null, "The role cannot be null."); - verifyIdentities(identities); - } - - private void verifyIdentities(Collection identities) { checkArgument(identities != null, "A role cannot be assigned to a null set of identities."); checkArgument(!identities.contains(null), "Null identities are not permitted."); } @@ -129,33 +98,33 @@ public final B removeBinding(R role) { } /** - * Adds one or more identities to an existing binding. - * - * @throws IllegalArgumentException if the policy doesn't contain a binding with the specified - * role or any identities are null + * Adds one or more identities to the policy under the role specified. Creates a new role + * binding if the binding corresponding to the given role did not previously exist. */ public final B addIdentity(R role, Identity first, Identity... others) { - checkArgument(bindings.containsKey(role), - "The policy doesn't contain the role " + role.toString() + "."); List toAdd = new LinkedList<>(); toAdd.add(first); toAdd.addAll(Arrays.asList(others)); - verifyIdentities(toAdd); - bindings.get(role).addAll(toAdd); + verifyBinding(role, toAdd); + Set identities = bindings.get(role); + if (identities == null) { + identities = new HashSet(); + bindings.put(role, identities); + } + identities.addAll(toAdd); return self(); } /** - * Removes one or more identities from an existing binding. - * - * @throws IllegalArgumentException if the policy doesn't contain a binding with the specified - * role + * Removes one or more identities from an existing binding. Does nothing if the binding + * associated with the provided role doesn't exist. */ public final B removeIdentity(R role, Identity first, Identity... others) { - checkArgument(bindings.containsKey(role), - "The policy doesn't contain the role " + role.toString() + "."); - bindings.get(role).remove(first); - bindings.get(role).removeAll(Arrays.asList(others)); + Set identities = bindings.get(role); + if (identities != null) { + identities.remove(first); + identities.removeAll(Arrays.asList(others)); + } return self(); } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java index db0935c4766d..2f40c3b76001 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java @@ -28,6 +28,7 @@ import org.junit.Test; +import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -46,8 +47,8 @@ public class IamPolicyTest { "editor", ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)); private static final PolicyImpl SIMPLE_POLICY = PolicyImpl.builder() - .addBinding("viewer", ImmutableSet.of(USER, SERVICE_ACCOUNT, ALL_USERS)) - .addBinding("editor", ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)) + .addIdentity("viewer", USER, SERVICE_ACCOUNT, ALL_USERS) + .addIdentity("editor", ALL_AUTH_USERS, GROUP, DOMAIN) .build(); private static final PolicyImpl FULL_POLICY = new PolicyImpl.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); @@ -105,22 +106,43 @@ public void testBuilder() { policy.bindings()); assertNull(policy.etag()); assertNull(policy.version()); - policy = PolicyImpl.builder().addBinding("owner", USER, SERVICE_ACCOUNT).build(); + policy = PolicyImpl.builder() + .removeIdentity("viewer", USER) + .addIdentity("owner", USER, SERVICE_ACCOUNT) + .build(); assertEquals( ImmutableMap.of("owner", ImmutableSet.of(USER, SERVICE_ACCOUNT)), policy.bindings()); assertNull(policy.etag()); assertNull(policy.version()); + } + + @Test + public void testIllegalPolicies() { + try { + PolicyImpl.builder().addIdentity(null, USER); + fail("Null role should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("The role cannot be null.", ex.getMessage()); + } + try { + PolicyImpl.builder().addIdentity("viewer", null, USER); + fail("Null identity should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("Null identities are not permitted.", ex.getMessage()); + } try { - SIMPLE_POLICY.toBuilder().addBinding("viewer", USER); - fail("Should have failed due to duplicate role."); - } catch (IllegalArgumentException e) { - assertEquals("The policy already contains a binding with the role viewer.", e.getMessage()); + PolicyImpl.builder().bindings(null); + fail("Null bindings map should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("The provided map of bindings cannot be null.", ex.getMessage()); } try { - SIMPLE_POLICY.toBuilder().addBinding("editor", ImmutableSet.of(USER)); - fail("Should have failed due to duplicate role."); - } catch (IllegalArgumentException e) { - assertEquals("The policy already contains a binding with the role editor.", e.getMessage()); + Map> bindings = new HashMap<>(); + bindings.put("viewer", null); + PolicyImpl.builder().bindings(bindings); + fail("Null set of identities should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("A role cannot be assigned to a null set of identities.", ex.getMessage()); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java index 7401f0b88bbc..478765a9ecf4 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java @@ -49,11 +49,7 @@ public static void main(String... args) { // Add a viewer Policy.Builder modifiedPolicy = policy.toBuilder(); Identity newViewer = Identity.user(""); - if (policy.bindings().containsKey(Role.viewer())) { - modifiedPolicy.addIdentity(Role.viewer(), newViewer); - } else { - modifiedPolicy.addBinding(Role.viewer(), newViewer); - } + modifiedPolicy.addIdentity(Role.viewer(), newViewer); // Write policy Policy updatedPolicy = project.replacePolicy(modifiedPolicy.build()); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java index dd252155645b..8c6a0eacd44f 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java @@ -202,10 +202,10 @@ public Project replace() { } /** - * Returns the IAM access control policy for the specified project. Returns {@code null} if the - * resource does not exist or if you do not have adequate permission to view the project or get - * the policy. + * Returns the IAM access control policy for this project. Returns {@code null} if the resource + * does not exist or if you do not have adequate permission to view the project or get the policy. * + * @return the IAM policy for the project * @throws ResourceManagerException upon failure * @see @@ -216,12 +216,12 @@ public Policy getPolicy() { } /** - * Sets the IAM access control policy for the specified project. Replaces any existing policy. - * It is recommended that you use the read-modify-write pattern. See code samples and important - * details of replacing policies in the documentation for {@link ResourceManager#replacePolicy}. + * Sets the IAM access control policy for this project. Replaces any existing policy. It is + * recommended that you use the read-modify-write pattern. See code samples and important details + * of replacing policies in the documentation for {@link ResourceManager#replacePolicy}. * + * @return the newly set IAM policy for this project * @throws ResourceManagerException upon failure - * @see ResourceManager#replacePolicy * @see * Resource Manager setIamPolicy @@ -237,7 +237,7 @@ public Policy replacePolicy(Policy newPolicy) { * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI * should be available to the logged-in user. * - * @return A list of booleans representing whether the caller has the permissions specified (in + * @return a list of booleans representing whether the caller has the permissions specified (in * the order of the given permissions) * @throws ResourceManagerException upon failure * @see testPermissions(List permissions) { * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI * should be available to the logged-in user. * - * @return A list of booleans representing whether the caller has the permissions specified (in + * @return a list of booleans representing whether the caller has the permissions specified (in * the order of the given permissions) * @throws ResourceManagerException upon failure * @see EMPTY_RPC_OPTIONS = ImmutableMap.of(); private static final Policy POLICY = Policy.builder() - .addBinding(Role.owner(), Identity.user("me@gmail.com")) - .addBinding(Role.editor(), Identity.serviceAccount("serviceaccount@gmail.com")) + .addIdentity(Role.owner(), Identity.user("me@gmail.com")) + .addIdentity(Role.editor(), Identity.serviceAccount("serviceaccount@gmail.com")) .build(); @Rule diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index f71f5d7989d6..9aef553caaa6 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.assertNotSame; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.gcloud.Identity; import com.google.gcloud.PageImpl; import com.google.gcloud.RetryParams; @@ -55,9 +54,8 @@ public class SerializationTest { ResourceManager.ProjectGetOption.fields(ResourceManager.ProjectField.NAME); private static final ResourceManager.ProjectListOption PROJECT_LIST_OPTION = ResourceManager.ProjectListOption.filter("name:*"); - private static final Policy POLICY = Policy.builder() - .addBinding(Policy.Role.viewer(), ImmutableSet.of(Identity.user("abc@gmail.com"))) - .build(); + private static final Policy POLICY = + Policy.builder().addIdentity(Policy.Role.viewer(), Identity.user("abc@gmail.com")).build(); @Test public void testServiceOptions() throws Exception {