Пример #1
0
  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)
Пример #2
0
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()
Пример #3
0
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)
Пример #4
0
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()
Пример #5
0
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)