comparison antispam/decorators.py @ 581:ee87ea74d46b

For Django 1.4, rearranged project structure for new manage.py.
author Brian Neal <bgneal@gmail.com>
date Sat, 05 May 2012 17:10:48 -0500
parents gpp/antispam/decorators.py@a5d11471d031
children 89b240fe9297
comparison
equal deleted inserted replaced
580:c525f3e0b5d0 581:ee87ea74d46b
1 """
2 This module contains decorators for the antispam application.
3
4 """
5 from datetime import timedelta
6 from functools import wraps
7
8 from django.shortcuts import render
9 from django.utils import simplejson
10
11 from antispam.rate_limit import RateLimiter, RateLimiterUnavailable
12
13
14 def rate_limit(count=10, interval=timedelta(minutes=1),
15 lockout=timedelta(hours=8)):
16
17 def decorator(fn):
18
19 @wraps(fn)
20 def wrapped(request, *args, **kwargs):
21
22 ip = request.META.get('REMOTE_ADDR')
23 try:
24 rate_limiter = RateLimiter(ip, count, interval, lockout)
25 if rate_limiter.is_blocked():
26 return render(request, 'antispam/blocked.html', status=403)
27
28 except RateLimiterUnavailable:
29 # just call the function and return the result
30 return fn(request, *args, **kwargs)
31
32 response = fn(request, *args, **kwargs)
33
34 if request.method == 'POST':
35
36 # Figure out if the view succeeded; if it is a non-ajax view,
37 # then success means a redirect is about to occur. If it is
38 # an ajax view, we have to decode the json response.
39 success = False
40 if not request.is_ajax():
41 success = (response and response.has_header('location') and
42 response.status_code == 302)
43 elif response:
44 json_resp = simplejson.loads(response.content)
45 success = json_resp['success']
46
47 if not success:
48 try:
49 blocked = rate_limiter.incr()
50 except RateLimiterUnavailable:
51 blocked = False
52
53 if blocked:
54 return render(request, 'antispam/blocked.html', status=403)
55
56 return response
57
58 return wrapped
59 return decorator