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