def put(self, comment_id): logging.debug("CommentHandler#put for comment %s", comment_id) # For HTTP PUT, the parameters are passed in URIencoded string in body sanitize_comment = get_sanitizer_func(self, allow_attributes = ['href', 'src'], blacklist_tags = ['img', 'script']) body = self.request.body params = cgi.parse_qs(body) for key, value in params.iteritems(): params[key] = value[0] if not isinstance(params[key], unicode): params[key] = params[key].decode(config.APP['charset']) tmp_hash = restful.get_sent_properties(self.request.get, [('commentEmail', cgi.escape), ('commentHomepage', cgi.escape), ('commentTitle', cgi.escape), ('commentName', cgi.escape), ('commentBody', sanitize_comment)]) property_hash = {} props = (("commentEmail", "email"), ("commentHomepage", "homepage"), ("commentTitle", "title"), ("commentBody", "body"), ('commentName', 'name')) for pair in props: if pair[0] in tmp_hash: logging.debug("Copying '%s' from received properties to '%s' in property hash (value: %s)", pair[0], pair[1], str(tmp_hash[pair[0]])) property_hash[pair[1]] = tmp_hash[pair[0]] if property_hash: comment = models.blog.Comment.get(db.Key(comment_id)) for key, value in property_hash.iteritems(): setattr(comment, key, value) comment.put() # Render just this comment and send it to client view_path = view.find_file(view.templates, "gablog/blog/comment.html") allow_comments = comment.article.allow_comments if allow_comments is None: age = (datetime.datetime.now() - comment.article.published).days allow_comments = (age <= config.BLOG['comment_window']) # response = template.render(os.path.join(config.APP['template_dir'], view_path), response = render_to_string(os.path.join(config.APP['template_dir'], view_path), { 'comment': comment, "use_gravatars": config.BLOG["use_gravatars"], "allow_comments": allow_comments, "user_is_admin": users.is_current_user_admin()}, debug = config.DEBUG) self.response.out.write(response) view.invalidate_cache(comment.article.permalink) else: self.error(400)
def process_comment_submission(handler, article): sanitize_comment = get_sanitizer_func(handler, allow_attributes=['href', 'src'], blacklist_tags=['img']) property_hash = restful.get_sent_properties(handler.request.get, ['name', 'email', 'homepage', 'title', ('body', sanitize_comment), 'key', 'thread', # If it's given, use it. Else generate it. 'captcha', ('published', get_datetime)]) # If we aren't administrator, abort if bad captcha if not users.is_current_user_admin(): if property_hash.get('captcha', None) != get_captcha(article.key()): logging.info("Received captcha (%s) != %s", property_hash.get('captcha', None), get_captcha(article.key())) handler.error(401) # Unauthorized return if 'key' not in property_hash and 'thread' not in property_hash: handler.error(401) return # Generate a thread string. if 'thread' not in property_hash: matchobj = re.match(r'[^#]+#comment-(?P<key>\w+)', property_hash['key']) if matchobj: logging.debug("Comment has parent: %s", matchobj.group('key')) comment_key = matchobj.group('key') # TODO -- Think about GQL injection security issue since # it can be submitted by public parent = models.blog.Comment.get(db.Key(comment_key)) thread_string = parent.next_child_thread_string() else: logging.debug("Comment is off main article") comment_key = None thread_string = article.next_comment_thread_string() if not thread_string: handler.error(400) return property_hash['thread'] = thread_string del property_hash['key'] # Get and store some pieces of information from parent article. # TODO: See if this overhead can be avoided if not article.num_comments: article.num_comments = 1 else: article.num_comments += 1 property_hash['article'] = article.put() try: comment = models.blog.Comment(**property_hash) comment.put() except: logging.debug("Bad comment: %s", property_hash) handler.error(400) return # Notify the author of a new comment (from matteocrippa.it) if config.BLOG['send_comment_notification']: recipient = "%s <%s>" % (config.BLOG['author'], config.BLOG['email'],) body = ("A new comment has just been posted on %s/%s by %s." % (config.BLOG['root_url'], article.permalink, comment.name)) mail.send_mail(sender=config.BLOG['email'], to=recipient, subject="New comment by %s" % (comment.name,), body=body) # Render just this comment and send it to client view_path = view.find_file(view.templates, "bloog/blog/comment.html") response = template.render( os.path.join("views", view_path), { 'comment': comment, "use_gravatars": config.BLOG["use_gravatars"] }, debug=config.DEBUG) handler.response.out.write(response) view.invalidate_cache()
def process_comment_submission(handler, parent=None): sanitize_comment = get_sanitizer_func(handler, allow_attributes=['href', 'src'], blacklist_tags=['img', 'script']) property_hash = restful.get_sent_properties(handler.request.get, [('name', cgi.escape), ('email', cgi.escape), ('homepage', cgi.escape), ('title', cgi.escape), ('body', sanitize_comment), ('article_id', cgi.escape), 'recaptcha_challenge_field', 'recaptcha_response_field', ('published', get_datetime)]) # If we aren't administrator, abort if bad captcha if not users.is_current_user_admin(): cap_challenge = property_hash.get('recaptcha_challenge_field') cap_response = property_hash.get('recaptcha_response_field') cap_validation = captcha.RecaptchaResponse(False) if cap_challenge and cap_response: cap_validation = captcha.submit( cap_challenge, cap_response, config.BLOG['recap_private_key'], handler.request.remote_addr ) if not cap_validation.is_valid: logging.info( "Invalid captcha: %s", cap_validation.error_code ) handler.response.set_status(401, 'Invalid Captcha') # Unauthorized return if 'article_id' not in property_hash: return handler.error(400) article = db.Query(models.blog.Article).filter( 'permalink =', property_hash['article_id'] ).get() # Generate a thread string. if parent: logging.debug("Comment has parent: %s", parent.key()) thread_string = parent.next_child_thread_string() else: logging.debug("Comment is off main article") thread_string = article.next_comment_thread_string() property_hash['thread'] = thread_string # Get and store some pieces of information from parent article. # TODO: See if this overhead can be avoided if not article.num_comments: article.num_comments = 1 else: article.num_comments += 1 property_hash['article'] = article.put() try: comment = models.blog.Comment(**property_hash) comment.put() except: logging.debug("Bad comment: %s", property_hash) return handler.error(400) # Notify the author of a new comment (from matteocrippa.it) if config.BLOG['send_comment_notification'] and not users.is_current_user_admin(): recipient = "%s <%s>" % (config.BLOG['author'], config.BLOG['email']) article_link = config.BLOG['root_url'] + "/" + article.permalink comment_link = '%s#comment-%s' % (article_link, comment.key()) body = ('''A new comment has just been posted on %s by %s:\n\n"%s" \n\nReply to the comment here: %s''' % (article_link, comment.name, comment.body, comment_link)) mail.send_mail(sender=config.BLOG['email'], to=recipient, subject="New comment by %s" % (comment.name), body=body) # Render just this comment and send it to client view_path = view.find_file(view.templates, "bloog/blog/comment.html") response = template.render( os.path.join("views", view_path), { 'comment': comment, "use_gravatars": config.BLOG["use_gravatars"] }, debug=config.DEBUG) handler.response.out.write(response) view.invalidate_cache(comment.article.permalink)
def process_comment_submission(handler, article): sanitize_comment = get_sanitizer_func(handler, allow_attributes=['href', 'src'], blacklist_tags=['img', 'script']) property_hash = restful.get_sent_properties( handler.request.get, [ ('name', cgi.escape), ('email', cgi.escape), ('homepage', cgi.escape), ('title', cgi.escape), ('body', sanitize_comment), ('key', cgi.escape), 'thread', # If it's given, use it. Else generate it. 'captcha', ('published', get_datetime) ]) # If we aren't administrator, abort if bad captcha if not users.is_current_user_admin(): if property_hash.get('captcha', None) != get_captcha(article.key()): logging.info("Received captcha (%s) != %s", property_hash.get('captcha', None), get_captcha(article.key())) handler.error(401) # Unauthorized return if 'key' not in property_hash and 'thread' not in property_hash: handler.error(401) return # Generate a thread string. if 'thread' not in property_hash: matchobj = re.match(r'[^#]+#comment-(?P<key>\w+)', property_hash['key']) if matchobj: logging.debug("Comment has parent: %s", matchobj.group('key')) comment_key = matchobj.group('key') # TODO -- Think about GQL injection security issue since # it can be submitted by public parent = models.blog.Comment.get(db.Key(comment_key)) thread_string = parent.next_child_thread_string() else: logging.debug("Comment is off main article") comment_key = None thread_string = article.next_comment_thread_string() if not thread_string: handler.error(400) return property_hash['thread'] = thread_string del property_hash['key'] # Get and store some pieces of information from parent article. # TODO: See if this overhead can be avoided if not article.num_comments: article.num_comments = 1 else: article.num_comments += 1 property_hash['article'] = article.put() try: comment = models.blog.Comment(**property_hash) comment.put() except: logging.debug("Bad comment: %s", property_hash) handler.error(400) return # Notify the author of a new comment (from matteocrippa.it) if config.BLOG['send_comment_notification']: recipient = "%s <%s>" % ( config.BLOG['author'], config.BLOG['email'], ) body = ("A new comment has just been posted on %s/%s by %s." % (config.BLOG['root_url'], article.permalink, comment.name)) mail.send_mail(sender=config.BLOG['email'], to=recipient, subject="New comment by %s" % (comment.name, ), body=body) # Render just this comment and send it to client view_path = view.find_file(view.templates, "bloog/blog/comment.html") response = template.render(os.path.join("views", view_path), { 'comment': comment, "use_gravatars": config.BLOG["use_gravatars"] }, debug=config.DEBUG) handler.response.out.write(response) view.invalidate_cache()
def process_comment_submission(handler, parent=None): sanitize_comment = get_sanitizer_func(handler, allow_attributes=['href', 'src'], blacklist_tags=['img', 'script']) property_hash = restful.get_sent_properties( handler.request.get, [('name', cgi.escape), ('email', cgi.escape), ('homepage', cgi.escape), ('title', cgi.escape), ('body', sanitize_comment), ('article_id', cgi.escape), 'recaptcha_challenge_field', 'recaptcha_response_field', ('published', get_datetime)]) # If we aren't administrator, abort if bad captcha if not users.is_current_user_admin(): cap_challenge = property_hash.get('recaptcha_challenge_field') cap_response = property_hash.get('recaptcha_response_field') cap_validation = captcha.RecaptchaResponse(False) if cap_challenge and cap_response: cap_validation = captcha.submit(cap_challenge, cap_response, config.BLOG['recap_private_key'], handler.request.remote_addr) if not cap_validation.is_valid: logging.info("Invalid captcha: %s", cap_validation.error_code) handler.response.set_status(401, 'Invalid Captcha') # Unauthorized return if 'article_id' not in property_hash: return handler.error(400) article = db.Query(models.blog.Article).filter( 'permalink =', property_hash['article_id']).get() # Generate a thread string. if parent: logging.debug("Comment has parent: %s", parent.key()) thread_string = parent.next_child_thread_string() else: logging.debug("Comment is off main article") thread_string = article.next_comment_thread_string() property_hash['thread'] = thread_string # Get and store some pieces of information from parent article. # TODO: See if this overhead can be avoided if not article.num_comments: article.num_comments = 1 else: article.num_comments += 1 property_hash['article'] = article.put() try: comment = models.blog.Comment(**property_hash) comment.put() except: logging.debug("Bad comment: %s", property_hash) return handler.error(400) # Notify the author of a new comment (from matteocrippa.it) if config.BLOG[ 'send_comment_notification'] and not users.is_current_user_admin(): recipient = "%s <%s>" % (config.BLOG['author'], config.BLOG['email']) article_link = config.BLOG['root_url'] + "/" + article.permalink comment_link = '%s#comment-%s' % (article_link, comment.key()) body = ('''A new comment has just been posted on %s by %s:\n\n"%s" \n\nReply to the comment here: %s''' % (article_link, comment.name, comment.body, comment_link)) mail.send_mail(sender=config.BLOG['email'], to=recipient, subject="New comment by %s" % (comment.name), body=body) # Render just this comment and send it to client view_path = view.find_file(view.templates, "bloog/blog/comment.html") response = template.render(os.path.join("views", view_path), { 'comment': comment, "use_gravatars": config.BLOG["use_gravatars"] }, debug=config.DEBUG) handler.response.out.write(response) view.invalidate_cache(comment.article.permalink)