001package com.box.sdk; 002 003import java.io.InputStream; 004import java.net.URL; 005import java.util.ArrayList; 006import java.util.Collection; 007import java.util.HashMap; 008import java.util.Iterator; 009import java.util.List; 010import java.util.Map; 011 012import com.eclipsesource.json.JsonArray; 013import com.eclipsesource.json.JsonObject; 014import com.eclipsesource.json.JsonValue; 015 016/** 017 * Represents a Box user account. 018 * 019 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked 020 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error 021 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p> 022 */ 023@BoxResourceType("user") 024public class BoxUser extends BoxCollaborator { 025 026 /** 027 * An array of all possible file fields that can be requested when calling {@link #getInfo(String...)}. 028 */ 029 public static final String[] ALL_FIELDS = {"type", "id", "name", "login", "created_at", "modified_at", "role", 030 "language", "timezone", "space_amount", "space_used", "max_upload_size", "tracking_codes", 031 "can_see_managed_users", "is_sync_enabled", "is_external_collab_restricted", "status", "job_title", "phone", 032 "address", "avatar_url", "is_exempt_from_device_limits", "is_exempt_from_login_verification", "enterprise", 033 "my_tags", "hostname", "is_platform_access_only", "external_app_user_id"}; 034 035 /** 036 * User URL Template. 037 */ 038 public static final URLTemplate USER_URL_TEMPLATE = new URLTemplate("users/%s"); 039 /** 040 * Get Me URL Template. 041 */ 042 public static final URLTemplate GET_ME_URL = new URLTemplate("users/me"); 043 /** 044 * Users URL Template. 045 */ 046 public static final URLTemplate USERS_URL_TEMPLATE = new URLTemplate("users"); 047 /** 048 * User Memberships URL Template. 049 */ 050 public static final URLTemplate USER_MEMBERSHIPS_URL_TEMPLATE = new URLTemplate("users/%s/memberships"); 051 /** 052 * E-Mail Alias URL Template. 053 */ 054 public static final URLTemplate EMAIL_ALIAS_URL_TEMPLATE = new URLTemplate("users/%s/email_aliases/%s"); 055 /** 056 * E-Mail Aliases URL Template. 057 */ 058 public static final URLTemplate EMAIL_ALIASES_URL_TEMPLATE = new URLTemplate("users/%s/email_aliases"); 059 /** 060 * Move Folder To User Template. 061 */ 062 public static final URLTemplate MOVE_FOLDER_TO_USER_TEMPLATE = new URLTemplate("users/%s/folders/%s"); 063 /** 064 * User Avatar Template. 065 */ 066 public static final URLTemplate USER_AVATAR_TEMPLATE = new URLTemplate("users/%s/avatar"); 067 068 /** 069 * Constructs a BoxUser for a user with a given ID. 070 * @param api the API connection to be used by the user. 071 * @param id the ID of the user. 072 */ 073 public BoxUser(BoxAPIConnection api, String id) { 074 super(api, id); 075 } 076 077 /** 078 * Provisions a new app user in an enterprise using Box Developer Edition. 079 * @param api the API connection to be used by the created user. 080 * @param name the name of the user. 081 * @return the created user's info. 082 */ 083 public static BoxUser.Info createAppUser(BoxAPIConnection api, String name) { 084 return createAppUser(api, name, new CreateUserParams()); 085 } 086 087 /** 088 * Provisions a new app user in an enterprise with additional user information using Box Developer Edition. 089 * @param api the API connection to be used by the created user. 090 * @param name the name of the user. 091 * @param params additional user information. 092 * @return the created user's info. 093 */ 094 public static BoxUser.Info createAppUser(BoxAPIConnection api, String name, 095 CreateUserParams params) { 096 097 params.setIsPlatformAccessOnly(true); 098 return createEnterpriseUser(api, null, name, params); 099 } 100 101 /** 102 * Provisions a new user in an enterprise. 103 * @param api the API connection to be used by the created user. 104 * @param login the email address the user will use to login. 105 * @param name the name of the user. 106 * @return the created user's info. 107 */ 108 public static BoxUser.Info createEnterpriseUser(BoxAPIConnection api, String login, String name) { 109 return createEnterpriseUser(api, login, name, null); 110 } 111 112 /** 113 * Provisions a new user in an enterprise with additional user information. 114 * @param api the API connection to be used by the created user. 115 * @param login the email address the user will use to login. 116 * @param name the name of the user. 117 * @param params additional user information. 118 * @return the created user's info. 119 */ 120 public static BoxUser.Info createEnterpriseUser(BoxAPIConnection api, String login, String name, 121 CreateUserParams params) { 122 123 JsonObject requestJSON = new JsonObject(); 124 requestJSON.add("login", login); 125 requestJSON.add("name", name); 126 127 if (params != null) { 128 if (params.getRole() != null) { 129 requestJSON.add("role", params.getRole().toJSONValue()); 130 } 131 132 if (params.getStatus() != null) { 133 requestJSON.add("status", params.getStatus().toJSONValue()); 134 } 135 136 requestJSON.add("language", params.getLanguage()); 137 requestJSON.add("is_sync_enabled", params.getIsSyncEnabled()); 138 requestJSON.add("job_title", params.getJobTitle()); 139 requestJSON.add("phone", params.getPhone()); 140 requestJSON.add("address", params.getAddress()); 141 requestJSON.add("space_amount", params.getSpaceAmount()); 142 requestJSON.add("can_see_managed_users", params.getCanSeeManagedUsers()); 143 requestJSON.add("timezone", params.getTimezone()); 144 requestJSON.add("is_exempt_from_device_limits", params.getIsExemptFromDeviceLimits()); 145 requestJSON.add("is_exempt_from_login_verification", params.getIsExemptFromLoginVerification()); 146 requestJSON.add("is_platform_access_only", params.getIsPlatformAccessOnly()); 147 requestJSON.add("external_app_user_id", params.getExternalAppUserId()); 148 requestJSON.add("is_external_collab_restricted", params.getIsExternalCollabRestricted()); 149 if (params.getTrackingCodes() != null) { 150 requestJSON.add("tracking_codes", toTrackingCodesJson(params.getTrackingCodes())); 151 } 152 } 153 154 URL url = USERS_URL_TEMPLATE.build(api.getBaseURL()); 155 BoxJSONRequest request = new BoxJSONRequest(api, url, "POST"); 156 request.setBody(requestJSON.toString()); 157 BoxJSONResponse response = (BoxJSONResponse) request.send(); 158 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 159 160 BoxUser createdUser = new BoxUser(api, responseJSON.get("id").asString()); 161 return createdUser.new Info(responseJSON); 162 } 163 164 /** 165 * Gets the current user. 166 * @param api the API connection of the current user. 167 * @return the current user. 168 */ 169 public static BoxUser getCurrentUser(BoxAPIConnection api) { 170 URL url = GET_ME_URL.build(api.getBaseURL()); 171 BoxAPIRequest request = new BoxAPIRequest(api, url, "GET"); 172 BoxJSONResponse response = (BoxJSONResponse) request.send(); 173 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 174 return new BoxUser(api, jsonObject.get("id").asString()); 175 } 176 177 /** 178 * Returns an iterable containing all the enterprise users. 179 * @param api the API connection to be used when retrieving the users. 180 * @return an iterable containing all the enterprise users. 181 */ 182 public static Iterable<BoxUser.Info> getAllEnterpriseUsers(final BoxAPIConnection api) { 183 return getAllEnterpriseUsers(api, false, null); 184 } 185 186 187 /** 188 * Returns an iterable containing all the enterprise users. Uses marker based pagination. 189 * @param api the API connection to be used when retrieving the users. 190 * @param usemarker Boolean that determines whether to use marker based pagination. 191 * @param marker The marker at which the iterator will begin. 192 * @return an iterable containing all the enterprise users. 193 */ 194 public static Iterable<BoxUser.Info> getAllEnterpriseUsers(final BoxAPIConnection api, final boolean usemarker, 195 final String marker) { 196 return getUsersInfoForType(api, null, null, null, usemarker, marker); 197 } 198 199 /** 200 * Returns an iterable containing all the enterprise users that matches the filter and specifies which child fields 201 * to retrieve from the API. 202 * @param api the API connection to be used when retrieving the users. 203 * @param filterTerm used to filter the results to only users starting with this string in either the name or the 204 * login. Can be null to not filter the results. 205 * @param fields the fields to retrieve. Leave this out for the standard fields. 206 * @return an iterable containing all the enterprise users that matches the filter. 207 */ 208 public static Iterable<BoxUser.Info> getAllEnterpriseUsers(final BoxAPIConnection api, final String filterTerm, 209 final String... fields) { 210 return getUsersInfoForType(api, filterTerm, null, null, false, null, fields); 211 } 212 213 /** 214 * Returns an iterable containing all the enterprise users that matches the filter and specifies which child fields 215 * to retrieve from the API. Uses marker based pagination. 216 * @param api the API connection to be used when retrieving the users. 217 * @param filterTerm used to filter the results to only users starting with this string in either the name or the 218 * login. Can be null to not filter the results. 219 * @param usemarker Boolean that determines whether to use marker based pagination. 220 * @param marker The marker at which the iterator will begin. 221 * @param fields the fields to retrieve. Leave this out for the standard fields. 222 * @return an iterable containing all the enterprise users that matches the filter. 223 */ 224 public static Iterable<BoxUser.Info> getAllEnterpriseUsers(final BoxAPIConnection api, final String filterTerm, 225 final boolean usemarker, final String marker, final String... fields) { 226 return getUsersInfoForType(api, filterTerm, null, null, usemarker, marker, fields); 227 } 228 229 /** 230 * Gets a limited set of information about an external user. (A user collaborating 231 * on content owned by the enterprise). Note: Only fields the user has permission to 232 * see will be returned with values. Other fields will return a value of null. 233 * @param api the API connection to be used when retrieving the users. 234 * @param filterTerm used to filter the results to only users matching the given login. 235 * This does exact match only, so if no filter term is passed in, nothing 236 * will be returned. 237 * @param fields the fields to retrieve. Leave this out for the standard fields. 238 * @return an iterable containing external users matching the given email 239 */ 240 public static Iterable<BoxUser.Info> getExternalUsers(final BoxAPIConnection api, final String filterTerm, 241 final String... fields) { 242 return getUsersInfoForType(api, filterTerm, "external", null, false, null, fields); 243 } 244 245 /** 246 * Gets a limited set of information about an external user. (A user collaborating 247 * on content owned by the enterprise). Note: Only fields the user has permission to 248 * see will be returned with values. Other fields will return a value of null. Uses marker based pagination. 249 * @param api the API connection to be used when retrieving the users. 250 * @param filterTerm used to filter the results to only users matching the given login. 251 * This does exact match only, so if no filter term is passed in, nothing 252 * will be returned. 253 * @param usemarker Boolean that determines whether to use marker based pagination. 254 * @param marker The marker at which the iterator will begin. 255 * @param fields the fields to retrieve. Leave this out for the standard fields. 256 * @return an iterable containing external users matching the given email 257 */ 258 public static Iterable<BoxUser.Info> getExternalUsers(final BoxAPIConnection api, final String filterTerm, 259 final boolean usemarker, final String marker, final String... fields) { 260 return getUsersInfoForType(api, filterTerm, "external", null, usemarker, marker, fields); 261 } 262 263 /** 264 * Gets any managed users that match the filter term as well as any external users that 265 * match the filter term. For managed users it matches any users names or emails that 266 * start with the term. For external, it only does full match on email. This method 267 * is ideal to use in the case where you have a full email for a user and you don't 268 * know if they're managed or external. 269 * @param api the API connection to be used when retrieving the users. 270 * @param filterTerm The filter term to lookup users by (login for external, login or name for managed) 271 * @param fields the fields to retrieve. Leave this out for the standard fields. 272 * @return an iterable containing users matching the given email 273 */ 274 public static Iterable<BoxUser.Info> getAllEnterpriseOrExternalUsers(final BoxAPIConnection api, 275 final String filterTerm, final String... fields) { 276 return getUsersInfoForType(api, filterTerm, "all", null, false, null, fields); 277 } 278 279 /** 280 * Gets any managed users that match the filter term as well as any external users that 281 * match the filter term. For managed users it matches any users names or emails that 282 * start with the term. For external, it only does full match on email. This method 283 * is ideal to use in the case where you have a full email for a user and you don't 284 * know if they're managed or external. Uses marker based pagination. 285 * @param api the API connection to be used when retrieving the users. 286 * @param filterTerm The filter term to lookup users by (login for external, login or name for managed) 287 * @param usemarker Boolean that determines whether to use marker based pagination. 288 * @param marker The marker at which the iterator will begin. 289 * @param fields the fields to retrieve. Leave this out for the standard fields. 290 * @return an iterable containing users matching the given email 291 */ 292 public static Iterable<BoxUser.Info> getAllEnterpriseOrExternalUsers(final BoxAPIConnection api, 293 final String filterTerm, final boolean usemarker, final String marker, final String... fields) { 294 return getUsersInfoForType(api, filterTerm, "all", null, usemarker, marker, fields); 295 } 296 297 /** 298 * Gets any app users that has an exact match with the externalAppUserId term. 299 * @param api the API connection to be used when retrieving the users. 300 * @param externalAppUserId the external app user id that has been set for app user 301 * @param fields the fields to retrieve. Leave this out for the standard fields. 302 * @return an iterable containing users matching the given email 303 */ 304 public static Iterable<BoxUser.Info> getAppUsersByExternalAppUserID(final BoxAPIConnection api, 305 final String externalAppUserId, final String... fields) { 306 return getUsersInfoForType(api, null, null, externalAppUserId, false, null, fields); 307 } 308 309 /** 310 * Gets any app users that has an exact match with the externalAppUserId term using marker based pagination. 311 * @param api the API connection to be used when retrieving the users. 312 * @param externalAppUserId the external app user id that has been set for app user 313 * @param usemarker Boolean that determines whether to use marker based pagination. 314 * @param marker The marker at which the iterator will begin. 315 * @param fields the fields to retrieve. Leave this out for the standard fields. 316 * @return an iterable containing users matching the given email 317 */ 318 public static Iterable<BoxUser.Info> getAppUsersByExternalAppUserID(final BoxAPIConnection api, 319 final String externalAppUserId, final boolean usemarker, String marker, final String... fields) { 320 return getUsersInfoForType(api, null, null, externalAppUserId, usemarker, marker, fields); 321 } 322 323 /** 324 * Helper method to abstract out the common logic from the various users methods. 325 * 326 * @param api the API connection to be used when retrieving the users. 327 * @param filterTerm The filter term to lookup users by (login for external, login or name for managed) 328 * @param userType The type of users we want to search with this request. 329 * Valid values are 'managed' (enterprise users), 'external' or 'all' 330 * @param externalAppUserId the external app user id that has been set for an app user 331 * @param usemarker Boolean that determines whether to use marker based pagination. 332 * @param marker The marker at which the iterator will begin. 333 * @param fields the fields to retrieve. Leave this out for the standard fields. 334 * @return An iterator over the selected users. 335 */ 336 private static Iterable<BoxUser.Info> getUsersInfoForType(final BoxAPIConnection api, final String filterTerm, 337 final String userType, final String externalAppUserId, final boolean usemarker, final String marker, 338 final String... fields) { 339 340 final QueryStringBuilder builder = new QueryStringBuilder(); 341 if (filterTerm != null) { 342 builder.appendParam("filter_term", filterTerm); 343 } 344 if (userType != null) { 345 builder.appendParam("user_type", userType); 346 } 347 if (externalAppUserId != null) { 348 builder.appendParam("external_app_user_id", externalAppUserId); 349 } 350 if (usemarker) { 351 builder.appendParam("usemarker", "true"); 352 } 353 if (fields.length > 0) { 354 builder.appendParam("fields", fields); 355 } 356 final URL url = USERS_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString()); 357 358 if (usemarker) { 359 return new BoxResourceIterable<BoxUser.Info>(api, url, 100, null, marker) { 360 @Override 361 protected BoxUser.Info factory(JsonObject jsonObject) { 362 BoxUser user = new BoxUser(api, jsonObject.get("id").asString()); 363 return user.new Info(jsonObject); 364 } 365 }; 366 } else { 367 return new Iterable<BoxUser.Info>() { 368 public Iterator<BoxUser.Info> iterator() { 369 return new BoxUserIterator(api, url); 370 } 371 }; 372 } 373 } 374 375 /** 376 * Gets information about this user. 377 * @param fields the optional fields to retrieve. 378 * @return info about this user. 379 */ 380 public BoxUser.Info getInfo(String... fields) { 381 URL url; 382 if (fields.length > 0) { 383 String queryString = new QueryStringBuilder().appendParam("fields", fields).toString(); 384 url = USER_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID()); 385 } else { 386 url = USER_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 387 } 388 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 389 BoxJSONResponse response = (BoxJSONResponse) request.send(); 390 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 391 return new Info(jsonObject); 392 } 393 394 /** 395 * Gets information about all of the group memberships for this user. 396 * Does not support paging. 397 * 398 * <p>Note: This method is only available to enterprise admins.</p> 399 * 400 * @return a collection of information about the group memberships for this user. 401 */ 402 public Collection<BoxGroupMembership.Info> getMemberships() { 403 BoxAPIConnection api = this.getAPI(); 404 URL url = USER_MEMBERSHIPS_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 405 406 BoxAPIRequest request = new BoxAPIRequest(api, url, "GET"); 407 BoxJSONResponse response = (BoxJSONResponse) request.send(); 408 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 409 410 int entriesCount = responseJSON.get("total_count").asInt(); 411 Collection<BoxGroupMembership.Info> memberships = new ArrayList<BoxGroupMembership.Info>(entriesCount); 412 JsonArray entries = responseJSON.get("entries").asArray(); 413 for (JsonValue entry : entries) { 414 JsonObject entryObject = entry.asObject(); 415 BoxGroupMembership membership = new BoxGroupMembership(api, entryObject.get("id").asString()); 416 BoxGroupMembership.Info info = membership.new Info(entryObject); 417 memberships.add(info); 418 } 419 420 return memberships; 421 } 422 423 /** 424 * Gets information about all of the group memberships for this user as iterable with paging support. 425 * @param fields the fields to retrieve. 426 * @return an iterable with information about the group memberships for this user. 427 */ 428 public Iterable<BoxGroupMembership.Info> getAllMemberships(String ... fields) { 429 final QueryStringBuilder builder = new QueryStringBuilder(); 430 if (fields.length > 0) { 431 builder.appendParam("fields", fields); 432 } 433 return new Iterable<BoxGroupMembership.Info>() { 434 public Iterator<BoxGroupMembership.Info> iterator() { 435 URL url = USER_MEMBERSHIPS_URL_TEMPLATE.buildWithQuery( 436 BoxUser.this.getAPI().getBaseURL(), builder.toString(), BoxUser.this.getID()); 437 return new BoxGroupMembershipIterator(BoxUser.this.getAPI(), url); 438 } 439 }; 440 } 441 442 /** 443 * Adds a new email alias to this user's account. 444 * @param email the email address to add as an alias. 445 * @return the newly created email alias. 446 */ 447 public EmailAlias addEmailAlias(String email) { 448 return this.addEmailAlias(email, false); 449 } 450 451 /** 452 * Adds a new email alias to this user's account and confirms it without user interaction. 453 * This functionality is only available for enterprise admins. 454 * @param email the email address to add as an alias. 455 * @param isConfirmed whether or not the email alias should be automatically confirmed. 456 * @return the newly created email alias. 457 */ 458 public EmailAlias addEmailAlias(String email, boolean isConfirmed) { 459 URL url = EMAIL_ALIASES_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 460 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 461 462 JsonObject requestJSON = new JsonObject() 463 .add("email", email); 464 465 if (isConfirmed) { 466 requestJSON.add("is_confirmed", isConfirmed); 467 } 468 469 request.setBody(requestJSON.toString()); 470 BoxJSONResponse response = (BoxJSONResponse) request.send(); 471 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 472 return new EmailAlias(responseJSON); 473 } 474 475 /** 476 * Deletes an email alias from this user's account. 477 * 478 * <p>The IDs of the user's email aliases can be found by calling {@link #getEmailAliases}.</p> 479 * 480 * @param emailAliasID the ID of the email alias to delete. 481 */ 482 public void deleteEmailAlias(String emailAliasID) { 483 URL url = EMAIL_ALIAS_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), emailAliasID); 484 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 485 BoxAPIResponse response = request.send(); 486 response.disconnect(); 487 } 488 489 /** 490 * Gets a collection of all the email aliases for this user. 491 * 492 * <p>Note that the user's primary login email is not included in the collection of email aliases.</p> 493 * 494 * @return a collection of all the email aliases for this user. 495 */ 496 public Collection<EmailAlias> getEmailAliases() { 497 URL url = EMAIL_ALIASES_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 498 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 499 BoxJSONResponse response = (BoxJSONResponse) request.send(); 500 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 501 502 int totalCount = responseJSON.get("total_count").asInt(); 503 Collection<EmailAlias> emailAliases = new ArrayList<EmailAlias>(totalCount); 504 JsonArray entries = responseJSON.get("entries").asArray(); 505 for (JsonValue value : entries) { 506 JsonObject emailAliasJSON = value.asObject(); 507 emailAliases.add(new EmailAlias(emailAliasJSON)); 508 } 509 510 return emailAliases; 511 } 512 513 /** 514 * Deletes a user from an enterprise account. 515 * @param notifyUser whether or not to send an email notification to the user that their account has been deleted. 516 * @param force whether or not this user should be deleted even if they still own files. 517 */ 518 public void delete(boolean notifyUser, boolean force) { 519 String queryString = new QueryStringBuilder() 520 .appendParam("notify", String.valueOf(notifyUser)) 521 .appendParam("force", String.valueOf(force)) 522 .toString(); 523 524 URL url = USER_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID()); 525 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 526 BoxAPIResponse response = request.send(); 527 response.disconnect(); 528 } 529 530 /** 531 * Updates the information about this user with any info fields that have been modified locally. 532 * 533 * <p>Note: This method is only available to enterprise admins.</p> 534 * 535 * @param info info the updated info. 536 */ 537 public void updateInfo(BoxUser.Info info) { 538 URL url = USER_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 539 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 540 request.setBody(info.getPendingChanges()); 541 BoxJSONResponse response = (BoxJSONResponse) request.send(); 542 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 543 info.update(jsonObject); 544 } 545 546 /** 547 * @deprecated As of release 2.22.0, replaced by {@link #transferContent(String)} ()} 548 * 549 * 550 * Moves all of the owned content from within one user’s folder into a new folder in another user's account. 551 * You can move folders across users as long as the you have administrative permissions and the 'source' 552 * user owns the folders. Per the documentation at the link below, this will move everything from the root 553 * folder, as this is currently the only mode of operation supported. 554 * 555 * See also https://developer.box.com/en/reference/put-users-id-folders-id/ 556 * 557 * @param sourceUserID the user id of the user whose files will be the source for this operation 558 * @return info for the newly created folder 559 */ 560 @Deprecated 561 public BoxFolder.Info moveFolderToUser(String sourceUserID) { 562 // Currently the API only supports moving of the root folder (0), hence the hard coded "0" 563 URL url = MOVE_FOLDER_TO_USER_TEMPLATE.build(this.getAPI().getBaseURL(), sourceUserID, "0"); 564 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 565 JsonObject idValue = new JsonObject(); 566 idValue.add("id", this.getID()); 567 JsonObject ownedBy = new JsonObject(); 568 ownedBy.add("owned_by", idValue); 569 request.setBody(ownedBy.toString()); 570 BoxJSONResponse response = (BoxJSONResponse) request.send(); 571 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 572 BoxFolder movedFolder = new BoxFolder(this.getAPI(), responseJSON.get("id").asString()); 573 574 return movedFolder.new Info(responseJSON); 575 } 576 577 /** 578 * Moves all of the owned content from within one user’s folder into a new folder in another user's account. 579 * You can move folders across users as long as the you have administrative permissions and the 'source' 580 * user owns the folders. Per the documentation at the link below, this will move everything from the root 581 * folder, as this is currently the only mode of operation supported. 582 * 583 * See also https://developer.box.com/en/reference/put-users-id-folders-id/ 584 * 585 * @param destinationUserID the user id of the user that you wish to transfer content to. 586 * @return info for the newly created folder. 587 */ 588 public BoxFolder.Info transferContent(String destinationUserID) { 589 URL url = MOVE_FOLDER_TO_USER_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), "0"); 590 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 591 JsonObject destinationUser = new JsonObject(); 592 destinationUser.add("id", destinationUserID); 593 JsonObject ownedBy = new JsonObject(); 594 ownedBy.add("owned_by", destinationUser); 595 request.setBody(ownedBy.toString()); 596 BoxJSONResponse response = (BoxJSONResponse) request.send(); 597 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 598 BoxFolder movedFolder = new BoxFolder(this.getAPI(), responseJSON.get("id").asString()); 599 600 return movedFolder.new Info(responseJSON); 601 } 602 603 604 /** 605 * Retrieves the avatar of a user as an InputStream. 606 * 607 * @return InputStream representing the user avater. 608 */ 609 public InputStream getAvatar() { 610 URL url = USER_AVATAR_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 611 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 612 BoxAPIResponse response = request.send(); 613 614 return response.getBody(); 615 } 616 617 private static JsonArray toTrackingCodesJson(Map<String, String> trackingCodes) { 618 JsonArray trackingCodesJsonArray = new JsonArray(); 619 for (String attrKey : trackingCodes.keySet()) { 620 JsonObject trackingCode = new JsonObject(); 621 trackingCode.set("type", "tracking_code"); 622 trackingCode.set("name", attrKey); 623 trackingCode.set("value", trackingCodes.get(attrKey)); 624 trackingCodesJsonArray.add(trackingCode); 625 } 626 return trackingCodesJsonArray; 627 } 628 629 /** 630 * Enumerates the possible roles that a user can have within an enterprise. 631 */ 632 public enum Role { 633 /** 634 * The user is an administrator of their enterprise. 635 */ 636 ADMIN ("admin"), 637 638 /** 639 * The user is a co-administrator of their enterprise. 640 */ 641 COADMIN ("coadmin"), 642 643 /** 644 * The user is a regular user within their enterprise. 645 */ 646 USER ("user"); 647 648 private final String jsonValue; 649 650 private Role(String jsonValue) { 651 this.jsonValue = jsonValue; 652 } 653 654 static Role fromJSONValue(String jsonValue) { 655 return Role.valueOf(jsonValue.toUpperCase()); 656 } 657 658 String toJSONValue() { 659 return this.jsonValue; 660 } 661 } 662 663 /** 664 * Enumerates the possible statuses that a user's account can have. 665 */ 666 public enum Status { 667 /** 668 * The user's account is active. 669 */ 670 ACTIVE ("active"), 671 672 /** 673 * The user's account is inactive. 674 */ 675 INACTIVE ("inactive"), 676 677 /** 678 * The user's account cannot delete or edit content. 679 */ 680 CANNOT_DELETE_EDIT ("cannot_delete_edit"), 681 682 /** 683 * The user's account cannot delete, edit, or upload content. 684 */ 685 CANNOT_DELETE_EDIT_UPLOAD ("cannot_delete_edit_upload"); 686 687 private final String jsonValue; 688 689 private Status(String jsonValue) { 690 this.jsonValue = jsonValue; 691 } 692 693 static Status fromJSONValue(String jsonValue) { 694 return Status.valueOf(jsonValue.toUpperCase()); 695 } 696 697 String toJSONValue() { 698 return this.jsonValue; 699 } 700 } 701 702 /** 703 * Contains information about a BoxUser. 704 */ 705 public class Info extends BoxCollaborator.Info { 706 private String login; 707 private Role role; 708 private String language; 709 private String timezone; 710 private long spaceAmount; 711 private long spaceUsed; 712 private long maxUploadSize; 713 private boolean canSeeManagedUsers; 714 private boolean isSyncEnabled; 715 private boolean isExternalCollabRestricted; 716 private Status status; 717 private String jobTitle; 718 private String phone; 719 private String address; 720 private String avatarURL; 721 private boolean isExemptFromDeviceLimits; 722 private boolean isExemptFromLoginVerification; 723 private boolean isPasswordResetRequired; 724 private boolean isPlatformAccessOnly; 725 private String externalAppUserId; 726 private BoxEnterprise enterprise; 727 private List<String> myTags; 728 private String hostname; 729 private Map<String, String> trackingCodes; 730 731 /** 732 * Constructs an empty Info object. 733 */ 734 public Info() { 735 super(); 736 } 737 738 /** 739 * Constructs an Info object by parsing information from a JSON string. 740 * @param json the JSON string to parse. 741 */ 742 public Info(String json) { 743 super(json); 744 } 745 746 Info(JsonObject jsonObject) { 747 super(jsonObject); 748 } 749 750 @Override 751 public BoxUser getResource() { 752 return BoxUser.this; 753 } 754 755 /** 756 * Gets the email address the user uses to login. 757 * @return the email address the user uses to login. 758 */ 759 public String getLogin() { 760 return this.login; 761 } 762 763 /** 764 * Sets the email address the user uses to login. The new login must be one of the user's already confirmed 765 * email aliases. 766 * @param login one of the user's confirmed email aliases. 767 */ 768 public void setLogin(String login) { 769 this.login = login; 770 this.addPendingChange("login", login); 771 } 772 773 /** 774 * Gets the user's enterprise role. 775 * @return the user's enterprise role. 776 */ 777 public Role getRole() { 778 return this.role; 779 } 780 781 /** 782 * Sets the user's role in their enterprise. 783 * @param role the user's new role in their enterprise. 784 */ 785 public void setRole(Role role) { 786 this.role = role; 787 this.addPendingChange("role", role.name().toLowerCase()); 788 } 789 790 /** 791 * Gets the language of the user. 792 * @return the language of the user. 793 */ 794 public String getLanguage() { 795 return this.language; 796 } 797 798 /** 799 * Sets the language of the user. 800 * @param language the new language of the user. 801 */ 802 public void setLanguage(String language) { 803 this.language = language; 804 this.addPendingChange("language", language); 805 } 806 807 /** 808 * Gets the timezone of the user. 809 * @return the timezone of the user. 810 */ 811 public String getTimezone() { 812 return this.timezone; 813 } 814 815 /** 816 * Sets the timezone of the user. 817 * @param timezone the new timezone of the user. 818 */ 819 public void setTimezone(String timezone) { 820 this.timezone = timezone; 821 this.addPendingChange("timezone", timezone); 822 } 823 824 /** 825 * Gets the user's total available space in bytes. 826 * @return the user's total available space in bytes. 827 */ 828 public long getSpaceAmount() { 829 return this.spaceAmount; 830 } 831 832 /** 833 * Sets the user's total available space in bytes. 834 * @param spaceAmount the new amount of space available to the user in bytes, or -1 for unlimited storage. 835 */ 836 public void setSpaceAmount(long spaceAmount) { 837 this.spaceAmount = spaceAmount; 838 this.addPendingChange("space_amount", spaceAmount); 839 } 840 841 /** 842 * Gets the amount of space the user has used in bytes. 843 * @return the amount of space the user has used in bytes. 844 */ 845 public long getSpaceUsed() { 846 return this.spaceUsed; 847 } 848 849 /** 850 * Gets the maximum individual file size in bytes the user can have. 851 * @return the maximum individual file size in bytes the user can have. 852 */ 853 public long getMaxUploadSize() { 854 return this.maxUploadSize; 855 } 856 857 /** 858 * Gets the user's current account status. 859 * @return the user's current account status. 860 */ 861 public Status getStatus() { 862 return this.status; 863 } 864 865 /** 866 * Sets the user's current account status. 867 * @param status the user's new account status. 868 */ 869 public void setStatus(Status status) { 870 this.status = status; 871 this.addPendingChange("status", status.name().toLowerCase()); 872 } 873 874 /** 875 * Gets the job title of the user. 876 * @return the job title of the user. 877 */ 878 public String getJobTitle() { 879 return this.jobTitle; 880 } 881 882 /** 883 * Sets the job title of the user. 884 * @param jobTitle the new job title of the user. 885 */ 886 public void setJobTitle(String jobTitle) { 887 this.jobTitle = jobTitle; 888 this.addPendingChange("job_title", jobTitle); 889 } 890 891 /** 892 * Gets the phone number of the user. 893 * @return the phone number of the user. 894 */ 895 public String getPhone() { 896 return this.phone; 897 } 898 899 /** 900 * Sets the phone number of the user. 901 * @param phone the new phone number of the user. 902 */ 903 public void setPhone(String phone) { 904 this.phone = phone; 905 this.addPendingChange("phone", phone); 906 } 907 908 /** 909 * Gets the address of the user. 910 * @return the address of the user. 911 */ 912 public String getAddress() { 913 return this.address; 914 } 915 916 /** 917 * Sets the address of the user. 918 * @param address the new address of the user. 919 */ 920 public void setAddress(String address) { 921 this.address = address; 922 this.addPendingChange("address", address); 923 } 924 925 /** 926 * Gets the URL of the user's avatar. 927 * @return the URL of the user's avatar. 928 */ 929 public String getAvatarURL() { 930 return this.avatarURL; 931 } 932 933 /** 934 * Gets the enterprise that the user belongs to. 935 * @return the enterprise that the user belongs to. 936 */ 937 public BoxEnterprise getEnterprise() { 938 return this.enterprise; 939 } 940 941 /** 942 * Removes the user from their enterprise and converts them to a standalone free user. 943 */ 944 public void removeEnterprise() { 945 this.removeChildObject("enterprise"); 946 this.enterprise = null; 947 this.addChildObject("enterprise", null); 948 } 949 950 /** 951 * Gets whether or not the user can use Box Sync. 952 * @return true if the user can use Box Sync; otherwise false. 953 */ 954 public boolean getIsSyncEnabled() { 955 return this.isSyncEnabled; 956 } 957 958 /** 959 * Sets whether this user is allowed or not to collaborate with users outside their enterprise. 960 * @param isExternalCollabRestricted whether the user is allowed to collaborate outside their enterprise. 961 */ 962 public void setIsExternalCollabRestricted(boolean isExternalCollabRestricted) { 963 this.isExternalCollabRestricted = isExternalCollabRestricted; 964 this.addPendingChange("is_external_collab_restricted", isExternalCollabRestricted); 965 } 966 967 /** 968 * Gets whether this user is allowed or not to collaborate with users outside their enterprise. 969 * @return true if this user is not allowed to collaborate with users outside their enterprise; otherwise false. 970 */ 971 public boolean getIsExternalCollabRestricted() { 972 return this.isExternalCollabRestricted; 973 } 974 975 /** 976 * Sets whether or not the user can use Box Sync. 977 * @param enabled whether or not the user can use Box Sync. 978 */ 979 public void setIsSyncEnabled(boolean enabled) { 980 this.isSyncEnabled = enabled; 981 this.addPendingChange("is_sync_enabled", enabled); 982 } 983 984 /** 985 * Gets whether or not the user can see other enterprise users in their contact list. 986 * @return true if the user can see other enterprise users in their contact list; otherwise false. 987 */ 988 public boolean getCanSeeManagedUsers() { 989 return this.canSeeManagedUsers; 990 } 991 992 /** 993 * Sets whether or not the user can see other enterprise users in their contact list. 994 * @param canSeeManagedUsers whether or not the user can see other enterprise users in their contact list. 995 */ 996 public void setCanSeeManagedUsers(boolean canSeeManagedUsers) { 997 this.canSeeManagedUsers = canSeeManagedUsers; 998 this.addPendingChange("can_see_managed_users", canSeeManagedUsers); 999 } 1000 1001 /** 1002 * Gets whether or not the user is exempt from enterprise device limits. 1003 * @return true if the user is exempt from enterprise device limits; otherwise false. 1004 */ 1005 public boolean getIsExemptFromDeviceLimits() { 1006 return this.isExemptFromDeviceLimits; 1007 } 1008 1009 /** 1010 * Sets whether or not the user is exempt from enterprise device limits. 1011 * @param isExemptFromDeviceLimits whether or not the user is exempt from enterprise device limits. 1012 */ 1013 public void setIsExemptFromDeviceLimits(boolean isExemptFromDeviceLimits) { 1014 this.isExemptFromDeviceLimits = isExemptFromDeviceLimits; 1015 this.addPendingChange("is_exempt_from_device_limits", isExemptFromDeviceLimits); 1016 } 1017 1018 /** 1019 * Gets whether or not the user must use two-factor authentication. 1020 * @return true if the user must use two-factor authentication; otherwise false. 1021 */ 1022 public boolean getIsExemptFromLoginVerification() { 1023 return this.isExemptFromLoginVerification; 1024 } 1025 1026 /** 1027 * Sets whether or not the user must use two-factor authentication. 1028 * @param isExemptFromLoginVerification whether or not the user must use two-factor authentication. 1029 */ 1030 public void setIsExemptFromLoginVerification(boolean isExemptFromLoginVerification) { 1031 this.isExemptFromLoginVerification = isExemptFromLoginVerification; 1032 this.addPendingChange("is_exempt_from_login_verification", isExemptFromLoginVerification); 1033 } 1034 1035 /** 1036 * Gets whether or not the user is required to reset password. 1037 * @return true if the user is required to reset password; otherwise false. 1038 */ 1039 public boolean getIsPasswordResetRequired() { 1040 return this.isPasswordResetRequired; 1041 } 1042 1043 /** 1044 * Sets whether or not the user is required to reset password. 1045 * @param isPasswordResetRequired whether or not the user is required to reset password. 1046 */ 1047 public void setIsPasswordResetRequired(boolean isPasswordResetRequired) { 1048 this.isPasswordResetRequired = isPasswordResetRequired; 1049 this.addPendingChange("is_password_reset_required", isPasswordResetRequired); 1050 } 1051 1052 /** 1053 * Gets whether or not the user we are creating is an app user with Box Developer Edition. 1054 * @return true if the new user is an app user for Box Developer Addition; otherwise false. 1055 */ 1056 public boolean getIsPlatformAccessOnly() { 1057 return this.isPlatformAccessOnly; 1058 } 1059 1060 /** 1061 * Gets the external app user id that has been set for the app user. 1062 * @return the external app user id. 1063 */ 1064 public String getExternalAppUserId() { 1065 return this.externalAppUserId; 1066 } 1067 1068 /** 1069 * Sets the external app user id. 1070 * @param externalAppUserId external app user id. 1071 */ 1072 public void setExternalAppUserId(String externalAppUserId) { 1073 this.externalAppUserId = externalAppUserId; 1074 this.addPendingChange("external_app_user_id", externalAppUserId); 1075 } 1076 1077 /** 1078 * Gets the tags for all files and folders owned by this user. 1079 * @return the tags for all files and folders owned by this user. 1080 */ 1081 public List<String> getMyTags() { 1082 return this.myTags; 1083 } 1084 1085 /** 1086 * Gets the root (protocol, subdomain, domain) of any links that need to be generated for this user. 1087 * @return the root (protocol, subdomain, domain) of any links that need to be generated for this user. 1088 */ 1089 public String getHostname() { 1090 return this.hostname; 1091 } 1092 1093 /** 1094 * Gets the tracking defined for each entity. 1095 * @return a Map with tracking codes. 1096 */ 1097 public Map<String, String> getTrackingCodes() { 1098 return this.trackingCodes; 1099 } 1100 1101 /** 1102 * Allows admin to set attributes specific for a group of users. 1103 * @param trackingCodes a Map representing the user's new tracking codes 1104 */ 1105 public void setTrackingCodes(Map<String, String> trackingCodes) { 1106 this.trackingCodes = trackingCodes; 1107 this.addPendingChange("tracking_codes", toTrackingCodesJson(this.trackingCodes)); 1108 } 1109 1110 /** 1111 * Allows the admin to append new tracking codes to the previous existing list. 1112 * @param name the name or `key` of the attribute to set. 1113 * @param value the value of the attribute to set. 1114 */ 1115 public void appendTrackingCodes(String name, String value) { 1116 this.getTrackingCodes().put(name, value); 1117 this.addPendingChange("tracking_codes", toTrackingCodesJson(this.trackingCodes)); 1118 } 1119 1120 @Override 1121 protected void parseJSONMember(JsonObject.Member member) { 1122 super.parseJSONMember(member); 1123 1124 JsonValue value = member.getValue(); 1125 String memberName = member.getName(); 1126 try { 1127 if (memberName.equals("login")) { 1128 this.login = value.asString(); 1129 } else if (memberName.equals("role")) { 1130 this.role = Role.fromJSONValue(value.asString()); 1131 } else if (memberName.equals("language")) { 1132 this.language = value.asString(); 1133 } else if (memberName.equals("timezone")) { 1134 this.timezone = value.asString(); 1135 } else if (memberName.equals("space_amount")) { 1136 this.spaceAmount = Double.valueOf(value.toString()).longValue(); 1137 } else if (memberName.equals("space_used")) { 1138 this.spaceUsed = Double.valueOf(value.toString()).longValue(); 1139 } else if (memberName.equals("max_upload_size")) { 1140 this.maxUploadSize = Double.valueOf(value.toString()).longValue(); 1141 } else if (memberName.equals("status")) { 1142 this.status = Status.fromJSONValue(value.asString()); 1143 } else if (memberName.equals("job_title")) { 1144 this.jobTitle = value.asString(); 1145 } else if (memberName.equals("phone")) { 1146 this.phone = value.asString(); 1147 } else if (memberName.equals("address")) { 1148 this.address = value.asString(); 1149 } else if (memberName.equals("avatar_url")) { 1150 this.avatarURL = value.asString(); 1151 } else if (memberName.equals("can_see_managed_users")) { 1152 this.canSeeManagedUsers = value.asBoolean(); 1153 } else if (memberName.equals("is_sync_enabled")) { 1154 this.isSyncEnabled = value.asBoolean(); 1155 } else if (memberName.equals("is_external_collab_restricted")) { 1156 this.isExternalCollabRestricted = value.asBoolean(); 1157 } else if (memberName.equals("is_exempt_from_device_limits")) { 1158 this.isExemptFromDeviceLimits = value.asBoolean(); 1159 } else if (memberName.equals("is_exempt_from_login_verification")) { 1160 this.isExemptFromLoginVerification = value.asBoolean(); 1161 } else if (memberName.equals("is_password_reset_required")) { 1162 this.isPasswordResetRequired = value.asBoolean(); 1163 } else if (memberName.equals("is_platform_access_only")) { 1164 this.isPlatformAccessOnly = value.asBoolean(); 1165 } else if (memberName.equals("external_app_user_id")) { 1166 this.externalAppUserId = value.asString(); 1167 } else if (memberName.equals("enterprise")) { 1168 JsonObject jsonObject = value.asObject(); 1169 if (this.enterprise == null) { 1170 this.enterprise = new BoxEnterprise(jsonObject); 1171 } else { 1172 this.enterprise.update(jsonObject); 1173 } 1174 } else if (memberName.equals("my_tags")) { 1175 this.myTags = this.parseMyTags(value.asArray()); 1176 } else if (memberName.equals("hostname")) { 1177 this.hostname = value.asString(); 1178 } else if (memberName.equals("tracking_codes")) { 1179 this.trackingCodes = this.parseTrackingCodes(value.asArray()); 1180 } 1181 } catch (Exception e) { 1182 throw new BoxDeserializationException(memberName, value.toString(), e); 1183 } 1184 1185 } 1186 1187 private List<String> parseMyTags(JsonArray jsonArray) { 1188 List<String> myTags = new ArrayList<String>(jsonArray.size()); 1189 for (JsonValue value : jsonArray) { 1190 myTags.add(value.asString()); 1191 } 1192 1193 return myTags; 1194 } 1195 private Map<String, String> parseTrackingCodes(JsonArray jsonArray) { 1196 Map<String, String> result = new HashMap<String, String>(); 1197 if (jsonArray == null) { 1198 return null; 1199 } 1200 List<JsonValue> valuesList = jsonArray.values(); 1201 for (JsonValue jsonValue : valuesList) { 1202 JsonObject object = jsonValue.asObject(); 1203 result.put(object.get("name").asString().toString(), object.get("value").asString().toString()); 1204 } 1205 return result; 1206 } 1207 } 1208}