2005-07-13 09:25:57 +08:00
from django . utils import httpwrappers
2005-10-15 04:10:13 +08:00
from django . core . extensions import DjangoContext
from django . core . extensions import render_to_response
2005-08-17 06:54:05 +08:00
from django . models . auth import users
2005-07-13 09:25:57 +08:00
from django . views . registration import passwords
2005-07-27 06:48:04 +08:00
from django . views . auth . login import logout
2005-07-13 09:25:57 +08:00
import base64 , md5
import cPickle as pickle
2005-07-20 08:37:45 +08:00
from django . conf . settings import SECRET_KEY
2005-07-13 09:25:57 +08:00
ERROR_MESSAGE = " Please enter a correct username and password. Note that both fields are case-sensitive. "
class AdminUserRequired :
"""
Admin middleware . If this is enabled , access to the site will be granted only
to valid users with the " is_staff " flag set .
"""
def process_view ( self , request , view_func , param_dict ) :
"""
Make sure the user is logged in and is a valid admin user before
allowing any access .
Done at the view point because we need to know if we ' re running the
password reset function .
"""
# If this is the password reset view, we don't want to require login
# Otherwise the password reset would need its own entry in the httpd
2005-07-27 06:48:04 +08:00
# conf, which is a little uglier than this. Same goes for the logout
# view.
2005-08-17 06:54:05 +08:00
2005-07-27 06:48:04 +08:00
if view_func in ( passwords . password_reset , passwords . password_reset_done , logout ) :
2005-07-13 09:25:57 +08:00
return
2005-08-17 06:54:05 +08:00
assert hasattr ( request , ' session ' ) , " The admin requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert ' django.middleware.sessions.SessionMiddleware ' before %r . " % self . __class__ . __name__
2005-07-13 09:25:57 +08:00
# Check for a logged in, valid user
if self . user_is_valid ( request . user ) :
return
2005-08-17 06:54:05 +08:00
# If this isn't already the login page, display it
2005-07-13 09:25:57 +08:00
if not request . POST . has_key ( ' this_is_the_login_form ' ) :
if request . POST :
message = " Please log in again, because your session has expired. " \
" Don ' t worry: Your submission has been saved. "
else :
message = " "
return self . display_login_form ( request , message )
2005-08-18 06:04:53 +08:00
# Check that the user accepts cookies.
if not request . session . test_cookie_worked ( ) :
message = " Looks like your browser isn ' t configured to accept cookies. Please enable cookies, reload this page, and try again. "
return self . display_login_form ( request , message )
2005-07-13 09:25:57 +08:00
# Check the password
username = request . POST . get ( ' username ' , ' ' )
try :
user = users . get_object ( username__exact = username )
except users . UserDoesNotExist :
message = ERROR_MESSAGE
if ' @ ' in username :
# Mistakenly entered e-mail address instead of username? Look it up.
try :
user = users . get_object ( email__exact = username )
except users . UserDoesNotExist :
message = " Usernames cannot contain the ' @ ' character. "
else :
message = " Your e-mail address is not your username. Try ' %s ' instead. " % user . username
return self . display_login_form ( request , message )
# The user data is correct; log in the user in and continue
else :
if self . authenticate_user ( user , request . POST . get ( ' password ' , ' ' ) ) :
2005-08-17 06:54:05 +08:00
request . session [ users . SESSION_KEY ] = user . id
2005-07-13 09:25:57 +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 ( ' this_is_the_login_form ' ) :
# overwrite request.POST with the saved post_data, and continue
request . POST = post_data
request . user = user
return
else :
2005-09-23 09:28:44 +08:00
request . session . delete_test_cookie ( )
2005-08-17 06:54:05 +08:00
return httpwrappers . HttpResponseRedirect ( request . path )
2005-07-13 09:25:57 +08:00
else :
return self . display_login_form ( request , ERROR_MESSAGE )
def display_login_form ( self , request , error_message = ' ' ) :
2005-08-18 06:04:53 +08:00
request . session . set_test_cookie ( )
2005-07-13 09:25:57 +08:00
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 ( { } )
2005-10-15 04:10:13 +08:00
return render_to_response ( self . get_login_template_name ( ) , {
2005-07-13 09:25:57 +08:00
' title ' : ' Log in ' ,
' app_path ' : request . path ,
' post_data ' : post_data ,
' error_message ' : error_message
2005-10-15 04:10:13 +08:00
} , context_instance = DjangoContext ( request ) )
2005-07-13 09:25:57 +08:00
def authenticate_user ( self , user , password ) :
return user . check_password ( password ) and user . is_staff
def user_is_valid ( self , user ) :
return not user . is_anonymous ( ) and user . is_staff
def get_login_template_name ( self ) :
return " login "
def encode_post_data ( post_data ) :
pickled = pickle . dumps ( post_data )
2005-07-20 08:37:45 +08:00
pickled_md5 = md5 . new ( pickled + SECRET_KEY ) . hexdigest ( )
2005-07-13 09:25:57 +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 : ]
2005-07-20 08:37:45 +08:00
if md5 . new ( pickled + SECRET_KEY ) . hexdigest ( ) != tamper_check :
2005-07-13 09:25:57 +08:00
from django . core . exceptions import SuspiciousOperation
raise SuspiciousOperation , " User may have tampered with session cookie. "
return pickle . loads ( pickled )