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