Django

Code

ContributedMiddleware: SSLMiddleware.py

File SSLMiddleware.py, 2.8 kB (added by sjzabel@gmail.com, 1 year ago)

Contains an urls.py based SSL approach

Line 
1 """
2 SSL Middleware
3 Stephen Zabel
4
5 This middleware answers the problem of redirecting of redirecting to SSL secured
6 directly in the urls.py file. To secure a path, add the additional view_kwarg
7 'SSL':True to the view_kwargs. For example
8
9 urlpatterns = patterns('some_site.some_app.views',
10     (r'^test/secure/$','test_secure',{'SSL':True}),
11      )
12
13 All paths where 'SSL':False or where the kwarg of 'SSL' is not specified are routed
14 to an unsecure path. For example
15
16 urlpatterns = patterns('some_site.some_app.views',
17     (r'^test/unsecure1/$','test_unsecure',{'SSL':False}),
18     (r'^test/unsecure2/$','test_unsecure'),
19      )
20
21 Gotcha's : Redirects should only occur during GETs; this is due to the fact that
22 POST data will get lost in the redirect.
23
24 A major benefit of this approach is that it allows you to secure django.contrib views
25 and generic views without having to modify the base code or wrapping the view.
26
27 This method is also better than the two alternative approaches of adding to the
28 settings file or using a decorator.
29
30 It is better than the tactic of creating a list of paths to secure in the settings
31 file, because you DRY. You are also not forced to consider all paths in a single
32 location. Instead you can address the security of a path in the urls file that it
33 is resolved in.
34
35 It is better than the tactic of using a @secure or @unsecure decorator, because
36 it prevents decorator build up on your view methods. Having a bunch of decorators
37 makes views cumbersome to read and looks pretty redundant. Also because the all
38 views pass through the middleware you can specify the only secure paths and the
39 remaining paths can be assumed to be unsecure and handled by the middleware.
40
41 This package is inspired by Antonio Cavedoni's SSL Middleware
42 """
43
44 __license__ = "Python"
45 __copyright__ = "Copyright (C) 2007, Stephen Zabel"
46 __author__ = "Stephen Zabel"
47
48
49 from django.conf import settings
50 from django.http import HttpResponseRedirect, get_host
51
52 SSL = 'SSL'
53
54 class SSLRedirect:
55     def process_view(self, request, view_func, view_args, view_kwargs):
56         if SSL in view_kwargs:
57             secure = view_kwargs[SSL]
58             del view_kwargs[SSL]
59         else:
60             secure = False
61
62         if not secure == request.is_secure():
63             return self._redirect(request, secure)
64
65     def _redirect(self, request, secure):
66         protocol = secure and "https" or "http"
67         newurl = "%s://%s%s" % (protocol,
68                                                                                   get_host(request),
69                                                                                   request.get_full_path())
70
71         if settings.DEBUG and request.method == 'POST':
72             raise RuntimeError, \
73 """Django can't perform a SSL redirect while maintaining POST data.
74 Please structure your views so that redirects only occur during GETs."""
75
76         return HttpResponseRedirect(newurl)