001package com.box.sdk;
002
003import com.eclipsesource.json.JsonObject;
004import com.eclipsesource.json.JsonValue;
005import java.net.URL;
006import java.util.Date;
007import java.util.HashMap;
008import java.util.Map;
009
010/**
011 * Represents a relationship between a user and a group.
012 *
013 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
014 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
015 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p>
016 */
017@BoxResourceType("group_membership")
018public class BoxGroupMembership extends BoxResource {
019
020    /**
021     * The URL template for all group membership requests.
022     *
023     * @see #getInfo()
024     */
025    public static final URLTemplate MEMBERSHIP_URL_TEMPLATE = new URLTemplate("group_memberships/%s");
026
027    /**
028     * Constructs a BoxGroupMembership for a group membership with a given ID.
029     *
030     * @param api the API connection to be used by the group membership.
031     * @param id  the ID of the group membership.
032     */
033    public BoxGroupMembership(BoxAPIConnection api, String id) {
034        super(api, id);
035    }
036
037    /**
038     * Gets information about this group membership.
039     *
040     * @return info about this group membership.
041     */
042    public Info getInfo() {
043        BoxAPIConnection api = this.getAPI();
044        URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID());
045
046        BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
047        BoxJSONResponse response = (BoxJSONResponse) request.send();
048        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
049        return new Info(jsonObject);
050    }
051
052    /**
053     * Updates the information about this group membership with any info fields that have been modified locally.
054     *
055     * @param info the updated info.
056     */
057    public void updateInfo(Info info) {
058        BoxAPIConnection api = this.getAPI();
059        URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID());
060
061        BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT");
062        request.setBody(info.getPendingChanges());
063        BoxJSONResponse response = (BoxJSONResponse) request.send();
064        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
065        info.update(jsonObject);
066    }
067
068    /**
069     * Deletes this group membership.
070     */
071    public void delete() {
072        BoxAPIConnection api = this.getAPI();
073        URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID());
074
075        BoxAPIRequest request = new BoxAPIRequest(api, url, "DELETE");
076        BoxAPIResponse response = request.send();
077        response.disconnect();
078    }
079
080    /**
081     * Enumerates the possible roles that a user can have within a group.
082     *
083     * @deprecated use GroupRole instead.
084     */
085    @Deprecated
086    public enum Role {
087        /**
088         * The user is an administrator in the group.
089         */
090        ADMIN("admin"),
091
092        /**
093         * The user is a submaster in the group.
094         */
095        SUBMASTER("submaster"),
096
097        /**
098         * The user is a regular member in the group.
099         */
100        MEMBER("member");
101
102        /**
103         * String representation of the role.
104         */
105        private final String jsonValue;
106
107        /**
108         * Constructor.
109         *
110         * @param jsonValue srting representation of the role.
111         */
112        Role(String jsonValue) {
113            this.jsonValue = jsonValue;
114        }
115
116        /**
117         * Creates the role from given string.
118         *
119         * @param jsonValue string to be converted to role.
120         * @return the role, created from string value.
121         */
122        static Role fromJSONString(String jsonValue) {
123            return Role.valueOf(jsonValue.toUpperCase());
124        }
125
126        /**
127         * @return string representation of the role.
128         */
129        String toJSONString() {
130            return this.jsonValue;
131        }
132    }
133
134    /**
135     * Enumerates the possible roles that a user can have within a group.
136     */
137    public enum GroupRole {
138        /**
139         * The user is an administrator in the group.
140         */
141        ADMIN("admin"),
142
143        /**
144         * The user is a coadmin in the group.
145         */
146        COADMIN("submaster"),
147
148        /**
149         * The user is a regular member in the group.
150         */
151        MEMBER("member");
152
153        /**
154         * String representation of the groupRole.
155         */
156        private final String jsonValue;
157
158        /**
159         * Constructor.
160         *
161         * @param jsonValue string representation of the role.
162         */
163        GroupRole(String jsonValue) {
164            this.jsonValue = jsonValue;
165        }
166
167        /**
168         * Creates the groupRole from given string.
169         *
170         * @param jsonValue string to be converted to role.
171         * @return the role, created from string value.
172         */
173        static GroupRole fromJSONString(String jsonValue) {
174            for (GroupRole role : GroupRole.values()) {
175                if (role.jsonValue.equalsIgnoreCase(jsonValue)) {
176                    return role;
177                }
178            }
179            throw new IllegalArgumentException("Invalid value for enum GroupRole: " + jsonValue);
180        }
181
182        /**
183         * @return string representation of the groupRole.
184         */
185        String toJSONString() {
186            return this.jsonValue;
187        }
188    }
189
190    /**
191     * Enumerates the possible permissions that a user can have as a group admin.
192     */
193    public enum Permission {
194        /**
195         * The user can create accounts.
196         */
197        CAN_CREATE_ACCOUNTS("can_create_accounts"),
198
199        /**
200         * The user can edit accounts.
201         */
202        CAN_EDIT_ACCOUNTS("can_edit_accounts"),
203
204        /**
205         * The user can instant login as another user.
206         */
207        CAN_INSTANT_LOGIN("can_instant_login"),
208
209        /**
210         * The user can run reports.
211         */
212        CAN_RUN_REPORTS("can_run_reports");
213
214        private final String jsonValue;
215
216        Permission(String jsonValue) {
217            this.jsonValue = jsonValue;
218        }
219
220        static Permission fromJSONValue(String jsonValue) {
221            return Permission.valueOf(jsonValue.toUpperCase());
222        }
223
224        String toJSONValue() {
225            return this.jsonValue;
226        }
227    }
228
229    /**
230     * Contains information about a BoxGroupMembership.
231     */
232    public class Info extends BoxResource.Info {
233
234        /**
235         * @see #getUser()
236         */
237        private BoxUser.Info user;
238
239        /**
240         * @see #getGroup()
241         */
242        private BoxGroup.Info group;
243
244        /**
245         * @see #getRole()
246         */
247        private Role role;
248
249        /**
250         * @see #getGroupRole()
251         */
252        private GroupRole groupRole;
253
254        /**
255         * @see #getCreatedAt()
256         */
257        private Date createdAt;
258
259        /**
260         * @see #getModifiedAt()
261         */
262        private Date modifiedAt;
263
264        /**
265         * @see #getPermissions()
266         */
267        private Map<Permission, Boolean> configurablePermissions;
268
269        /**
270         * Constructs an empty Info object.
271         */
272        public Info() {
273            super();
274        }
275
276        /**
277         * Constructs an Info object by parsing information from a JSON string.
278         *
279         * @param json the JSON string to parse.
280         */
281        public Info(String json) {
282            super(json);
283        }
284
285        /**
286         * Constructs an Info object using an already parsed JSON object.
287         *
288         * @param jsonObject the parsed JSON object.
289         */
290        Info(JsonObject jsonObject) {
291            super(jsonObject);
292        }
293
294        /**
295         * Gets the user belonging to the group.
296         *
297         * <p>Note: the BoxUser.Info returned by this method will only have the ID, name, and login fields
298         * populated.</p>
299         *
300         * @return the user belonging to the group.
301         */
302        public BoxUser.Info getUser() {
303            return this.user;
304        }
305
306        /**
307         * Gets the group the user belongs to.
308         *
309         * <p>Note: the BoxGroup.Info returned by this method will only have the ID and name fields populated.</p>
310         *
311         * @return the group the user belongs to.
312         */
313        public BoxGroup.Info getGroup() {
314            return this.group;
315        }
316
317        /**
318         * Gets the level of access the user has.
319         *
320         * @return the level of access the user has.
321         * @deprecated use getGroupRole() instead.
322         */
323        @Deprecated
324        public Role getRole() {
325            return this.role;
326        }
327
328        /**
329         * Sets the level of access the user has.
330         *
331         * @param role the new level of access to give the user.
332         * @deprecated use setGroupRole() instead.
333         */
334        @Deprecated
335        public void setRole(Role role) {
336            this.role = role;
337            this.addPendingChange("role", role.toJSONString());
338        }
339
340        /**
341         * Gets the level of access the user has.
342         *
343         * @return the level of access the user has.
344         */
345        public GroupRole getGroupRole() {
346            return this.groupRole;
347        }
348
349        /**
350         * Sets the level of access the user has.
351         *
352         * @param role the new level of access to give the user.
353         */
354        public void setGroupRole(GroupRole role) {
355            this.groupRole = role;
356            this.addPendingChange("role", role.toJSONString());
357        }
358
359        /**
360         * Gets the time the group membership was created.
361         *
362         * @return the time the group membership was created.
363         */
364        public Date getCreatedAt() {
365            return this.createdAt;
366        }
367
368        /**
369         * Gets the time the group membership was last modified.
370         *
371         * @return the time the group membership was last modified.
372         */
373        public Date getModifiedAt() {
374            return this.modifiedAt;
375        }
376
377        /**
378         * Gets the configurablePermissions that the current user has on the group as group admin.
379         *
380         * @return the configurablePermissions that the current user has on the group as group admin.
381         */
382        public Map<Permission, Boolean> getConfigurablePermissions() {
383            return this.configurablePermissions;
384        }
385
386        /**
387         * Sets the configurablePermissions that the current user has on the group as group admin.
388         *
389         * @param configurablePermissions a Map representing the group admin configurable permissions
390         */
391        public void setConfigurablePermissions(Map<Permission, Boolean> configurablePermissions) {
392            this.configurablePermissions = configurablePermissions;
393            this.addPendingChange("configurable_permissions", this.configurablePermissionJson());
394        }
395
396        /**
397         * append new configurable permissions to the previous existing list.
398         *
399         * @param permission the group admin permission one wants to enable or disable of the user on the group.
400         * @param value      the true/false value of the attribute to set.
401         */
402        public void appendConfigurablePermissions(Permission permission, Boolean value) {
403            this.configurablePermissions.put(permission, value);
404            this.addPendingChange("configurable_permissions", this.configurablePermissionJson());
405        }
406
407        private JsonObject configurablePermissionJson() {
408            JsonObject configurablePermissionJson = new JsonObject();
409            for (Permission attrKey : this.configurablePermissions.keySet()) {
410                configurablePermissionJson.set(attrKey.toJSONValue(), this.configurablePermissions.get(attrKey));
411            }
412            return configurablePermissionJson;
413        }
414
415        /**
416         * {@inheritDoc}
417         */
418        @Override
419        public BoxGroupMembership getResource() {
420            return BoxGroupMembership.this;
421        }
422
423        private Map<Permission, Boolean> parseConfigurablePermissions(JsonObject jsonObject) {
424            if (jsonObject == null) {
425                return null;
426            }
427            Map<Permission, Boolean> permissions = new HashMap<Permission, Boolean>();
428            for (JsonObject.Member member : jsonObject) {
429                String memberName = member.getName();
430                boolean memberValue = member.getValue().asBoolean();
431                if (memberName.equals("can_create_accounts")) {
432                    permissions.put(Permission.CAN_CREATE_ACCOUNTS, memberValue);
433                } else if (memberName.equals("can_edit_accounts")) {
434                    permissions.put(Permission.CAN_EDIT_ACCOUNTS, memberValue);
435                } else if (memberName.equals("can_instant_login")) {
436                    permissions.put(Permission.CAN_INSTANT_LOGIN, memberValue);
437                } else if (memberName.equals("can_run_reports")) {
438                    permissions.put(Permission.CAN_RUN_REPORTS, memberValue);
439                }
440            }
441            return permissions;
442        }
443
444        /**
445         * {@inheritDoc}
446         */
447        @Override
448        protected void parseJSONMember(JsonObject.Member member) {
449            super.parseJSONMember(member);
450
451            String memberName = member.getName();
452            JsonValue value = member.getValue();
453
454            try {
455                if (memberName.equals("user")) {
456                    JsonObject userJSON = value.asObject();
457                    if (this.user == null) {
458                        String userID = userJSON.get("id").asString();
459                        BoxUser user = new BoxUser(getAPI(), userID);
460                        this.user = user.new Info(userJSON);
461                    } else {
462                        this.user.update(userJSON);
463                    }
464
465                } else if (memberName.equals("group")) {
466                    JsonObject groupJSON = value.asObject();
467                    if (this.group == null) {
468                        String userID = groupJSON.get("id").asString();
469                        BoxGroup group = new BoxGroup(getAPI(), userID);
470                        this.group = group.new Info(groupJSON);
471                    } else {
472                        this.group.update(groupJSON);
473                    }
474
475                } else if (memberName.equals("role")) {
476                    this.role = Role.fromJSONString(value.asString());
477                    this.groupRole = GroupRole.fromJSONString(value.asString());
478
479                } else if (memberName.equals("created_at")) {
480                    this.createdAt = BoxDateFormat.parse(value.asString());
481
482                } else if (memberName.equals("modified_at")) {
483                    this.modifiedAt = BoxDateFormat.parse(value.asString());
484
485                } else if (memberName.equals("configurable_permissions")) {
486                    this.configurablePermissions = this.parseConfigurablePermissions(value.asObject());
487
488                }
489            } catch (Exception e) {
490                throw new BoxDeserializationException(memberName, value.toString(), e);
491            }
492        }
493    }
494}