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