367ab53f6c0ee4e1c813881efc1080871757f0cf
[mir.git] / source / mircoders / servlet / ServletModuleUsers.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir 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 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir 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 Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30
31 package mircoders.servlet;
32
33 import mir.entity.adapter.EntityAdapterModel;
34 import mir.entity.adapter.EntityIteratorAdapter;
35 import mir.log.LoggerWrapper;
36 import mir.servlet.ServletModule;
37 import mir.servlet.ServletModuleExc;
38 import mir.servlet.ServletModuleFailure;
39 import mir.servlet.ServletModuleUserExc;
40 import mir.util.CachingRewindableIterator;
41 import mir.util.HTTPRequestParser;
42 import mir.util.URLBuilder;
43 import mircoders.entity.EntityUsers;
44 import mircoders.global.MirGlobal;
45 import mircoders.module.ModuleUsers;
46 import mircoders.storage.DatabaseUsers;
47
48 import javax.servlet.http.HttpServletRequest;
49 import javax.servlet.http.HttpServletResponse;
50 import java.util.*;
51
52 /**
53  *
54  *
55  */
56 public class ServletModuleUsers extends ServletModule
57 {
58   private static ServletModuleUsers instance = new ServletModuleUsers();
59   public static ServletModule getInstance() { return instance; }
60   protected ModuleUsers usersModule;
61
62   private ServletModuleUsers() {
63     super();
64     logger = new LoggerWrapper("ServletModule.Users");
65
66     try {
67       definition = "user";
68       usersModule = new ModuleUsers();
69       mainModule = usersModule;
70     }
71     catch (Throwable e) {
72       logger.debug("initialization of ServletModuleUsers failed!: " + e.getMessage());
73     }
74   }
75
76   public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
77   {
78     String idParam = aRequest.getParameter("id");
79
80     if (idParam == null)
81       throw new ServletModuleExc("ServletModuleUser.edit: invalid call: (id) not specified");
82
83     try {
84       EntityUsers user = (EntityUsers) mainModule.getById(idParam);
85       MirGlobal.accessControl().user().assertMayEditUser(ServletHelper.getUser(aRequest), user);
86
87       showUser(idParam, false, aRequest, aResponse);
88     }
89     catch (Throwable e) {
90       throw new ServletModuleFailure(e);
91     }
92   }
93
94   public void add(HttpServletRequest aRequest, HttpServletResponse aResponse)
95       throws ServletModuleExc
96   {
97     try {
98       MirGlobal.accessControl().user().assertMayAddUsers(ServletHelper.getUser(aRequest));
99
100       showUser(null, false, aRequest, aResponse);
101     }
102     catch (Throwable e) {
103       throw new ServletModuleFailure(e);
104     }
105   }
106
107   public String validatePassword(EntityUsers aUser, HTTPRequestParser aRequestParser) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
108   {
109     if ( (aRequestParser.getParameter("newpassword") != null &&
110           aRequestParser.getParameter("newpassword").length() > 0) ||
111          (aRequestParser.getParameter("newpassword2") != null &&
112           aRequestParser.getParameter("newpassword2").length() > 0)
113         ) {
114       String newPassword = aRequestParser.getParameterWithDefault("newpassword", "");
115       String newPassword2 = aRequestParser.getParameterWithDefault("newpassword2", "");
116       String oldPassword = aRequestParser.getParameterWithDefault("oldpassword", "");
117
118       try {
119         if (!usersModule.checkUserPassword(aUser, oldPassword)) {
120           throw new ServletModuleUserExc("user.error.incorrectpassword", new String[] {});
121         }
122       }
123       catch (Throwable t) {
124         throw new ServletModuleFailure(t);
125       }
126
127
128       if (newPassword.length() == 0 || newPassword2.length() == 0) {
129         throw new ServletModuleUserExc("user.error.missingpasswords", new String[] {});
130       }
131
132       if (!newPassword.equals(newPassword2)) {
133         throw new ServletModuleUserExc("user.error.passwordmismatch", new String[] {});
134       }
135
136       return newPassword;
137     }
138     else
139       return null;
140   }
141
142   public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse)
143       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
144   {
145     try {
146       MirGlobal.accessControl().user().assertMayAddUsers(ServletHelper.getUser(aRequest));
147
148       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
149       Map withValues = getIntersectingValues(aRequest, mainModule.getStorageObject());
150
151       String newPassword=validatePassword(ServletHelper.getUser(aRequest), requestParser);
152       if (newPassword!=null)
153         withValues.put("password", newPassword);
154       else
155         throw new ServletModuleUserExc("user.error.missingpassword", new String[] {});
156
157       String id = mainModule.add(withValues);
158
159       logAdminUsage(aRequest, id, "object added");
160
161       if (requestParser.hasParameter("returnurl"))
162         ServletHelper.redirect(aResponse, requestParser.getParameter("returnurl"));
163       else
164         list(aRequest, aResponse);
165     }
166     catch (Throwable e) {
167       throw new ServletModuleFailure(e);
168     }
169   }
170
171   public void update(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
172   {
173     try {
174       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
175       String id = requestParser.getParameter("id");
176       EntityUsers user = (EntityUsers) mainModule.getById(id);
177       MirGlobal.accessControl().user().assertMayEditUser(ServletHelper.getUser(aRequest), user);
178
179       Map withValues = getIntersectingValues(aRequest, mainModule.getStorageObject());
180       if (!withValues.containsKey("is_admin"))
181         withValues.put("is_admin","0");
182       if (!withValues.containsKey("is_disabled"))
183         withValues.put("is_disabled","0");
184
185       String newPassword=validatePassword(ServletHelper.getUser(aRequest), requestParser);
186       if (newPassword!=null)
187         withValues.put("password", MirGlobal.localizer().adminInterface().makePasswordDigest(newPassword));
188
189       mainModule.set(withValues);
190
191       logAdminUsage(aRequest, id, "object modified");
192
193       if (requestParser.hasParameter("returnurl"))
194         ServletHelper.redirect(aResponse, requestParser.getParameter("returnurl"));
195       else
196         list(aRequest, aResponse);
197     }
198     catch (Throwable e) {
199       throw new ServletModuleFailure(e);
200     }
201   }
202
203   public void updatepassword(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
204   {
205     try {
206       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
207       String id = requestParser.getParameter("id");
208       EntityUsers user = (EntityUsers) mainModule.getById(id);
209       MirGlobal.accessControl().user().assertMayChangeUserPassword(ServletHelper.getUser(aRequest), user);
210
211       String newPassword=validatePassword(ServletHelper.getUser(aRequest), requestParser);
212       if (newPassword!=null) {
213         user.setFieldValue("password", MirGlobal.localizer().adminInterface().makePasswordDigest(newPassword));
214         user.update();
215
216         logAdminUsage(aRequest, id, "password changed");
217
218         // hackish: to make sure the cached logged in user is up-to-date:
219         ServletHelper.setUser(aRequest, (EntityUsers) mainModule.getById(ServletHelper.getUser(aRequest).getId()));
220       }
221
222       if (requestParser.hasParameter("returnurl"))
223         ServletHelper.redirect(aResponse, requestParser.getParameter("returnurl"));
224       else
225         ServletHelper.redirect(aResponse, "");
226     }
227     catch (Throwable e) {
228       throw new ServletModuleFailure(e);
229     }
230   }
231
232   public void list(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
233   {
234     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
235
236     int offset = requestParser.getIntegerWithDefault("offset", 0);
237
238     returnUserList(aRequest, aResponse, offset);
239   }
240
241   public void returnUserList(
242        HttpServletRequest aRequest,
243        HttpServletResponse aResponse,
244        int anOffset) throws ServletModuleExc {
245
246     URLBuilder urlBuilder = new URLBuilder();
247     int count;
248
249     try {
250       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
251       model = MirGlobal.localizer().dataModel().adapterModel();
252
253       Object userList =
254           new CachingRewindableIterator(
255             new EntityIteratorAdapter( "", "login", nrEntitiesPerListPage,
256                MirGlobal.localizer().dataModel().adapterModel(), "user", nrEntitiesPerListPage, anOffset)
257       );
258
259       responseData.put("nexturl", null);
260       responseData.put("prevurl", null);
261
262       count=mainModule.getSize("");
263
264       urlBuilder.setValue("module", "Users");
265       urlBuilder.setValue("do", "list");
266
267       urlBuilder.setValue("offset", anOffset);
268       responseData.put("offset" , new Integer(anOffset).toString());
269       responseData.put("thisurl" , urlBuilder.getQuery());
270
271       if (count>=anOffset+nrEntitiesPerListPage) {
272         urlBuilder.setValue("offset", (anOffset + nrEntitiesPerListPage));
273         responseData.put("nexturl" , urlBuilder.getQuery());
274       }
275
276       if (anOffset>0) {
277         urlBuilder.setValue("offset", Math.max(anOffset - nrEntitiesPerListPage, 0));
278         responseData.put("prevurl" , urlBuilder.getQuery());
279       }
280
281       responseData.put("users", userList);
282       responseData.put("mayDeleteUsers", new Boolean(MirGlobal.accessControl().user().mayDeleteUsers(ServletHelper.getUser(aRequest))));
283       responseData.put("mayAddUsers", new Boolean(MirGlobal.accessControl().user().mayAddUsers(ServletHelper.getUser(aRequest))));
284       responseData.put("mayEditUsers", new Boolean(MirGlobal.accessControl().user().mayEditUsers(ServletHelper.getUser(aRequest))));
285
286       responseData.put("from" , Integer.toString(anOffset+1));
287       responseData.put("count", Integer.toString(count));
288       responseData.put("to", Integer.toString(Math.min(anOffset+nrEntitiesPerListPage, count)));
289       responseData.put("offset" , Integer.toString(anOffset));
290
291       ServletHelper.generateResponse(aResponse.getWriter(), responseData, listGenerator);
292     }
293     catch (Throwable e) {
294       throw new ServletModuleFailure(e);
295     }
296   }
297
298   public void showUser(String anId, boolean anOnlyPassword, HttpServletRequest aRequest, HttpServletResponse aResponse)
299       throws ServletModuleExc {
300     try {
301       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
302       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
303       EntityAdapterModel model = MirGlobal.localizer().dataModel().adapterModel();
304       Map user;
305       URLBuilder urlBuilder = new URLBuilder();
306
307       urlBuilder.setValue("module", "Users");
308       if (anOnlyPassword)
309         urlBuilder.setValue("do", "changepassword");
310       else
311         urlBuilder.setValue("do", "edit");
312       urlBuilder.setValue("id", anId);
313       urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
314
315       if (anId!=null) {
316         responseData.put("new", Boolean.FALSE);
317         user = model.makeEntityAdapter("user", mainModule.getById(anId));
318       }
319       else {
320         List fields = DatabaseUsers.getInstance().getFieldNames();
321         responseData.put("new", Boolean.TRUE);
322         user = new HashMap();
323         Iterator i = fields.iterator();
324         while (i.hasNext()) {
325           user.put(i.next(), null);
326         }
327
328         MirGlobal.localizer().adminInterface().initializeArticle(user);
329       }
330       responseData.put("user", user);
331       responseData.put("passwordonly", new Boolean(anOnlyPassword));
332
333       responseData.put("returnurl", requestParser.getParameter("returnurl"));
334       responseData.put("thisurl", urlBuilder.getQuery());
335
336       ServletHelper.generateResponse(aResponse.getWriter(), responseData, editGenerator);
337     }
338     catch (Throwable e) {
339       throw new ServletModuleFailure(e);
340     }
341   }
342
343   public void delete(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleUserExc, ServletModuleExc, ServletModuleFailure {
344     try {
345       EntityUsers user = (EntityUsers) mainModule.getById(aRequest.getParameter("id"));
346
347       MirGlobal.accessControl().user().assertMayDeleteUser(ServletHelper.getUser(aRequest), user);
348
349       super.delete(aRequest, aResponse);
350     }
351     catch (Throwable t) {
352       throw new ServletModuleFailure(t);
353     }
354   }
355
356   public void changepassword(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
357   {
358     String idParam = aRequest.getParameter("id");
359
360     if (idParam == null)
361       throw new ServletModuleExc("ServletModuleUser.edit: invalid call: (id) not specified");
362
363     try {
364       EntityUsers user = (EntityUsers) mainModule.getById(idParam);
365       MirGlobal.accessControl().user().assertMayChangeUserPassword(ServletHelper.getUser(aRequest), user);
366
367       showUser(idParam, true, aRequest, aResponse);
368     }
369     catch (Throwable e) {
370       throw new ServletModuleFailure(e);
371     }
372   }
373 }
374