Index: django/contrib/admin/views/decorators.py =================================================================== --- django/contrib/admin/views/decorators.py (revision 4649) +++ django/contrib/admin/views/decorators.py (working copy) @@ -2,6 +2,7 @@ from django.conf import settings from django.contrib.auth.models import User from django.contrib.auth import authenticate, login +from django.contrib.auth.middleware import basic_challenge from django.shortcuts import render_to_response from django.utils.translation import gettext_lazy import base64, datetime, md5 @@ -11,6 +12,8 @@ LOGIN_FORM_KEY = 'this_is_the_login_form' def _display_login_form(request, error_message=''): + if getattr(settings, 'BASIC_WWW_AUTHENTICATION', False): + return basic_challenge() request.session.set_test_cookie() if request.POST and request.POST.has_key('post_data'): # User has failed login BUT has previously saved post data. Index: django/contrib/auth/middleware.py =================================================================== --- django/contrib/auth/middleware.py (revision 4649) +++ django/contrib/auth/middleware.py (working copy) @@ -1,3 +1,40 @@ +from django.conf import settings +from django.http import HttpResponse + +from django.contrib.auth import authenticate, login, logout + +def basic_challenge(realm = None): + if realm is None: + realm = getattr(settings, 'WWW_AUTHENTICATION_REALM', _('Restricted Access')) + # TODO: Make a nice template for a 401 message? + response = HttpResponse(_('Authorization Required'), mimetype="text/plain") + response['WWW-Authenticate'] = 'Basic realm="%s"' % (realm) + response.status_code = 401 + return response + +def basic_authenticate(authentication): + # Taken from paste.auth + (authmeth, auth) = authentication.split(' ',1) + if 'basic' != authmeth.lower(): + return None + auth = auth.strip().decode('base64') + username, password = auth.split(':',1) + return authenticate(username = username, password = password) + +class BasicAuthenticationMiddleware: + def process_request(self, request): + if not getattr(settings, 'BASIC_WWW_AUTHENTICATION', False): + return None + if not request.META.has_key('HTTP_AUTHORIZATION'): + # If the user out of the session as well + logout(request) + return None + user = basic_authenticate(request.META['HTTP_AUTHORIZATION']) + if user is None: + return basic_challenge() + else: + login(request, user) + class LazyUser(object): def __get__(self, request, obj_type=None): if not hasattr(request, '_cached_user'): Index: django/contrib/auth/views.py =================================================================== --- django/contrib/auth/views.py (revision 4649) +++ django/contrib/auth/views.py (working copy) @@ -35,6 +35,12 @@ "Logs out the user and displays 'You are logged out' message." from django.contrib.auth import logout logout(request) + + # This 'works' as a way to log out users but it is confusing. You + # log out and it asks for your credentials again? + #if not getattr(settings, 'BASIC_WWW_AUTHENTICATION', False): + # from middleware import basic_challenge + # return basic_challenge() if next_page is None: return render_to_response(template_name, {'title': _('Logged out')}, context_instance=RequestContext(request)) else: Index: django/contrib/auth/decorators.py =================================================================== --- django/contrib/auth/decorators.py (revision 4649) +++ django/contrib/auth/decorators.py (working copy) @@ -1,3 +1,5 @@ +from django.conf import settings + from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME from django.http import HttpResponseRedirect from urllib import quote @@ -2,2 +4,4 @@ +from django.contrib.auth.middleware import basic_challenge + def user_passes_test(test_func, login_url=LOGIN_URL): @@ -12,10 +16,12 @@ def _checklogin(request, *args, **kwargs): if test_func(request.user): return view_func(request, *args, **kwargs) - return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path()))) + if getattr(settings, 'BASIC_WWW_AUTHENTICATION', False): + return basic_challenge() + else: + return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path()))) _checklogin.__doc__ = view_func.__doc__ _checklogin.__dict__ = view_func.__dict__ - return _checklogin return _dec