def dispatch(self, request, *args, **kwargs): # create a dummy function and dynamically set its name. This way, # the ratelimit decorator is specific to the method in each class. def func(request): pass func.__name__ = str('%s_dispatch' % self.__class__.__name__) func = ratelimit(method='POST', rate='10/m')(func) ratelimit(method='GET', rate='30/m')(func)(request) if getattr(request, 'limited', False): raise RateException() try: return super(AntiSpamFormView, self).dispatch(request, *args, **kwargs) except RecaptchaUnreachableError as e: raise TemporaryError(_("The ReCAPTCHA server was unreacheable.")) except KeyError as e: raise TemporaryError(_("The ReCAPTCHA didn't work properly."))
class PleaOnlineViews(StorageView): start = "enter_urn" def __init__(self, *args, **kwargs): super(PleaOnlineViews, self).__init__(*args, **kwargs) self.index = None self.storage = None def dispatch(self, request, *args, **kwargs): # If the session has timed out, redirect to start page if not request.session.get("plea_data") and kwargs.get( "stage", self.start) != self.start: # messages.add_message(request, messages.ERROR, _("Your session has timed out"), extra_tags="session_timeout") return HttpResponseRedirect("/") # Store the index if we've got one idx = kwargs.pop("index", None) try: self.index = int(idx) except (ValueError, TypeError): self.index = 0 # Load storage self.storage = self.get_storage(request, "plea_data") return super(PleaOnlineViews, self).dispatch(request, *args, **kwargs) def get(self, request, stage=None): if not stage: stage = PleaOnlineForms.stage_classes[0].name return HttpResponseRedirect( reverse_lazy("plea_form_step", args=(stage, ))) form = PleaOnlineForms(self.storage, stage, self.index) case_redirect = form.load(RequestContext(request)) if case_redirect: return case_redirect form.process_messages(request) if stage == "complete": self.clear_storage(request, "plea_data") return form.render() @method_decorator(ratelimit(block=True, rate=settings.RATE_LIMIT)) def post(self, request, stage): nxt = request.GET.get("next", None) form = PleaOnlineForms(self.storage, stage, self.index) form.save(request.POST, RequestContext(request), nxt) if not form._urn_invalid: form.process_messages(request) request.session.modified = True return form.render()
def test_dont_use_request_path(self): """Test use_request_path=False for the same view function above""" cache.set(self.KEYS.fake_login_path_ip_60, 6) rl = ratelimit(method='POST', use_request_path=False, rate='5/m', block=True) result = self.client.post(rl(fake_login_use_request_path), self.bad_payload) self.assertEqual(result.status_code, 200)
def test_use_request_path(self): """Test use_request_path=True = use request.path instead of view function name in cache key""" cache.set(self.KEYS.fake_login_path_ip_60, 6) rl = ratelimit(method='POST', use_request_path=True, rate='5/m', block=True) result = self.client.post(rl(fake_login_use_request_path), self.bad_payload) self.assertEqual(result.status_code, 429)
def dispatch(self, request, *args, **kwargs): remote_ip = get_client_ip(request) if settings.DEBUG is False and remote_ip not in settings.RATELIMIT_WHITELIST: # create a dummy function and dynamically set its name. This way, # the ratelimit decorator is specific to the method in each class. def func(request): pass func.__name__ = str('%s_dispatch' % self.__class__.__name__) func = ratelimit(method='POST', rate='10/m')(func) ratelimit(method='GET', rate='30/m')(func)(request) if getattr(request, 'limited', False): raise RateException() # We sometimes get requests *without* a user agent. We assume these are automated requests. if not request.META.get('HTTP_USER_AGENT'): raise SpamException("No user agent passed.") return super(AntiSpamFormView, self).dispatch(request, *args, **kwargs)
class FeedbackViews(StorageView): def get(self, request, stage=None): storage = self.get_storage(request, "feedback_data") kw_args = {k: v for (k, v) in request.GET.items()} if request.GET.get("next"): nxt = kw_args.pop("next") if kw_args: redirect_url = reverse(nxt, kwargs=kw_args) try: if kw_args["stage"] == "complete": redirect_url = "/" except KeyError: pass else: redirect_url = reverse(nxt) storage["feedback_redirect"] = redirect_url if not storage.get("user_agent"): storage["user_agent"] = request.META["HTTP_USER_AGENT"] if not stage: stage = FeedbackForms.stage_classes[0].name return HttpResponseRedirect(reverse_lazy("feedback_form_step", args=(stage,))) form = FeedbackForms(storage, stage) redirect = form.load(RequestContext(request)) if redirect: return redirect form.process_messages(request) if stage == "complete": redirect_url = storage.get("feedback_redirect", "/") self.clear_storage(request, "feedback_data") return HttpResponseRedirect(redirect_url) return form.render() @method_decorator(ratelimit(block=True, rate=settings.RATE_LIMIT)) def post(self, request, stage): storage = self.get_storage(request, "feedback_data") nxt = request.GET.get("next", None) form = FeedbackForms(storage, stage) form.save(request.POST, RequestContext(request), nxt) form.process_messages(request) request.session.modified = True return form.render()
def test_dont_use_request_path(self): """Test use_request_path=False for the same view function above""" cache.set(self.KEYS.fake_login_path_ip_60, (6, time.time() + 120)) rl = ratelimit(method='POST', use_request_path=False, rate='5/m', block=True) result = self.client.post(rl(fake_login_use_request_path), self.bad_payload) self.assertEqual(result.status_code, 200)
def test_use_request_path(self): """Test use_request_path=True = use request.path instead of view function name in cache key""" cache.set(self.KEYS.fake_login_path_ip_60, (6, time.time() + 120)) rl = ratelimit(method='POST', use_request_path=True, rate='5/m', block=True) result = self.client.post(rl(fake_login_use_request_path), self.bad_payload) self.assertEqual(result.status_code, 429)
def dispatch(self, *args, **kwargs): return ratelimit( **self.get_ratelimit_config() )(super(RatelimitMixin, self).dispatch)(*args, **kwargs)
class FeedbackViews(StorageView): start = "service" def __init__(self, *args, **kwargs): super(FeedbackViews, self).__init__(*args, **kwargs) self.storage = {} def dispatch(self, request, *args, **kwargs): self.storage = self.get_storage(request, "feedback_data") self.redirect_url = self.storage.get("feedback_redirect", "/") # If the session has timed out, redirect to start page if not request.session.get("feedback_data") and kwargs.get( "stage", self.start) != self.start: return HttpResponseRedirect(self.redirect_url) return super(FeedbackViews, self).dispatch(request, *args, **kwargs) def get(self, request, stage=None): kw_args = {k: v for (k, v) in request.GET.items()} if request.GET.get("next"): nxt = kw_args.pop("next") if kw_args: redirect_url = reverse(nxt, kwargs=kw_args) try: if kw_args["stage"] == "complete": redirect_url = "/" except KeyError: pass else: if nxt == "plea_form_step": nxt = "plea_form" redirect_url = reverse(nxt) self.storage["feedback_redirect"] = redirect_url if not self.storage.get("user_agent"): self.storage["user_agent"] = request.META["HTTP_USER_AGENT"] if not stage: stage = FeedbackForms.stage_classes[0].name return HttpResponseRedirect( reverse_lazy("feedback_form_step", args=(stage, ))) form = FeedbackForms(self.storage, stage) redirect = form.load(RequestContext(request)) if redirect: return redirect form.process_messages(request) if stage == "complete": self.clear_storage(request, "feedback_data") return form.render(request) @method_decorator(ratelimit(block=True, rate=settings.RATE_LIMIT)) def post(self, request, stage): nxt = request.GET.get("next", None) form = FeedbackForms(self.storage, stage) form.save(request.POST, RequestContext(request), nxt) form.process_messages(request) request.session.modified = True return form.render(request)
def dispatch(self, *args, **kwargs): return ratelimit(**self.get_ratelimit_config())(super( RatelimitMixin, self).dispatch)(*args, **kwargs)