Package madrona :: Package common :: Module basic_auth
[hide private]

Source Code for Module madrona.common.basic_auth

  1  import base64 
  2   
  3  from django.http import HttpResponse 
  4  from django.contrib.auth import authenticate, login 
  5   
  6  ############################################################################# 
  7  # 
8 -def view_or_basicauth(view, request, test_func, realm="", *args, **kwargs):
9 """ 10 This is a helper function used by both 'logged_in_or_basicauth' and 11 'has_perm_or_basicauth' that does the nitty of determining if they 12 are already logged in or if they have provided proper http-authorization 13 and returning the view if all goes well, otherwise responding with a 401. 14 """ 15 if test_func(request.user): 16 # Already logged in, just return the view. 17 # 18 return view(request, *args, **kwargs) 19 20 # They are not logged in. See if they provided login credentials 21 # 22 if 'HTTP_AUTHORIZATION' in request.META: 23 auth = request.META['HTTP_AUTHORIZATION'].split() 24 if len(auth) == 2: 25 # NOTE: We are only support basic authentication for now. 26 # 27 if auth[0].lower() == "basic": 28 uname, passwd = base64.b64decode(auth[1]).split(':') 29 user = authenticate(username=uname, password=passwd) 30 if user is not None: 31 if user.is_active: 32 login(request, user) 33 request.user = user 34 return view(request, *args, **kwargs) 35 36 # Either they did not provide an authorization header or 37 # something in the authorization attempt failed. Send a 401 38 # back to them to ask them to authenticate. 39 # 40 response = HttpResponse() 41 response.status_code = 401 42 response['WWW-Authenticate'] = 'Basic realm="%s"' % realm 43 return response
44 45 ############################################################################# 46 #
47 -def logged_in_or_basicauth(realm=""):
48 """ 49 A simple decorator that requires a user to be logged in. If they are not 50 logged in the request is examined for a 'authorization' header. 51 52 If the header is present it is tested for basic authentication and 53 the user is logged in with the provided credentials. 54 55 If the header is not present a http 401 is sent back to the 56 requestor to provide credentials. 57 58 The purpose of this is that in several django projects I have needed 59 several specific views that need to support basic authentication, yet the 60 web site as a whole used django's provided authentication. 61 62 The uses for this are for urls that are access programmatically such as 63 by rss feed readers, yet the view requires a user to be logged in. Many rss 64 readers support supplying the authentication credentials via http basic 65 auth (and they do NOT support a redirect to a form where they post a 66 username/password.) 67 68 Use is simple: 69 70 @logged_in_or_basicauth 71 def your_view: 72 ... 73 74 You can provide the name of the realm to ask for authentication within. 75 """ 76 def view_decorator(func): 77 def wrapper(request, *args, **kwargs): 78 return view_or_basicauth(func, request, 79 lambda u: u.is_authenticated(), 80 realm, *args, **kwargs)
81 return wrapper 82 return view_decorator 83 84 ############################################################################# 85 #
86 -def has_perm_or_basicauth(perm, realm=""):
87 """ 88 This is similar to the above decorator 'logged_in_or_basicauth' 89 except that it requires the logged in user to have a specific 90 permission. 91 92 Use: 93 94 @logged_in_or_basicauth('asforums.view_forumcollection') 95 def your_view: 96 ... 97 98 """ 99 def view_decorator(func): 100 def wrapper(request, *args, **kwargs): 101 return view_or_basicauth(func, request, 102 lambda u: u.has_perm(perm), 103 realm, *args, **kwargs)
104 return wrapper 105 return view_decorator 106