summaryrefslogtreecommitdiff
path: root/django/middleware/admin.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/middleware/admin.py')
-rw-r--r--django/middleware/admin.py120
1 files changed, 120 insertions, 0 deletions
diff --git a/django/middleware/admin.py b/django/middleware/admin.py
new file mode 100644
index 0000000000..f91b856d3b
--- /dev/null
+++ b/django/middleware/admin.py
@@ -0,0 +1,120 @@
+from django.utils import httpwrappers
+from django.core import template_loader
+from django.core.extensions import CMSContext as Context
+from django.models.auth import sessions, users
+from django.views.registration import passwords
+import base64, md5
+import cPickle as pickle
+
+# secret used in pickled data to guard against tampering
+TAMPER_SECRET = '09VJWE9_RIZZO_j0jwfe09j'
+
+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
+ # conf, which is a little uglier than this.
+ if view_func == passwords.password_reset or view_func == passwords.password_reset_done:
+ return
+
+ # Check for a logged in, valid user
+ if self.user_is_valid(request.user):
+ return
+
+ # If this isn't alreay the login page, display it
+ 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)
+
+ # 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', '')):
+ 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
+ request.session = sessions.create_session(user.id)
+ return
+ else:
+ response = httpwrappers.HttpResponseRedirect(request.path)
+ sessions.start_web_session(user.id, request, response)
+ return response
+ else:
+ return self.display_login_form(request, ERROR_MESSAGE)
+
+ def display_login_form(self, request, error_message=''):
+ 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({})
+ t = template_loader.get_template(self.get_login_template_name())
+ c = Context(request, {
+ 'title': 'Log in',
+ 'app_path': request.path,
+ 'post_data': post_data,
+ 'error_message': error_message
+ })
+ return httpwrappers.HttpResponse(t.render(c))
+
+ 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)
+ pickled_md5 = md5.new(pickled + TAMPER_SECRET).hexdigest()
+ 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:]
+ if md5.new(pickled + TAMPER_SECRET).hexdigest() != tamper_check:
+ from django.core.exceptions import SuspiciousOperation
+ raise SuspiciousOperation, "User may have tampered with session cookie."
+ return pickle.loads(pickled)