Guest User

Untitled

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