001package com.box.sdk; 002 003import com.eclipsesource.json.Json; 004import com.eclipsesource.json.JsonObject; 005import com.eclipsesource.json.JsonValue; 006import java.net.URL; 007import java.util.Date; 008import java.util.HashMap; 009import java.util.Map; 010 011/** 012 * Represents a relationship between a user and a group. 013 * 014 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link 015 * BoxAPIException} (unchecked meaning that the compiler won't force you to handle it) if an error 016 * occurs. If you wish to implement custom error handling for errors related to the Box REST API, 017 * you should capture this exception explicitly. 018 */ 019@BoxResourceType("group_membership") 020public class BoxGroupMembership extends BoxResource { 021 022 /** 023 * The URL template for all group membership requests. 024 * 025 * @see #getInfo() 026 */ 027 public static final URLTemplate MEMBERSHIP_URL_TEMPLATE = new URLTemplate("group_memberships/%s"); 028 029 /** 030 * Constructs a BoxGroupMembership for a group membership with a given ID. 031 * 032 * @param api the API connection to be used by the group membership. 033 * @param id the ID of the group membership. 034 */ 035 public BoxGroupMembership(BoxAPIConnection api, String id) { 036 super(api, id); 037 } 038 039 /** 040 * Gets information about this group membership. 041 * 042 * @return info about this group membership. 043 */ 044 public Info getInfo() { 045 BoxAPIConnection api = this.getAPI(); 046 URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID()); 047 048 BoxJSONRequest request = new BoxJSONRequest(api, url, "GET"); 049 try (BoxJSONResponse response = request.send()) { 050 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 051 return new Info(jsonObject); 052 } 053 } 054 055 /** 056 * Updates the information about this group membership with any info fields that have been 057 * modified locally. 058 * 059 * @param info the updated info. 060 */ 061 public void updateInfo(Info info) { 062 BoxAPIConnection api = this.getAPI(); 063 URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID()); 064 065 BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT"); 066 request.setBody(info.getPendingChanges()); 067 try (BoxJSONResponse response = request.send()) { 068 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 069 info.update(jsonObject); 070 } 071 } 072 073 /** Deletes this group membership. */ 074 public void delete() { 075 BoxAPIConnection api = this.getAPI(); 076 URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID()); 077 078 BoxAPIRequest request = new BoxAPIRequest(api, url, "DELETE"); 079 request.send().close(); 080 } 081 082 /** Enumerates the possible roles that a user can have within a group. */ 083 public enum GroupRole { 084 /** The user is an administrator in the group. */ 085 ADMIN("admin"), 086 087 /** The user is a regular member in the group. */ 088 MEMBER("member"); 089 090 /** String representation of the groupRole. */ 091 private final String jsonValue; 092 093 /** 094 * Constructor. 095 * 096 * @param jsonValue string representation of the role. 097 */ 098 GroupRole(String jsonValue) { 099 this.jsonValue = jsonValue; 100 } 101 102 /** 103 * Creates the groupRole from given string. 104 * 105 * @param jsonValue string to be converted to role. 106 * @return the role, created from string value. 107 */ 108 static GroupRole fromJSONString(String jsonValue) { 109 for (GroupRole role : GroupRole.values()) { 110 if (role.jsonValue.equalsIgnoreCase(jsonValue)) { 111 return role; 112 } 113 } 114 throw new IllegalArgumentException("Invalid value for enum GroupRole: " + jsonValue); 115 } 116 117 /** @return string representation of the groupRole. */ 118 String toJSONString() { 119 return this.jsonValue; 120 } 121 } 122 123 /** Enumerates the possible permissions that a user can have as a group admin. */ 124 public enum Permission { 125 /** The user can create accounts. */ 126 CAN_CREATE_ACCOUNTS("can_create_accounts"), 127 128 /** The user can edit accounts. */ 129 CAN_EDIT_ACCOUNTS("can_edit_accounts"), 130 131 /** The user can instant login as another user. */ 132 CAN_INSTANT_LOGIN("can_instant_login"), 133 134 /** The user can run reports. */ 135 CAN_RUN_REPORTS("can_run_reports"); 136 137 private final String jsonValue; 138 139 Permission(String jsonValue) { 140 this.jsonValue = jsonValue; 141 } 142 143 static Permission fromJSONValue(String jsonValue) { 144 return Permission.valueOf(jsonValue.toUpperCase(java.util.Locale.ROOT)); 145 } 146 147 String toJSONValue() { 148 return this.jsonValue; 149 } 150 } 151 152 /** Contains information about a BoxGroupMembership. */ 153 public class Info extends BoxResource.Info { 154 155 /** @see #getUser() */ 156 private BoxUser.Info user; 157 158 /** @see #getGroup() */ 159 private BoxGroup.Info group; 160 161 /** @see #getGroupRole() */ 162 private GroupRole groupRole; 163 164 /** @see #getCreatedAt() */ 165 private Date createdAt; 166 167 /** @see #getModifiedAt() */ 168 private Date modifiedAt; 169 170 /** @see #getConfigurablePermissions() */ 171 private Map<Permission, Boolean> configurablePermissions; 172 173 /** Constructs an empty Info object. */ 174 public Info() { 175 super(); 176 } 177 178 /** 179 * Constructs an Info object by parsing information from a JSON string. 180 * 181 * @param json the JSON string to parse. 182 */ 183 public Info(String json) { 184 super(json); 185 } 186 187 /** 188 * Constructs an Info object using an already parsed JSON object. 189 * 190 * @param jsonObject the parsed JSON object. 191 */ 192 Info(JsonObject jsonObject) { 193 super(jsonObject); 194 } 195 196 /** 197 * Gets the user belonging to the group. 198 * 199 * <p>Note: the BoxUser.Info returned by this method will only have the ID, name, and login 200 * fields populated. 201 * 202 * @return the user belonging to the group. 203 */ 204 public BoxUser.Info getUser() { 205 return this.user; 206 } 207 208 /** 209 * Gets the group the user belongs to. 210 * 211 * <p>Note: the BoxGroup.Info returned by this method will only have the ID and name fields 212 * populated. 213 * 214 * @return the group the user belongs to. 215 */ 216 public BoxGroup.Info getGroup() { 217 return this.group; 218 } 219 220 /** 221 * Gets the level of access the user has. 222 * 223 * @return the level of access the user has. 224 */ 225 public GroupRole getGroupRole() { 226 return this.groupRole; 227 } 228 229 /** 230 * Sets the level of access the user has. 231 * 232 * @param role the new level of access to give the user. 233 */ 234 public void setGroupRole(GroupRole role) { 235 this.groupRole = role; 236 this.addPendingChange("role", role.toJSONString()); 237 } 238 239 /** 240 * Gets the time the group membership was created. 241 * 242 * @return the time the group membership was created. 243 */ 244 public Date getCreatedAt() { 245 return this.createdAt; 246 } 247 248 /** 249 * Gets the time the group membership was last modified. 250 * 251 * @return the time the group membership was last modified. 252 */ 253 public Date getModifiedAt() { 254 return this.modifiedAt; 255 } 256 257 /** 258 * Gets the configurablePermissions that the current user has on the group as group admin. 259 * 260 * @return the configurablePermissions that the current user has on the group as group admin. 261 */ 262 public Map<Permission, Boolean> getConfigurablePermissions() { 263 return this.configurablePermissions; 264 } 265 266 /** 267 * Sets the configurablePermissions that the current user has on the group as group admin. 268 * 269 * @param configurablePermissions a Map representing the group admin configurable permissions 270 */ 271 public void setConfigurablePermissions(Map<Permission, Boolean> configurablePermissions) { 272 this.configurablePermissions = configurablePermissions; 273 this.addPendingChange("configurable_permissions", this.configurablePermissionJson()); 274 } 275 276 /** 277 * append new configurable permissions to the previous existing list. 278 * 279 * @param permission the group admin permission one wants to enable or disable of the user on 280 * the group. 281 * @param value the true/false value of the attribute to set. 282 */ 283 public void appendConfigurablePermissions(Permission permission, Boolean value) { 284 this.configurablePermissions.put(permission, value); 285 this.addPendingChange("configurable_permissions", this.configurablePermissionJson()); 286 } 287 288 private JsonObject configurablePermissionJson() { 289 JsonObject configurablePermissionJson = new JsonObject(); 290 for (Permission attrKey : this.configurablePermissions.keySet()) { 291 configurablePermissionJson.set( 292 attrKey.toJSONValue(), this.configurablePermissions.get(attrKey)); 293 } 294 return configurablePermissionJson; 295 } 296 297 /** {@inheritDoc} */ 298 @Override 299 public BoxGroupMembership getResource() { 300 return BoxGroupMembership.this; 301 } 302 303 private Map<Permission, Boolean> parseConfigurablePermissions(JsonObject jsonObject) { 304 if (jsonObject == null) { 305 return null; 306 } 307 Map<Permission, Boolean> permissions = new HashMap<>(); 308 for (JsonObject.Member member : jsonObject) { 309 String memberName = member.getName(); 310 boolean memberValue = member.getValue().asBoolean(); 311 switch (memberName) { 312 case "can_create_accounts": 313 permissions.put(Permission.CAN_CREATE_ACCOUNTS, memberValue); 314 break; 315 case "can_edit_accounts": 316 permissions.put(Permission.CAN_EDIT_ACCOUNTS, memberValue); 317 break; 318 case "can_instant_login": 319 permissions.put(Permission.CAN_INSTANT_LOGIN, memberValue); 320 break; 321 case "can_run_reports": 322 permissions.put(Permission.CAN_RUN_REPORTS, memberValue); 323 break; 324 default: 325 break; 326 } 327 } 328 return permissions; 329 } 330 331 /** {@inheritDoc} */ 332 @Override 333 protected void parseJSONMember(JsonObject.Member member) { 334 super.parseJSONMember(member); 335 336 String memberName = member.getName(); 337 JsonValue value = member.getValue(); 338 339 try { 340 switch (memberName) { 341 case "user": 342 JsonObject userJSON = value.asObject(); 343 if (this.user == null) { 344 String userID = userJSON.get("id").asString(); 345 BoxUser user = new BoxUser(getAPI(), userID); 346 this.user = user.new Info(userJSON); 347 } else { 348 this.user.update(userJSON); 349 } 350 351 break; 352 case "group": 353 JsonObject groupJSON = value.asObject(); 354 if (this.group == null) { 355 String userID = groupJSON.get("id").asString(); 356 BoxGroup group = new BoxGroup(getAPI(), userID); 357 this.group = group.new Info(groupJSON); 358 } else { 359 this.group.update(groupJSON); 360 } 361 362 break; 363 case "role": 364 this.groupRole = GroupRole.fromJSONString(value.asString()); 365 366 break; 367 case "created_at": 368 this.createdAt = BoxDateFormat.parse(value.asString()); 369 370 break; 371 case "modified_at": 372 this.modifiedAt = BoxDateFormat.parse(value.asString()); 373 374 break; 375 case "configurable_permissions": 376 this.configurablePermissions = this.parseConfigurablePermissions(value.asObject()); 377 378 break; 379 default: 380 break; 381 } 382 } catch (Exception e) { 383 throw new BoxDeserializationException(memberName, value.toString(), e); 384 } 385 } 386 } 387}