Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Ticket #18616: contrib.auth signal user_login_fail #201

Closed
wants to merge 12 commits into from

4 participants

@micolous

https://code.djangoproject.com/ticket/18616

Note: it seems I made a typo on the branch name, it is ticket_18686 instead of ticket_18616.

@brad

I personally think user_login_failed would be a better name for this signal, to better match the verb form of the other two.

You raise a good point Brad, I'll update this pull request with another commit changing to this.

@micolous micolous per a suggestion by Brad Pitcher, I have changed the signal name to "…
…user_login_failed" to match the verb tense of the other signals emitted by contrib.auth.
3918f25
@apollo13
Owner

@brad, @micolous Please incorporate the Doc PR into this PR.

@brad

I'll send a pull request your way, @micolous

@brad

GitHub won't let me send you a pull request, even when I branch directly from you. If you like you could pull my ticket_18616_docs branch to get the docs. I made updated to the sender documentation.

@micolous

Done.

@brad

Sorry, looks like I forgot to get that sender doc change in that branch. I have made the change now if you want to pull again.

@jezdez
Owner

Remember folks to always mention in the ticket which pull request is the correct one!

@brad

Sorry, my mistake.

@micolous

Merged Brad's documentation fixes.

@brad

This patch no longer applies cleanly to master. Can you fix it, or pull from https://github.com/brad/django/tree/ticket_18616. We are in the middle of a sprint so we may manage to get it merged in today.

@apollo13
Owner

This was fixed in 7cc4068

@apollo13 apollo13 closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 12, 2012
  1. @micolous
  2. @micolous
  3. @brad
  4. @micolous

    per a suggestion by Brad Pitcher, I have changed the signal name to "…

    micolous authored
    …user_login_failed" to match the verb tense of the other signals emitted by contrib.auth.
Commits on Jul 17, 2012
  1. @brad
  2. @brad
Commits on Jul 18, 2012
  1. @brad

    fix copy/pasted sender doc

    brad authored
Commits on Jul 23, 2012
  1. @micolous
Commits on Sep 8, 2012
  1. @brad

    fix docs merge conflict

    brad authored
Commits on Sep 17, 2012
  1. @micolous

    Merge branch 'ticket_18616' of git://github.com/brad/django into tick…

    micolous authored
    …et_18686
    
    Resolved Conflicts:
    	docs/releases/1.5.txt
  2. @micolous

    Merge branch 'django/master' into ticket_18686

    micolous authored
    Resolved Conflicts:
    	docs/releases/1.5.txt
Commits on Sep 18, 2012
  1. @micolous
This page is out of date. Refresh to see the latest.
View
5 django/contrib/auth/__init__.py
@@ -1,6 +1,6 @@
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module
-from django.contrib.auth.signals import user_logged_in, user_logged_out
+from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
SESSION_KEY = '_auth_user_id'
BACKEND_SESSION_KEY = '_auth_user_backend'
@@ -45,6 +45,9 @@ def authenticate(**credentials):
# Annotate the user object with the path of the backend.
user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
return user
+
+ # The credentials supplied are invalid to all backends, fire signal
+ user_login_failed.send(sender=__name__, credentials=credentials)
def login(request, user):
"""
View
1  django/contrib/auth/signals.py
@@ -1,4 +1,5 @@
from django.dispatch import Signal
user_logged_in = Signal(providing_args=['request', 'user'])
+user_login_failed = Signal(providing_args=['credentials'])
user_logged_out = Signal(providing_args=['request', 'user'])
View
14 django/contrib/auth/tests/signals.py
@@ -16,27 +16,39 @@ def listener_login(self, user, **kwargs):
def listener_logout(self, user, **kwargs):
self.logged_out.append(user)
+ def listener_login_failed(self, sender, credentials, **kwargs):
+ self.login_failed.append(credentials['username'])
+
def setUp(self):
"""Set up the listeners and reset the logged in/logged out counters"""
self.logged_in = []
self.logged_out = []
+ self.login_failed = []
signals.user_logged_in.connect(self.listener_login)
signals.user_logged_out.connect(self.listener_logout)
+ signals.user_login_failed.connect(self.listener_login_failed)
def tearDown(self):
"""Disconnect the listeners"""
signals.user_logged_in.disconnect(self.listener_login)
signals.user_logged_out.disconnect(self.listener_logout)
+ signals.user_login_failed.disconnect(self.listener_login_failed)
def test_login(self):
- # Only a successful login will trigger the signal.
+ # Only a successful login will trigger the success signal.
self.client.login(username='testclient', password='bad')
self.assertEqual(len(self.logged_in), 0)
+ self.assertEqual(len(self.login_failed), 1)
+ self.assertEqual(self.login_failed[0], 'testclient')
+
# Like this:
self.client.login(username='testclient', password='password')
self.assertEqual(len(self.logged_in), 1)
self.assertEqual(self.logged_in[0].username, 'testclient')
+ # Ensure there were no more failures.
+ self.assertEqual(len(self.login_failed), 1)
+
def test_logout_anonymous(self):
# The log_out function will still trigger the signal for anonymous
# users.
View
4 docs/releases/1.5.txt
@@ -121,6 +121,10 @@ Django 1.5 also includes several smaller improvements worth noting:
argument. By default the batch_size is unlimited except for SQLite where
single batch is limited so that 999 parameters per query isn't exceeded.
+* :mod:`django.contrib.auth` provides a new signal that is emitted
+ whenever a user fails to login successfully. See
+ :data:`~django.contrib.auth.signals.user_login_failed`
+
* The :setting:`LOGIN_URL` and :setting:`LOGIN_REDIRECT_URL` settings now also
accept view function names and
:ref:`named URL patterns <naming-url-patterns>`. This allows you to reduce
View
21 docs/topics/auth.txt
@@ -866,13 +866,15 @@ The auth framework uses two :doc:`signals </topics/signals>` that can be used
for notification when a user logs in or out.
.. data:: django.contrib.auth.signals.user_logged_in
+ :module:
+.. versionadded:: 1.3
Sent when a user logs in successfully.
Arguments sent with this signal:
``sender``
- As above: the class of the user that just logged in.
+ The class of the user that just logged in.
``request``
The current :class:`~django.http.HttpRequest` instance.
@@ -881,6 +883,8 @@ Arguments sent with this signal:
The user instance that just logged in.
.. data:: django.contrib.auth.signals.user_logged_out
+ :module:
+.. versionadded:: 1.3
Sent when the logout method is called.
@@ -895,6 +899,21 @@ Sent when the logout method is called.
The user instance that just logged out or ``None`` if the
user was not authenticated.
+.. data:: django.contrib.auth.signals.user_login_failed
+ :module:
+.. versionadded:: 1.5
+
+Sent when the user failed to login successfully
+
+``sender``
+ The name of the module used for authentication.
+
+``credentials``
+ A dictonary of keyword arguments containing the user credentials that
+ were passed to :func:`~django.contrib.auth.authenticate()` or
+ your own custom authentication backend. Most of the time this dictionary
+ will just include ``username`` and ``password``.
+
Limiting access to logged-in users
----------------------------------
Something went wrong with that request. Please try again.