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