Beispiel #1
0
def moderate_post_edits(request):
    if request.user.is_anonymous():
        raise exceptions.PermissionDenied()
    if not request.user.is_administrator_or_moderator():
        raise exceptions.PermissionDenied()

    post_data = json.loads(request.raw_post_data)
    #{'action': 'decline-with-reason', 'items': ['posts'], 'reason': 1, 'edit_ids': [827]}

    memo_set = models.ActivityAuditStatus.objects.filter(
        id__in=post_data['edit_ids'])
    result = {'message': '', 'memo_ids': set()}

    # if we are approving or declining users we need to expand the memo_set
    # to all of their edits of those users
    if post_data['action'] in ('block',
                               'approve') and 'users' in post_data['items']:
        editors = exclude_admins(get_editors(memo_set))
        items = models.Activity.objects.filter(
            activity_type__in=const.MODERATED_EDIT_ACTIVITY_TYPES,
            user__in=editors)
        memo_filter = Q(user=request.user, activity__in=items)
        memo_set |= models.ActivityAuditStatus.objects.filter(memo_filter)

    memo_set.select_related('activity')

    if post_data['action'] == 'approve':
        num_posts = 0
        if 'posts' in post_data['items']:
            for memo in memo_set:
                if memo.activity.activity_type == const.TYPE_ACTIVITY_MARK_OFFENSIVE:
                    # unflag the post
                    content_object = memo.activity.content_object
                    request.user.flag_post(content_object,
                                           cancel_all=True,
                                           force=True)
                    num_posts += 1
                else:
                    revision = memo.activity.content_object
                    if isinstance(revision, models.PostRevision):
                        request.user.approve_post_revision(revision)
                        num_posts += 1

            if num_posts > 0:
                posts_message = ungettext('%d post approved',
                                          '%d posts approved',
                                          num_posts) % num_posts
                result['message'] = concat_messages(result['message'],
                                                    posts_message)

        if 'users' in post_data['items']:
            editors = exclude_admins(get_editors(memo_set))
            assert (request.user not in editors)
            for editor in editors:
                editor.set_status('a')

            num_users = len(editors)
            if num_users:
                users_message = ungettext('%d user approved',
                                          '%d users approved',
                                          num_users) % num_users
                result['message'] = concat_messages(result['message'],
                                                    users_message)

    elif post_data['action'] == 'decline-with-reason':
        # TODO: bunch notifications - one per recipient
        num_posts = 0
        for memo in memo_set:
            post = get_object(memo)
            request.user.delete_post(post)
            reject_reason = models.PostFlagReason.objects.get(
                id=post_data['reason'])

            from askbot.mail.messages import RejectedPost
            email = RejectedPost({
                'post': post.html,
                'reject_reason': reject_reason.details.html
            })
            email.send([
                post.author.email,
            ])
            num_posts += 1

        # message to moderator
        if num_posts:
            posts_message = ungettext('%d post deleted', '%d posts deleted',
                                      num_posts) % num_posts
            result['message'] = concat_messages(result['message'],
                                                posts_message)

    elif post_data['action'] == 'block':

        num_users = 0
        num_posts = 0
        num_ips = 0

        moderate_ips = getattr(django_settings, 'ASKBOT_IP_MODERATION_ENABLED',
                               False)
        # If we block by IPs we always block users and posts
        # so we use a "spider" algorithm to find posts, users and IPs to block.
        # once we find users, posts and IPs, we block all of them summarily.
        if moderate_ips and 'ips' in post_data['items']:
            assert ('users' in post_data['items'])
            assert ('posts' in post_data['items'])
            assert (len(post_data['items']) == 3)

            revs = get_revision_set(memo_set)
            revs = expand_revision_set(revs)
            ips, users = get_revision_ips_and_authors(revs)
            memo_set = get_memos_by_revisions(revs, request.user)

            # to make sure to not block the admin and
            # in case REMOTE_ADDR is a proxy server - not
            # block access to the site
            my_ip = request.META.get('REMOTE_ADDR')
            if my_ip in ips:
                ips.remove(my_ip)

            # block IPs
            from stopforumspam.models import Cache
            already_blocked = Cache.objects.filter(ip__in=ips)
            already_blocked.update(permanent=True)
            already_blocked_ips = already_blocked.values_list('ip', flat=True)
            ips = ips - set(already_blocked_ips)
            for ip in ips:
                cache = Cache(ip=ip, permanent=True)
                cache.save()

            # block users and all their content
            users = exclude_admins(users)
            for user in users:
                user.set_status('b')
                # delete all content by the user
                num_posts += request.user.delete_all_content_authored_by_user(
                    user)

            num_ips = len(ips)
            num_users = len(users)

        elif 'users' in post_data['items']:
            editors = exclude_admins(get_editors(memo_set))
            assert (request.user not in editors)
            for editor in editors:
                # block user
                editor.set_status('b')
                # delete all content by the user
                num_posts += request.user.delete_all_content_authored_by_user(
                    editor)
            num_users = len(editors)

        if num_ips:
            ips_message = ungettext('%d ip blocked', '%d ips blocked',
                                    num_ips) % num_ips
            result['message'] = concat_messages(result['message'], ips_message)

        if num_users:
            users_message = ungettext('%d user blocked', '%d users blocked',
                                      num_users) % num_users
            result['message'] = concat_messages(result['message'],
                                                users_message)

        if num_posts:
            posts_message = ungettext('%d post deleted', '%d posts deleted',
                                      num_posts) % num_posts
            result['message'] = concat_messages(result['message'],
                                                posts_message)

    result['memo_ids'] = [memo.id for memo in memo_set
                          ]  # why values_list() fails here?
    result['message'] = force_text(result['message'])

    # delete items from the moderation queue
    act_ids = list(memo_set.values_list('activity_id', flat=True))
    acts = models.Activity.objects.filter(id__in=act_ids)

    memos = models.ActivityAuditStatus.objects.filter(activity__id__in=act_ids)
    memos.delete()

    acts.delete()

    request.user.update_response_counts()
    result['memo_count'] = request.user.get_notifications(
        const.MODERATED_ACTIVITY_TYPES).count()
    return result
Beispiel #2
0
def moderate_post_edits(request):
    if request.user.is_anonymous():
        raise exceptions.PermissionDenied()
    if not request.user.is_administrator_or_moderator():
        raise exceptions.PermissionDenied()

    post_data = decode_and_loads(request.body)
    #{'action': 'decline-with-reason', 'items': ['posts'], 'reason': 1, 'edit_ids': [827]}

    memo_set = models.ActivityAuditStatus.objects.filter(id__in=post_data['edit_ids'])
    result = {
        'message': '',
        'memo_ids': set()
    }

    #if we are approving or declining users we need to expand the memo_set
    #to all of their edits of those users
    if post_data['action'] in ('block', 'approve') and 'users' in post_data['items']:
        editors = exclude_admins(get_editors(memo_set))
        items = models.Activity.objects.filter(
                                activity_type__in=const.MODERATED_EDIT_ACTIVITY_TYPES,
                                user__in=editors
                            )
        memo_filter = Q(user=request.user, activity__in=items)
        memo_set |= models.ActivityAuditStatus.objects.filter(memo_filter)

    memo_set.select_related('activity')

    if post_data['action'] == 'approve':
        num_posts = 0
        if 'posts' in post_data['items']:
            for memo in memo_set:
                if memo.activity.activity_type == const.TYPE_ACTIVITY_MARK_OFFENSIVE:
                    #unflag the post
                    content_object = memo.activity.content_object
                    request.user.flag_post(content_object, cancel_all=True, force=True)
                    num_posts += 1
                else:
                    revision = memo.activity.content_object
                    if isinstance(revision, models.PostRevision):
                        request.user.approve_post_revision(revision)
                        num_posts += 1

            if num_posts > 0:
                posts_message = ungettext('%d post approved', '%d posts approved', num_posts) % num_posts
                result['message'] = concat_messages(result['message'], posts_message)

        if 'users' in post_data['items']:
            editors = exclude_admins(get_editors(memo_set))
            assert(request.user not in editors)
            for editor in editors:
                editor.set_status('a')

            num_users = len(editors)
            if num_users:
                users_message = ungettext('%d user approved', '%d users approved', num_users) % num_users
                result['message'] = concat_messages(result['message'], users_message)

    elif post_data['action'] == 'decline-with-reason':
        #todo: bunch notifications - one per recipient
        num_posts = 0
        for memo in memo_set:
            post = get_object(memo)
            request.user.delete_post(post)
            reject_reason = models.PostFlagReason.objects.get(id=post_data['reason'])

            from askbot.mail.messages import RejectedPost
            email = RejectedPost({
                        'post': post.html,
                        'reject_reason': reject_reason.details.html
                    })
            email.send([post.author.email,])
            num_posts += 1

        #message to moderator
        if num_posts:
            posts_message = ungettext('%d post deleted', '%d posts deleted', num_posts) % num_posts
            result['message'] = concat_messages(result['message'], posts_message)

    elif post_data['action'] == 'block':

        num_users = 0
        num_posts = 0
        num_ips = 0

        moderate_ips = getattr(django_settings, 'ASKBOT_IP_MODERATION_ENABLED', False)
        # If we block by IPs we always block users and posts
        # so we use a "spider" algorithm to find posts, users and IPs to block.
        # once we find users, posts and IPs, we block all of them summarily.
        if moderate_ips and 'ips' in post_data['items']:
            assert('users' in post_data['items'])
            assert('posts' in post_data['items'])
            assert(len(post_data['items']) == 3)

            revs = get_revision_set(memo_set)
            revs = expand_revision_set(revs)
            ips, users = get_revision_ips_and_authors(revs)
            #important: evaluate the query here b/c some memos related to
            #comments will be lost when blocking users
            memo_set = set(get_memos_by_revisions(revs, request.user))

            #to make sure to not block the admin and
            #in case REMOTE_ADDR is a proxy server - not
            #block access to the site
            good_ips = set(getattr(django_settings, 'ASKBOT_WHITELISTED_IPS', ()))
            good_ips.add(request.META['REMOTE_ADDR'])
            ips = ips - good_ips

            #block IPs
            from stopforumspam.models import Cache
            already_blocked = Cache.objects.filter(ip__in=ips)
            already_blocked.update(permanent=True)
            already_blocked_ips = already_blocked.values_list('ip', flat=True)
            ips = ips - set(already_blocked_ips)
            for ip in ips:
                cache = Cache(ip=ip, permanent=True)
                cache.save()

            #block users and all their content
            users = exclude_admins(users)
            num_users = 0
            for user in users:
                if user.status != 'b':
                    user.set_status('b')
                    num_users += 1
                #delete all content by the user
                num_posts += request.user.delete_all_content_authored_by_user(user)

            num_ips = len(ips)

        elif 'users' in post_data['items']:
            memo_set = set(memo_set)#evaluate memo_set before deleting content
            editors = exclude_admins(get_editors(memo_set))
            assert(request.user not in editors)
            num_users = 0
            for editor in editors:
                #block user
                if editor.status != 'b':
                    editor.set_status('b')
                    num_users += 1
                #delete all content by the user
                num_posts += request.user.delete_all_content_authored_by_user(editor)

        if num_ips:
            ips_message = ungettext('%d ip blocked', '%d ips blocked', num_ips) % num_ips
            result['message'] = concat_messages(result['message'], ips_message)

        if num_users:
            users_message = ungettext('%d user blocked', '%d users blocked', num_users) % num_users
            result['message'] = concat_messages(result['message'], users_message)

        if num_posts:
            posts_message = ungettext('%d post deleted', '%d posts deleted', num_posts) % num_posts
            result['message'] = concat_messages(result['message'], posts_message)

    result['memo_ids'] = [memo.id for memo in memo_set]
    result['message'] = force_text(result['message'])

    #delete items from the moderation queue
    act_ids = [memo.activity_id for memo in memo_set]
    acts = models.Activity.objects.filter(id__in=act_ids)

    memos = models.ActivityAuditStatus.objects.filter(activity__id__in=act_ids)
    memos.delete()

    acts.delete()

    request.user.update_response_counts()
    result['memo_count'] = request.user.get_notifications(const.MODERATED_ACTIVITY_TYPES).count()
    return result