示例#1
0
文件: views.py 项目: zctyhj/kitsune
def _is_ratelimited(request):
    """Ratelimiting helper for kbforum threads and replies.

    They are ratelimited together with the same key.
    """
    return (is_ratelimited(request, 'kbforum-post-min', '4/m')
            or is_ratelimited(request, 'kbforum-post-day', '50/d'))
示例#2
0
文件: views.py 项目: runt18/kitsune
def _is_ratelimited(request):
    """Ratelimiting helper for kbforum threads and replies.

    They are ratelimited together with the same key.
    """
    return (
        is_ratelimited(request, 'kbforum-post-min', '4/m') or
        is_ratelimited(request, 'kbforum-post-day', '50/d'))
示例#3
0
def _is_ratelimited(request):
    """Ratelimiting helper for kbforum threads and replies.

    They are ratelimited together with the same key.
    """
    return is_ratelimited(request,
                          "kbforum-post-min", "4/m") or is_ratelimited(
                              request, "kbforum-post-day", "50/d")
示例#4
0
    def test_ratelimited(self):
        u = UserFactory()
        request = Mock()
        request.user = u
        request.limited = False
        request.method = "POST"

        # One call to the rate limit won't trigger it.
        eq_(is_ratelimited(request, "test-ratelimited", "1/min"), False)
        # But two will
        eq_(is_ratelimited(request, "test-ratelimited", "1/min"), True)
    def test_ratelimited(self):
        u = profile().user
        request = Mock()
        request.user = u
        request.limited = False
        request.method = 'POST'

        # One call to the rate limit won't trigger it.
        eq_(is_ratelimited(request, 'test-ratelimited', '1/min'), False)
        # But two will
        eq_(is_ratelimited(request, 'test-ratelimited', '1/min'), True)
示例#6
0
    def test_ratelimited(self):
        u = profile().user
        request = Mock()
        request.user = u
        request.limited = False
        request.method = 'POST'

        # One call to the rate limit won't trigger it.
        eq_(is_ratelimited(request, 'test-ratelimited', '1/min'), False)
        # But two will
        eq_(is_ratelimited(request, 'test-ratelimited', '1/min'), True)
    def test_ratelimit_bypass(self):
        u = profile().user
        bypass = Permission.objects.get(codename='bypass_ratelimit')
        u.user_permissions.add(bypass)
        request = Mock()
        request.user = u
        request.limited = False
        request.method = 'POST'

        # One call to the rate limit won't trigger it.
        eq_(is_ratelimited(request, 'test-ratelimited', '1/min'), False)
        # And a second one still won't, because the user has the bypass permission.
        eq_(is_ratelimited(request, 'test-ratelimited', '1/min'), False)
示例#8
0
    def test_ratelimit_bypass(self):
        u = UserFactory()
        bypass = Permission.objects.get(codename="bypass_ratelimit")
        u.user_permissions.add(bypass)
        request = Mock()
        request.user = u
        request.limited = False
        request.method = "POST"

        # One call to the rate limit won't trigger it.
        eq_(is_ratelimited(request, "test-ratelimited", "1/min"), False)
        # And a second one still won't, because the user has the bypass permission.
        eq_(is_ratelimited(request, "test-ratelimited", "1/min"), False)
示例#9
0
    def test_ratelimit_bypass(self):
        u = profile().user
        bypass = Permission.objects.get(codename='bypass_ratelimit')
        u.user_permissions.add(bypass)
        request = Mock()
        request.user = u
        request.limited = False
        request.method = 'POST'

        # One call to the rate limit won't trigger it.
        eq_(is_ratelimited(request, 'test-ratelimited', '1/min'), False)
        # And a second one still won't, because the user has the bypass permission.
        eq_(is_ratelimited(request, 'test-ratelimited', '1/min'), False)
示例#10
0
    def test_ratelimit_logging(self):
        u = profile().user
        request = Mock()
        request.user = u
        request.limited = False
        request.method = 'POST'

        eq_(Record.objects.count(), 0)

        # Two calls will trigger the ratelimit once.
        is_ratelimited(request, 'test-ratelimited', '1/min')
        is_ratelimited(request, 'test-ratelimited', '1/min')

        eq_(Record.objects.count(), 1)
    def test_ratelimit_logging(self):
        u = profile().user
        request = Mock()
        request.user = u
        request.limited = False
        request.method = 'POST'

        eq_(Record.objects.count(), 0)

        # Two calls will trigger the ratelimit once.
        is_ratelimited(request, 'test-ratelimited', '1/min')
        is_ratelimited(request, 'test-ratelimited', '1/min')

        eq_(Record.objects.count(), 1)
示例#12
0
    def test_ratelimit_logging(self):
        u = UserFactory()
        request = Mock()
        request.user = u
        request.limited = False
        request.method = "POST"

        eq_(Record.objects.count(), 0)

        # Two calls will trigger the ratelimit once.
        is_ratelimited(request, "test-ratelimited", "1/min")
        is_ratelimited(request, "test-ratelimited", "1/min")

        eq_(Record.objects.count(), 1)
示例#13
0
文件: views.py 项目: 1234-/kitsune
def new_message(request, template):
    """Send a new private message."""
    to = request.GET.get('to')
    if to:
        try:
            for username in to.split(','):
                User.objects.get(username=username)
        except User.DoesNotExist:
            contrib_messages.add_message(
                request, contrib_messages.ERROR,
                _('Invalid username provided. Enter a new username below.'))
            return HttpResponseRedirect(reverse('messages.new'))

    message = request.GET.get('message')

    form = MessageForm(request.POST or None, initial={'to': to, 'message': message})

    if (request.method == 'POST' and form.is_valid() and
            not is_ratelimited(request, 'primate-message-day', '50/d')):
        send_message(form.cleaned_data['to'], form.cleaned_data['message'],
                     request.user)
        if form.cleaned_data['in_reply_to']:
            irt = form.cleaned_data['in_reply_to']
            try:
                m = InboxMessage.objects.get(pk=irt, to=request.user)
                m.update(replied=True)
            except InboxMessage.DoesNotExist:
                pass
        contrib_messages.add_message(request, contrib_messages.SUCCESS,
                                     _('Your message was sent!'))
        return HttpResponseRedirect(reverse('messages.inbox'))

    return render(request, template, {'form': form})
示例#14
0
def new_message(request, template):
    """Send a new private message."""
    to = request.GET.get('to')
    if to:
        try:
            User.objects.get(username=to)
        except User.DoesNotExist:
            contrib_messages.add_message(
                request, contrib_messages.ERROR,
                _('Invalid username provided. Enter a new username below.'))
            return HttpResponseRedirect(reverse('messages.new'))

    form = MessageForm(request.POST or None, initial={'to': to})

    if (request.method == 'POST' and form.is_valid() and
            not is_ratelimited(request, 'primate-message-day', '50/d')):
        send_message(form.cleaned_data['to'], form.cleaned_data['message'],
                     request.user)
        if form.cleaned_data['in_reply_to']:
            irt = form.cleaned_data['in_reply_to']
            try:
                m = InboxMessage.objects.get(pk=irt, to=request.user)
                m.update(replied=True)
            except InboxMessage.DoesNotExist:
                pass
        contrib_messages.add_message(request, contrib_messages.SUCCESS,
                                     _('Your message was sent!'))
        return HttpResponseRedirect(reverse('messages.inbox'))

    return render(request, template, {'form': form})
示例#15
0
def reply(request, forum_slug, thread_id):
    """Reply to a thread."""
    forum = get_object_or_404(Forum, slug=forum_slug)
    user = request.user
    if not forum.allows_posting_by(user):
        if forum.allows_viewing_by(user):
            raise PermissionDenied
        else:
            raise Http404

    form = ReplyForm(request.POST)
    post_preview = None
    if form.is_valid():
        thread = get_object_or_404(Thread, pk=thread_id, forum=forum)

        if not thread.is_locked:
            reply_ = form.save(commit=False)
            reply_.thread = thread
            reply_.author = request.user
            if "preview" in request.POST:
                post_preview = reply_
                post_preview.author_post_count = reply_.author.post_set.count()
            elif not is_ratelimited(request, "forum-post", "15/d"):
                reply_.save()

                # Subscribe the user to the thread.
                if Setting.get_for_user(request.user, "forums_watch_after_reply"):
                    NewPostEvent.notify(request.user, thread)

                # Send notifications to thread/forum watchers.
                NewPostEvent(reply_).fire(exclude=reply_.author)

                return HttpResponseRedirect(thread.get_last_post_url())

    return posts(request, forum_slug, thread_id, form, post_preview, is_reply=True)
示例#16
0
def new_thread(request, forum_slug):
    """Start a new thread."""
    forum = get_object_or_404(Forum, slug=forum_slug)
    user = request.user
    if not forum.allows_posting_by(user):
        if forum.allows_viewing_by(user):
            raise PermissionDenied
        else:
            raise Http404

    if request.method == "GET":
        form = NewThreadForm()
        return render(request, "forums/new_thread.html", {
            "form": form,
            "forum": forum
        })

    form = NewThreadForm(request.POST)
    post_preview = None
    if form.is_valid():
        if "preview" in request.POST:
            thread = Thread(creator=request.user,
                            title=form.cleaned_data["title"])
            post_preview = Post(thread=thread,
                                author=request.user,
                                content=form.cleaned_data["content"])
            post_preview.author_post_count = post_preview.author.post_set.count(
            )
        elif not is_ratelimited(request, "forum-post", "5/d"):
            thread = forum.thread_set.create(creator=request.user,
                                             title=form.cleaned_data["title"])
            thread.save()
            post = thread.new_post(author=request.user,
                                   content=form.cleaned_data["content"])
            post.save()

            NewThreadEvent(post).fire(exclude=post.author)

            # Add notification automatically if needed.
            if Setting.get_for_user(request.user, "forums_watch_new_thread"):
                NewPostEvent.notify(request.user, thread)

            url = reverse("forums.posts", args=[forum_slug, thread.id])
            return HttpResponseRedirect(urlparams(url, last=post.id))

    return render(
        request,
        "forums/new_thread.html",
        {
            "form": form,
            "forum": forum,
            "post_preview": post_preview
        },
    )
示例#17
0
def new_thread(request, forum_slug):
    """Start a new thread."""
    forum = get_object_or_404(Forum, slug=forum_slug)
    user = request.user
    if not forum.allows_posting_by(user):
        if forum.allows_viewing_by(user):
            raise PermissionDenied
        else:
            raise Http404

    if request.method == 'GET':
        form = NewThreadForm()
        return render(request, 'forums/new_thread.html', {
            'form': form, 'forum': forum})

    form = NewThreadForm(request.POST)
    post_preview = None
    if form.is_valid():
        if 'preview' in request.POST:
            thread = Thread(creator=request.user,
                            title=form.cleaned_data['title'])
            post_preview = Post(thread=thread, author=request.user,
                                content=form.cleaned_data['content'])
            post_preview.author_post_count = \
                post_preview.author.post_set.count()
        elif not is_ratelimited(request, 'forum-post', '5/d'):
            thread = forum.thread_set.create(creator=request.user,
                                             title=form.cleaned_data['title'])
            thread.save()
            statsd.incr('forums.thread')
            post = thread.new_post(author=request.user,
                                   content=form.cleaned_data['content'])
            post.save()

            NewThreadEvent(post).fire(exclude=post.author)

            # Add notification automatically if needed.
            if Setting.get_for_user(request.user, 'forums_watch_new_thread'):
                NewPostEvent.notify(request.user, thread)

            url = reverse('forums.posts', args=[forum_slug, thread.id])
            return HttpResponseRedirect(urlparams(url, last=post.id))

    return render(request, 'forums/new_thread.html', {
        'form': form, 'forum': forum,
        'post_preview': post_preview})
示例#18
0
def reply(request, forum_slug, thread_id):
    """Reply to a thread."""
    forum = get_object_or_404(Forum, slug=forum_slug)
    user = request.user
    if not forum.allows_posting_by(user):
        if forum.allows_viewing_by(user):
            raise PermissionDenied
        else:
            raise Http404

    form = ReplyForm(request.POST)
    post_preview = None
    if form.is_valid():
        thread = get_object_or_404(Thread, pk=thread_id, forum=forum)

        if not thread.is_locked:
            reply_ = form.save(commit=False)
            reply_.thread = thread
            reply_.author = request.user
            if 'preview' in request.POST:
                post_preview = reply_
                post_preview.author_post_count = \
                    reply_.author.post_set.count()
            elif not is_ratelimited(request, 'forum-post', '15/d'):
                reply_.save()
                statsd.incr('forums.reply')

                # Subscribe the user to the thread.
                if Setting.get_for_user(request.user,
                                        'forums_watch_after_reply'):
                    NewPostEvent.notify(request.user, thread)

                # Send notifications to thread/forum watchers.
                NewPostEvent(reply_).fire(exclude=reply_.author)

                return HttpResponseRedirect(thread.get_last_post_url())

    return posts(request, forum_slug, thread_id, form, post_preview,
                 is_reply=True)
示例#19
0
文件: views.py 项目: zu83/kitsune
def new_message(request):
    """Send a new private message."""
    to = request.GET.get("to")
    if to:
        try:
            for username in to.split(","):
                User.objects.get(username=username)
        except User.DoesNotExist:
            contrib_messages.add_message(
                request,
                contrib_messages.ERROR,
                _("Invalid username provided. Enter a new username below."),
            )
            return HttpResponseRedirect(reverse("messages.new"))

    message = request.GET.get("message")

    form = MessageForm(request.POST or None,
                       initial={
                           "to": to,
                           "message": message
                       })

    if (request.method == "POST" and form.is_valid()
            and not is_ratelimited(request, "primate-message-day", "50/d")):
        send_message(form.cleaned_data["to"], form.cleaned_data["message"],
                     request.user)
        if form.cleaned_data["in_reply_to"]:
            irt = form.cleaned_data["in_reply_to"]
            try:
                m = InboxMessage.objects.get(pk=irt, to=request.user)
                m.update(replied=True)
            except InboxMessage.DoesNotExist:
                pass
        contrib_messages.add_message(request, contrib_messages.SUCCESS,
                                     _("Your message was sent!"))
        return HttpResponseRedirect(reverse("messages.inbox"))

    return render(request, "messages/new.html", {"form": form})
示例#20
0
def aaq(request, product_key=None, category_key=None, step=1):
    """Ask a new question."""

    template = "questions/new_question.html"

    # Check if any product forum has a locale in the user's current locale
    if (request.LANGUAGE_CODE not in QuestionLocale.objects.locales_list()
            and request.LANGUAGE_CODE != settings.WIKI_DEFAULT_LANGUAGE):

        locale, path = split_path(request.path)
        path = "/" + settings.WIKI_DEFAULT_LANGUAGE + "/" + path

        old_lang = settings.LANGUAGES_DICT[request.LANGUAGE_CODE.lower()]
        new_lang = settings.LANGUAGES_DICT[
            settings.WIKI_DEFAULT_LANGUAGE.lower()]
        msg = _(
            "The questions forum isn't available in {old_lang}, we "
            "have redirected you to the {new_lang} questions forum.").format(
                old_lang=old_lang, new_lang=new_lang)
        messages.add_message(request, messages.WARNING, msg)

        return HttpResponseRedirect(path)

    # Check if the user is using a mobile device,
    # render step 2 if they are
    product_key = product_key or request.GET.get("product")
    if product_key is None:

        change_product = False
        if request.GET.get("q") == "change_product":
            change_product = True

        is_mobile_device = get_user_agent(request).is_mobile

        if is_mobile_device and not change_product:
            user_agent = request.META.get("HTTP_USER_AGENT", "")
            product_key = get_mobile_product_from_ua(user_agent)
            if product_key:
                # redirect needed for InAAQMiddleware
                step_2 = reverse("questions.aaq_step2",
                                 kwargs={"product_key": product_key})
                return HttpResponseRedirect(step_2)

    # Return 404 if the product doesn't exist in config
    product_config = config.products.get(product_key)
    if product_key and not product_config:
        raise Http404

    # If the selected product doesn't exist in DB, render a 404
    if step > 1:
        try:
            product = Product.objects.get(slug=product_config["product"])
        except Product.DoesNotExist:
            raise Http404
        else:
            # Check if the selected product has a forum in the user's locale
            if not product.questions_locales.filter(
                    locale=request.LANGUAGE_CODE).count():
                locale, path = split_path(request.path)
                path = "/" + settings.WIKI_DEFAULT_LANGUAGE + "/" + path

                old_lang = settings.LANGUAGES_DICT[
                    request.LANGUAGE_CODE.lower()]
                new_lang = settings.LANGUAGES_DICT[
                    settings.WIKI_DEFAULT_LANGUAGE.lower()]
                msg = _(
                    "The questions forum isn't available for {product} in {old_lang}, we "
                    "have redirected you to the {new_lang} questions forum."
                ).format(product=product.title,
                         old_lang=old_lang,
                         new_lang=new_lang)
                messages.add_message(request, messages.WARNING, msg)

                return HttpResponseRedirect(path)

    context = {
        "products": config.products,
        "current_product": product_config,
        "current_step": step,
        "host": Site.objects.get_current().domain,
    }

    if step == 2:
        context["featured"] = get_featured_articles(
            product, locale=request.LANGUAGE_CODE)
        context["topics"] = topics_for(product, parent=None)
    elif step == 3:
        form = NewQuestionForm(
            product=product_config,
            data=request.POST or None,
            initial={"category": category_key},
        )
        context["form"] = form

        # NOJS: upload image
        if "upload_image" in request.POST:
            upload_imageattachment(request, request.user)

        if form.is_valid() and not is_ratelimited(request, "aaq-day", "5/d"):

            question = form.save(
                user=request.user,
                locale=request.LANGUAGE_CODE,
                product=product,
                product_config=product_config,
            )

            if form.cleaned_data.get("is_spam"):
                _add_to_moderation_queue(request, question)

            # Submitting the question counts as a vote
            question_vote(request, question.id)

            my_questions_url = reverse("users.questions",
                                       args=[request.user.username])
            messages.add_message(
                request,
                messages.SUCCESS,
                _("Done! Your question is now posted on the Mozilla community support forum. "
                  +
                  "You can see your post anytime by visiting the {a_open}My Questions"
                  + "{a_close} page in your profile.").format(
                      a_open="<a href='" + my_questions_url + "'>",
                      a_close="</a>"),
                extra_tags="safe",
            )

            request.session["aaq-final-step"] = True

            url = reverse("questions.details",
                          kwargs={"question_id": question.id})
            return HttpResponseRedirect(url)

        if getattr(request, "limited", False):
            raise PermissionDenied

        user_ct = ContentType.objects.get_for_model(request.user)
        context["images"] = ImageAttachment.objects.filter(
            creator=request.user,
            content_type=user_ct,
        ).order_by("-id")[:IMG_LIMIT]

    return render(request, template, context)
示例#21
0
 def _wrapped(request, *args, **kwargs):
     # Sets ``request.limited`` on ``request``.
     is_ratelimited(request, name, rate, method, skip_if)
     return fn(request, *args, **kwargs)
示例#22
0
def _is_ratelimited(request):
    """Ratelimiting helper for kbforum threads and replies.

    They are ratelimited together with the same key.
    """
    return is_ratelimited(request, "kbforum-post-min", "4/m") or is_ratelimited(request, "kbforum-post-day", "50/d")
示例#23
0
 def _wrapped(request, *args, **kwargs):
     # Sets ``request.limited`` on ``request``.
     is_ratelimited(request, name, rate, method, skip_if)
     return fn(request, *args, **kwargs)