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