diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 6cb0c21795..5bb53886c6 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -1,3 +1,8 @@ +import base64 +import cPickle as pickle +import datetime +import re + from django import http, template from django.contrib.admin import ModelAdmin from django.contrib.auth import authenticate, login @@ -9,11 +14,7 @@ from django.utils.text import capfirst from django.utils.translation import ugettext_lazy, ugettext as _ from django.views.decorators.cache import never_cache from django.conf import settings -import base64 -import cPickle as pickle -import datetime -import md5 -import re +from django.utils.hashcompat import md5_constructor ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.") LOGIN_FORM_KEY = 'this_is_the_login_form' @@ -29,14 +30,14 @@ class NotRegistered(Exception): def _encode_post_data(post_data): from django.conf import settings pickled = pickle.dumps(post_data) - pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest() + pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest() return base64.encodestring(pickled + pickled_md5) def _decode_post_data(encoded_data): from django.conf import settings encoded_data = base64.decodestring(encoded_data) pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] - if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: + if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: from django.core.exceptions import SuspiciousOperation raise SuspiciousOperation, "User may have tampered with session cookie." return pickle.loads(pickled) @@ -48,10 +49,10 @@ class AdminSite(object): register() method, and the root() method can then be used as a Django view function that presents a full admin interface for the collection of registered models. """ - + index_template = None login_template = None - + def __init__(self): self._registry = {} # model_class class -> admin_class instance @@ -117,23 +118,23 @@ class AdminSite(object): return request.user.is_authenticated() and request.user.is_staff def root(self, request, url): - """ + """ Handles main URL routing for the admin app. `url` is the remainder of the URL -- e.g. 'comments/comment/'. """ if request.method == 'GET' and not request.path.endswith('/'): return http.HttpResponseRedirect(request.path + '/') - + # Figure out the admin base URL path and stash it for later use self.root_path = re.sub(re.escape(url) + '$', '', request.path) - + url = url.rstrip('/') # Trim trailing slash, if it exists. # The 'logout' view doesn't require that the person is logged in. if url == 'logout': return self.logout(request) - + # Check permission to continue or display login form. if not self.has_permission(request): return self.login(request) @@ -154,7 +155,7 @@ class AdminSite(object): match = USER_CHANGE_PASSWORD_URL_RE.match(url) if match: return self.user_change_password(request, match.group(1)) - + if '/' in url: return self.model_page(request, *url.split('/', 2)) @@ -320,14 +321,14 @@ class AdminSite(object): # Sort the models alphabetically within each app. for app in app_list: app['models'].sort(lambda x, y: cmp(x['name'], y['name'])) - + context = { 'title': _('Site administration'), 'app_list': app_list, 'root_path': self.root_path, } context.update(extra_context or {}) - return render_to_response(self.index_template or 'admin/index.html', context, + return render_to_response(self.index_template or 'admin/index.html', context, context_instance=template.RequestContext(request) ) index = never_cache(index) @@ -342,7 +343,7 @@ class AdminSite(object): post_data = _encode_post_data(request.POST) else: post_data = _encode_post_data({}) - + context = { 'title': _('Log in'), 'app_path': request.path, diff --git a/django/contrib/admin/views/decorators.py b/django/contrib/admin/views/decorators.py index 57517cc821..cf0cd704c2 100644 --- a/django/contrib/admin/views/decorators.py +++ b/django/contrib/admin/views/decorators.py @@ -1,5 +1,4 @@ import base64 -import md5 import cPickle as pickle try: from functools import wraps @@ -12,6 +11,7 @@ from django.contrib.auth.models import User from django.contrib.auth import authenticate, login from django.shortcuts import render_to_response from django.utils.translation import ugettext_lazy, ugettext as _ +from django.utils.hashcompat import md5_constructor ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.") LOGIN_FORM_KEY = 'this_is_the_login_form' @@ -35,13 +35,13 @@ def _display_login_form(request, error_message=''): def _encode_post_data(post_data): pickled = pickle.dumps(post_data) - pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest() + pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).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 + settings.SECRET_KEY).hexdigest() != tamper_check: + if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: from django.core.exceptions import SuspiciousOperation raise SuspiciousOperation, "User may have tampered with session cookie." return pickle.loads(pickled) @@ -87,7 +87,7 @@ def staff_member_required(view_func): if len(users) == 1: message = _("Your e-mail address is not your username. Try '%s' instead.") % users[0].username else: - # Either we cannot find the user, or if more than 1 + # Either we cannot find the user, or if more than 1 # we cannot guess which user is the correct one. message = _("Usernames cannot contain the '@' character.") return _display_login_form(request, message) diff --git a/django/contrib/auth/tokens.py b/django/contrib/auth/tokens.py index acfbc3bb9c..c9b353583c 100644 --- a/django/contrib/auth/tokens.py +++ b/django/contrib/auth/tokens.py @@ -50,17 +50,17 @@ class PasswordResetTokenGenerator(object): # last_login will also change), we produce a hash that will be # invalid as soon as it is used. # We limit the hash to 20 chars to keep URL short - import sha - hash = sha.new(settings.SECRET_KEY + unicode(user.id) + - user.password + unicode(user.last_login) + - unicode(timestamp)).hexdigest()[::2] + from django.utils.hashcompat import sha_constructor + hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) + + user.password + unicode(user.last_login) + + unicode(timestamp)).hexdigest()[::2] return "%s-%s" % (ts_b36, hash) def _num_days(self, dt): - return (dt - date(2001,1,1)).days + return (dt - date(2001,1,1)).days def _today(self): # Used for mocking in tests - return date.today() + return date.today() default_token_generator = PasswordResetTokenGenerator() diff --git a/django/contrib/comments/models.py b/django/contrib/comments/models.py index a13fec9e6e..fdf34c8997 100644 --- a/django/contrib/comments/models.py +++ b/django/contrib/comments/models.py @@ -29,8 +29,8 @@ class CommentManager(models.Manager): 'pa,ra') and target (something like 'lcom.eventtimes:5157'). Used to validate that submitted form options have not been tampered-with. """ - import md5 - return md5.new(options + photo_options + rating_options + target + settings.SECRET_KEY).hexdigest() + from django.utils.hashcompat import md5_constructor + return md5_constructor(options + photo_options + rating_options + target + settings.SECRET_KEY).hexdigest() def get_rating_options(self, rating_string): """ diff --git a/django/contrib/csrf/middleware.py b/django/contrib/csrf/middleware.py index 1a75a5d6ab..24c1511c91 100644 --- a/django/contrib/csrf/middleware.py +++ b/django/contrib/csrf/middleware.py @@ -2,44 +2,45 @@ Cross Site Request Forgery Middleware. This module provides a middleware that implements protection -against request forgeries from other sites. - +against request forgeries from other sites. """ -from django.conf import settings -from django.http import HttpResponseForbidden -from django.utils.safestring import mark_safe -import md5 + import re import itertools +from django.conf import settings +from django.http import HttpResponseForbidden +from django.utils.hashcompat import md5_constructor +from django.utils.safestring import mark_safe + _ERROR_MSG = mark_safe('
Cross Site Request Forgery detected. Request aborted.
') _POST_FORM_RE = \ re.compile(r'(