Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

feat: implement testPermission api of organizations #125

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- see http://mojo.codehaus.org/clirr-maven-plugin/examples/ignored-differences.html -->
<differences>
<difference>
<className>com/google/cloud/resourcemanager/ResourceManager</className>
<method>java.util.List testOrgPermissions(java.lang.String, java.util.List)</method>
<differenceType>7012</differenceType>
</difference>
<difference>
<className>com/google/cloud/resourcemanager/spi/v1beta1/ResourceManagerRpc</className>
<method>java.util.List testOrgPermissions(java.lang.String, java.util.List)</method>
<differenceType>7012</differenceType>
</difference>
</differences>
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,20 @@ public static ProjectListOption fields(ProjectField... fields) {
* Platform Services</a>
*/
List<Boolean> testPermissions(String projectId, List<String> permissions);

/**
* Returns a list of booleans representing whether the caller has the permissions on the specified
* Organization.
*
* @param resource the organization's resource name, e.g. "organizations/123"
* @param permissions the set of permissions to check for the resource. Permissions with wildcards
* (such as '*' or 'storage.*') are not allowed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

period

* @return A list of booleans representing whether the caller has the permissions specified (in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: A --> a

* the order of the given permissions)
* @throws ResourceManagerException upon failure
* @see <a href=
* "https://cloud.google.com/resource-manager/reference/rest/v1/organizations/testIamPermissions">
* Resource Manager testIamPermissions</a>
*/
List<Boolean> testOrgPermissions(String resource, List<String> permissions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,24 @@ public List<Boolean> call() {
}
}

@Override
public List<Boolean> testOrgPermissions(final String resource, final List<String> permissions) {
try {
return runWithRetries(
new Callable<List<Boolean>>() {
@Override
public List<Boolean> call() {
return resourceManagerRpc.testOrgPermissions(resource, permissions);
}
},
getOptions().getRetrySettings(),
EXCEPTION_HANDLER,
getOptions().getClock());
} catch (RetryHelperException ex) {
throw ResourceManagerException.translateAndThrow(ex);
}
}

private Map<ResourceManagerRpc.Option, ?> optionMap(Option... options) {
Map<ResourceManagerRpc.Option, Object> temp = Maps.newEnumMap(ResourceManagerRpc.Option.class);
for (Option option : options) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,25 @@ projectId, new TestIamPermissionsRequest().setPermissions(permissions))
throw translate(ex);
}
}

@Override
public List<Boolean> testOrgPermissions(String resource, List<String> permissions) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API is strange. One rarely encounters a list of booleans. What does someone do with it? How do you know which boolean maps to which permission?

try {
TestIamPermissionsResponse response =
resourceManager
.organizations()
.testIamPermissions(
resource, new TestIamPermissionsRequest().setPermissions(permissions))
.execute();
Set<String> permissionsOwned =
ImmutableSet.copyOf(firstNonNull(response.getPermissions(), ImmutableList.<String>of()));
ImmutableList.Builder<Boolean> answer = ImmutableList.builder();
for (String permission : permissions) {
answer.add(permissionsOwned.contains(permission));
}
return answer.build();
} catch (IOException ex) {
throw translate(ex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,12 @@ Integer getInt(Map<Option, ?> options) {
*/
List<Boolean> testPermissions(String projectId, List<String> permissions);

// TODO(ajaykannan): implement "Organization" functionality when available (issue #319)
/**
* Tests whether the caller has the given permissions on the specified Organization. Returns a
* list of booleans corresponding to whether or not the user has the permission in the same
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we maybe just want the logical AND of all these permissions?

Or perhaps what you want to return is a Map<String, boolean> that lists the permissions and their results?

* position of input list.
*
* @throws ResourceManagerException upon failure
*/
List<Boolean> testOrgPermissions(String resource, List<String> permissions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -456,4 +456,42 @@ public void testRuntimeException() {
assertEquals(exceptionMessage, exception.getCause().getMessage());
}
}

@Test
public void testTestOrgPermissions() {
ResourceManagerRpcFactory rpcFactoryMock = EasyMock.createMock(ResourceManagerRpcFactory.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer Mockito per Google Java policy

ResourceManagerRpc resourceManagerRpcMock = EasyMock.createMock(ResourceManagerRpc.class);
EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(ResourceManagerOptions.class)))
.andReturn(resourceManagerRpcMock);
EasyMock.replay(rpcFactoryMock);
ResourceManager resourceManagerMock =
ResourceManagerOptions.newBuilder()
.setServiceRpcFactory(rpcFactoryMock)
.build()
.getService();
String organization = "organization/12345";
List<String> permissions =
ImmutableList.of(
"resourcemanager.organizations.get", "resourcemanager.organizations.getIamPolicy");
List<Boolean> booleans = ImmutableList.of(true, false);
EasyMock.expect(resourceManagerRpcMock.testOrgPermissions(organization, permissions))
.andReturn(booleans);
EasyMock.replay(resourceManagerRpcMock);
List<Boolean> values = resourceManagerMock.testOrgPermissions(organization, permissions);
assertEquals(booleans, values);
}

@Test
public void testTestOrgPermissionsWithException() {
List<String> permissions =
ImmutableList.of(
"resourcemanager.organizations.get", "resourcemanager.organizations.getIamPolicy");
try {
RESOURCE_MANAGER.testOrgPermissions("organizations/12345", permissions);
fail();
} catch (ResourceManagerException exception) {
assertEquals(404, exception.getCode());
assertTrue(exception.getMessage().contains("Not Found"));
}
}
}