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