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

Michael Farrell Florian Apolloner Brad Pitcher Jannis Leidel
Michael Farrell

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 Pitcher

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.

Michael Farrell 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
Florian Apolloner
Owner

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

Brad Pitcher

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

Brad Pitcher

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.

Michael Farrell

Done.

Brad Pitcher

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.

Jannis Leidel
Owner

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

Brad Pitcher

Sorry, my mistake.

Michael Farrell

Merged Brad's documentation fixes.

Brad Pitcher

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.

Florian Apolloner
Owner

This was fixed in 7cc4068

Florian Apolloner 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. Michael Farrell
  2. Michael Farrell
  3. Brad Pitcher
  4. Michael Farrell

    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 Pitcher
  2. Brad Pitcher
Commits on Jul 18, 2012
  1. Brad Pitcher

    fix copy/pasted sender doc

    brad authored
Commits on Jul 23, 2012
  1. Michael Farrell
Commits on Sep 8, 2012
  1. Brad Pitcher

    fix docs merge conflict

    brad authored
Commits on Sep 17, 2012
  1. Michael Farrell

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

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

    Merge branch 'django/master' into ticket_18686

    micolous authored
    Resolved Conflicts:
    	docs/releases/1.5.txt
Commits on Sep 18, 2012
  1. Michael Farrell
This page is out of date. Refresh to see the latest.
5 django/contrib/auth/__init__.py
View
@@ -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):
"""
1  django/contrib/auth/signals.py
View
@@ -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'])
14 django/contrib/auth/tests/signals.py
View
@@ -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.
4 docs/releases/1.5.txt
View
@@ -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
21 docs/topics/auth.txt
View
@@ -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.