84 lines
3.2 KiB
Python
84 lines
3.2 KiB
Python
from django.http import HttpResponseRedirect
|
|
from django.conf import settings
|
|
import re
|
|
|
|
class EnforceLoginMiddleware(object):
|
|
"""
|
|
Middlware class which requires the user to be authenticated for all urls except
|
|
those defined in PUBLIC_URLS in settings.py. PUBLIC_URLS should be a tuple of regular
|
|
expresssions for the urls you want anonymous users to have access to. If PUBLIC_URLS
|
|
is not defined, it falls back to LOGIN_URL or failing that '/accounts/login/'.
|
|
Requests for urls not matching PUBLIC_URLS get redirected to LOGIN_URL with next set
|
|
to original path of the unauthenticted request.
|
|
Any urls statically served by django are excluded from this check. To enforce the same
|
|
validation on these set SERVE_STATIC_TO_PUBLIC to False.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.login_url = getattr(settings, 'LOGIN_URL', '/accounts/login/' )
|
|
|
|
if hasattr(settings,'PUBLIC_URLS'):
|
|
public_urls = [re.compile(url) for url in settings.PUBLIC_URLS]
|
|
else:
|
|
public_urls = [(re.compile("^%s/?$" % ( self.login_url[1:] )))]
|
|
if getattr(settings, 'SERVE_STATIC_TO_PUBLIC', True ):
|
|
root_urlconf = __import__(settings.ROOT_URLCONF)
|
|
public_urls.extend([ re.compile(url.regex)
|
|
for url in root_urlconf.urls.urlpatterns
|
|
if url.__dict__.get('_callback_str') == 'django.views.static.serve'
|
|
])
|
|
self.public_urls = tuple(public_urls)
|
|
|
|
def process_request(self, request):
|
|
"""
|
|
Redirect anonymous users to login_url from non public urls
|
|
"""
|
|
try:
|
|
if request.user.is_anonymous():
|
|
for url in self.public_urls:
|
|
if url.match(request.path[1:]):
|
|
return None
|
|
return HttpResponseRedirect("%s?next=%s" % (self.login_url, request.path))
|
|
except AttributeError:
|
|
return HttpResponseRedirect("%s?next=%s" % (self.login_url, request.path))
|
|
|
|
|
|
|
|
class DetectDevice(object):
|
|
|
|
def process_request(self, request):
|
|
device = self.mobile(request)
|
|
|
|
request.device = device
|
|
|
|
def mobile(self, request):
|
|
device = {}
|
|
|
|
ua = request.META.get('HTTP_USER_AGENT', '').lower()
|
|
|
|
if ua.find("iphone") > 0:
|
|
device['iphone'] = "iphone" + re.search("iphone os (\d)", ua).groups(0)[0]
|
|
|
|
if ua.find("ipad") > 0:
|
|
device['ipad'] = "ipad"
|
|
|
|
if ua.find("android") > 0:
|
|
device['android'] = "android" + re.search("android (\d\.\d)", ua).groups(0)[0].translate(None, '.')
|
|
|
|
if ua.find("blackberry") > 0:
|
|
device['blackberry'] = "blackberry"
|
|
|
|
if ua.find("windows phone os 7") > 0:
|
|
device['winphone7'] = "winphone7"
|
|
|
|
if ua.find("iemobile") > 0:
|
|
device['winmo'] = "winmo"
|
|
|
|
if not device: # either desktop, or something we don't care about.
|
|
device['baseline'] = "baseline"
|
|
|
|
# spits out device names for CSS targeting, to be applied to <html> or <body>.
|
|
device['classes'] = " ".join(v for (k,v) in device.items())
|
|
|
|
return device
|