Mercurial > public > sg101
view antispam/decorators.py @ 628:c6292e46e617
For local testing, set wiki cookie domain to None.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Mon, 12 Nov 2012 16:40:54 -0600 |
parents | ee87ea74d46b |
children | 89b240fe9297 |
line wrap: on
line source
""" This module contains decorators for the antispam application. """ from datetime import timedelta from functools import wraps from django.shortcuts import render from django.utils import simplejson from antispam.rate_limit import RateLimiter, RateLimiterUnavailable def rate_limit(count=10, interval=timedelta(minutes=1), lockout=timedelta(hours=8)): def decorator(fn): @wraps(fn) def wrapped(request, *args, **kwargs): ip = request.META.get('REMOTE_ADDR') try: rate_limiter = RateLimiter(ip, count, interval, lockout) if rate_limiter.is_blocked(): return render(request, 'antispam/blocked.html', status=403) except RateLimiterUnavailable: # just call the function and return the result return fn(request, *args, **kwargs) response = fn(request, *args, **kwargs) if request.method == 'POST': # Figure out if the view succeeded; if it is a non-ajax view, # then success means a redirect is about to occur. If it is # an ajax view, we have to decode the json response. success = False if not request.is_ajax(): success = (response and response.has_header('location') and response.status_code == 302) elif response: json_resp = simplejson.loads(response.content) success = json_resp['success'] if not success: try: blocked = rate_limiter.incr() except RateLimiterUnavailable: blocked = False if blocked: return render(request, 'antispam/blocked.html', status=403) return response return wrapped return decorator