Ejemplo n.º 1
0
def dislike(request, comment_id, next=None):
    """
    Dislike a comment. Confirmation on GET, action on POST.

    Templates: :template:`django_comments_xtd/dislike.html`,
    Context:
        comment
            the flagged `comments.comment` object
    """
    comment = get_object_or_404(get_comment_model(),
                                pk=comment_id,
                                site__pk=get_current_site_id(request))
    if not get_app_model_options(comment=comment)['allow_feedback']:
        ctype = ContentType.objects.get_for_model(comment.content_object)
        raise Http404("Comments posted to instances of '%s.%s' are not "
                      "explicitly allowed to receive 'disliked it' flags. "
                      "Check the COMMENTS_XTD_APP_MODEL_OPTIONS "
                      "setting." % (ctype.app_label, ctype.model))
    # Flag on POST
    if request.method == 'POST':
        perform_dislike(request, comment)
        return next_redirect(request,
                             fallback=(next or 'comments-xtd-dislike-done'),
                             c=comment.pk)
    # Render a form on GET
    else:
        flag_qs = comment.flags.prefetch_related('user')\
            .filter(flag=DISLIKEDIT_FLAG)
        users_dislikedit = [item.user for item in flag_qs]
        return render(
            request, 'django_comments_xtd/dislike.html', {
                'comment': comment,
                'already_disliked_it': request.user in users_dislikedit,
                'next': next
            })
Ejemplo n.º 2
0
def reply(request, cid):
    try:
        comment = XtdComment.objects.get(pk=cid)
        if not comment.allow_thread():
            raise MaxThreadLevelExceededException(comment)
    except MaxThreadLevelExceededException as exc:
        return HttpResponseForbidden(exc)
    except XtdComment.DoesNotExist as exc:
        raise Http404(exc)

    ct_str = "%s.%s" % (comment.content_type.app_label,
                        comment.content_type.model)
    options = get_app_model_options(content_type=ct_str)

    if (not request.user.is_authenticated
            and options['who_can_post'] == 'users'):
        path = request.build_absolute_uri()
        resolved_login_url = resolve_url(settings.LOGIN_URL)
        return redirect_to_login(path, resolved_login_url, REDIRECT_FIELD_NAME)

    form = get_form()(comment.content_object, comment=comment)
    next = request.GET.get("next", reverse("comments-xtd-sent"))

    template_arg = [
        "django_comments_xtd/%s/%s/reply.html" %
        (comment.content_type.app_label, comment.content_type.model),
        "django_comments_xtd/%s/reply.html" %
        (comment.content_type.app_label, ), "django_comments_xtd/reply.html"
    ]
    return render(request, template_arg, {
        "comment": comment,
        "form": form,
        "cid": cid,
        "next": next
    })
Ejemplo n.º 3
0
def flag(request, comment_id, next=None):
    """
    Flags a comment. Confirmation on GET, action on POST.

    Templates: :template:`comments/flag.html`,
    Context:
        comment
            the flagged `comments.comment` object
    """
    comment = get_object_or_404(get_comment_model(),
                                pk=comment_id,
                                site__pk=get_current_site_id(request))
    if not get_app_model_options(comment=comment)['allow_flagging']:
        ctype = ContentType.objects.get_for_model(comment.content_object)
        raise Http404("Comments posted to instances of '%s.%s' are not "
                      "explicitly allowed to receive 'removal suggestion' "
                      "flags. Check the COMMENTS_XTD_APP_MODEL_OPTIONS "
                      "setting." % (ctype.app_label, ctype.model))
    # Flag on POST
    if request.method == 'POST':
        perform_flag(request, comment)
        return next_redirect(request,
                             fallback=next or 'comments-flag-done',
                             c=comment.pk)

    # Render a form on GET
    else:
        return render(request, 'comments/flag.html', {
            'comment': comment,
            'next': next
        })
Ejemplo n.º 4
0
def can_receive_comments_from(obj, user):
    ct = ContentType.objects.get_for_model(obj)
    app_label = '%s.%s' % (ct.app_label, ct.model)
    options = get_app_model_options(content_type=app_label)
    who_can_post = options['who_can_post']
    if (who_can_post == 'all'
            or (who_can_post == 'users' and user.is_authenticated)):
        return True
    else:
        return False
Ejemplo n.º 5
0
    def validate(self, data):
        ctype = data.get("content_type")
        object_pk = data.get("object_pk")
        if ctype is None or object_pk is None:
            return serializers.ValidationError("Missing content_type or "
                                               "object_pk field.")
        try:
            model = apps.get_model(*ctype.split(".", 1))
            target = model._default_manager.get(pk=object_pk)
            whocan = get_app_model_options(content_type=ctype)['who_can_post']
        except (AttributeError, TypeError, LookupError):
            raise serializers.ValidationError("Invalid content_type value: %r"
                                              % escape(ctype))
        except model.ObjectDoesNotExist:
            raise serializers.ValidationError(
                "No object matching content-type %r and object PK %r exists."
                % (escape(ctype), escape(object_pk)))
        except (ValueError, serializers.ValidationError) as e:
            raise serializers.ValidationError(
                "Attempting to get content-type %r and object PK %r exists "
                "raised %s" % (escape(ctype), escape(object_pk),
                               e.__class__.__name__))
        else:
            if whocan == "users" and not self.request.user.is_authenticated:
                raise serializers.ValidationError("User not authenticated")

        # Signal that the request allows to be authorized.
        responses = should_request_be_authorized.send(
            sender=target.__class__,
            comment=target,
            request=self.request
        )

        for (receiver, response) in responses:
            if response is True:
                # A positive response indicates that the POST request
                # must be trusted. So inject the CommentSecurityForm values
                # to pass the form validation step.
                secform = CommentSecurityForm(target)
                data.update({
                    "honeypot": "",
                    "timestamp": secform['timestamp'].value(),
                    "security_hash": secform['security_hash'].value()
                })
                break
        self.form = get_form()(target, data=data)

        # Check security information.
        if self.form.security_errors():
            raise exceptions.PermissionDenied()
        if self.form.errors:
            raise serializers.ValidationError(self.form.errors)
        return data
Ejemplo n.º 6
0
 def validate(self, data):
     # Validate flag.
     if data['flag'] not in self.flag_choices:
         raise serializers.ValidationError("Invalid flag.")
     # Check commenting options on object being commented.
     option = ''
     if data['flag'] in ['like', 'dislike']:
         option = 'allow_feedback'
     elif data['flag'] == 'report':
         option = 'allow_flagging'
     comment = data['comment']
     ctype = ContentType.objects.get_for_model(comment.content_object)
     key = "%s.%s" % (ctype.app_label, ctype.model)
     if not get_app_model_options(content_type=key)[option]:
         raise serializers.ValidationError(
             "Comments posted to instances of '%s' are not explicitly "
             "allowed to receive '%s' flags. Check the "
             "COMMENTS_XTD_APP_MODEL_OPTIONS setting." %
             (key, data['flag']))
     data['flag'] = self.flag_choices[data['flag']]
     return data
Ejemplo n.º 7
0
def on_comment_will_be_posted(sender, comment, request, **kwargs):
    """
    Check whether there are conditions to reject the post.

    Returns False if there are conditions to reject the comment.
    """
    if settings.COMMENTS_APP != "django_comments_xtd":
        # Do not kill the post if handled by other commenting app.
        return True

    if comment.user:
        user_is_authenticated = comment.user.is_authenticated
    else:
        user_is_authenticated = False

    ct = comment.get("content_type")
    ct_str = "%s.%s" % (ct.app_label, ct.model)
    options = get_app_model_options(content_type=ct_str)

    if not user_is_authenticated and options['who_can_post'] == 'users':
        # Reject comment.
        return False
    else:
        return True
Ejemplo n.º 8
0
def commentbox_props(obj, user, request=None):
    """
    Returns a JSON object with the initial props for the CommentBox component.

    The returned JSON object contains the following attributes::
        {
            comment_count: <int>,  // Count of comments posted to the object.
            allow_comments: <bool>,  // Whether to allow comments to this post.
            current_user: <str as "user_id:user_name">,
            is_authenticated: <bool>,  // Whether current_user is authenticated.
            request_name: <bool>,  // True when auth user has no actual name.
            request_email_address: <bool>,  // True when auth user has no email.
            allow_flagging: false,
            allow_feedback: false,
            show_feedback: false,
            can_moderate: <bool>,  // Whether current_user can moderate.
            polling_interval: 2000, // Check for new comments every 2 seconds.
            feedback_url: <api-url-to-send-like/dislike-feedback>,
            delete_url: <api-url-for-moderators-to-remove-comment>,
            login_url: settings.LOGIN_URL,
            reply_url: <api-url-to-reply-comments>,
            flag_url: <api-url-to-suggest-comment-removal>,
            list_url: <api-url-to-list-comments>,
            count_url: <api-url-to-count-comments>,
            send_url: <api-url-to-send-a-comment>,
            preview_url: <api-url-to-preview-users-avatar>,
            form: {
                content_type: <value>,
                object_pk: <value>,
                timestamp: <value>,
                security_hash: <value>
            },
            login_url: <only_when_user_is_not_authenticated>,
            like_url: <only_when_user_is_not_authenticated>,
            dislike_url: <only_when_user_is_not_authenticated>,
            html_id_suffix: <html_element_id_suffix>
        }
    """

    def _reverse(*args, **kwargs):
        """do not inject request to avoid http:// urls on https:// only sites"""
        return reverse(*args, **kwargs)

    form = CommentSecurityForm(obj)
    ctype = ContentType.objects.get_for_model(obj)
    queryset = XtdComment.objects.filter(content_type=ctype,
                                         object_pk=obj.pk,
                                         site__pk=get_current_site_id(request),
                                         is_public=True)
    ctype_slug = "%s-%s" % (ctype.app_label, ctype.model)
    ctype_key = "%s.%s" % (ctype.app_label, ctype.model)
    options = get_app_model_options(content_type=ctype_key)
    d = {
        "comment_count": queryset.count(),
        "allow_comments": True,
        "current_user": "******",
        "request_name": False,
        "request_email_address": False,
        "is_authenticated": False,
        "who_can_post": options['who_can_post'],
        "allow_flagging": False,
        "allow_feedback": False,
        "show_feedback": False,
        "can_moderate": False,
        "polling_interval": 2000,
        "feedback_url": _reverse("comments-xtd-api-feedback"),
        "delete_url": _reverse("comments-delete", args=(0,)),
        "reply_url": _reverse("comments-xtd-reply", kwargs={'cid': 0}),
        "flag_url": _reverse("comments-flag", args=(0,)),
        "list_url": _reverse('comments-xtd-api-list',
                             kwargs={'content_type': ctype_slug,
                                     'object_pk': obj.id}),
        "count_url": _reverse('comments-xtd-api-count',
                              kwargs={'content_type': ctype_slug,
                                      'object_pk': obj.id}),
        "send_url": _reverse("comments-xtd-api-create"),
        "preview_url": _reverse("comments-xtd-api-preview"),
        "form": {
            "content_type": form['content_type'].value(),
            "object_pk": form['object_pk'].value(),
            "timestamp": form['timestamp'].value(),
            "security_hash": form['security_hash'].value()
        },
        "html_id_suffix": get_html_id_suffix(obj),
        "max_thread_level": max_thread_level_for_content_type(ctype),
    }
    try:
        user_is_authenticated = user.is_authenticated()
    except TypeError:  # Django >= 1.11
        user_is_authenticated = user.is_authenticated
    if user and user_is_authenticated:
        d['current_user'] = "******" % (
            user.pk, settings.COMMENTS_XTD_API_USER_REPR(user))
        d['is_authenticated'] = True
        d['can_moderate'] = user.has_perm("django_comments.can_moderate")
        d['request_name'] = True if not len(user.get_full_name()) else False
        d['request_email_address'] = True if not user.email else False
    else:
        d['login_url'] = settings.LOGIN_URL
        d['like_url'] = reverse("comments-xtd-like", args=(0,))
        d['dislike_url'] = reverse("comments-xtd-dislike", args=(0,))

    return d
Ejemplo n.º 9
0
 def render(self, context):
     context[self.as_varname] = get_app_model_options(
         content_type=self.content_type)['who_can_post']
     return ''