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