001: /**
002: * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
003: *
004: * This program is free software; you can redistribute it and/or modify
005: * it under the terms of the latest version of the GNU Lesser General
006: * Public License as published by the Free Software Foundation;
007: *
008: * This program is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
011: * GNU Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public License
014: * along with this program (LICENSE.txt); if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
016: */package org.jamwiki.servlets;
017:
018: import java.util.Collection;
019: import java.util.Iterator;
020: import java.util.LinkedHashMap;
021: import java.util.Properties;
022: import java.util.Vector;
023: import javax.servlet.http.HttpServletRequest;
024: import javax.servlet.http.HttpServletResponse;
025: import org.apache.commons.lang.StringUtils;
026: import org.apache.commons.pool.impl.GenericObjectPool;
027: import org.jamwiki.Environment;
028: import org.jamwiki.WikiBase;
029: import org.jamwiki.WikiConfiguration;
030: import org.jamwiki.WikiMessage;
031: import org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter;
032: import org.jamwiki.authentication.WikiUserAuth;
033: import org.jamwiki.db.WikiDatabase;
034: import org.jamwiki.model.Role;
035: import org.jamwiki.model.VirtualWiki;
036: import org.jamwiki.model.WikiUser;
037: import org.jamwiki.utils.Encryption;
038: import org.jamwiki.utils.SpamFilter;
039: import org.jamwiki.utils.Utilities;
040: import org.jamwiki.utils.WikiCache;
041: import org.jamwiki.utils.WikiLogger;
042: import org.springframework.web.servlet.ModelAndView;
043:
044: /**
045: * Used to provide administrative functions including changing Wiki
046: * configuration settings and refreshing internal Wiki objects.
047: */
048: public class AdminServlet extends JAMWikiServlet {
049:
050: private static final WikiLogger logger = WikiLogger
051: .getLogger(AdminServlet.class.getName());
052: protected static final String JSP_ADMIN = "admin.jsp";
053: protected static final String JSP_ADMIN_SYSTEM = "admin-maintenance.jsp";
054:
055: /**
056: * This method handles the request after its parent class receives control.
057: *
058: * @param request - Standard HttpServletRequest object.
059: * @param response - Standard HttpServletResponse object.
060: * @return A <code>ModelAndView</code> object to be handled by the rest of the Spring framework.
061: */
062: protected ModelAndView handleJAMWikiRequest(
063: HttpServletRequest request, HttpServletResponse response,
064: ModelAndView next, WikiPageInfo pageInfo) throws Exception {
065: String function = request.getParameter("function");
066: if (StringUtils.isBlank(function)
067: && ServletUtil.isTopic(request, "Special:Maintenance")) {
068: viewAdminSystem(request, next, pageInfo);
069: } else if (StringUtils.isBlank(function)) {
070: viewAdmin(request, next, pageInfo, null);
071: } else if (function.equals("cache")) {
072: cache(request, next, pageInfo);
073: } else if (function.equals("refreshIndex")) {
074: refreshIndex(request, next, pageInfo);
075: } else if (function.equals("properties")) {
076: properties(request, next, pageInfo);
077: } else if (function.equals("addVirtualWiki")) {
078: addVirtualWiki(request, next, pageInfo);
079: } else if (function.equals("recentChanges")) {
080: recentChanges(request, next, pageInfo);
081: } else if (function.equals("spamFilter")) {
082: spamFilter(request, next, pageInfo);
083: }
084: return next;
085: }
086:
087: /**
088: *
089: */
090: private void addVirtualWiki(HttpServletRequest request,
091: ModelAndView next, WikiPageInfo pageInfo) throws Exception {
092: WikiUser user = ServletUtil.currentUser();
093: try {
094: VirtualWiki virtualWiki = new VirtualWiki();
095: if (!StringUtils.isBlank(request
096: .getParameter("virtualWikiId"))) {
097: virtualWiki.setVirtualWikiId(new Integer(request
098: .getParameter("virtualWikiId")).intValue());
099: }
100: virtualWiki.setName(request.getParameter("name"));
101: virtualWiki.setDefaultTopicName(Utilities
102: .encodeForURL(request
103: .getParameter("defaultTopicName")));
104: WikiBase.getDataHandler().writeVirtualWiki(virtualWiki,
105: null);
106: if (StringUtils.isBlank(request
107: .getParameter("virtualWikiId"))) {
108: WikiBase.getDataHandler().setupSpecialPages(
109: request.getLocale(), user, virtualWiki, null);
110: }
111: next.addObject("message", new WikiMessage(
112: "admin.message.virtualwikiadded"));
113: } catch (Exception e) {
114: logger.severe("Failure while adding virtual wiki", e);
115: next.addObject("message", new WikiMessage(
116: "admin.message.virtualwikifail", e.getMessage()));
117: }
118: viewAdminSystem(request, next, pageInfo);
119: }
120:
121: /**
122: *
123: */
124: private void cache(HttpServletRequest request, ModelAndView next,
125: WikiPageInfo pageInfo) throws Exception {
126: try {
127: WikiCache.initialize();
128: next.addObject("message", new WikiMessage(
129: "admin.message.cache"));
130: } catch (Exception e) {
131: logger.severe("Failure while clearing cache", e);
132: next.addObject("errors", new WikiMessage(
133: "admin.cache.message.clearfailed", e.getMessage()));
134: }
135: viewAdminSystem(request, next, pageInfo);
136: }
137:
138: /**
139: *
140: */
141: private void properties(HttpServletRequest request,
142: ModelAndView next, WikiPageInfo pageInfo) throws Exception {
143: Properties props = new Properties();
144: try {
145: setProperty(props, request,
146: Environment.PROP_BASE_DEFAULT_TOPIC);
147: setProperty(props, request,
148: Environment.PROP_BASE_LOGO_IMAGE);
149: setProperty(props, request,
150: Environment.PROP_BASE_META_DESCRIPTION);
151: setBooleanProperty(props, request,
152: Environment.PROP_TOPIC_WYSIWYG);
153: setProperty(props, request,
154: Environment.PROP_IMAGE_RESIZE_INCREMENT);
155: setProperty(props, request,
156: Environment.PROP_RECENT_CHANGES_NUM);
157: setBooleanProperty(props, request,
158: Environment.PROP_TOPIC_SPAM_FILTER);
159: setBooleanProperty(props, request,
160: Environment.PROP_TOPIC_USE_PREVIEW);
161: setBooleanProperty(props, request,
162: Environment.PROP_PRINT_NEW_WINDOW);
163: setBooleanProperty(props, request,
164: Environment.PROP_EXTERNAL_LINK_NEW_WINDOW);
165: setProperty(props, request,
166: Environment.PROP_BASE_SEARCH_ENGINE);
167: setProperty(props, request, Environment.PROP_PARSER_CLASS);
168: setBooleanProperty(props, request,
169: Environment.PROP_PARSER_TOC);
170: setProperty(props, request,
171: Environment.PROP_PARSER_TOC_DEPTH);
172: setBooleanProperty(props, request,
173: Environment.PROP_PARSER_ALLOW_HTML);
174: setBooleanProperty(props, request,
175: Environment.PROP_PARSER_ALLOW_JAVASCRIPT);
176: setBooleanProperty(props, request,
177: Environment.PROP_PARSER_ALLOW_TEMPLATES);
178: setProperty(props, request,
179: Environment.PROP_PARSER_SIGNATURE_USER_PATTERN);
180: setProperty(props, request,
181: Environment.PROP_PARSER_SIGNATURE_DATE_PATTERN);
182: setProperty(props, request, Environment.PROP_BASE_FILE_DIR);
183: setProperty(props, request,
184: Environment.PROP_BASE_PERSISTENCE_TYPE);
185: if (props.getProperty(
186: Environment.PROP_BASE_PERSISTENCE_TYPE).equals(
187: WikiBase.PERSISTENCE_EXTERNAL)) {
188: setProperty(props, request, Environment.PROP_DB_DRIVER);
189: setProperty(props, request, Environment.PROP_DB_TYPE);
190: setProperty(props, request, Environment.PROP_DB_URL);
191: setProperty(props, request,
192: Environment.PROP_DB_USERNAME);
193: setPassword(props, request, next,
194: Environment.PROP_DB_PASSWORD, "dbPassword");
195: } else {
196: WikiDatabase.setupDefaultDatabase(props);
197: }
198: setProperty(props, request,
199: Environment.PROP_DBCP_MAX_ACTIVE);
200: setProperty(props, request, Environment.PROP_DBCP_MAX_IDLE);
201: setBooleanProperty(props, request,
202: Environment.PROP_DBCP_TEST_ON_BORROW);
203: setBooleanProperty(props, request,
204: Environment.PROP_DBCP_TEST_ON_RETURN);
205: setBooleanProperty(props, request,
206: Environment.PROP_DBCP_TEST_WHILE_IDLE);
207: setProperty(props, request,
208: Environment.PROP_DBCP_MIN_EVICTABLE_IDLE_TIME);
209: setProperty(props, request,
210: Environment.PROP_DBCP_TIME_BETWEEN_EVICTION_RUNS);
211: setProperty(props, request,
212: Environment.PROP_DBCP_NUM_TESTS_PER_EVICTION_RUN);
213: setProperty(props, request,
214: Environment.PROP_DBCP_WHEN_EXHAUSTED_ACTION);
215: int maxFileSizeInKB = Integer.parseInt(request
216: .getParameter(Environment.PROP_FILE_MAX_FILE_SIZE));
217: props.setProperty(Environment.PROP_FILE_MAX_FILE_SIZE,
218: Integer.toString(maxFileSizeInKB * 1000));
219: setProperty(props, request,
220: Environment.PROP_FILE_DIR_FULL_PATH);
221: setProperty(props, request,
222: Environment.PROP_FILE_DIR_RELATIVE_PATH);
223: setProperty(props, request,
224: Environment.PROP_FILE_BLACKLIST_TYPE);
225: setProperty(props, request, Environment.PROP_FILE_BLACKLIST);
226: setProperty(props, request, Environment.PROP_FILE_WHITELIST);
227: /*
228: setProperty(props, request, Environment.PROP_EMAIL_SMTP_HOST);
229: setProperty(props, request, Environment.PROP_EMAIL_SMTP_USERNAME);
230: setPassword(props, request, next, Environment.PROP_EMAIL_SMTP_PASSWORD, "smtpPassword");
231: setProperty(props, request, Environment.PROP_EMAIL_REPLY_ADDRESS);
232: */
233: setProperty(props, request, Environment.PROP_LDAP_CONTEXT);
234: setProperty(props, request,
235: Environment.PROP_LDAP_FACTORY_CLASS);
236: setProperty(props, request,
237: Environment.PROP_LDAP_FIELD_EMAIL);
238: setProperty(props, request,
239: Environment.PROP_LDAP_FIELD_FIRST_NAME);
240: setProperty(props, request,
241: Environment.PROP_LDAP_FIELD_LAST_NAME);
242: setProperty(props, request,
243: Environment.PROP_LDAP_FIELD_USERID);
244: setProperty(props, request,
245: Environment.PROP_BASE_USER_HANDLER);
246: setProperty(props, request, Environment.PROP_LDAP_LOGIN);
247: setPassword(props, request, next,
248: Environment.PROP_LDAP_PASSWORD, "ldapPassword");
249: setProperty(props, request,
250: Environment.PROP_LDAP_SECURITY_AUTHENTICATION);
251: setProperty(props, request, Environment.PROP_LDAP_URL);
252: setProperty(props, request,
253: Environment.PROP_CACHE_INDIVIDUAL_SIZE);
254: setProperty(props, request, Environment.PROP_CACHE_MAX_AGE);
255: setProperty(props, request,
256: Environment.PROP_CACHE_MAX_IDLE_AGE);
257: setProperty(props, request,
258: Environment.PROP_CACHE_TOTAL_SIZE);
259: setBooleanProperty(props, request,
260: Environment.PROP_RSS_ALLOWED);
261: setProperty(props, request, Environment.PROP_RSS_TITLE);
262: Vector errors = ServletUtil.validateSystemSettings(props);
263: if (!errors.isEmpty()) {
264: next.addObject("errors", errors);
265: next.addObject("message", new WikiMessage(
266: "admin.message.changesnotsaved"));
267: } else {
268: // all is well, save the properties
269: Iterator iterator = props.keySet().iterator();
270: while (iterator.hasNext()) {
271: String key = (String) iterator.next();
272: String value = props.getProperty(key);
273: Environment.setValue(key, value);
274: }
275: Environment.saveProperties();
276: // re-initialize to reset database settings (if needed)
277: WikiUserAuth user = ServletUtil.currentUser();
278: if (user == null || !user.hasRole(Role.ROLE_USER)) {
279: throw new IllegalArgumentException(
280: "Cannot pass null or anonymous WikiUser object to setupAdminUser");
281: }
282: WikiBase.reset(request.getLocale(), user);
283: JAMWikiAnonymousProcessingFilter.reset();
284: WikiUserAuth.resetDefaultGroupRoles();
285: next.addObject("message", new WikiMessage(
286: "admin.message.changessaved"));
287: }
288: } catch (Exception e) {
289: logger
290: .severe("Failure while processing property values",
291: e);
292: next.addObject("message", new WikiMessage(
293: "admin.message.propertyfailure", e.getMessage()));
294: }
295: viewAdmin(request, next, pageInfo, props);
296: }
297:
298: /**
299: *
300: */
301: private void recentChanges(HttpServletRequest request,
302: ModelAndView next, WikiPageInfo pageInfo) throws Exception {
303: try {
304: WikiBase.getDataHandler().reloadRecentChanges(null);
305: next.addObject("message", new WikiMessage(
306: "admin.message.recentchanges"));
307: } catch (Exception e) {
308: logger.severe("Failure while loading recent changes", e);
309: next.addObject("errors", new WikiMessage(
310: "admin.message.recentchangesfail", e.getMessage()));
311: }
312: viewAdminSystem(request, next, pageInfo);
313: }
314:
315: /**
316: *
317: */
318: private void refreshIndex(HttpServletRequest request,
319: ModelAndView next, WikiPageInfo pageInfo) throws Exception {
320: try {
321: WikiBase.getSearchEngine().refreshIndex();
322: next.addObject("message", new WikiMessage(
323: "admin.message.indexrefreshed"));
324: } catch (Exception e) {
325: logger.severe("Failure while refreshing search index", e);
326: next.addObject("message", new WikiMessage(
327: "admin.message.searchrefresh", e.getMessage()));
328: }
329: viewAdminSystem(request, next, pageInfo);
330: }
331:
332: /**
333: *
334: */
335: private static void setBooleanProperty(Properties props,
336: HttpServletRequest request, String parameter) {
337: boolean value = (request.getParameter(parameter) != null);
338: props.setProperty(parameter, Boolean.toString(value));
339: }
340:
341: /**
342: *
343: */
344: private static void setPassword(Properties props,
345: HttpServletRequest request, ModelAndView next,
346: String parameter, String passwordParam) throws Exception {
347: if (!StringUtils.isBlank(request.getParameter(parameter))) {
348: String value = request.getParameter(parameter);
349: Encryption.setEncryptedProperty(parameter, value, props);
350: next.addObject(passwordParam, request
351: .getParameter(parameter));
352: } else {
353: props.setProperty(parameter, Environment
354: .getValue(parameter));
355: }
356: }
357:
358: /**
359: *
360: */
361: private static void setProperty(Properties props,
362: HttpServletRequest request, String parameter) {
363: String value = request.getParameter(parameter);
364: if (value == null) {
365: value = "";
366: }
367: props.setProperty(parameter, value);
368: }
369:
370: /**
371: *
372: */
373: private void spamFilter(HttpServletRequest request,
374: ModelAndView next, WikiPageInfo pageInfo) throws Exception {
375: try {
376: SpamFilter.reload();
377: next.addObject("message", new WikiMessage(
378: "admin.message.spamfilter"));
379: } catch (Exception e) {
380: logger.severe(
381: "Failure while reloading spam filter patterns", e);
382: next.addObject("errors", new WikiMessage(
383: "admin.message.spamfilterfail", e.getMessage()));
384: }
385: viewAdminSystem(request, next, pageInfo);
386: }
387:
388: /**
389: *
390: */
391: private void viewAdmin(HttpServletRequest request,
392: ModelAndView next, WikiPageInfo pageInfo, Properties props)
393: throws Exception {
394: pageInfo.setContentJsp(JSP_ADMIN);
395: pageInfo.setAdmin(true);
396: pageInfo.setPageTitle(new WikiMessage("admin.title"));
397: Collection userHandlers = WikiConfiguration.getInstance()
398: .getUserHandlers();
399: next.addObject("userHandlers", userHandlers);
400: Collection dataHandlers = WikiConfiguration.getInstance()
401: .getDataHandlers();
402: next.addObject("dataHandlers", dataHandlers);
403: Collection searchEngines = WikiConfiguration.getInstance()
404: .getSearchEngines();
405: next.addObject("searchEngines", searchEngines);
406: Collection parsers = WikiConfiguration.getInstance()
407: .getParsers();
408: next.addObject("parsers", parsers);
409: LinkedHashMap poolExhaustedMap = new LinkedHashMap();
410: poolExhaustedMap.put(new Integer(
411: GenericObjectPool.WHEN_EXHAUSTED_FAIL),
412: "admin.persistence.caption.whenexhaustedaction.fail");
413: poolExhaustedMap.put(new Integer(
414: GenericObjectPool.WHEN_EXHAUSTED_BLOCK),
415: "admin.persistence.caption.whenexhaustedaction.block");
416: poolExhaustedMap.put(new Integer(
417: GenericObjectPool.WHEN_EXHAUSTED_GROW),
418: "admin.persistence.caption.whenexhaustedaction.grow");
419: next.addObject("poolExhaustedMap", poolExhaustedMap);
420: LinkedHashMap blacklistTypesMap = new LinkedHashMap();
421: blacklistTypesMap.put(new Integer(WikiBase.UPLOAD_ALL),
422: "admin.upload.caption.allowall");
423: blacklistTypesMap.put(new Integer(WikiBase.UPLOAD_NONE),
424: "admin.upload.caption.allownone");
425: blacklistTypesMap.put(new Integer(WikiBase.UPLOAD_BLACKLIST),
426: "admin.upload.caption.useblacklist");
427: blacklistTypesMap.put(new Integer(WikiBase.UPLOAD_WHITELIST),
428: "admin.upload.caption.usewhitelist");
429: next.addObject("blacklistTypes", blacklistTypesMap);
430: if (props == null) {
431: props = Environment.getInstance();
432: }
433: Integer maximumFileSize = new Integer(new Integer(props
434: .getProperty(Environment.PROP_FILE_MAX_FILE_SIZE))
435: .intValue() / 1000);
436: next.addObject("maximumFileSize", maximumFileSize);
437: next.addObject("props", props);
438: }
439:
440: /**
441: *
442: */
443: private void viewAdminSystem(HttpServletRequest request,
444: ModelAndView next, WikiPageInfo pageInfo) throws Exception {
445: pageInfo.setContentJsp(JSP_ADMIN_SYSTEM);
446: pageInfo.setAdmin(true);
447: pageInfo
448: .setPageTitle(new WikiMessage("admin.maintenance.title"));
449: Collection virtualWikiList = WikiBase.getDataHandler()
450: .getVirtualWikiList(null);
451: next.addObject("wikis", virtualWikiList);
452: }
453: }
|