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'))
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'))
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")
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)
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)
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)
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 = 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)
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})
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})
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)
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 }, )
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})
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)
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})
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)
def _wrapped(request, *args, **kwargs): # Sets ``request.limited`` on ``request``. is_ratelimited(request, name, rate, method, skip_if) return fn(request, *args, **kwargs)
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")