コード例 #1
0
def api_comment_allow_user(comment_id):
    comment = db.session.query(TComments).filter(TComments.comments_id == comment_id).first()
    if comment:
        addr = db.session.query(TEmail).filter(TEmail.email == comment.email).first()
        if addr:
            setattr(addr, 'is_allowed', True)
            setattr(addr, 'is_blocked', False)
        else:
            new_mail = {
                "email": comment.email,
                "is_allowed": True,
                "is_blocked": False
            }
            db.session.add(TEmail(**new_mail))

    # Allow all comments made by this mail address
    all_comments = db.session.query(TComments).filter(TComments.email == comment.email).all()
    if all_comments:
        for comment in all_comments:
            setattr(comment, 'is_published', True)
            setattr(comment, 'is_spam', False)

    db.session.commit()

    # Get location id from get params
    location_id = request.args.get('location')

    export_location(location_id)
    return redirect(request.referrer)
コード例 #2
0
def api_comments_delete_comment(comment_id):
    db.session.query(TComments).filter(TComments.comments_id == comment_id).delete()
    db.session.commit()

    # Get location id from get params
    location_id = request.args.get('location')

    export_location(location_id)
    return redirect(request.referrer)
コード例 #3
0
def api_comment_allow_comment(comment_id):
    comment = db.session.query(TComments).filter(TComments.comments_id == comment_id).first()
    if comment:
        setattr(comment, 'is_published', True)
        setattr(comment, 'is_spam', False)
        db.session.commit()

    # Get location id from get params
    location_id = request.args.get('location')

    export_location(location_id)
    return redirect(request.referrer)
コード例 #4
0
def api_export_all_by_project(name):
    proj_id = get_id_from_project_name(name)
    if proj_id == -1:
        return make_response(jsonify(status='not-found'), 400)

    try:
        locations = db.session.query(TLocation).all()
        for each in locations:
            export_location(each.id_location)
    except Exception as e:
        return make_response(jsonify(status='sql-error', msg=str(e)), 400)

    return make_response(jsonify(status='ok'), 200)
コード例 #5
0
def check_deletion_link(name, email_hash):
    project = db.session.query(TProjects).filter(
        TProjects.name == name).first()
    comment = db.session.query(TComments).filter(
        TComments.deletion == email_hash).first()

    if comment:
        location = db.session.query(TLocation).filter(
            TLocation.id_location == comment.location_id).first()
        if compare_digest(comment.deletion, email_hash):
            db.session.delete(comment)
            db.session.commit()
            url = f"{project.blogurl}?deleted=true"
            export_location(location.id_location)
            return redirect(url)

    return redirect(f"{project.blogurl}?cnf=true")
コード例 #6
0
def check_confirmation_link(name, email_hash):
    comment = db.session.query(TComments).filter(
        TComments.confirmation == email_hash).first()
    project = db.session.query(TProjects).filter(
        TProjects.name == name).first()

    if comment:
        location = db.session.query(TLocation).filter(
            TLocation.id_location == comment.location_id).first()
        if compare_digest(comment.confirmation, email_hash):
            comment.confirmation = None
            if not comment.is_spam:
                setattr(comment, "is_published", True)
            db.session.commit()
            url = f"{project.blogurl}{location.location}#comment_{comment.comments_id}"
            export_location(location.id_location)
            return redirect(url)

    return redirect(f"{project.blogurl}?cnf=true")
コード例 #7
0
def api_comment_block_mail(comment_id):
    comment = db.session.query(TComments).filter(TComments.comments_id == comment_id).first()
    if comment:
        addr = db.session.query(TEmail).filter(TEmail.email == comment.email).first()
        if addr:
            setattr(addr, 'is_allowed', False)
            setattr(addr, 'is_blocked', True)
        else:
            new_mail = {
                "email": comment.first().email,
                "is_allowed": False,
                "is_blocked": True
            }
            db.session.add(TEmail(**new_mail))

    # Delete all comments made by this mail address
    db.session.query(TComments).filter(TComments.email == comment.email).delete()
    db.session.commit()

    # Get location id from get params
    location_id = request.args.get('location')

    export_location(location_id)
    return redirect(request.referrer)
コード例 #8
0
def check_and_insert_new_comment(name):

    # Get project
    project = db.session.query(TProjects).filter(
        TProjects.name == name).first()

    # Check refferer, this is not bullet proof
    if not compare_digest(request.origin, project.blogurl):
        return make_response(jsonify(status="not-allowed"), 403)

    if not project:
        return make_response(jsonify(status="post-project-not-found"), 400)

    if compare_digest(request.method, "POST"):
        smileys = Smileys()
        sender = Mail()

        # Check length of content and abort if too long or too short
        if request.content_length > 2048:
            return make_response(jsonify(status="post-max-length"), 400)
        if request.content_length == 0:
            return make_response(jsonify(status="post-min-length"), 400)

        # get json from request
        new_comment = request.json

        # save and sanitize location, nice try, bitch
        location = new_comment['location'].strip().replace('.', '')

        # Validate json and check length again
        if not is_valid_json(new_comment) or \
                len(new_comment['content']) < 40 or \
                len(new_comment['email']) < 5:
            return make_response(jsonify(status='post-invalid-json'), 400)

        # Strip any HTML from message body
        tags = re.compile('<.*?>')
        special = re.compile('[&].*[;]')
        content = re.sub(tags, '', new_comment['content']).strip()
        content = re.sub(special, '', content).strip()

        # Convert smileys if enabled
        if project.addon_smileys:
            for key, value in smileys.smileys.items():
                content = content.replace(key, value)

        # Validate replied_to field is integer
        replied_to = new_comment['replied_to']
        try:
            if replied_to:
                replied_to = int(replied_to)

        # not a valid id at all
        except ValueError:
            return make_response(jsonify(status="bad-reply"), 400)

        # Update values
        new_comment.update({"content": content})
        new_comment.update({"email": new_comment['email'].strip()})
        new_comment.update({"location": location})
        new_comment.update({"replied_to": replied_to})

        # Check mail
        if not sender.validate(new_comment['email']):
            return make_response(jsonify(status='post-invalid-email'), 400)

        # check for spam
        is_spam = spam(new_comment['content'])
        has_score = score(new_comment['content'])

        # Insert mail into spam if detected, allow if listed as such
        email = db.session.query(TEmail).filter(
            TEmail.email == new_comment['email']).first()
        if not email:
            if is_spam:
                entry = {
                    "email": new_comment['email'],
                    "is_blocked": True,
                    "is_allowed": False
                }
                db.session.add(TEmail(**entry))
        if email:
            if not email.is_allowed:
                is_spam = True
            if email.is_allowed:
                # This forces the comment to be not spam if the address is in the allowed list,
                # but the commenter will still need to confirm it to avoid brute
                # force attacks against this feature
                is_spam = False

        # Look for location
        loc_query = db.session.query(TLocation) \
            .filter(TLocation.location == new_comment['location'])

        if loc_query.first():
            # Location exists, set existing location id
            new_comment.update({'location_id': loc_query.first().id_location})
            # TComments does not have this field
            new_comment.pop("location")
        else:
            # Insert new location
            loc_table = {
                'location': new_comment['location'],
                'project_id': project.id_project
            }
            new_loc = TLocation(**loc_table)
            db.session.add(new_loc)
            db.session.flush()
            db.session.refresh(new_loc)
            new_comment.update({'location_id': new_loc.id_location})

            # TComments does not have this field
            new_comment.pop("location")

        # insert comment
        # noinspection PyBroadException
        try:
            if project.sendotp:
                new_comment.update({"is_published": False})
            else:
                new_comment.update({"is_published": True})
            new_comment.update({"created_on": default_timestamp()})
            new_comment.update({"is_spam": is_spam})
            new_comment.update({"spam_score": has_score})
            new_comment.update({
                "gravatar":
                check_gravatar(new_comment['email'], project.name)
            })
            new_comment.update({"project_id": project.id_project})
            t_comment = TComments(**new_comment)
            db.session.add(t_comment)
            db.session.commit()
            db.session.flush()
            db.session.refresh(t_comment)

            # Send confirmation link and store returned value
            if project.sendotp:
                hashes = sender.send_confirmation_link(new_comment['email'],
                                                       project.name)
                setattr(t_comment, "confirmation", hashes[0])
                setattr(t_comment, "deletion", hashes[1])
                db.session.commit()

        except exc.IntegrityError as e:
            # Comment body exists, because content is unique
            print(
                f"Duplicate from {request.environ['REMOTE_ADDR']}, error is:\n{e}",
                file=stderr)
            return make_response(jsonify(status="post-duplicate"), 400)

        except Exception:  # must be at bottom
            return make_response(jsonify(status="post-internal-server-error"),
                                 400)

        export_location(t_comment.location_id)
        return make_response(
            jsonify(status="post-success",
                    comment_id=t_comment.comments_id,
                    sendotp=project.sendotp), 200)
コード例 #9
0
ファイル: spam.py プロジェクト: domeniko-gentner/labertasche
def dashboard_review_spam(project: str):
    """
    Shows the manage spam template
    :param project: The project used for displaying data
    :return: The template to display for this rouet
    """
    location_id = 0
    proj_id = get_id_from_project_name(project)
    all_locations = db.session.query(TLocation).filter(
        TLocation.project_id == proj_id).all()

    # Check if there is a comment, otherwise don't show on management page
    # This can happen when the last comment was deleted, the location
    # won't be removed.
    tmp_list = list()
    for each in all_locations:
        comment_count = db.session.query(TComments.comments_id) \
                                  .filter(TComments.location_id == each.id_location) \
                                  .filter(TComments.is_spam == True) \
                                  .count()
        if comment_count > 0:
            tmp_list.append(each)

    all_locations = tmp_list

    # Project does not exist, error code is used by Javascript, not Flask
    if proj_id == -1:
        return redirect(
            url_for("bp_dashboard.dashboard_project_list", error=404))

    if request.args.get('location'):
        location_id = request.args.get('location')

    # no parameters found
    if location_id is None:
        return render_template("manage-comments.html",
                               locations=all_locations,
                               selected=location_id,
                               title="Review Spam",
                               action="spam")

    try:
        if int(location_id) >= 1:
            spam_comments = db.session.query(TComments) \
                .filter(TComments.project_id == proj_id) \
                .filter(TComments.location_id == location_id) \
                .filter(TComments.is_spam == True)

            return render_template("manage-comments.html",
                                   locations=all_locations,
                                   selected=location_id,
                                   spam_comments=spam_comments,
                                   project=project,
                                   title="Review Spam",
                                   action="spam")
    except ValueError:
        pass

    export_location(location_id)
    return render_template("manage-comments.html",
                           locations=all_locations,
                           selected=location_id,
                           project=project,
                           title="Review Spam",
                           action="spam")