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