PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/roller-5.0.1/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/CommentServlet.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 378 lines | 239 code | 66 blank | 73 comment | 44 complexity | 15dde050545ba5abe82cf8cd734f0f8b MD5 | raw file
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. The ASF licenses this file to You
  4. * under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License. For additional information regarding
  15. * copyright in this work, please see the NOTICE file in the top level
  16. * directory of this distribution.
  17. */
  18. package org.apache.roller.weblogger.ui.rendering.servlets;
  19. import java.io.IOException;
  20. import java.sql.Timestamp;
  21. import java.util.Iterator;
  22. import javax.servlet.RequestDispatcher;
  23. import javax.servlet.ServletConfig;
  24. import javax.servlet.ServletException;
  25. import javax.servlet.http.HttpServlet;
  26. import javax.servlet.http.HttpServletRequest;
  27. import javax.servlet.http.HttpServletResponse;
  28. import org.apache.commons.logging.Log;
  29. import org.apache.commons.logging.LogFactory;
  30. import org.apache.roller.weblogger.WebloggerException;
  31. import org.apache.roller.weblogger.config.WebloggerConfig;
  32. import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
  33. import org.apache.roller.weblogger.business.search.IndexManager;
  34. import org.apache.roller.weblogger.business.WebloggerFactory;
  35. import org.apache.roller.weblogger.business.WeblogEntryManager;
  36. import org.apache.roller.weblogger.pojos.WeblogEntryComment;
  37. import org.apache.roller.weblogger.pojos.WeblogEntry;
  38. import org.apache.roller.weblogger.pojos.Weblog;
  39. import org.apache.roller.weblogger.ui.rendering.plugins.comments.CommentAuthenticator;
  40. import org.apache.roller.weblogger.ui.rendering.plugins.comments.CommentValidationManager;
  41. import org.apache.roller.weblogger.ui.rendering.plugins.comments.DefaultCommentAuthenticator;
  42. import org.apache.roller.weblogger.ui.rendering.util.WeblogCommentRequest;
  43. import org.apache.roller.weblogger.ui.rendering.util.WeblogEntryCommentForm;
  44. import org.apache.roller.weblogger.util.GenericThrottle;
  45. import org.apache.roller.weblogger.util.IPBanList;
  46. import org.apache.roller.weblogger.util.MailUtil;
  47. import org.apache.roller.weblogger.util.I18nMessages;
  48. import org.apache.roller.weblogger.util.RollerMessages;
  49. import org.apache.roller.weblogger.util.RollerMessages.RollerMessage;
  50. import org.apache.roller.weblogger.util.URLUtilities;
  51. import org.apache.roller.weblogger.util.Utilities;
  52. import org.apache.roller.weblogger.util.cache.CacheManager;
  53. /**
  54. * The CommentServlet handles all incoming weblog entry comment posts.
  55. *
  56. * We validate each incoming comment based on various comment settings and
  57. * if all checks are passed then the comment is saved.
  58. *
  59. * Incoming comments are tested against the MT Blacklist. If they are found
  60. * to be spam, then they are marked as spam and hidden from view.
  61. *
  62. * If email notification is turned on, each new comment will result in an
  63. * email sent to the blog owner and all who have commented on the same post.
  64. */
  65. public class CommentServlet extends HttpServlet {
  66. private static Log log = LogFactory.getLog(CommentServlet.class);
  67. private CommentAuthenticator authenticator = null;
  68. private CommentValidationManager commentValidationManager = null;
  69. private GenericThrottle commentThrottle = null;
  70. /**
  71. * Initialization.
  72. */
  73. @Override
  74. public void init(ServletConfig servletConfig) throws ServletException {
  75. super.init(servletConfig);
  76. log.info("Initializing CommentServlet");
  77. // lookup the authenticator we are going to use and instantiate it
  78. try {
  79. String name = WebloggerConfig.getProperty("comment.authenticator.classname");
  80. Class clazz = Class.forName(name);
  81. this.authenticator = (CommentAuthenticator) clazz.newInstance();
  82. } catch(Exception e) {
  83. log.error(e);
  84. this.authenticator = new DefaultCommentAuthenticator();
  85. }
  86. // instantiate a comment validation manager for comment spam checking
  87. commentValidationManager = new CommentValidationManager();
  88. // instantiate a comment format manager for comment formatting
  89. String fmtrs = WebloggerConfig.getProperty("comment.formatter.classnames");
  90. String[] formatters = Utilities.stringToStringArray(fmtrs, ",");
  91. // are we doing throttling?
  92. if(WebloggerConfig.getBooleanProperty("comment.throttle.enabled")) {
  93. int threshold = 25;
  94. try {
  95. threshold = Integer.parseInt(WebloggerConfig.getProperty("comment.throttle.threshold"));
  96. } catch(Exception e) {
  97. log.warn("bad input for config property comment.throttle.threshold", e);
  98. }
  99. int interval = 60000;
  100. try {
  101. interval = Integer.parseInt(WebloggerConfig.getProperty("comment.throttle.interval"));
  102. // convert from seconds to milliseconds
  103. interval = interval * 1000;
  104. } catch(Exception e) {
  105. log.warn("bad input for config property comment.throttle.interval", e);
  106. }
  107. int maxEntries = 250;
  108. try {
  109. maxEntries = Integer.parseInt(WebloggerConfig.getProperty("comment.throttle.maxentries"));
  110. } catch(Exception e) {
  111. log.warn("bad input for config property comment.throttle.maxentries", e);
  112. }
  113. commentThrottle = new GenericThrottle(threshold, interval, maxEntries);
  114. log.info("Comment Throttling ENABLED");
  115. } else {
  116. log.info("Comment Throttling DISABLED");
  117. }
  118. }
  119. /**
  120. * Handle incoming http GET requests.
  121. *
  122. * The CommentServlet does not support GET requests, it's a 404.
  123. */
  124. @Override
  125. public void doGet(HttpServletRequest request, HttpServletResponse response)
  126. throws IOException, ServletException {
  127. response.sendError(HttpServletResponse.SC_NOT_FOUND);
  128. }
  129. /**
  130. * Service incoming POST requests.
  131. *
  132. * Here we handle incoming comment postings.
  133. */
  134. @Override
  135. public void doPost(HttpServletRequest request, HttpServletResponse response)
  136. throws IOException, ServletException {
  137. String error = null;
  138. String dispatch_url = null;
  139. Weblog weblog = null;
  140. WeblogEntry entry = null;
  141. String message = null;
  142. RollerMessages messages = new RollerMessages();
  143. // are we doing a preview? or a post?
  144. String method = request.getParameter("method");
  145. final boolean preview;
  146. if (method != null && method.equals("preview")) {
  147. preview = true;
  148. messages.addMessage("commentServlet.previewCommentOnly");
  149. log.debug("Handling comment preview post");
  150. } else {
  151. preview = false;
  152. log.debug("Handling regular comment post");
  153. }
  154. // throttling protection against spammers
  155. if(commentThrottle != null &&
  156. commentThrottle.processHit(request.getRemoteAddr())) {
  157. log.debug("ABUSIVE "+request.getRemoteAddr());
  158. IPBanList.getInstance().addBannedIp(request.getRemoteAddr());
  159. response.sendError(HttpServletResponse.SC_NOT_FOUND);
  160. return;
  161. }
  162. WeblogCommentRequest commentRequest = null;
  163. try {
  164. commentRequest = new WeblogCommentRequest(request);
  165. // lookup weblog specified by comment request
  166. weblog = WebloggerFactory.getWeblogger().getWeblogManager()
  167. .getWeblogByHandle(commentRequest.getWeblogHandle());
  168. if(weblog == null) {
  169. throw new WebloggerException("unable to lookup weblog: "+
  170. commentRequest.getWeblogHandle());
  171. }
  172. // lookup entry specified by comment request
  173. entry = commentRequest.getWeblogEntry();
  174. if(entry == null) {
  175. throw new WebloggerException("unable to lookup entry: "+
  176. commentRequest.getWeblogAnchor());
  177. }
  178. // we know what the weblog entry is, so setup our urls
  179. dispatch_url = "/roller-ui/rendering/page/"+weblog.getHandle();
  180. if(commentRequest.getLocale() != null) {
  181. dispatch_url += "/"+commentRequest.getLocale();
  182. }
  183. dispatch_url += "/entry/"+URLUtilities.encode(commentRequest.getWeblogAnchor());
  184. } catch (Exception e) {
  185. // some kind of error parsing the request or looking up weblog
  186. log.debug("error creating page request", e);
  187. response.sendError(HttpServletResponse.SC_NOT_FOUND);
  188. return;
  189. }
  190. log.debug("Doing comment posting for entry = "+entry.getPermalink());
  191. // collect input from request params and construct new comment object
  192. // fields: name, email, url, content, notify
  193. // TODO: data validation on collected comment data
  194. WeblogEntryComment comment = new WeblogEntryComment();
  195. comment.setName(commentRequest.getName());
  196. comment.setEmail(commentRequest.getEmail());
  197. comment.setUrl(commentRequest.getUrl());
  198. comment.setContent(commentRequest.getContent());
  199. comment.setNotify(Boolean.valueOf(commentRequest.isNotify()));
  200. comment.setWeblogEntry(entry);
  201. comment.setRemoteHost(request.getRemoteHost());
  202. comment.setPostTime(new Timestamp(System.currentTimeMillis()));
  203. // set comment content-type depending on if html is allowed
  204. if(WebloggerRuntimeConfig.getBooleanProperty("users.comments.htmlenabled")) {
  205. comment.setContentType("text/html");
  206. } else {
  207. comment.setContentType("text/plain");
  208. }
  209. // set whatever comment plugins are configured
  210. comment.setPlugins(WebloggerRuntimeConfig.getProperty("users.comments.plugins"));
  211. WeblogEntryCommentForm cf = new WeblogEntryCommentForm();
  212. cf.setData(comment);
  213. if (preview) {
  214. cf.setPreview(comment);
  215. }
  216. I18nMessages messageUtils = I18nMessages.getMessages(commentRequest.getLocaleInstance());
  217. // check if comments are allowed for this entry
  218. // this checks site-wide settings, weblog settings, and entry settings
  219. if(!entry.getCommentsStillAllowed() || !entry.isPublished()) {
  220. error = messageUtils.getString("comments.disabled");
  221. // if this is a real comment post then authenticate request
  222. } else if(!preview && !this.authenticator.authenticate(request)) {
  223. error = messageUtils.getString("error.commentAuthFailed");
  224. log.debug("Comment failed authentication");
  225. }
  226. // bail now if we have already found an error
  227. if(error != null) {
  228. cf.setError(error);
  229. request.setAttribute("commentForm", cf);
  230. RequestDispatcher dispatcher = request.getRequestDispatcher(dispatch_url);
  231. dispatcher.forward(request, response);
  232. return;
  233. }
  234. int validationScore = commentValidationManager.validateComment(comment, messages);
  235. log.debug("Comment Validation score: " + validationScore);
  236. if (!preview) {
  237. if (validationScore == 100 && weblog.getCommentModerationRequired()) {
  238. // Valid comments go into moderation if required
  239. comment.setStatus(WeblogEntryComment.PENDING);
  240. message = messageUtils.getString("commentServlet.submittedToModerator");
  241. } else if (validationScore == 100) {
  242. // else they're approved
  243. comment.setStatus(WeblogEntryComment.APPROVED);
  244. message = messageUtils.getString("commentServlet.commentAccepted");
  245. } else {
  246. // Invalid comments are marked as spam
  247. log.debug("Comment marked as spam");
  248. comment.setStatus(WeblogEntryComment.SPAM);
  249. error = messageUtils.getString("commentServlet.commentMarkedAsSpam");
  250. // add specific error messages if they exist
  251. if(messages.getErrorCount() > 0) {
  252. Iterator errors = messages.getErrors();
  253. RollerMessage errorKey = null;
  254. StringBuilder buf = new StringBuilder();
  255. buf.append("<ul>");
  256. while(errors.hasNext()) {
  257. errorKey = (RollerMessage)errors.next();
  258. buf.append("<li>");
  259. if(errorKey.getArgs() != null) {
  260. buf.append(messageUtils.getString(errorKey.getKey(), errorKey.getArgs()));
  261. } else {
  262. buf.append(messageUtils.getString(errorKey.getKey()));
  263. }
  264. buf.append("</li>");
  265. }
  266. buf.append("</ul>");
  267. error += buf.toString();
  268. }
  269. }
  270. try {
  271. if(!WeblogEntryComment.SPAM.equals(comment.getStatus()) ||
  272. !WebloggerRuntimeConfig.getBooleanProperty("comments.ignoreSpam.enabled")) {
  273. WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager();
  274. mgr.saveComment(comment);
  275. WebloggerFactory.getWeblogger().flush();
  276. // Send email notifications only to subscribers if comment is 100% valid
  277. boolean notifySubscribers = (validationScore == 100);
  278. MailUtil.sendEmailNotification(comment, messages, messageUtils, notifySubscribers);
  279. // only re-index/invalidate the cache if comment isn't moderated
  280. if(!weblog.getCommentModerationRequired()) {
  281. IndexManager manager = WebloggerFactory.getWeblogger().getIndexManager();
  282. // remove entry before (re)adding it, or in case it isn't Published
  283. manager.removeEntryIndexOperation(entry);
  284. // if published, index the entry
  285. if (entry.isPublished()) {
  286. manager.addEntryIndexOperation(entry);
  287. }
  288. // Clear all caches associated with comment
  289. CacheManager.invalidate(comment);
  290. }
  291. // comment was successful, clear the comment form
  292. cf = new WeblogEntryCommentForm();
  293. }
  294. } catch (WebloggerException re) {
  295. log.error("Error saving comment", re);
  296. error = re.getMessage();
  297. }
  298. }
  299. // the work has been done, now send the user back to the entry page
  300. if (error != null) {
  301. cf.setError(error);
  302. }
  303. if (message != null) {
  304. cf.setMessage(message);
  305. }
  306. request.setAttribute("commentForm", cf);
  307. log.debug("comment processed, forwarding to "+dispatch_url);
  308. RequestDispatcher dispatcher =
  309. request.getRequestDispatcher(dispatch_url);
  310. dispatcher.forward(request, response);
  311. }
  312. }