001package com.box.sdk;
002
003import java.net.URL;
004import java.util.Date;
005import java.util.HashMap;
006import java.util.Map;
007
008import com.eclipsesource.json.JsonObject;
009import com.eclipsesource.json.JsonValue;
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     * @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     * @param  api the API connection to be used by the group membership.
030     * @param  id  the ID of the group membership.
031     */
032    public BoxGroupMembership(BoxAPIConnection api, String id) {
033        super(api, id);
034    }
035
036    /**
037     * Gets information about this group membership.
038     * @return info about this group membership.
039     */
040    public Info getInfo() {
041        BoxAPIConnection api = this.getAPI();
042        URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID());
043
044        BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
045        BoxJSONResponse response = (BoxJSONResponse) request.send();
046        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
047        return new Info(jsonObject);
048    }
049
050    /**
051     * Updates the information about this group membership with any info fields that have been modified locally.
052     * @param info the updated info.
053     */
054    public void updateInfo(Info info) {
055        BoxAPIConnection api = this.getAPI();
056        URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID());
057
058        BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT");
059        request.setBody(info.getPendingChanges());
060        BoxJSONResponse response = (BoxJSONResponse) request.send();
061        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
062        info.update(jsonObject);
063    }
064
065    /**
066     * Deletes this group membership.
067     */
068    public void delete() {
069        BoxAPIConnection api = this.getAPI();
070        URL url = MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL(), this.getID());
071
072        BoxAPIRequest request = new BoxAPIRequest(api, url, "DELETE");
073        BoxAPIResponse response = request.send();
074        response.disconnect();
075    }
076
077    /**
078     * Contains information about a BoxGroupMembership.
079     */
080    public class Info extends BoxResource.Info {
081
082        /**
083         * @see #getUser()
084         */
085        private BoxUser.Info user;
086
087        /**
088         * @see #getGroup()
089         */
090        private BoxGroup.Info group;
091
092        /**
093         * @see #getRole()
094         */
095        private Role role;
096
097        /**
098         * @see #getCreatedAt()
099         */
100        private Date createdAt;
101
102        /**
103         * @see #getModifiedAt()
104         */
105        private Date modifiedAt;
106
107        /**
108         * @see #getPermissions()
109         */
110        private Map<Permission, Boolean> configurablePermissions;
111
112        /**
113         * Constructs an empty Info object.
114         */
115        public Info() {
116            super();
117        }
118
119        /**
120         * Constructs an Info object by parsing information from a JSON string.
121         * @param  json the JSON string to parse.
122         */
123        public Info(String json) {
124            super(json);
125        }
126
127        /**
128         * Constructs an Info object using an already parsed JSON object.
129         * @param  jsonObject the parsed JSON object.
130         */
131        Info(JsonObject jsonObject) {
132            super(jsonObject);
133        }
134
135        /**
136         * Gets the user belonging to the group.
137         *
138         * <p>Note: the BoxUser.Info returned by this method will only have the ID, name, and login fields
139         * populated.</p>
140         *
141         * @return the user belonging to the group.
142         */
143        public BoxUser.Info getUser() {
144            return this.user;
145        }
146
147        /**
148         * Gets the group the user belongs to.
149         *
150         * <p>Note: the BoxGroup.Info returned by this method will only have the ID and name fields populated.</p>
151         *
152         * @return the group the user belongs to.
153         */
154        public BoxGroup.Info getGroup() {
155            return this.group;
156        }
157
158        /**
159         * Gets the level of access the user has.
160         * @return the level of access the user has.
161         */
162        public Role getRole() {
163            return this.role;
164        }
165
166        /**
167         * Sets the level of access the user has.
168         * @param role the new level of access to give the user.
169         */
170        public void setRole(Role role) {
171            this.role = role;
172            this.addPendingChange("role", role.toJSONString());
173        }
174
175        /**
176         * Gets the time the group membership was created.
177         * @return the time the group membership was created.
178         */
179        public Date getCreatedAt() {
180            return this.createdAt;
181        }
182
183        /**
184         * Gets the time the group membership was last modified.
185         * @return the time the group membership was last modified.
186         */
187        public Date getModifiedAt() {
188            return this.modifiedAt;
189        }
190
191        /**
192         * Gets the configurablePermissions that the current user has on the group as group admin.
193         *
194         * @return the configurablePermissions that the current user has on the group as group admin.
195         */
196        public Map<Permission, Boolean> getConfigurablePermissions() {
197            return this.configurablePermissions;
198        }
199
200        /**
201         * Sets the configurablePermissions that the current user has on the group as group admin.
202         * @param configurablePermissions a Map representing the group admin configurable permissions
203         */
204        public void setConfigurablePermissions(Map<Permission, Boolean> configurablePermissions) {
205            this.configurablePermissions = configurablePermissions;
206            this.addPendingChange("configurable_permissions", this.configurablePermissionJson());
207        }
208
209        /**
210         * append new configurable permissions to the previous existing list.
211         * @param permission the group admin permission one wants to enable or disable of the user on the group.
212         * @param value the true/false value of the attribute to set.
213         */
214        public void appendConfigurablePermissions(Permission permission, Boolean value) {
215            this.configurablePermissions.put(permission, value);
216            this.addPendingChange("configurable_permissions", this.configurablePermissionJson());
217        }
218
219        private JsonObject configurablePermissionJson() {
220            JsonObject configurablePermissionJson = new JsonObject();
221            for (Permission attrKey : this.configurablePermissions.keySet()) {
222                configurablePermissionJson.set(attrKey.toJSONValue(), this.configurablePermissions.get(attrKey));
223            }
224            return configurablePermissionJson;
225        }
226
227        /**
228         * {@inheritDoc}
229         */
230        @Override
231        public BoxGroupMembership getResource() {
232            return BoxGroupMembership.this;
233        }
234
235        private Map<Permission, Boolean> parseConfigurablePermissions(JsonObject jsonObject) {
236            if (jsonObject == null) {
237                return null;
238            }
239            Map<Permission, Boolean> permissions = new HashMap<Permission, Boolean>();
240            for (JsonObject.Member member : jsonObject) {
241                String memberName = member.getName();
242                boolean memberValue = member.getValue().asBoolean();
243                if (memberName.equals("can_create_accounts")) {
244                    permissions.put(Permission.CAN_CREATE_ACCOUNTS, memberValue);
245                } else if (memberName.equals("can_edit_accounts")) {
246                    permissions.put(Permission.CAN_EDIT_ACCOUNTS, memberValue);
247                } else if (memberName.equals("can_instant_login")) {
248                    permissions.put(Permission.CAN_INSTANT_LOGIN, memberValue);
249                } else if (memberName.equals("can_run_reports")) {
250                    permissions.put(Permission.CAN_RUN_REPORTS, memberValue);
251                }
252            }
253            return permissions;
254        }
255
256        /**
257         * {@inheritDoc}
258         */
259        @Override
260        protected void parseJSONMember(JsonObject.Member member) {
261            super.parseJSONMember(member);
262
263            String memberName = member.getName();
264            JsonValue value = member.getValue();
265
266            try {
267                if (memberName.equals("user")) {
268                    JsonObject userJSON = value.asObject();
269                    if (this.user == null) {
270                        String userID = userJSON.get("id").asString();
271                        BoxUser user = new BoxUser(getAPI(), userID);
272                        this.user = user.new Info(userJSON);
273                    } else {
274                        this.user.update(userJSON);
275                    }
276
277                } else if (memberName.equals("group")) {
278                    JsonObject groupJSON = value.asObject();
279                    if (this.group == null) {
280                        String userID = groupJSON.get("id").asString();
281                        BoxGroup group = new BoxGroup(getAPI(), userID);
282                        this.group = group.new Info(groupJSON);
283                    } else {
284                        this.group.update(groupJSON);
285                    }
286
287                } else if (memberName.equals("role")) {
288                    this.role = Role.fromJSONString(value.asString());
289
290                } else if (memberName.equals("created_at")) {
291                    this.createdAt = BoxDateFormat.parse(value.asString());
292
293                } else if (memberName.equals("modified_at")) {
294                    this.modifiedAt = BoxDateFormat.parse(value.asString());
295
296                } else if (memberName.equals("configurable_permissions")) {
297                    this.configurablePermissions = this.parseConfigurablePermissions(value.asObject());
298
299                }
300            } catch (Exception e) {
301                throw new BoxDeserializationException(memberName, value.toString(), e);
302            }
303        }
304    }
305
306    /**
307     * Enumerates the possible roles that a user can have within a group.
308     */
309    public enum Role {
310        /**
311         * The user is an administrator in the group.
312         */
313        ADMIN ("admin"),
314
315        /**
316         * The user is a submaster in the group.
317         */
318        SUBMASTER ("submaster"),
319
320        /**
321         * The user is a regular member in the group.
322         */
323        MEMBER ("member");
324
325        /**
326         * String representation of the role.
327         */
328        private final String jsonValue;
329
330        /**
331         * Constructor.
332         * @param jsonValue srting representation of the role.
333         */
334        private Role(String jsonValue) {
335            this.jsonValue = jsonValue;
336        }
337
338        /**
339         * Creates the role from given string.
340         * @param jsonValue string to be converted to role.
341         * @return the role, created from string value.
342         */
343        static Role fromJSONString(String jsonValue) {
344            return Role.valueOf(jsonValue.toUpperCase());
345        }
346
347        /**
348         * @return string representation of the role.
349         */
350        String toJSONString() {
351            return this.jsonValue;
352        }
353    }
354
355    /**
356     * Enumerates the possible permissions that a user can have as a group admin.
357     */
358    public enum Permission {
359        /**
360         * The user can create accounts.
361         */
362        CAN_CREATE_ACCOUNTS("can_create_accounts"),
363
364        /**
365         * The user can edit accounts.
366         */
367        CAN_EDIT_ACCOUNTS("can_edit_accounts"),
368
369        /**
370         * The user can instant login as another user.
371         */
372        CAN_INSTANT_LOGIN("can_instant_login"),
373
374        /**
375         * The user can run reports.
376         */
377        CAN_RUN_REPORTS("can_run_reports");
378
379        private final String jsonValue;
380
381        private Permission(String jsonValue) {
382            this.jsonValue = jsonValue;
383        }
384
385        static Permission fromJSONValue(String jsonValue) {
386            return Permission.valueOf(jsonValue.toUpperCase());
387        }
388
389        String toJSONValue() {
390            return this.jsonValue;
391        }
392    }
393}