1 /* 2 * Copyright 2016 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.cloud; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 21 import com.google.api.core.ApiFunction; 22 import com.google.common.base.CaseFormat; 23 import java.io.Serializable; 24 import java.util.Objects; 25 26 /** 27 * An identity in a {@link Policy}. The following types of identities are permitted in IAM policies: 28 * 29 * <ul> 30 * <li>Google account 31 * <li>Service account 32 * <li>Google group 33 * <li>Google Apps domain 34 * </ul> 35 * 36 * <p>There are also two special identities that represent all users and all Google-authenticated 37 * accounts. 38 * 39 * @see <a href="https://cloud.google.com/iam/docs/overview#concepts_related_to_identity">Concepts 40 * related to identity</a> 41 */ 42 public final class Identity implements Serializable { 43 44 private static final long serialVersionUID = -8181841964597657446L; 45 46 private final Type type; 47 private final String value; 48 49 /** The types of IAM identities. */ 50 public static final class Type extends StringEnumValue { 51 private static final long serialVersionUID = 3809891273596003916L; 52 Type(String constant)53 private Type(String constant) { 54 super(constant); 55 } 56 57 private static final ApiFunction<String, Type> CONSTRUCTOR = 58 new ApiFunction<String, Type>() { 59 @Override 60 public Type apply(String constant) { 61 return new Type(constant); 62 } 63 }; 64 65 private static final StringEnumType<Type> type = new StringEnumType(Type.class, CONSTRUCTOR); 66 67 /** Represents anyone who is on the internet; with or without a Google account. */ 68 public static final Type ALL_USERS = type.createAndRegister("ALL_USERS"); 69 70 /** Represents anyone who is authenticated with a Google account or a service account. */ 71 public static final Type ALL_AUTHENTICATED_USERS = 72 type.createAndRegister("ALL_AUTHENTICATED_USERS"); 73 74 /** Represents a specific Google account. */ 75 public static final Type USER = type.createAndRegister("USER"); 76 77 /** Represents a service account. */ 78 public static final Type SERVICE_ACCOUNT = type.createAndRegister("SERVICE_ACCOUNT"); 79 80 /** Represents a Google group. */ 81 public static final Type GROUP = type.createAndRegister("GROUP"); 82 83 /** Represents all the users of a Google Apps domain name. */ 84 public static final Type DOMAIN = type.createAndRegister("DOMAIN"); 85 86 /** Represents owners of a Google Cloud Platform project. */ 87 public static final Type PROJECT_OWNER = type.createAndRegister("PROJECT_OWNER"); 88 89 /** Represents editors of a Google Cloud Platform project. */ 90 public static final Type PROJECT_EDITOR = type.createAndRegister("PROJECT_EDITOR"); 91 92 /** Represents viewers of a Google Cloud Platform project. */ 93 public static final Type PROJECT_VIEWER = type.createAndRegister("PROJECT_VIEWER"); 94 95 /** 96 * Get the Type for the given String constant, and throw an exception if the constant is not 97 * recognized. 98 */ valueOfStrict(String constant)99 public static Type valueOfStrict(String constant) { 100 return type.valueOfStrict(constant); 101 } 102 103 /** Get the Type for the given String constant, and allow unrecognized values. */ valueOf(String constant)104 public static Type valueOf(String constant) { 105 return type.valueOf(constant); 106 } 107 108 /** Return the known values for Type. */ values()109 public static Type[] values() { 110 return type.values(); 111 } 112 } 113 Identity(Type type, String value)114 private Identity(Type type, String value) { 115 this.type = type; 116 this.value = value; 117 } 118 getType()119 public Type getType() { 120 return type; 121 } 122 123 /** 124 * Returns the string identifier for this identity. The value corresponds to: 125 * 126 * <ul> 127 * <li>email address (for identities of type {@code USER}, {@code SERVICE_ACCOUNT}, and {@code 128 * GROUP}) 129 * <li>domain (for identities of type {@code DOMAIN}) 130 * <li>{@code null} (for identities of type {@code ALL_USERS} and {@code 131 * ALL_AUTHENTICATED_USERS}) 132 * </ul> 133 */ getValue()134 public String getValue() { 135 return value; 136 } 137 138 /** 139 * Returns a new identity representing anyone who is on the internet; with or without a Google 140 * account. 141 */ allUsers()142 public static Identity allUsers() { 143 return new Identity(Type.ALL_USERS, null); 144 } 145 146 /** 147 * Returns a new identity representing anyone who is authenticated with a Google account or a 148 * service account. 149 */ allAuthenticatedUsers()150 public static Identity allAuthenticatedUsers() { 151 return new Identity(Type.ALL_AUTHENTICATED_USERS, null); 152 } 153 154 /** 155 * Returns a new user identity. 156 * 157 * @param email An email address that represents a specific Google account. For example, 158 * <I>alice@gmail.com</I> or <I>joe@example.com</I>. 159 */ user(String email)160 public static Identity user(String email) { 161 return new Identity(Type.USER, checkNotNull(email)); 162 } 163 164 /** 165 * Returns a new service account identity. 166 * 167 * @param email An email address that represents a service account. For example, 168 * <I>my-other-app@appspot.gserviceaccount.com</I>. 169 */ serviceAccount(String email)170 public static Identity serviceAccount(String email) { 171 return new Identity(Type.SERVICE_ACCOUNT, checkNotNull(email)); 172 } 173 174 /** 175 * Returns a new group identity. 176 * 177 * @param email An email address that represents a Google group. For example, 178 * <I>admins@example.com</I>. 179 */ group(String email)180 public static Identity group(String email) { 181 return new Identity(Type.GROUP, checkNotNull(email)); 182 } 183 184 /** 185 * Returns a new domain identity. 186 * 187 * @param domain A Google Apps domain name that represents all the users of that domain. For 188 * example, <I>google.com</I> or <I>example.com</I>. 189 */ domain(String domain)190 public static Identity domain(String domain) { 191 return new Identity(Type.DOMAIN, checkNotNull(domain)); 192 } 193 194 /** 195 * Returns a new project owner identity. 196 * 197 * @param projectId A Google Cloud Platform project ID. For example, <I>my-sample-project</I>. 198 */ projectOwner(String projectId)199 public static Identity projectOwner(String projectId) { 200 return new Identity(Type.PROJECT_OWNER, checkNotNull(projectId)); 201 } 202 203 /** 204 * Returns a new project editor identity. 205 * 206 * @param projectId A Google Cloud Platform project ID. For example, <I>my-sample-project</I>. 207 */ projectEditor(String projectId)208 public static Identity projectEditor(String projectId) { 209 return new Identity(Type.PROJECT_EDITOR, checkNotNull(projectId)); 210 } 211 212 /** 213 * Returns a new project viewer identity. 214 * 215 * @param projectId A Google Cloud Platform project ID. For example, <I>my-sample-project</I>. 216 */ projectViewer(String projectId)217 public static Identity projectViewer(String projectId) { 218 return new Identity(Type.PROJECT_VIEWER, checkNotNull(projectId)); 219 } 220 221 @Override toString()222 public String toString() { 223 return strValue(); 224 } 225 226 @Override hashCode()227 public int hashCode() { 228 return Objects.hash(value, type); 229 } 230 231 @Override equals(Object obj)232 public boolean equals(Object obj) { 233 if (!(obj instanceof Identity)) { 234 return false; 235 } 236 Identity other = (Identity) obj; 237 return Objects.equals(value, other.getValue()) && Objects.equals(type, other.getType()); 238 } 239 240 /** 241 * Returns the string value associated with the identity. Used primarily for converting from 242 * {@code Identity} objects to strings for protobuf-generated policies. 243 */ strValue()244 public String strValue() { 245 String protobufString = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, type.toString()); 246 if (value == null) { 247 return protobufString; 248 } else { 249 return protobufString + ":" + value; 250 } 251 } 252 253 /** 254 * Converts a string to an {@code Identity}. Used primarily for converting protobuf-generated 255 * policy identities to {@code Identity} objects. 256 */ valueOf(String identityStr)257 public static Identity valueOf(String identityStr) { 258 String[] info = identityStr.split(":", 2); 259 Type type = Type.valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, info[0])); 260 if (info.length == 1) { 261 return new Identity(type, null); 262 } else if (info.length == 2) { 263 return new Identity(type, info[1]); 264 } else { 265 throw new IllegalArgumentException("Illegal identity string: \"" + identityStr + "\""); 266 } 267 } 268 } 269