PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/django/contrib/auth/__init__.py

https://github.com/insane/django
Python | 147 lines | 105 code | 16 blank | 26 comment | 12 complexity | 69852bf345c74d296b743e1814f95cde MD5 | raw file
Possible License(s): BSD-3-Clause
  1. import re
  2. from django.conf import settings
  3. from django.core.exceptions import ImproperlyConfigured, PermissionDenied
  4. from django.utils.module_loading import import_by_path
  5. from django.middleware.csrf import rotate_token
  6. from .signals import user_logged_in, user_logged_out, user_login_failed
  7. SESSION_KEY = '_auth_user_id'
  8. BACKEND_SESSION_KEY = '_auth_user_backend'
  9. REDIRECT_FIELD_NAME = 'next'
  10. def load_backend(path):
  11. return import_by_path(path)()
  12. def get_backends():
  13. backends = []
  14. for backend_path in settings.AUTHENTICATION_BACKENDS:
  15. backends.append(load_backend(backend_path))
  16. if not backends:
  17. raise ImproperlyConfigured('No authentication backends have been defined. Does AUTHENTICATION_BACKENDS contain anything?')
  18. return backends
  19. def _clean_credentials(credentials):
  20. """
  21. Cleans a dictionary of credentials of potentially sensitive info before
  22. sending to less secure functions.
  23. Not comprehensive - intended for user_login_failed signal
  24. """
  25. SENSITIVE_CREDENTIALS = re.compile('api|token|key|secret|password|signature', re.I)
  26. CLEANSED_SUBSTITUTE = '********************'
  27. for key in credentials:
  28. if SENSITIVE_CREDENTIALS.search(key):
  29. credentials[key] = CLEANSED_SUBSTITUTE
  30. return credentials
  31. def authenticate(**credentials):
  32. """
  33. If the given credentials are valid, return a User object.
  34. """
  35. for backend in get_backends():
  36. try:
  37. user = backend.authenticate(**credentials)
  38. except TypeError:
  39. # This backend doesn't accept these credentials as arguments. Try the next one.
  40. continue
  41. except PermissionDenied:
  42. # This backend says to stop in our tracks - this user should not be allowed in at all.
  43. return None
  44. if user is None:
  45. continue
  46. # Annotate the user object with the path of the backend.
  47. user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
  48. return user
  49. # The credentials supplied are invalid to all backends, fire signal
  50. user_login_failed.send(sender=__name__,
  51. credentials=_clean_credentials(credentials))
  52. def login(request, user):
  53. """
  54. Persist a user id and a backend in the request. This way a user doesn't
  55. have to reauthenticate on every request. Note that data set during
  56. the anonymous session is retained when the user logs in.
  57. """
  58. if user is None:
  59. user = request.user
  60. # TODO: It would be nice to support different login methods, like signed cookies.
  61. if SESSION_KEY in request.session:
  62. if request.session[SESSION_KEY] != user.pk:
  63. # To avoid reusing another user's session, create a new, empty
  64. # session if the existing session corresponds to a different
  65. # authenticated user.
  66. request.session.flush()
  67. else:
  68. request.session.cycle_key()
  69. request.session[SESSION_KEY] = user.pk
  70. request.session[BACKEND_SESSION_KEY] = user.backend
  71. if hasattr(request, 'user'):
  72. request.user = user
  73. rotate_token(request)
  74. user_logged_in.send(sender=user.__class__, request=request, user=user)
  75. def logout(request):
  76. """
  77. Removes the authenticated user's ID from the request and flushes their
  78. session data.
  79. """
  80. # Dispatch the signal before the user is logged out so the receivers have a
  81. # chance to find out *who* logged out.
  82. user = getattr(request, 'user', None)
  83. if hasattr(user, 'is_authenticated') and not user.is_authenticated():
  84. user = None
  85. user_logged_out.send(sender=user.__class__, request=request, user=user)
  86. request.session.flush()
  87. if hasattr(request, 'user'):
  88. from django.contrib.auth.models import AnonymousUser
  89. request.user = AnonymousUser()
  90. def get_user_model():
  91. """
  92. Returns the User model that is active in this project.
  93. """
  94. from django.db.models import get_model
  95. try:
  96. app_label, model_name = settings.AUTH_USER_MODEL.split('.')
  97. except ValueError:
  98. raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
  99. user_model = get_model(app_label, model_name)
  100. if user_model is None:
  101. raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)
  102. return user_model
  103. def get_user(request):
  104. """
  105. Returns the user model instance associated with the given request session.
  106. If no user is retrieved an instance of `AnonymousUser` is returned.
  107. """
  108. from .models import AnonymousUser
  109. try:
  110. user_id = request.session[SESSION_KEY]
  111. backend_path = request.session[BACKEND_SESSION_KEY]
  112. assert backend_path in settings.AUTHENTICATION_BACKENDS
  113. backend = load_backend(backend_path)
  114. user = backend.get_user(user_id) or AnonymousUser()
  115. except (KeyError, AssertionError):
  116. user = AnonymousUser()
  117. return user
  118. def get_permission_codename(action, opts):
  119. """
  120. Returns the codename of the permission for the specified action.
  121. """
  122. return '%s_%s' % (action, opts.model_name)