diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index 979de6e95580..6d79faf18862 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -18,6 +18,7 @@ import com.google.common.base.Joiner; import com.google.common.collect.Sets; +import com.google.gcloud.IamPolicy; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.spi.ResourceManagerRpc; @@ -184,10 +185,12 @@ public enum Permission { SET_BILLING("setBillingAccount"), UNDELETE("undelete"); + private static final String PREFIX = "resourcemanager.projects."; + private final String strValue; Permission(String suffix) { - this.strValue = "resourcemanager.projects." + suffix; + this.strValue = PREFIX + suffix; } String strValue() { @@ -196,7 +199,7 @@ String strValue() { } /** - * Create a new project. + * Creates a new project. * *
Initially, the project resource is owned by its creator exclusively. The creator can later * grant permission to others to read or update the project. Several APIs are activated @@ -307,7 +310,7 @@ String strValue() { * Sets the IAM access control policy for the specified project. Replaces any existing policy. The * following constraints apply: *
{@code @@ -356,7 +359,25 @@ String strValue() { * @see * Resource Manager testIamPermissions + * @return A list of booleans representing whether the caller has the permissions specified. The + * boolean responses are in the same order as the given list of permissions. * @throws ResourceManagerException upon failure */ ListtestPermissions(String projectId, List permissions); + + /** + * Returns the permissions that a caller has on the specified project. You typically don't call + * this method if you're using Google Cloud Platform directly to manage permissions. This method + * is intended for integration with your proprietary software, such as a customized graphical user + * interface. For example, the Cloud Platform Console tests IAM permissions internally to + * determine which UI should be available to the logged-in user. + * + * @see + * Resource Manager testIamPermissions + * @return A list of booleans representing whether the caller has the permissions specified. The + * boolean responses are in the same order as the given permissions. + * @throws ResourceManagerException upon failure + */ + List testPermissions(String projectId, Permission first, Permission... others); } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java index 09f8a9bb9229..b1a844361b85 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java @@ -33,6 +33,8 @@ import com.google.gcloud.spi.ResourceManagerRpc; import com.google.gcloud.spi.ResourceManagerRpc.Tuple; +import java.util.Arrays; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; @@ -57,8 +59,8 @@ public com.google.api.services.cloudresourcemanager.model.Project call() { return resourceManagerRpc.create(project.toPb()); } }, options().retryParams(), EXCEPTION_HANDLER)); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -72,8 +74,8 @@ public Void call() { return null; } }, options().retryParams(), EXCEPTION_HANDLER); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -89,8 +91,8 @@ public com.google.api.services.cloudresourcemanager.model.Project call() { } }, options().retryParams(), EXCEPTION_HANDLER); return answer == null ? null : Project.fromPb(this, answer); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -148,8 +150,8 @@ public Project apply( }); return new PageImpl<>( new ProjectPageFetcher(serviceOptions, cursor, optionsMap), cursor, projects); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -163,8 +165,8 @@ public com.google.api.services.cloudresourcemanager.model.Project call() { return resourceManagerRpc.replace(newProject.toPb()); } }, options().retryParams(), EXCEPTION_HANDLER)); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -178,8 +180,8 @@ public Void call() { return null; } }, options().retryParams(), EXCEPTION_HANDLER); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -197,8 +199,8 @@ public com.google.api.services.cloudresourcemanager.model.Policy call() { options().retryParams(), EXCEPTION_HANDLER); return answer == null ? null : Policy.fromPb(answer); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -212,8 +214,8 @@ public com.google.api.services.cloudresourcemanager.model.Policy call() { return resourceManagerRpc.replacePolicy(projectId, newPolicy.toPb()); } }, options().retryParams(), EXCEPTION_HANDLER)); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -227,17 +229,25 @@ public List call() { return resourceManagerRpc.testPermissions(projectId, Lists.transform(permissions, new Function () { @Override - public String apply(Permission p) { - return p.strValue(); + public String apply(Permission permission) { + return permission.strValue(); } })); } }, options().retryParams(), EXCEPTION_HANDLER); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } + @Override + public List testPermissions(String projectId, Permission first, Permission... others) { + List permissions = new LinkedList<>(); + permissions.add(first); + permissions.addAll(Arrays.asList(others)); + return testPermissions(projectId, permissions); + } + private Map optionMap(Option... options) { Map temp = Maps.newEnumMap(ResourceManagerRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index b8bfcb77b76c..45e8a09b089b 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -59,14 +59,14 @@ * * *
- This mock assumes you have adequate permissions for any action. Related to this, - * testIamPermissions always indicates that the caller has all permissions listed in the + * testIamPermissions always indicates that the caller has all permissions listed in the * request. *
- IAM policies are set to an empty policy with version 0 (only legacy roles supported) upon * project creation. The actual service will not have an empty list of bindings and may also * set your version to 1. *
- There is no input validation for the policy provided when replacing a policy. - *
- In this mock, projects never move from the DELETE_REQUESTED lifecycle state to - * DELETE_IN_PROGRESS without an explicit call to the utility method + *
- In this mock, projects never move from the DELETE_REQUESTED lifecycle state to + * DELETE_IN_PROGRESS without an explicit call to the utility method * {@link #changeLifecycleState}. Similarly, a project is never completely removed without an * explicit call to the utility method {@link #removeProject}. *
- The messages in the error responses given by this mock do not necessarily match the messages diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java index fab14061d433..6902f1ce1685 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java @@ -1,5 +1,6 @@ package com.google.gcloud.spi; +import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.gcloud.spi.ResourceManagerRpc.Option.FIELDS; import static com.google.gcloud.spi.ResourceManagerRpc.Option.FILTER; import static com.google.gcloud.spi.ResourceManagerRpc.Option.PAGE_SIZE; @@ -152,7 +153,8 @@ public List
testPermissions(String projectId, List permissions) .testIamPermissions( projectId, new TestIamPermissionsRequest().setPermissions(permissions)) .execute(); - Set permissionsOwned = ImmutableSet.copyOf(response.getPermissions()); + Set permissionsOwned = + ImmutableSet.copyOf(firstNonNull(response.getPermissions(), ImmutableList. of())); ImmutableList.Builder answer = ImmutableList.builder(); for (String p : permissions) { answer.add(permissionsOwned.contains(p)); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java index dd009c52b05e..c556ea684380 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java @@ -131,7 +131,7 @@ public Y y() { Policy getPolicy(String projectId); /** - * Replaces the IAM policy associated with the given project ID. + * Replaces the IAM policy associated with the given project. * * @throws ResourceManagerException upon failure */ diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 68a70f65114a..ada14ab4c977 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -378,6 +378,9 @@ public void testTestPermissions() { RESOURCE_MANAGER.create(PARTIAL_PROJECT); assertEquals(ImmutableList.of(true), RESOURCE_MANAGER.testPermissions(PARTIAL_PROJECT.projectId(), permissions)); + assertEquals(ImmutableList.of(true, true), + RESOURCE_MANAGER.testPermissions( + PARTIAL_PROJECT.projectId(), Permission.DELETE, Permission.OWN)); } @Test