Mercurial > public > sg101
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 |