Ticket #5612: 5612.diff

File 5612.diff, 7.1 KB (added by Chris Beaven, 14 years ago)
  • django/contrib/auth/__init__.py

    diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
    index 169ae01..2d6511d 100644
    a b import datetime  
    22from warnings import warn
    33from django.core.exceptions import ImproperlyConfigured
    44from django.utils.importlib import import_module
     5from django.contrib.auth import signals
    56
    67SESSION_KEY = '_auth_user_id'
    78BACKEND_SESSION_KEY = '_auth_user_backend'
    def login(request, user):  
    6566    if user is None:
    6667        user = request.user
    6768    # TODO: It would be nice to support different login methods, like signed cookies.
    68     user.last_login = datetime.datetime.now()
    69     user.save()
     69    signals.user_logged_in.send(sender=user.__class__, request=request,
     70                                user=user)
    7071
    7172    if SESSION_KEY in request.session:
    7273        if request.session[SESSION_KEY] != user.id:
    def logout(request):  
    8687    Removes the authenticated user's ID from the request and flushes their
    8788    session data.
    8889    """
     90    # Dispatch the signal before the user is logged out so the receivers have a
     91    # chance to find out *who* logged out.
     92    user = getattr(request, 'user', None)
     93    if hasattr(user, 'is_authenticated') and not user.is_authenticated():
     94        user = None
     95    signals.user_logged_out.send(sender=user.__class__, request=request,
     96                                 user=user)
     97
    8998    request.session.flush()
    9099    if hasattr(request, 'user'):
    91100        from django.contrib.auth.models import AnonymousUser
  • django/contrib/auth/models.py

    diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
    index 681cf14..551410c 100644
    a b import datetime  
    22import urllib
    33
    44from django.contrib import auth
     5from django.contrib.auth import signals
    56from django.core.exceptions import ImproperlyConfigured
    67from django.db import models
    78from django.db.models.manager import EmptyManager
  • new file django/contrib/auth/signals.py

    diff --git a/django/contrib/auth/signals.py b/django/contrib/auth/signals.py
    new file mode 100644
    index 0000000..ae66b6d
    - +  
     1import datetime
     2import django.dispatch
     3
     4user_logged_in = django.dispatch.Signal(providing_args=['request', 'user'])
     5user_logged_out = django.dispatch.Signal(providing_args=['request', 'user'])
     6
     7
     8def update_last_login(sender, user, **kwargs):
     9    """
     10    A signal receiver which updates the last_login date for the user logging
     11    in.
     12
     13    """
     14    user.last_login = datetime.datetime.now()
     15    user.save()
     16
     17
     18user_logged_in.connect(update_last_login)
  • django/contrib/auth/tests/__init__.py

    diff --git a/django/contrib/auth/tests/__init__.py b/django/contrib/auth/tests/__init__.py
    index 965ea2d..226c284 100644
    a b from django.contrib.auth.tests.forms import FORM_TESTS  
    55from django.contrib.auth.tests.remote_user \
    66        import RemoteUserTest, RemoteUserNoCreateTest, RemoteUserCustomTest
    77from django.contrib.auth.tests.models import ProfileTestCase
     8from django.contrib.auth.tests.signals import SignalTestCase
    89from django.contrib.auth.tests.tokens import TOKEN_GENERATOR_TESTS
    910from django.contrib.auth.tests.views \
    1011        import PasswordResetTest, ChangePasswordTest, LoginTest, LogoutTest
  • new file django/contrib/auth/tests/signals.py

    diff --git a/django/contrib/auth/tests/signals.py b/django/contrib/auth/tests/signals.py
    new file mode 100644
    index 0000000..3806021
    - +  
     1from django.test import TestCase
     2from django.contrib.auth import signals
     3
     4
     5class SignalTestCase(TestCase):
     6    urls = 'django.contrib.auth.tests.urls'
     7    fixtures = ['authtestdata.json']
     8
     9    def listener_login(self, user, **kwargs):
     10        self.logged_in.append(user)
     11
     12    def listener_logout(self, user, **kwargs):
     13        self.logged_out.append(user)
     14
     15    def setUp(self):
     16        """Set up the listeners and reset the logged in/logged out counters"""
     17        self.logged_in = []
     18        self.logged_out = []
     19        signals.user_logged_in.connect(self.listener_login)
     20        signals.user_logged_out.connect(self.listener_logout)
     21
     22    def tearDown(self):
     23        """Disconnect the listeners"""
     24        signals.user_logged_in.disconnect(self.listener_login)
     25        signals.user_logged_out.disconnect(self.listener_logout)
     26
     27    def test_login(self):
     28        # Only a successful login will trigger the signal.
     29        self.client.login(username='testclient', password='bad')
     30        self.assertEqual(len(self.logged_in), 0)
     31        # Like this:
     32        self.client.login(username='testclient', password='password')
     33        self.assertEqual(len(self.logged_in), 1)
     34        self.assertEqual(self.logged_in[0].username, 'testclient')
     35
     36    def test_logout_anonymous(self):
     37        # The log_out function will still trigger the signal for anonymous
     38        # users.
     39        self.client.get('/logout/next_page/')
     40        self.assertEqual(len(self.logged_out), 1)
     41        self.assertEqual(self.logged_out[0], None)
     42
     43    def test_logout(self):
     44        self.client.login(username='testclient', password='password')
     45        self.client.get('/logout/next_page/')
     46        self.assertEqual(len(self.logged_out), 1)
     47        self.assertEqual(self.logged_out[0].username, 'testclient')
  • docs/ref/signals.txt

    diff --git a/docs/ref/signals.txt b/docs/ref/signals.txt
    index d79232e..290acf7 100644
    a b A list of all the signals that Django sends.  
    1414    The :ref:`comment framework <ref-contrib-comments-index>` sends a :ref:`set
    1515    of comment-related signals <ref-contrib-comments-signals>`.
    1616
     17    The :ref:`authentication framework <topics-auth>` sends :ref:`signals when
     18    a user is logged in / out <topics-auth-signals>`.
     19
    1720Model signals
    1821=============
    1922
  • docs/topics/auth.txt

    diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
    index d796625..f8f19d7 100644
    a b How to log a user out  
    667667    immediately after logging out, do that *after* calling
    668668    :func:`django.contrib.auth.logout()`.
    669669
     670.. _topics-auth-signals:
     671
     672Login and logout signals
     673------------------------
     674
     675The auth framework uses two :ref:`signals <topic-signals>` that can be used for
     676notification when a user logs in or out.
     677
     678**:data:`django.contrib.auth.signals.user_logged_in`**
     679
     680Sent when a user logs in successfully.
     681
     682Arguments sent with this signal:
     683
     684    ``sender``
     685        As above: the class of the user that just logged in.
     686
     687    ``request``
     688        The current :class:`~django.http.HttpRequest` instance.
     689
     690    ``user``
     691        The user instance that just logged in.
     692
     693**:data:`django.contrib.auth.signals.user_logged_out`**   
     694
     695Sent when the logout method is called.
     696
     697    ``sender``
     698        As above: the class of the user that just logged out or ``None``
     699        if the user was not authenticated.
     700
     701    ``request``
     702        The current :class:`~django.http.HttpRequest` instance.
     703
     704    ``user``
     705        The user instance that just logged out or ``None`` if the
     706        user was not authenticated.
     707
    670708Limiting access to logged-in users
    671709----------------------------------
    672710
Back to Top