Statistics
| Branch: | Tag: | Revision:

root / src / gr / ebs / gss / server / rest / GroupsHandler.java @ f9bd859c

History | View | Annotate | Download (11.9 kB)

1
/*
2
 * Copyright 2008, 2009 Electronic Business Systems Ltd.
3
 *
4
 * This file is part of GSS.
5
 *
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.
10
 *
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.
15
 *
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/>.
18
 */
19
package gr.ebs.gss.server.rest;
20

    
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;
28
import gr.ebs.gss.server.ejb.TransactionHelper;
29

    
30
import java.io.IOException;
31
import java.net.URLDecoder;
32
import java.net.URLEncoder;
33
import java.util.List;
34
import java.util.concurrent.Callable;
35

    
36
import javax.servlet.http.HttpServletRequest;
37
import javax.servlet.http.HttpServletResponse;
38

    
39
import org.apache.commons.logging.Log;
40
import org.apache.commons.logging.LogFactory;
41
import org.json.JSONArray;
42
import org.json.JSONException;
43
import org.json.JSONObject;
44

    
45

    
46
/**
47
 * A class that handles operations on the 'groups' namespace.
48
 *
49
 * @author past
50
 */
51
public class GroupsHandler extends RequestHandler {
52
        /**
53
         * The logger.
54
         */
55
        private static Log logger = LogFactory.getLog(GroupsHandler.class);
56

    
57
    /**
58
     * Serve the groups namespace for the user.
59
     *
60
     * @param req The servlet request we are processing
61
     * @param resp The servlet response we are processing
62
     * @throws IOException if an input/output error occurs
63
         */
64
        void serveGroups(HttpServletRequest req, HttpServletResponse resp) throws IOException {
65
            String parentUrl = getContextPath(req, true);
66
        String path = getInnerPath(req, PATH_GROUPS);
67
                if (path.equals(""))
68
                        path = "/";
69

    
70
            User user = getUser(req);
71
            User owner = getOwner(req);
72
            if (!owner.equals(user)) {
73
                    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
74
                    return;
75
            }
76
            if (path.equals("/"))
77
                        // Request to serve all groups
78
                try {
79
                    List<GroupDTO> groups = getService().getGroups(owner.getId());
80
                    JSONArray json = new JSONArray();
81
                    for (GroupDTO group: groups) {
82
                            JSONObject j = new JSONObject();
83
                            j.put("name", group.getName()).
84
                                    put("uri", parentUrl + URLEncoder.encode(group.getName(),"UTF-8"));
85
                                json.put(j);
86
                    }
87

    
88
                    sendJson(req, resp, json.toString());
89
                    } catch (ObjectNotFoundException e) {
90
                            logger.error("User not found", e);
91
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
92
                            return;
93
                    } catch (RpcException e) {
94
                            logger.error("", e);
95
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
96
                            return;
97
                    } catch (JSONException e) {
98
                            logger.error("", e);
99
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
100
                            return;
101
                        }
102
                else {
103
                    // Chop any trailing slash
104
                path = path.endsWith("/")? path.substring(0, path.length()-1): path;
105
                // Chop any leading slash
106
                path = path.startsWith("/")? path.substring(1): path;
107
                int slash = path.indexOf('/');
108
                        try {
109
                        if (slash != -1) {
110
                                // Request to serve group member
111
                                if (logger.isDebugEnabled())
112
                                        logger.debug("Serving member " + path.substring(slash + 1) +
113
                                                                " from group " + path.substring(0, slash));
114
                                GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path.substring(0, slash),"UTF-8"));
115
                                for (UserDTO u: group.getMembers())
116
                                        if (u.getUsername().equals(path.substring(slash + 1))) {
117
                                                    // Build the proper parent URL
118
                                                    String pathInfo = req.getPathInfo();
119
                                                    parentUrl = parentUrl.replaceFirst(pathInfo, "");
120
                                            JSONObject json = new JSONObject();
121
                                                json.put("username", u.getUsername()).put("name", u.getName()).
122
                                                                put("home", parentUrl + u.getUsername());
123

    
124
                                            sendJson(req, resp, json.toString());
125
                                        }
126
                        } else {
127
                                // Request to serve group
128
                                if (logger.isDebugEnabled())
129
                                        logger.debug("Serving group " + path);
130
                                    GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
131
                                JSONArray json = new JSONArray();
132
                                for (UserDTO u: group.getMembers())
133
                                            json.put(parentUrl + u.getUsername());
134

    
135
                                sendJson(req, resp, json.toString());
136
                        }
137
                        } catch (ObjectNotFoundException e) {
138
                            logger.error("", e);
139
                            resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
140
                            return;
141
                        } catch (RpcException e) {
142
                            logger.error("", e);
143
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
144
                            return;
145
                        } catch (JSONException e) {
146
                                logger.error("", e);
147
                                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
148
                                return;
149
                        }
150
            }
151
            // Workaround for IE's broken caching behavior.
152
                resp.setHeader("Expires", "-1");
153
        }
154

    
155
        /**
156
         * Handle POST requests in the groups namespace.
157
         *
158
     * @param req The servlet request we are processing
159
     * @param resp The servlet response we are processing
160
     * @throws IOException if an input/output error occurs
161
         */
162
        void postGroup(HttpServletRequest req, HttpServletResponse resp) throws IOException {
163
            // Identify the requested resource path
164
        String path = getInnerPath(req, PATH_GROUPS);
165
                if (path.equals(""))
166
                        path = "/";
167

    
168
                try {
169
                    User user = getUser(req);
170
                final User owner = getOwner(req);
171
                if (!owner.equals(user))
172
                        throw new InsufficientPermissionsException("User " + user.getUsername()
173
                                                + " does not have permission to modify the groups owned by "
174
                                                + owner.getUsername());
175
                    if (path.equals("/")) {
176
                        // Request to add group
177
                            final String group = req.getParameter(GROUP_PARAMETER);
178
                            if (!isValidResourceName(group)) {
179
                                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
180
                                return;
181
                        }
182
                            if (logger.isDebugEnabled())
183
                                    logger.debug("Adding group " + group);
184
                                    new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
185
                                                @Override
186
                                                public Void call() throws Exception {
187
                                                        getService().createGroup(owner.getId(), group);
188
                                                        return null;
189
                                                }
190
                                        });
191
                                resp.setStatus(HttpServletResponse.SC_CREATED);
192
                    } else {
193
                        // Request to add group member
194
                        String username = req.getParameter(USERNAME_PARAMETER);
195
                            if (!isValidResourceName(username)) {
196
                                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
197
                                return;
198
                        }
199
                            // Chop any trailing slash
200
                        path = path.endsWith("/")? path.substring(0, path.length()-1): path;
201
                        // Chop any leading slash
202
                        path = path.startsWith("/")? path.substring(1): path;
203
                        if (logger.isDebugEnabled())
204
                                logger.debug("Adding member " + username +
205
                                                        " to group " + path);
206
                        final GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
207
                        final User member = getService().findUser(username);
208
                        if (member == null) {
209
                                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "User " + username + " not found");
210
                                return;
211
                        }
212
                        new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
213
                                        @Override
214
                                        public Void call() throws Exception {
215
                                                getService().addUserToGroup(owner.getId(), group.getId(), member.getId());
216
                                                return null;
217
                                        }
218
                                });
219
                        resp.setStatus(HttpServletResponse.SC_CREATED);
220
                    }
221
                    // Workaround for IE's broken caching behavior.
222
                        resp.setHeader("Expires", "-1");
223
                } catch (ObjectNotFoundException e) {
224
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
225
                } catch (IllegalArgumentException e) {
226
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
227
                } catch (DuplicateNameException e) {
228
                        resp.sendError(HttpServletResponse.SC_CONFLICT, e.getMessage());
229
                } catch (RpcException e) {
230
                        logger.error("", e);
231
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
232
                } catch (InsufficientPermissionsException e) {
233
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, e.getMessage());
234
                } catch (Exception e) {
235
                        logger.error("", e);
236
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
237
                }
238

    
239
        }
240

    
241
        /**
242
         * Handle DELETE requests in the groups namespace.
243
         *
244
     * @param req The servlet request we are processing
245
     * @param resp The servlet response we are processing
246
     * @throws IOException if an input/output error occurs
247
         */
248
        void deleteGroup(HttpServletRequest req, HttpServletResponse resp) throws IOException {
249
        String path = getInnerPath(req, PATH_GROUPS);
250
                if (path.equals(""))
251
                        path = "/";
252

    
253
            if (path.equals("/"))
254
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, METHOD_GET + ", " + METHOD_POST);
255
                else {
256
                    // Chop any trailing slash
257
                path = path.endsWith("/")? path.substring(0, path.length()-1): path;
258
                // Chop any leading slash
259
                path = path.startsWith("/")? path.substring(1): path;
260
                int slash = path.indexOf('/');
261
                try {
262
                    User user = getUser(req);
263
                    final User owner = getOwner(req);
264
                    if (!owner.equals(user))
265
                            throw new InsufficientPermissionsException("User " + user.getUsername()
266
                                                    + " does not have permission to modify the groups owned by "
267
                                                    + owner.getUsername());
268
                    if (slash != -1) {
269
                            // Request to delete group member
270
                            if (logger.isDebugEnabled())
271
                                    logger.debug("Removing member " + path.substring(slash + 1) +
272
                                                            " from group " + path.substring(0, slash));
273
                            final GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path.substring(0, slash),"UTF-8"));
274
                            for (final UserDTO u: group.getMembers())
275
                                    if (u.getUsername().equals(path.substring(slash + 1)))
276
                                            new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
277
                                                    @Override
278
                                                    public Void call() throws Exception {
279
                                                            getService().removeMemberFromGroup(owner.getId(), group.getId(), u.getId());
280
                                                            return null;
281
                                                    }
282
                                            });
283
                    } else {
284
                            if (logger.isDebugEnabled())
285
                                    logger.debug("Removing group " + path);
286
                                final GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
287
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
288
                                            @Override
289
                                            public Void call() throws Exception {
290
                                                    getService().deleteGroup(owner.getId(), group.getId());
291
                                                    return null;
292
                                            }
293
                                    });
294
                    }
295
                        resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
296
                        // Workaround for IE's broken caching behavior.
297
                            resp.setHeader("Expires", "-1");
298
                } catch (RpcException e) {
299
                            logger.error("", e);
300
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
301
                } catch (ObjectNotFoundException e) {
302
                            resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
303
                        } catch (InsufficientPermissionsException e) {
304
                                resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, e.getMessage());
305
                        } catch (Exception e) {
306
                            logger.error("", e);
307
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
308
                        }
309
            }
310
        }
311

    
312
}