2 * Copyright 2008, 2009 Electronic Business Systems Ltd.
4 * This file is part of GSS.
6 * GSS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GSS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GSS. If not, see <http://www.gnu.org/licenses/>.
19 package gr.ebs.gss.server.rest;
21 import gr.ebs.gss.client.exceptions.DuplicateNameException;
22 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
23 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
24 import gr.ebs.gss.client.exceptions.RpcException;
25 import gr.ebs.gss.server.domain.User;
26 import gr.ebs.gss.server.domain.dto.GroupDTO;
27 import gr.ebs.gss.server.domain.dto.UserDTO;
29 import java.io.IOException;
30 import java.net.URLDecoder;
31 import java.net.URLEncoder;
32 import java.util.List;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.json.JSONArray;
40 import org.json.JSONException;
41 import org.json.JSONObject;
45 * A class that handles operations on the 'groups' namespace.
49 public class GroupsHandler extends RequestHandler {
53 private static Log logger = LogFactory.getLog(GroupsHandler.class);
56 * Serve the groups namespace for the user.
58 * @param req The servlet request we are processing
59 * @param resp The servlet response we are processing
60 * @throws IOException if an input/output error occurs
62 void serveGroups(HttpServletRequest req, HttpServletResponse resp) throws IOException {
63 String parentUrl = getContextPath(req, true);
64 String path = getInnerPath(req, PATH_GROUPS);
68 User user = getUser(req);
69 User owner = getOwner(req);
70 if (!owner.equals(user)) {
71 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
75 // Request to serve all groups
77 List<GroupDTO> groups = getService().getGroups(owner.getId());
78 JSONArray json = new JSONArray();
79 for (GroupDTO group: groups) {
80 JSONObject j = new JSONObject();
81 j.put("name", group.getName()).
82 put("uri", parentUrl + URLEncoder.encode(group.getName(),"UTF-8"));
86 sendJson(req, resp, json.toString());
87 } catch (ObjectNotFoundException e) {
88 logger.error("User not found", e);
89 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
91 } catch (RpcException e) {
93 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
95 } catch (JSONException e) {
97 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
101 // Chop any trailing slash
102 path = path.endsWith("/")? path.substring(0, path.length()-1): path;
103 // Chop any leading slash
104 path = path.startsWith("/")? path.substring(1): path;
105 int slash = path.indexOf('/');
108 // Request to serve group member
109 if (logger.isDebugEnabled())
110 logger.debug("Serving member " + path.substring(slash + 1) +
111 " from group " + path.substring(0, slash));
112 GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path.substring(0, slash),"UTF-8"));
113 for (UserDTO u: group.getMembers())
114 if (u.getUsername().equals(path.substring(slash + 1))) {
115 // Build the proper parent URL
116 String pathInfo = req.getPathInfo();
117 parentUrl = parentUrl.replaceFirst(pathInfo, "");
118 JSONObject json = new JSONObject();
119 json.put("username", u.getUsername()).put("name", u.getName()).
120 put("home", parentUrl + u.getUsername());
122 sendJson(req, resp, json.toString());
125 // Request to serve group
126 if (logger.isDebugEnabled())
127 logger.debug("Serving group " + path);
128 GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
129 JSONArray json = new JSONArray();
130 for (UserDTO u: group.getMembers())
131 json.put(parentUrl + u.getUsername());
133 sendJson(req, resp, json.toString());
135 } catch (ObjectNotFoundException e) {
137 resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
139 } catch (RpcException e) {
141 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
143 } catch (JSONException e) {
145 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
149 // Workaround for IE's broken caching behavior.
150 resp.setHeader("Expires", "-1");
154 * Handle POST requests in the groups namespace.
156 * @param req The servlet request we are processing
157 * @param resp The servlet response we are processing
158 * @throws IOException if an input/output error occurs
160 void postGroup(HttpServletRequest req, HttpServletResponse resp) throws IOException {
161 // Identify the requested resource path
162 String path = getInnerPath(req, PATH_GROUPS);
167 User user = getUser(req);
168 User owner = getOwner(req);
169 if (!owner.equals(user))
170 throw new InsufficientPermissionsException("User " + user.getUsername()
171 + " does not have permission to modify the groups owned by "
172 + owner.getUsername());
173 if (path.equals("/")) {
174 // Request to add group
175 String group = req.getParameter(GROUP_PARAMETER);
176 if (logger.isDebugEnabled())
177 logger.debug("Adding group " + group);
178 getService().createGroup(owner.getId(), group);
179 resp.setStatus(HttpServletResponse.SC_CREATED);
181 // Request to add group member
182 String username = req.getParameter(USERNAME_PARAMETER);
183 // Chop any trailing slash
184 path = path.endsWith("/")? path.substring(0, path.length()-1): path;
185 // Chop any leading slash
186 path = path.startsWith("/")? path.substring(1): path;
187 if (logger.isDebugEnabled())
188 logger.debug("Adding member " + username +
189 " to group " + path);
190 GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
191 User member = getService().findUser(username);
192 if (member == null) {
193 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "User " + username + " not found");
196 getService().addUserToGroup(owner.getId(), group.getId(), member.getId());
197 resp.setStatus(HttpServletResponse.SC_CREATED);
199 // Workaround for IE's broken caching behavior.
200 resp.setHeader("Expires", "-1");
201 } catch (ObjectNotFoundException e) {
202 resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
203 } catch (DuplicateNameException e) {
204 resp.sendError(HttpServletResponse.SC_CONFLICT, e.getMessage());
205 } catch (RpcException e) {
207 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
208 } catch (InsufficientPermissionsException e) {
209 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, e.getMessage());
214 * Handle DELETE requests in the groups namespace.
216 * @param req The servlet request we are processing
217 * @param resp The servlet response we are processing
218 * @throws IOException if an input/output error occurs
220 void deleteGroup(HttpServletRequest req, HttpServletResponse resp) throws IOException {
221 String path = getInnerPath(req, PATH_GROUPS);
225 if (path.equals("/"))
226 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, METHOD_GET + ", " + METHOD_POST);
228 // Chop any trailing slash
229 path = path.endsWith("/")? path.substring(0, path.length()-1): path;
230 // Chop any leading slash
231 path = path.startsWith("/")? path.substring(1): path;
232 int slash = path.indexOf('/');
234 User user = getUser(req);
235 User owner = getOwner(req);
236 if (!owner.equals(user))
237 throw new InsufficientPermissionsException("User " + user.getUsername()
238 + " does not have permission to modify the groups owned by "
239 + owner.getUsername());
241 // Request to delete group member
242 if (logger.isDebugEnabled())
243 logger.debug("Removing member " + path.substring(slash + 1) +
244 " from group " + path.substring(0, slash));
245 GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path.substring(0, slash),"UTF-8"));
246 for (UserDTO u: group.getMembers())
247 if (u.getUsername().equals(path.substring(slash + 1)))
248 getService().removeMemberFromGroup(owner.getId(), group.getId(), u.getId());
250 if (logger.isDebugEnabled())
251 logger.debug("Removing group " + path);
252 GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
253 getService().deleteGroup(owner.getId(), group.getId());
255 resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
256 // Workaround for IE's broken caching behavior.
257 resp.setHeader("Expires", "-1");
258 } catch (RpcException e) {
260 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
261 } catch (ObjectNotFoundException e) {
262 resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
263 } catch (InsufficientPermissionsException e) {
264 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, e.getMessage());