misc fixes + updates:
[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 java.util.HashMap;\r
34 import java.util.Iterator;\r
35 import java.util.List;\r
36 import java.util.Locale;\r
37 import java.util.Map;\r
38 import javax.servlet.http.HttpServletRequest;\r
39 import javax.servlet.http.HttpServletResponse;\r
40 \r
41 import mir.entity.adapter.EntityAdapterModel;\r
42 import mir.entity.adapter.EntityIteratorAdapter;\r
43 import mir.log.LoggerWrapper;\r
44 import mir.servlet.ServletModule;\r
45 import mir.servlet.ServletModuleExc;\r
46 import mir.servlet.ServletModuleFailure;\r
47 import mir.servlet.ServletModuleUserExc;\r
48 import mir.storage.StorageObjectFailure;\r
49 import mir.util.CachingRewindableIterator;\r
50 import mir.util.HTTPRequestParser;\r
51 import mir.util.URLBuilder;\r
52 import mircoders.entity.EntityUsers;\r
53 import mircoders.global.MirGlobal;\r
54 import mircoders.module.ModuleUsers;\r
55 import mircoders.storage.DatabaseUsers;
56
57 /*
58  *  ServletModuleUsers -
59  *  liefert HTML fuer Users
60  *
61  *
62  * @author RK
63  */
64
65 public class ServletModuleUsers extends ServletModule
66 {
67   private String editTemplate;
68   private String listTemplate;
69
70   private static ServletModuleUsers instance = new ServletModuleUsers();
71   public static ServletModule getInstance() { return instance; }
72   protected ModuleUsers usersModule;
73
74   private ServletModuleUsers() {
75     super();
76     logger = new LoggerWrapper("ServletModule.Users");
77
78     listTemplate = configuration.getString("ServletModule.Users.ListTemplate");
79     editTemplate = configuration.getString("ServletModule.Users.ObjektTemplate");
80     templateConfirmString = configuration.getString("ServletModule.Users.ConfirmTemplate");
81
82     try {
83       usersModule = new ModuleUsers(DatabaseUsers.getInstance());
84       mainModule = usersModule;
85     }
86     catch (StorageObjectFailure e) {
87       logger.debug("initialization of ServletModuleUsers failed!: " + e.getMessage());
88     }
89   }
90
91   public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
92   {
93     String idParam = aRequest.getParameter("id");
94
95     if (idParam == null)
96       throw new ServletModuleExc("ServletModuleUser.edit: invalid call: (id) not specified");
97
98     try {
99       EntityUsers user = (EntityUsers) mainModule.getById(idParam);
100       MirGlobal.accessControl().user().assertMayEditUser(ServletHelper.getUser(aRequest), user);
101
102       showUser(idParam, false, aRequest, aResponse);
103     }
104     catch (Throwable e) {
105       throw new ServletModuleFailure(e);
106     }
107   }
108
109   public void add(HttpServletRequest aRequest, HttpServletResponse aResponse)
110       throws ServletModuleExc
111   {
112     try {
113       MirGlobal.accessControl().user().assertMayAddUsers(ServletHelper.getUser(aRequest));
114
115       showUser(null, false, aRequest, aResponse);
116     }
117     catch (Throwable e) {
118       throw new ServletModuleFailure(e);
119     }
120   }
121
122   public String validatePassword(EntityUsers aUser, HTTPRequestParser aRequestParser) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
123   {
124     if ( (aRequestParser.getParameter("newpassword") != null &&
125           aRequestParser.getParameter("newpassword").length() > 0) ||
126         (aRequestParser.getParameter("newpassword2") != null &&
127          aRequestParser.getParameter("newpassword2").length() > 0)
128         ) {
129       String newPassword = aRequestParser.getParameterWithDefault("newpassword", "");
130       String newPassword2 = aRequestParser.getParameterWithDefault("newpassword2", "");
131       String oldPassword = aRequestParser.getParameterWithDefault("oldpassword", "");
132
133       try {
134         if (!usersModule.checkUserPassword(aUser, oldPassword)) {
135           throw new ServletModuleUserExc("user.error.incorrectpassword", new String[] {});
136         }
137       }
138       catch (Throwable t) {
139         throw new ServletModuleFailure(t);
140       }
141
142
143       if (newPassword.length() == 0 || newPassword2.length() == 0) {
144         throw new ServletModuleUserExc("user.error.missingpasswords", new String[] {});
145       }
146
147       if (!newPassword.equals(newPassword2)) {
148         throw new ServletModuleUserExc("user.error.passwordmismatch", new String[] {});
149       }
150
151       return newPassword;
152     }
153     else
154       return null;
155   }
156
157   public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse)
158       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
159   {
160     try {
161       MirGlobal.accessControl().user().assertMayAddUsers(ServletHelper.getUser(aRequest));
162
163       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
164       Map withValues = getIntersectingValues(aRequest, mainModule.getStorageObject());
165
166       String newPassword=validatePassword(ServletHelper.getUser(aRequest), requestParser);
167       if (newPassword!=null)
168         withValues.put("password", newPassword);
169       else
170         throw new ServletModuleUserExc("user.error.missingpassword", new String[] {});
171
172       String id = mainModule.add(withValues);
173       if (requestParser.hasParameter("returnurl"))
174         redirect(aResponse, requestParser.getParameter("returnurl"));
175       else
176         list(aRequest, aResponse);
177     }
178     catch (Throwable e) {
179       throw new ServletModuleFailure(e);
180     }
181   }
182
183   public void update(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
184   {
185     try {
186       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
187       EntityUsers user = (EntityUsers) mainModule.getById(requestParser.getParameter("id"));
188       MirGlobal.accessControl().user().assertMayEditUser(ServletHelper.getUser(aRequest), user);
189
190       Map withValues = getIntersectingValues(aRequest, mainModule.getStorageObject());
191       if (!withValues.containsKey("is_admin"))
192         withValues.put("is_admin","0");
193
194       String newPassword=validatePassword(ServletHelper.getUser(aRequest), requestParser);
195       if (newPassword!=null)
196         withValues.put("password", MirGlobal.localizer().adminInterface().makePasswordDigest(newPassword));
197
198       mainModule.set(withValues);
199
200       if (requestParser.hasParameter("returnurl"))
201         redirect(aResponse, requestParser.getParameter("returnurl"));
202       else
203         list(aRequest, aResponse);
204     }
205     catch (Throwable e) {
206       throw new ServletModuleFailure(e);
207     }
208   }
209
210   public void updatepassword(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure
211   {
212     try {
213       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
214       EntityUsers user = (EntityUsers) mainModule.getById(requestParser.getParameter("id"));
215       MirGlobal.accessControl().user().assertMayChangeUserPassword(ServletHelper.getUser(aRequest), user);
216
217       String newPassword=validatePassword(ServletHelper.getUser(aRequest), requestParser);
218       if (newPassword!=null) {
219         user.setValueForProperty("password", MirGlobal.localizer().adminInterface().makePasswordDigest(newPassword));
220         user.update();
221
222         // hackish: to make sure the cached logged in user is up-to-date:
223         ServletHelper.setUser(aRequest, (EntityUsers) mainModule.getById(ServletHelper.getUser(aRequest).getId()));
224       }
225
226       if (requestParser.hasParameter("returnurl"))
227         redirect(aResponse, requestParser.getParameter("returnurl"));
228       else
229         redirect(aResponse, "");
230     }
231     catch (Throwable e) {
232       throw new ServletModuleFailure(e);
233     }
234   }
235
236   public void list(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
237   {
238     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
239
240     int offset = requestParser.getIntegerWithDefault("offset", 0);
241
242     returnUserList(aRequest, aResponse, offset);
243   }
244
245   public void returnUserList(
246        HttpServletRequest aRequest,
247        HttpServletResponse aResponse,
248        int anOffset) throws ServletModuleExc {
249
250     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
251     URLBuilder urlBuilder = new URLBuilder();
252     EntityAdapterModel model;
253     int count;
254     int nrUsersPerPage = 20;
255
256     try {
257       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
258       model = MirGlobal.localizer().dataModel().adapterModel();
259
260       Object userList =
261           new CachingRewindableIterator(
262             new EntityIteratorAdapter( "", "login", nrUsersPerPage,
263                MirGlobal.localizer().dataModel().adapterModel(), "user", nrUsersPerPage, anOffset)
264       );
265
266       responseData.put("nexturl", null);
267       responseData.put("prevurl", null);
268
269       count=mainModule.getSize("");
270
271       urlBuilder.setValue("module", "Users");
272       urlBuilder.setValue("do", "list");
273
274       urlBuilder.setValue("offset", anOffset);
275       responseData.put("offset" , new Integer(anOffset).toString());
276       responseData.put("thisurl" , urlBuilder.getQuery());
277
278       if (count>=anOffset+nrUsersPerPage) {
279         urlBuilder.setValue("offset", (anOffset + nrUsersPerPage));
280         responseData.put("nexturl" , urlBuilder.getQuery());
281       }
282
283       if (anOffset>0) {
284         urlBuilder.setValue("offset", Math.max(anOffset - nrUsersPerPage, 0));
285         responseData.put("prevurl" , urlBuilder.getQuery());
286       }
287
288       responseData.put("users", userList);
289       responseData.put("mayDeleteUsers", new Boolean(MirGlobal.accessControl().user().mayDeleteUsers(ServletHelper.getUser(aRequest))));
290       responseData.put("mayAddUsers", new Boolean(MirGlobal.accessControl().user().mayAddUsers(ServletHelper.getUser(aRequest))));
291       responseData.put("mayEditUsers", new Boolean(MirGlobal.accessControl().user().mayEditUsers(ServletHelper.getUser(aRequest))));
292
293       responseData.put("from" , Integer.toString(anOffset+1));
294       responseData.put("count", Integer.toString(count));
295       responseData.put("to", Integer.toString(Math.min(anOffset+nrUsersPerPage, count)));
296       responseData.put("offset" , Integer.toString(anOffset));
297
298       ServletHelper.generateResponse(aResponse.getWriter(), responseData, listTemplate);
299     }
300     catch (Throwable e) {
301       throw new ServletModuleFailure(e);
302     }
303   }
304
305   public void showUser(String anId, boolean anOnlyPassword, HttpServletRequest aRequest, HttpServletResponse aResponse)
306       throws ServletModuleExc {
307     try {
308       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
309       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
310       EntityAdapterModel model = MirGlobal.localizer().dataModel().adapterModel();
311       Map user;
312       URLBuilder urlBuilder = new URLBuilder();
313
314       urlBuilder.setValue("module", "Users");
315       if (anOnlyPassword)
316         urlBuilder.setValue("do", "changepassword");
317       else
318         urlBuilder.setValue("do", "edit");
319       urlBuilder.setValue("id", anId);
320       urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
321
322       if (anId!=null) {
323         responseData.put("new", Boolean.FALSE);
324         user = model.makeEntityAdapter("user", mainModule.getById(anId));
325       }
326       else {
327         List fields = DatabaseUsers.getInstance().getFields();
328         responseData.put("new", Boolean.TRUE);
329         user = new HashMap();
330         Iterator i = fields.iterator();
331         while (i.hasNext()) {
332           user.put(i.next(), null);
333         }
334
335         MirGlobal.localizer().adminInterface().initializeArticle(user);
336       }
337       responseData.put("user", user);
338       responseData.put("passwordonly", new Boolean(anOnlyPassword));
339
340       responseData.put("returnurl", requestParser.getParameter("returnurl"));
341       responseData.put("thisurl", urlBuilder.getQuery());
342
343       ServletHelper.generateResponse(aResponse.getWriter(), responseData, editTemplate);
344     }
345     catch (Throwable e) {
346       throw new ServletModuleFailure(e);
347     }
348   }
349
350   public void delete(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleUserExc, ServletModuleExc, ServletModuleFailure {
351     try {
352       EntityUsers user = (EntityUsers) mainModule.getById(aRequest.getParameter("id"));
353
354       MirGlobal.accessControl().user().assertMayDeleteUser(ServletHelper.getUser(aRequest), user);
355
356       super.delete(aRequest, aResponse);
357     }
358     catch (Throwable t) {
359       throw new ServletModuleFailure(t);
360     }
361   }
362
363   public void changepassword(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
364   {
365     String idParam = aRequest.getParameter("id");
366
367     if (idParam == null)
368       throw new ServletModuleExc("ServletModuleUser.edit: invalid call: (id) not specified");
369
370     try {
371       EntityUsers user = (EntityUsers) mainModule.getById(idParam);
372       MirGlobal.accessControl().user().assertMayChangeUserPassword(ServletHelper.getUser(aRequest), user);
373
374       showUser(idParam, true, aRequest, aResponse);
375     }
376     catch (Throwable e) {
377       throw new ServletModuleFailure(e);
378     }
379   }
380
381 }
382