Changeset 8193
- Timestamp:
- 08/02/08 00:56:57 (4 months ago)
- Files:
-
- django/trunk/django/contrib/admin/sites.py (modified) (12 diffs)
- django/trunk/django/contrib/admin/views/decorators.py (modified) (5 diffs)
- django/trunk/django/contrib/auth/tokens.py (modified) (1 diff)
- django/trunk/django/contrib/comments/models.py (modified) (1 diff)
- django/trunk/django/contrib/csrf/middleware.py (modified) (5 diffs)
- django/trunk/django/contrib/formtools/preview.py (modified) (3 diffs)
- django/trunk/django/contrib/formtools/wizard.py (modified) (3 diffs)
- django/trunk/django/contrib/sessions/backends/base.py (modified) (5 diffs)
- django/trunk/django/contrib/sessions/models.py (modified) (4 diffs)
- django/trunk/django/core/cache/backends/filebased.py (modified) (8 diffs)
- django/trunk/django/db/backends/util.py (modified) (2 diffs)
- django/trunk/django/middleware/common.py (modified) (4 diffs)
- django/trunk/django/utils/cache.py (modified) (4 diffs)
- django/trunk/django/utils/hashcompat.py (added)
- django/trunk/tests/regressiontests/cache/tests.py (modified) (7 diffs)
- django/trunk/tests/regressiontests/file_uploads/tests.py (modified) (3 diffs)
- django/trunk/tests/regressiontests/test_client_regress/models.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/contrib/admin/sites.py
r8063 r8193 1 import base64 2 import cPickle as pickle 3 import datetime 4 import re 5 1 6 from django import http, template 2 7 from django.contrib.admin import ModelAdmin … … 10 15 from django.views.decorators.cache import never_cache 11 16 from django.conf import settings 12 import base64 13 import cPickle as pickle 14 import datetime 15 import md5 16 import re 17 from django.utils.hashcompat import md5_constructor 17 18 18 19 ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.") … … 30 31 from django.conf import settings 31 32 pickled = pickle.dumps(post_data) 32 pickled_md5 = md5 .new(pickled + settings.SECRET_KEY).hexdigest()33 pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest() 33 34 return base64.encodestring(pickled + pickled_md5) 34 35 … … 37 38 encoded_data = base64.decodestring(encoded_data) 38 39 pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] 39 if md5 .new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:40 if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: 40 41 from django.core.exceptions import SuspiciousOperation 41 42 raise SuspiciousOperation, "User may have tampered with session cookie." … … 49 50 that presents a full admin interface for the collection of registered models. 50 51 """ 51 52 52 53 index_template = None 53 54 login_template = None 54 55 55 56 def __init__(self): 56 57 self._registry = {} # model_class class -> admin_class instance … … 118 119 119 120 def root(self, request, url): 120 """ 121 """ 121 122 Handles main URL routing for the admin app. 122 123 … … 125 126 if request.method == 'GET' and not request.path.endswith('/'): 126 127 return http.HttpResponseRedirect(request.path + '/') 127 128 128 129 # Figure out the admin base URL path and stash it for later use 129 130 self.root_path = re.sub(re.escape(url) + '$', '', request.path) 130 131 131 132 url = url.rstrip('/') # Trim trailing slash, if it exists. 132 133 … … 134 135 if url == 'logout': 135 136 return self.logout(request) 136 137 137 138 # Check permission to continue or display login form. 138 139 if not self.has_permission(request): … … 155 156 if match: 156 157 return self.user_change_password(request, match.group(1)) 157 158 158 159 if '/' in url: 159 160 return self.model_page(request, *url.split('/', 2)) … … 321 322 for app in app_list: 322 323 app['models'].sort(lambda x, y: cmp(x['name'], y['name'])) 323 324 324 325 context = { 325 326 'title': _('Site administration'), … … 328 329 } 329 330 context.update(extra_context or {}) 330 return render_to_response(self.index_template or 'admin/index.html', context, 331 return render_to_response(self.index_template or 'admin/index.html', context, 331 332 context_instance=template.RequestContext(request) 332 333 ) … … 343 344 else: 344 345 post_data = _encode_post_data({}) 345 346 346 347 context = { 347 348 'title': _('Log in'), django/trunk/django/contrib/admin/views/decorators.py
r7967 r8193 1 1 import base64 2 import md53 2 import cPickle as pickle 4 3 try: … … 13 12 from django.shortcuts import render_to_response 14 13 from django.utils.translation import ugettext_lazy, ugettext as _ 14 from django.utils.hashcompat import md5_constructor 15 15 16 16 ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.") … … 36 36 def _encode_post_data(post_data): 37 37 pickled = pickle.dumps(post_data) 38 pickled_md5 = md5 .new(pickled + settings.SECRET_KEY).hexdigest()38 pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest() 39 39 return base64.encodestring(pickled + pickled_md5) 40 40 … … 42 42 encoded_data = base64.decodestring(encoded_data) 43 43 pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] 44 if md5 .new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:44 if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: 45 45 from django.core.exceptions import SuspiciousOperation 46 46 raise SuspiciousOperation, "User may have tampered with session cookie." … … 88 88 message = _("Your e-mail address is not your username. Try '%s' instead.") % users[0].username 89 89 else: 90 # Either we cannot find the user, or if more than 1 90 # Either we cannot find the user, or if more than 1 91 91 # we cannot guess which user is the correct one. 92 92 message = _("Usernames cannot contain the '@' character.") django/trunk/django/contrib/auth/tokens.py
r8162 r8193 51 51 # invalid as soon as it is used. 52 52 # We limit the hash to 20 chars to keep URL short 53 import sha54 hash = sha .new(settings.SECRET_KEY + unicode(user.id) +55 user.password + unicode(user.last_login) +56 unicode(timestamp)).hexdigest()[::2]53 from django.utils.hashcompat import sha_constructor 54 hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) + 55 user.password + unicode(user.last_login) + 56 unicode(timestamp)).hexdigest()[::2] 57 57 return "%s-%s" % (ts_b36, hash) 58 58 59 59 def _num_days(self, dt): 60 return (dt - date(2001,1,1)).days 60 return (dt - date(2001,1,1)).days 61 61 62 62 def _today(self): 63 63 # Used for mocking in tests 64 return date.today() 64 return date.today() 65 65 66 66 default_token_generator = PasswordResetTokenGenerator() django/trunk/django/contrib/comments/models.py
r7967 r8193 30 30 validate that submitted form options have not been tampered-with. 31 31 """ 32 import md533 return md5 .new(options + photo_options + rating_options + target + settings.SECRET_KEY).hexdigest()32 from django.utils.hashcompat import md5_constructor 33 return md5_constructor(options + photo_options + rating_options + target + settings.SECRET_KEY).hexdigest() 34 34 35 35 def get_rating_options(self, rating_string): django/trunk/django/contrib/csrf/middleware.py
r6671 r8193 3 3 4 4 This module provides a middleware that implements protection 5 against request forgeries from other sites. 5 against request forgeries from other sites. 6 """ 6 7 7 """ 8 import re 9 import itertools 10 8 11 from django.conf import settings 9 12 from django.http import HttpResponseForbidden 13 from django.utils.hashcompat import md5_constructor 10 14 from django.utils.safestring import mark_safe 11 import md512 import re13 import itertools14 15 15 16 _ERROR_MSG = mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>') … … 17 18 _POST_FORM_RE = \ 18 19 re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE) 19 20 _HTML_TYPES = ('text/html', 'application/xhtml+xml') 20 21 _HTML_TYPES = ('text/html', 'application/xhtml+xml') 21 22 22 23 def _make_token(session_id): 23 return md5 .new(settings.SECRET_KEY + session_id).hexdigest()24 return md5_constructor(settings.SECRET_KEY + session_id).hexdigest() 24 25 25 26 class CsrfMiddleware(object): 26 27 """Django middleware that adds protection against Cross Site 27 Request Forgeries by adding hidden form fields to POST forms and 28 checking requests for the correct value. 29 30 In the list of middlewares, SessionMiddleware is required, and must come 31 after this middleware. CsrfMiddleWare must come after compression 28 Request Forgeries by adding hidden form fields to POST forms and 29 checking requests for the correct value. 30 31 In the list of middlewares, SessionMiddleware is required, and must come 32 after this middleware. CsrfMiddleWare must come after compression 32 33 middleware. 33 34 If a session ID cookie is present, it is hashed with the SECRET_KEY 35 setting to create an authentication token. This token is added to all 36 outgoing POST forms and is expected on all incoming POST requests that 34 35 If a session ID cookie is present, it is hashed with the SECRET_KEY 36 setting to create an authentication token. This token is added to all 37 outgoing POST forms and is expected on all incoming POST requests that 37 38 have a session ID cookie. 38 39 If you are setting cookies directly, instead of using Django's session 39 40 If you are setting cookies directly, instead of using Django's session 40 41 framework, this middleware will not work. 41 42 """ 42 43 43 44 def process_request(self, request): 44 45 if request.method == 'POST': … … 55 56 except KeyError: 56 57 return HttpResponseForbidden(_ERROR_MSG) 57 58 58 59 if request_csrf_token != csrf_token: 59 60 return HttpResponseForbidden(_ERROR_MSG) 60 61 61 62 return None 62 63 … … 67 68 csrf_token = _make_token(cookie.value) 68 69 except KeyError: 69 # No outgoing cookie to set session, but 70 # No outgoing cookie to set session, but 70 71 # a session might already exist. 71 72 try: … … 75 76 # no incoming or outgoing cookie 76 77 pass 77 78 78 79 if csrf_token is not None and \ 79 80 response['Content-Type'].split(';')[0] in _HTML_TYPES: 80 81 81 82 # ensure we don't add the 'id' attribute twice (HTML validity) 82 idattributes = itertools.chain(("id='csrfmiddlewaretoken'",), 83 idattributes = itertools.chain(("id='csrfmiddlewaretoken'",), 83 84 itertools.repeat('')) 84 85 def add_csrf_field(match): django/trunk/django/contrib/formtools/preview.py
r7277 r8193 2 2 Formtools Preview application. 3 3 """ 4 5 import cPickle as pickle 4 6 5 7 from django.conf import settings … … 7 9 from django.shortcuts import render_to_response 8 10 from django.template.context import RequestContext 9 import cPickle as pickle 10 import md5 11 from django.utils.hashcompat import md5_constructor 11 12 12 13 AUTO_ID = 'formtools_%s' # Each form here uses this as its auto_id parameter. … … 110 111 # Python 2.3, but Django requires 2.3 anyway, so that's OK. 111 112 pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) 112 return md5 .new(pickled).hexdigest()113 return md5_constructor(pickled).hexdigest() 113 114 114 115 def failed_hash(self, request): django/trunk/django/contrib/formtools/wizard.py
r7971 r8193 5 5 """ 6 6 7 import cPickle as pickle 8 7 9 from django import forms 8 10 from django.conf import settings … … 10 12 from django.shortcuts import render_to_response 11 13 from django.template.context import RequestContext 12 import cPickle as pickle 13 import md5 14 from django.utils.hashcompat import md5_constructor 14 15 15 16 class FormWizard(object): … … 151 152 # Python 2.3, but Django requires 2.3 anyway, so that's OK. 152 153 pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) 153 return md5 .new(pickled).hexdigest()154 return md5_constructor(pickled).hexdigest() 154 155 155 156 def determine_step(self, request, *args, **kwargs): django/trunk/django/contrib/sessions/backends/base.py
r7725 r8193 1 1 import base64 2 import md53 2 import os 4 3 import random … … 13 12 from django.conf import settings 14 13 from django.core.exceptions import SuspiciousOperation 14 from django.utils.hashcompat import md5_constructor 15 15 16 16 … … 74 74 "Returns the given session dictionary pickled and encoded as a string." 75 75 pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL) 76 pickled_md5 = md5 .new(pickled + settings.SECRET_KEY).hexdigest()76 pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest() 77 77 return base64.encodestring(pickled + pickled_md5) 78 78 … … 80 80 encoded_data = base64.decodestring(session_data) 81 81 pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] 82 if md5 .new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:82 if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: 83 83 raise SuspiciousOperation("User tampered with session cookie.") 84 84 try: … … 118 118 pid = 1 119 119 while 1: 120 session_key = md5 .new("%s%s%s%s" % (random.randint(0, sys.maxint - 1),121 pid, time.time(), settings.SECRET_KEY)).hexdigest()120 session_key = md5_constructor("%s%s%s%s" % (random.randint(0, sys.maxint - 1), 121 pid, time.time(), settings.SECRET_KEY)).hexdigest() 122 122 if not self.exists(session_key): 123 123 break django/trunk/django/contrib/sessions/models.py
r7725 r8193 1 1 import base64 2 import md53 2 import cPickle as pickle 4 3 … … 6 5 from django.utils.translation import ugettext_lazy as _ 7 6 from django.conf import settings 7 from django.utils.hashcompat import md5_constructor 8 8 9 9 … … 14 14 """ 15 15 pickled = pickle.dumps(session_dict) 16 pickled_md5 = md5 .new(pickled + settings.SECRET_KEY).hexdigest()16 pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest() 17 17 return base64.encodestring(pickled + pickled_md5) 18 18 … … 57 57 encoded_data = base64.decodestring(self.session_data) 58 58 pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] 59 if md5 .new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:59 if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: 60 60 from django.core.exceptions import SuspiciousOperation 61 61 raise SuspiciousOperation, "User tampered with session cookie." django/trunk/django/core/cache/backends/filebased.py
r6887 r8193 1 1 "File-based cache backend" 2 2 3 import md54 import os,time3 import os 4 import time 5 5 try: 6 6 import cPickle as pickle 7 7 except ImportError: 8 8 import pickle 9 9 10 from django.core.cache.backends.base import BaseCache 11 from django.utils.hashcompat import md5_constructor 10 12 11 13 class CacheClass(BaseCache): 12 14 def __init__(self, dir, params): 13 15 BaseCache.__init__(self, params) 14 16 15 17 max_entries = params.get('max_entries', 300) 16 18 try: … … 18 20 except (ValueError, TypeError): 19 21 self._max_entries = 300 20 22 21 23 cull_frequency = params.get('cull_frequency', 3) 22 24 try: … … 24 26 except (ValueError, TypeError): 25 27 self._cull_frequency = 3 26 28 27 29 self._dir = dir 28 30 if not os.path.exists(self._dir): … … 32 34 if self.has_key(key): 33 35 return None 34 36 35 37 self.set(key, value, timeout) 36 38 … … 53 55 fname = self._key_to_file(key) 54 56 dirname = os.path.dirname(fname) 55 57 56 58 if timeout is None: 57 59 timeout = self.default_timeout 58 60 59 61 self._cull() 60 62 61 63 try: 62 64 if not os.path.exists(dirname): … … 104 106 if int(self._num_entries) < self._max_entries: 105 107 return 106 108 107 109 try: 108 110 filelist = os.listdir(self._dir) 109 111 except (IOError, OSError): 110 112 return 111 113 112 114 if self._cull_frequency == 0: 113 115 doomed = filelist … … 134 136 bits of the path into directory prefixes to be nice to filesystems 135 137 that have problems with large numbers of files in a directory. 136 138 137 139 Thus, a cache key of "foo" gets turnned into a file named 138 140 ``{cache-dir}ac/bd/18db4cc2f85cedef654fccc4a4d8``. 139 141 """ 140 path = md5 .new(key.encode('utf-8')).hexdigest()142 path = md5_constructor(key.encode('utf-8')).hexdigest() 141 143 path = os.path.join(path[:2], path[2:4], path[4:]) 142 144 return os.path.join(self._dir, path) … … 148 150 return count 149 151 _num_entries = property(_get_num_entries) 150 django/trunk/django/db/backends/util.py
r8131 r8193 1 1 import datetime 2 import md53 2 from time import time 3 4 from django.utils.hashcompat import md5_constructor 4 5 5 6 try: … … 115 116 return name 116 117 117 hash = md5 .md5(name).hexdigest()[:4]118 hash = md5_constructor(name).hexdigest()[:4] 118 119 119 120 return '%s%s' % (name[:length-4], hash) django/trunk/django/middleware/common.py
r7659 r8193 1 import md52 1 import re 3 2 … … 7 6 from django.utils.http import urlquote 8 7 from django.core import urlresolvers 8 from django.utils.hashcompat import md5_constructor 9 9 10 10 class CommonMiddleware(object): … … 22 22 appending a slash at the end. If this new URL is found in 23 23 urlpatterns, then an HTTP-redirect is returned to this new URL; 24 otherwise the initial URL is processed as usual. 24 otherwise the initial URL is processed as usual. 25 25 26 26 - ETags: If the USE_ETAGS setting is set, ETags will be calculated from … … 109 109 etag = response['ETag'] 110 110 else: 111 etag = '"%s"' % md5 .new(response.content).hexdigest()111 etag = '"%s"' % md5_constructor(response.content).hexdigest() 112 112 if response.status_code >= 200 and response.status_code < 300 and request.META.get('HTTP_IF_NONE_MATCH') == etag: 113 113 cookies = response.cookies django/trunk/django/utils/cache.py
r7659 r8193 18 18 """ 19 19 20 import md521 20 import re 22 21 import time … … 30 29 from django.utils.encoding import smart_str, iri_to_uri 31 30 from django.utils.http import http_date 31 from django.utils.hashcompat import md5_constructor 32 32 33 33 cc_delim_re = re.compile(r'\s*,\s*') … … 105 105 cache_timeout = 0 # Can't have max-age negative 106 106 if not response.has_header('ETag'): 107 response['ETag'] = '"%s"' % md5 .new(response.content).hexdigest()107 response['ETag'] = '"%s"' % md5_constructor(response.content).hexdigest() 108 108 if not response.has_header('Last-Modified'): 109 109 response['Last-Modified'] = http_date() … … 139 139 def _generate_cache_key(request, headerlist, key_prefix): 140 140 """Returns a cache key from the headers given in the header list.""" 141 ctx = md5 .new()141 ctx = md5_constructor() 142 142 for header in headerlist: 143 143 value = request.META.get(header, None) django/trunk/tests/regressiontests/cache/tests.py
r8085 r8193 4 4 # Uses whatever cache backend is set in the test settings file. 5 5 6 import os 7 import shutil 8 import tempfile 6 9 import time 7 10 import unittest 11 8 12 from django.core.cache import cache 13 from django.core.cache.backends.filebased import CacheClass as FileCache 14 from django.http import HttpResponse 9 15 from django.utils.cache import patch_vary_headers 10 from django. http import HttpResponse16 from django.utils.hashcompat import md5_constructor 11 17 12 18 # functions/classes for complex data type tests … … 28 34 cache.add("addkey1", "newvalue") 29 35 self.assertEqual(cache.get("addkey1"), "value") 30 36 31 37 def test_non_existent(self): 32 38 # get with non-existent keys … … 81 87 cache.set('expire3', 'very quickly', 1) 82 88 83 time.sleep(2) 89 time.sleep(2) 84 90 self.assertEqual(cache.get("expire1"), None) 85 91 86 92 cache.add("expire2", "newvalue") 87 93 self.assertEqual(cache.get("expire2"), "newvalue") … … 99 105 self.assertEqual(cache.get(key), value) 100 106 101 import os102 import md5103 import shutil104 import tempfile105 from django.core.cache.backends.filebased import CacheClass as FileCache106 107 107 108 class FileBasedCacheTests(unittest.TestCase): … … 113 114 os.mkdir(self.dirname) 114 115 self.cache = FileCache(self.dirname, {}) 115 116 116 117 def tearDown(self): 117 118 shutil.rmtree(self.dirname) 118 119 119 120 def test_hashing(self): 120 121 """Test that keys are hashed into subdirectories correctly""" 121 122 self.cache.set("foo", "bar") 122 keyhash = md5 .new("foo").hexdigest()123 keyhash = md5_constructor("foo").hexdigest() 123 124 keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:]) 124 125 self.assert_(os.path.exists(keypath)) 125 126 126 127 def test_subdirectory_removal(self): 127 128 """ … … 129 130 """ 130 131 self.cache.set("foo", "bar") 131 keyhash = md5 .new("foo").hexdigest()132 keyhash = md5_constructor("foo").hexdigest() 132 133 keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:]) 133 134 self.assert_(os.path.exists(keypath)) … … 140 141 class CacheUtils(unittest.TestCase): 141 142 """TestCase for django.utils.cache functions.""" 142 143 143 144 def test_patch_vary_headers(self): 144 headers = ( 145 headers = ( 145 146 # Initial vary, new headers, resulting vary. 146 147 (None, ('Accept-Encoding',), 'Accept-Encoding'), django/trunk/tests/regressiontests/file_uploads/tests.py
r8096 r8193 1 1 import os 2 2 import errno 3 import sha4 3 import shutil 5 4 import unittest … … 9 8 from django.test import TestCase, client 10 9 from django.utils import simplejson 10 from django.utils.hashcompat import sha_constructor 11 11 12 12 from models import FileModel, UPLOAD_ROOT, UPLOAD_TO … … 46 46 for key in post_data.keys(): 47 47 try: 48 post_data[key + '_hash'] = sha .new(post_data[key].read()).hexdigest()48 post_data[key + '_hash'] = sha_constructor(post_data[key].read()).hexdigest() 49 49 post_data[key].seek(0) 50 50 except AttributeError: 51 post_data[key + '_hash'] = sha .new(post_data[key]).hexdigest()51 post_data[key + '_hash'] = sha_constructor(post_data[key]).hexdigest() 52 52 53 53 response = self.client.post('/file_uploads/verify/', post_data) django/trunk/tests/regressiontests/test_client_regress/models.py
r8082 r8193 1 1 """ 2 2 Regression tests for the Test Client, especially the customized assertions. 3 4 3 """ 4 5 5 from django.test import Client, TestCase 6 6 from django.core.urlresolvers import reverse 7 7 from django.core.exceptions import SuspiciousOperation 8 import os9 import sha10 8 11 9 class AssertContainsTests(TestCase): … … 25 23 except AssertionError, e: 26 24 self.assertEquals(str(e), "Response should not contain 'once'") 27 25 28 26 try: 29 27 self.assertContains(response, 'never', 1) … … 288 286 class ExceptionTests(TestCase): 289 287 fixtures = ['testdata.json'] 290 288 291 289 def test_exception_cleared(self): 292 290 "#5836 - A stale user exception isn't re-raised by the test client." … … 301 299 302 300 # At this point, an exception has been raised, and should be cleared. 303 301 304 302 # This next operation should be successful; if it isn't we have a problem. 305 303 login = self.client.login(username='staff', password='password')
