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 })
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 })
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 })
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
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
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
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
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
def render(self, context): context[self.as_varname] = get_app_model_options( content_type=self.content_type)['who_can_post'] return ''