My app seeks to wrap the django.contrib.auth.views login and logout views with some basic auditing/logging capabilities. I'm following the prescription as described in the django-axes project, and in running on a server and some other tests, it works as expected, transparently without issue.
The code goes like this:
from django.contrib.auth import views as auth_views
from myapp.watchers import watch_login
class WatcherMiddleware(object):
def __init__(self):
auth_views.login = watch_login(auth_views.login)
And
def watch_login(func):
def decorated_login(request, *args, **kwargs):
#do some stuff
response = func(request, *args, **kwargs)
#more stuff
return response
return decorated_login
Urls:
#Edit: Added project's urls - just using vanilla django's auth login
(r'^accounts/login/$', 'django.contrib.auth.views.login',{"template_name":settings.LOGIN_TEMPLATE }),
However, in our build workflow, we run into some issues in the django.contrib.auth.tests.views.
Specifically, these are the tests that fail in django.contrib.auth:
ERROR: test_current_site_in_context_after_login (django.contrib.auth.tests.views.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python26\lib\site-packages\django\contrib\auth\tests\views.py", line 192, in test_current_site_in_context_after_login
response = self.client.get(reverse('django.contrib.auth.views.login'))
File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 351, in reverse
*args, **kwargs)))
File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 297, in reverse
"arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'myapp.watchers.decorated_login' with arguments '()' and keyword arguments '{}' not found.
======================================================================
ERROR: test_security_check (django.contrib.auth.tests.views.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python26\lib\site-packages\django\contrib\auth\tests\views.py", line 204, in test_security_check
login_url = reverse('django.contrib.auth.views.login')
File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 351, in reverse
*args, **kwargs)))
File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 297, in reverse
"arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'myapp.watchers.decorated_login' with arguments '()' and keyword arguments '{}' not found.
Only these two tests fail with the inclusion of the wrapped login monkey patch.
It seems like the reverse() call in the django auth test behaves differently than how an unpatched function does its thing.
The reason why we're going this route for wrapping logging vs. using django 1.3's new authentication signals is because the logging method provided there only tells you if a wrong attempts happens - it doesn't give you access to the request object to log additional information around that improper request. Patching the authentication form in that case would not have been helpful, hence our need to wrap the login function.
Am I doing something wrong with my wrap of the login function? Or is this as to be expected with tests failing due to other side effects, despite no change in overall functionality?
edit: I'm running python 2.6.4, django 1.2.5
Couldn't you simply wrap it in another view?
urls
:
url(
r'^accounts/login/$',
'accounts.views.login',
{"template_name":settings.LOGIN_TEMPLATE }
),
accounts.views
:
from django.contrib.auth import views as auth_views
def login(request, *args, **kwars):
# do some stuff
response = auth_views.login(request, *args, **kwars)
# more stuff
return response
Like this, django.contrib.auth.tests
will be testing the view which they were written for and you can write your own tests for the "more stuff" you need.