2006-05-02 09:31:56 +08:00
from django import http , template
from django . conf import settings
2006-06-29 00:37:02 +08:00
from django . contrib . auth . models import User
from django . contrib . auth import authenticate , login
2006-05-02 09:31:56 +08:00
from django . shortcuts import render_to_response
2007-02-11 14:20:52 +08:00
from django . utils . translation import gettext_lazy , gettext as _
2006-01-17 02:54:41 +08:00
import base64 , datetime , md5
2005-10-18 12:21:07 +08:00
import cPickle as pickle
2005-12-26 19:52:42 +08:00
ERROR_MESSAGE = gettext_lazy ( " Please enter a correct username and password. Note that both fields are case-sensitive. " )
2005-10-18 12:21:07 +08:00
LOGIN_FORM_KEY = ' this_is_the_login_form '
def _display_login_form ( request , error_message = ' ' ) :
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.
post_data = request . POST [ ' post_data ' ]
elif request . POST :
# User's session must have expired; save their post data.
post_data = _encode_post_data ( request . POST )
else :
post_data = _encode_post_data ( { } )
2006-05-02 09:31:56 +08:00
return render_to_response ( ' admin/login.html ' , {
2005-11-25 10:18:37 +08:00
' title ' : _ ( ' Log in ' ) ,
2005-10-18 12:21:07 +08:00
' app_path ' : request . path ,
' post_data ' : post_data ,
' error_message ' : error_message
2006-05-02 09:31:56 +08:00
} , context_instance = template . RequestContext ( request ) )
2005-10-18 12:21:07 +08:00
def _encode_post_data ( post_data ) :
pickled = pickle . dumps ( post_data )
2006-05-02 09:31:56 +08:00
pickled_md5 = md5 . new ( pickled + settings . SECRET_KEY ) . hexdigest ( )
2005-10-18 12:21:07 +08:00
return base64 . encodestring ( pickled + pickled_md5 )
def _decode_post_data ( encoded_data ) :
encoded_data = base64 . decodestring ( encoded_data )
pickled , tamper_check = encoded_data [ : - 32 ] , encoded_data [ - 32 : ]
2006-05-02 09:31:56 +08:00
if md5 . new ( pickled + settings . SECRET_KEY ) . hexdigest ( ) != tamper_check :
2005-10-18 12:21:07 +08:00
from django . core . exceptions import SuspiciousOperation
raise SuspiciousOperation , " User may have tampered with session cookie. "
return pickle . loads ( pickled )
def staff_member_required ( view_func ) :
"""
Decorator for views that checks that the user is logged in and is a staff
member , displaying the login page if necessary .
"""
def _checklogin ( request , * args , * * kwargs ) :
2006-07-19 10:09:26 +08:00
if request . user . is_authenticated ( ) and request . user . is_staff :
2005-10-18 12:21:07 +08:00
# The user is valid. Continue to the admin page.
2006-01-17 02:54:41 +08:00
if request . POST . has_key ( ' post_data ' ) :
# User must have re-authenticated through a different window
# or tab.
request . POST = _decode_post_data ( request . POST [ ' post_data ' ] )
2005-10-18 12:21:07 +08:00
return view_func ( request , * args , * * kwargs )
2006-05-02 09:31:56 +08:00
assert hasattr ( request , ' session ' ) , " The Django admin requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert ' django.contrib.sessions.middleware.SessionMiddleware ' . "
2005-10-18 12:21:07 +08:00
# If this isn't already the login page, display it.
if not request . POST . has_key ( LOGIN_FORM_KEY ) :
if request . POST :
2005-11-25 10:18:37 +08:00
message = _ ( " Please log in again, because your session has expired. Don ' t worry: Your submission has been saved. " )
2005-10-18 12:21:07 +08:00
else :
message = " "
return _display_login_form ( request , message )
# Check that the user accepts cookies.
if not request . session . test_cookie_worked ( ) :
2005-11-25 10:18:37 +08:00
message = _ ( " Looks like your browser isn ' t configured to accept cookies. Please enable cookies, reload this page, and try again. " )
2005-10-18 12:21:07 +08:00
return _display_login_form ( request , message )
# Check the password.
2006-06-29 00:37:02 +08:00
username = request . POST . get ( ' username ' , None )
password = request . POST . get ( ' password ' , None )
user = authenticate ( username = username , password = password )
if user is None :
2005-10-18 12:21:07 +08:00
message = ERROR_MESSAGE
if ' @ ' in username :
# Mistakenly entered e-mail address instead of username? Look it up.
try :
2006-05-02 09:31:56 +08:00
user = User . objects . get ( email = username )
except User . DoesNotExist :
2005-11-25 10:18:37 +08:00
message = _ ( " Usernames cannot contain the ' @ ' character. " )
2005-10-18 12:21:07 +08:00
else :
2005-11-25 10:18:37 +08:00
message = _ ( " Your e-mail address is not your username. Try ' %s ' instead. " ) % user . username
2005-10-18 12:21:07 +08:00
return _display_login_form ( request , message )
# The user data is correct; log in the user in and continue.
else :
2006-09-29 21:37:58 +08:00
if user . is_active and user . is_staff :
2006-06-29 00:37:02 +08:00
login ( request , user )
# TODO: set last_login with an event.
2006-01-17 02:54:41 +08:00
user . last_login = datetime . datetime . now ( )
user . save ( )
2005-10-18 12:21:07 +08:00
if request . POST . has_key ( ' post_data ' ) :
post_data = _decode_post_data ( request . POST [ ' post_data ' ] )
if post_data and not post_data . has_key ( LOGIN_FORM_KEY ) :
# overwrite request.POST with the saved post_data, and continue
request . POST = post_data
request . user = user
return view_func ( request , * args , * * kwargs )
else :
request . session . delete_test_cookie ( )
2006-05-02 09:31:56 +08:00
return http . HttpResponseRedirect ( request . path )
2005-10-18 12:21:07 +08:00
else :
return _display_login_form ( request , ERROR_MESSAGE )
return _checklogin