Skip to content

Commit

Permalink
Merge pull request #772 from ajkannan/support-more-iam-roles
Browse files Browse the repository at this point in the history
Make Role and Permission strings to allow for service-specific values
  • Loading branch information
ajkannan committed Mar 22, 2016
2 parents 5fbb41c + 52bf6c1 commit a78f0a7
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 238 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

import com.google.gcloud.Identity;
import com.google.gcloud.resourcemanager.Policy;
import com.google.gcloud.resourcemanager.Policy.Role;
import com.google.gcloud.resourcemanager.Policy.ProjectRole;
import com.google.gcloud.resourcemanager.Project;
import com.google.gcloud.resourcemanager.ResourceManager;
import com.google.gcloud.resourcemanager.ResourceManagerOptions;
Expand All @@ -49,7 +49,7 @@ public static void main(String... args) {
// Add a viewer
Policy.Builder modifiedPolicy = policy.toBuilder();
Identity newViewer = Identity.user("<insert user's email address here>");
modifiedPolicy.addIdentity(Role.viewer(), newViewer);
modifiedPolicy.addIdentity(ProjectRole.VIEWER.value(), newViewer);

// Write policy
Policy updatedPolicy = project.replacePolicy(modifiedPolicy.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@
import com.google.gcloud.IamPolicy;
import com.google.gcloud.Identity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
Expand All @@ -42,120 +40,63 @@
*
* @see <a href="https://cloud.google.com/iam/reference/rest/v1/Policy">Policy</a>
*/
public class Policy extends IamPolicy<Policy.Role> {
public class Policy extends IamPolicy<String> {

private static final long serialVersionUID = -5573557282693961850L;

/**
* Represents legacy roles in an IAM Policy.
* The project-level roles in an IAM policy. This enum is not an exhaustive list of all roles
* you can use in an IAM policy. You can also use service-specific roles (e.g.
* "roles/pubsub.editor"). See the <i>Supported Cloud Platform Services</i> page for links
* to service-specific roles.
*
* @see <a href="https://cloud.google.com/iam/#supported_cloud_platform_services">Supported Cloud
* Platform Services</a>
*/
public static class Role implements Serializable {
public enum ProjectRole {

/**
* The recognized roles in a Project's IAM policy.
* Permissions for read-only actions that preserve state.
*/
public enum Type {

/**
* Permissions for read-only actions that preserve state.
*/
VIEWER,

/**
* All viewer permissions and permissions for actions that modify state.
*/
EDITOR,

/**
* All editor permissions and permissions for the following actions:
* <ul>
* <li>Manage access control for a resource.
* <li>Set up billing (for a project).
* </ul>
*/
OWNER
}

private static final long serialVersionUID = 2421978909244287488L;

private final String value;
private final Type type;

private Role(String value, Type type) {
this.value = value;
this.type = type;
}

String value() {
return value;
}
VIEWER("roles/viewer"),

/**
* Returns the type of role (editor, owner, or viewer). Returns {@code null} if the role type
* is unrecognized.
* All viewer permissions and permissions for actions that modify state.
*/
public Type type() {
return type;
}
EDITOR("roles/editor"),

/**
* Returns a {@code Role} of type {@link Type#VIEWER VIEWER}.
* All editor permissions and permissions for the following actions:
* <ul>
* <li>Manage access control for a resource.
* <li>Set up billing (for a project).
* </ul>
*/
public static Role viewer() {
return new Role("roles/viewer", Type.VIEWER);
}
OWNER("roles/owner");

/**
* Returns a {@code Role} of type {@link Type#EDITOR EDITOR}.
*/
public static Role editor() {
return new Role("roles/editor", Type.EDITOR);
private final String value;

private ProjectRole(String value) {
this.value = value;
}

/**
* Returns a {@code Role} of type {@link Type#OWNER OWNER}.
* Returns the string value associated with the role.
*/
public static Role owner() {
return new Role("roles/owner", Type.OWNER);
}

static Role rawRole(String roleStr) {
return new Role(roleStr, null);
}

static Role fromStr(String roleStr) {
try {
Type type = Type.valueOf(roleStr.split("/")[1].toUpperCase());
return new Role(roleStr, type);
} catch (Exception ex) {
return new Role(roleStr, null);
}
}

@Override
public final int hashCode() {
return Objects.hash(value, type);
}

@Override
public final boolean equals(Object obj) {
if (!(obj instanceof Role)) {
return false;
}
Role other = (Role) obj;
return Objects.equals(value, other.value()) && Objects.equals(type, other.type());
public String value() {
return value;
}
}

/**
* Builder for an IAM Policy.
*/
public static class Builder extends IamPolicy.Builder<Role, Builder> {
public static class Builder extends IamPolicy.Builder<String, Builder> {

private Builder() {}

@VisibleForTesting
Builder(Map<Role, Set<Identity>> bindings, String etag, Integer version) {
Builder(Map<String, Set<Identity>> bindings, String etag, Integer version) {
bindings(bindings).etag(etag).version(version);
}

Expand Down Expand Up @@ -188,10 +129,10 @@ com.google.api.services.cloudresourcemanager.model.Policy toPb() {
new com.google.api.services.cloudresourcemanager.model.Policy();
List<com.google.api.services.cloudresourcemanager.model.Binding> bindingPbList =
new LinkedList<>();
for (Map.Entry<Role, Set<Identity>> binding : bindings().entrySet()) {
for (Map.Entry<String, Set<Identity>> binding : bindings().entrySet()) {
com.google.api.services.cloudresourcemanager.model.Binding bindingPb =
new com.google.api.services.cloudresourcemanager.model.Binding();
bindingPb.setRole(binding.getKey().value());
bindingPb.setRole(binding.getKey());
bindingPb.setMembers(
Lists.transform(
new ArrayList<>(binding.getValue()),
Expand All @@ -211,11 +152,11 @@ public String apply(Identity identity) {

static Policy fromPb(
com.google.api.services.cloudresourcemanager.model.Policy policyPb) {
Map<Role, Set<Identity>> bindings = new HashMap<>();
Map<String, Set<Identity>> bindings = new HashMap<>();
for (com.google.api.services.cloudresourcemanager.model.Binding bindingPb :
policyPb.getBindings()) {
bindings.put(
Role.fromStr(bindingPb.getRole()),
bindingPb.getRole(),
ImmutableSet.copyOf(
Lists.transform(
bindingPb.getMembers(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.gcloud.resourcemanager.ResourceManager.Permission;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;
Expand Down Expand Up @@ -235,35 +233,22 @@ public Policy replacePolicy(Policy newPolicy) {
* 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.
* should be available to the logged-in user. Each service that supports IAM lists the possible
* permissions; see the <i>Supported Cloud Platform services</i> page below for links to these
* lists.
*
* @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 <a href=
* "https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/testIamPermissions">
* Resource Manager testIamPermissions</a>
*/
List<Boolean> testPermissions(List<Permission> permissions) {
return resourceManager.testPermissions(projectId(), permissions);
}

/**
* Returns the permissions that a caller has on this 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.
*
* @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 <a href=
* "https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/testIamPermissions">
* Resource Manager testIamPermissions</a>
* "https://cloud.google.com/iam/#supported_cloud_platform_services">Supported Cloud Platform
* Services</a>
*/
List<Boolean> testPermissions(Permission first, Permission... others) {
return resourceManager.testPermissions(projectId(), first, others);
List<Boolean> testPermissions(List<String> permissions) {
return resourceManager.testPermissions(projectId(), permissions);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,38 +169,6 @@ public static ProjectListOption fields(ProjectField... fields) {
}
}

/**
* The permissions associated with a Google Cloud project. These values can be used when calling
* {@link #testPermissions}.
*
* @see <a href=
* "https://cloud.google.com/resource-manager/docs/access-control-proj#project-level_roles">
* Project-level roles</a>
*/
enum Permission {
DELETE("delete"),
GET("get"),
GET_POLICY("getIamPolicy"),
REPLACE("update"),
REPLACE_POLICY("setIamPolicy"),
UNDELETE("undelete");

private static final String PREFIX = "resourcemanager.projects.";

private final String value;

Permission(String suffix) {
this.value = PREFIX + suffix;
}

/**
* Returns the string representation of the permission.
*/
public String value() {
return value;
}
}

/**
* Creates a new project.
*
Expand Down Expand Up @@ -358,30 +326,19 @@ public String value() {
* 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.
* determine which UI should be available to the logged-in user. Each service that supports IAM
* lists the possible permissions; see the <i>Supported Cloud Platform services</i> page below for
* links to these lists.
*
* @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 <a href=
* "https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/testIamPermissions">
* Resource Manager testIamPermissions</a>
*/
List<Boolean> testPermissions(String projectId, List<Permission> 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.
*
* @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 <a href=
* "https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/testIamPermissions">
* Resource Manager testIamPermissions</a>
* "https://cloud.google.com/iam/#supported_cloud_platform_services">Supported Cloud Platform
* Services</a>
*/
List<Boolean> testPermissions(String projectId, Permission first, Permission... others);
List<Boolean> testPermissions(String projectId, List<String> permissions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gcloud.BaseService;
import com.google.gcloud.Page;
Expand Down Expand Up @@ -216,31 +215,20 @@ public com.google.api.services.cloudresourcemanager.model.Policy call() {
}

@Override
public List<Boolean> testPermissions(final String projectId, final List<Permission> permissions) {
public List<Boolean> testPermissions(final String projectId, final List<String> permissions) {
try {
return runWithRetries(
new Callable<List<Boolean>>() {
@Override
public List<Boolean> call() {
return resourceManagerRpc.testPermissions(projectId,
Lists.transform(permissions, new Function<Permission, String>() {
@Override
public String apply(Permission permission) {
return permission.value();
}
}));
return resourceManagerRpc.testPermissions(projectId, permissions);
}
}, options().retryParams(), EXCEPTION_HANDLER);
} catch (RetryHelperException ex) {
throw ResourceManagerException.translateAndThrow(ex);
}
}

@Override
public List<Boolean> testPermissions(String projectId, Permission first, Permission... others) {
return testPermissions(projectId, Lists.asList(first, others));
}

private Map<ResourceManagerRpc.Option, ?> optionMap(Option... options) {
Map<ResourceManagerRpc.Option, Object> temp = Maps.newEnumMap(ResourceManagerRpc.Option.class);
for (Option option : options) {
Expand Down
Loading

0 comments on commit a78f0a7

Please sign in to comment.