Permalink
Browse files

Merge branch 'master' of github.com:django/django

  • Loading branch information...
2 parents acd0bb3 + bd97f7d commit dc8814bf7dc5139f3d11b8f9f44f54c7f77d2714 @apollo13 apollo13 committed May 18, 2013
View
@@ -505,6 +505,7 @@ answer newbie questions, and generally made Django that much better:
Bernd Schlapsi
schwank@gmail.com
scott@staplefish.com
+ Olivier Sels <olivier.sels@gmail.com>
Ilya Semenov <semenov@inetss.com>
Aleksandra Sendecka <asendecka@hauru.eu>
serbaut@gmail.com
@@ -1,7 +1,6 @@
from django.conf import settings
from django.contrib.flatpages.models import FlatPage
from django.contrib.sites.models import get_current_site
-from django.core.xheaders import populate_xheaders
from django.http import Http404, HttpResponse, HttpResponsePermanentRedirect
from django.shortcuts import get_object_or_404
from django.template import loader, RequestContext
@@ -70,5 +69,4 @@ def render_flatpage(request, f):
'flatpage': f,
})
response = HttpResponse(t.render(c))
- populate_xheaders(request, response, FlatPage, f.id)
return response
@@ -118,8 +118,8 @@ def get_validation_errors(outfile, app=None):
e.add(opts, '"%s": "choices" should be iterable (e.g., a tuple or list).' % f.name)
else:
for c in f.choices:
- if not isinstance(c, (list, tuple)) or len(c) != 2:
- e.add(opts, '"%s": "choices" should be a sequence of two-tuples.' % f.name)
+ if isinstance(c, six.string_types) or not is_iterable(c) or len(c) != 2:
+ e.add(opts, '"%s": "choices" should be a sequence of two-item iterables (e.g. list of 2 item tuples).' % f.name)
if f.db_index not in (None, True, False):
e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name)
@@ -1,24 +0,0 @@
-"""
-Pages in Django can are served up with custom HTTP headers containing useful
-information about those pages -- namely, the content type and object ID.
-
-This module contains utility functions for retrieving and doing interesting
-things with these special "X-Headers" (so called because the HTTP spec demands
-that custom headers are prefixed with "X-").
-
-Next time you're at slashdot.org, watch out for X-Fry and X-Bender. :)
-"""
-
-def populate_xheaders(request, response, model, object_id):
- """
- Adds the "X-Object-Type" and "X-Object-Id" headers to the given
- HttpResponse according to the given model and object_id -- but only if the
- given HttpRequest object has an IP address within the INTERNAL_IPS setting
- or if the request is from a logged in staff member.
- """
- from django.conf import settings
- if (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
- or (hasattr(request, 'user') and request.user.is_active
- and request.user.is_staff)):
- response['X-Object-Type'] = "%s.%s" % (model._meta.app_label, model._meta.model_name)
- response['X-Object-Id'] = str(object_id)
@@ -670,6 +670,10 @@ def split_url(url):
value = urlunsplit(url_fields)
return value
+ def clean(self, value):
+ value = self.to_python(value).strip()
+ return super(URLField, self).clean(value)
+
class BooleanField(Field):
widget = CheckboxInput
@@ -1105,3 +1109,7 @@ def to_python(self, value):
class SlugField(CharField):
default_validators = [validators.validate_slug]
+
+ def clean(self, value):
+ value = self.to_python(value).strip()
+ return super(SlugField, self).clean(value)
@@ -29,11 +29,6 @@
of the response's "Cache-Control" header, falling back to the
CACHE_MIDDLEWARE_SECONDS setting if the section was not found.
-* If CACHE_MIDDLEWARE_ANONYMOUS_ONLY is set to True, only anonymous requests
- (i.e., those not made by a logged-in user) will be cached. This is a simple
- and effective way of avoiding the caching of the Django admin (and any other
- user-specific content).
-
* This middleware expects that a HEAD request is answered with the same response
headers exactly like the corresponding GET request.
@@ -48,6 +43,8 @@
"""
+import warnings
+
from django.conf import settings
from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS
from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age
@@ -200,5 +197,9 @@ def __init__(self, cache_timeout=None, cache_anonymous_only=None, **kwargs):
else:
self.cache_anonymous_only = cache_anonymous_only
+ if self.cache_anonymous_only:
+ msg = "CACHE_MIDDLEWARE_ANONYMOUS_ONLY has been deprecated and will be removed in Django 1.8."
+ warnings.warn(msg, PendingDeprecationWarning, stacklevel=1)
+
self.cache = get_cache(self.cache_alias, **cache_kwargs)
self.cache_timeout = self.cache.default_timeout
@@ -83,6 +83,13 @@ def _accept(self, request):
return None
def _reject(self, request, reason):
+ logger.warning('Forbidden (%s): %s',
+ reason, request.path,
+ extra={
+ 'status_code': 403,
+ 'request': request,
+ }
+ )
return _get_failure_view()(request, reason=reason)
def process_view(self, request, callback, callback_args, callback_kwargs):
@@ -134,38 +141,18 @@ def process_view(self, request, callback, callback_args, callback_kwargs):
# we can use strict Referer checking.
referer = request.META.get('HTTP_REFERER')
if referer is None:
- logger.warning('Forbidden (%s): %s',
- REASON_NO_REFERER, request.path,
- extra={
- 'status_code': 403,
- 'request': request,
- }
- )
return self._reject(request, REASON_NO_REFERER)
# Note that request.get_host() includes the port.
good_referer = 'https://%s/' % request.get_host()
if not same_origin(referer, good_referer):
reason = REASON_BAD_REFERER % (referer, good_referer)
- logger.warning('Forbidden (%s): %s', reason, request.path,
- extra={
- 'status_code': 403,
- 'request': request,
- }
- )
return self._reject(request, reason)
if csrf_token is None:
# No CSRF cookie. For POST requests, we insist on a CSRF cookie,
# and in this way we can avoid all CSRF attacks, including login
# CSRF.
- logger.warning('Forbidden (%s): %s',
- REASON_NO_CSRF_COOKIE, request.path,
- extra={
- 'status_code': 403,
- 'request': request,
- }
- )
return self._reject(request, REASON_NO_CSRF_COOKIE)
# Check non-cookie token for match.
@@ -179,13 +166,6 @@ def process_view(self, request, callback, callback_args, callback_kwargs):
request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
if not constant_time_compare(request_csrf_token, csrf_token):
- logger.warning('Forbidden (%s): %s',
- REASON_BAD_TOKEN, request.path,
- extra={
- 'status_code': 403,
- 'request': request,
- }
- )
return self._reject(request, REASON_BAD_TOKEN)
return self._accept(request)
View
@@ -1,4 +1,5 @@
import re
+import sys
import warnings
from functools import wraps
from xml.dom.minidom import parseString, Node
@@ -380,3 +381,23 @@ def __exit__(self, exc_type, exc_value, traceback):
if exc_type is not None:
return
self.final_queries = len(self.connection.queries)
+
+
+class IgnoreDeprecationWarningsMixin(object):
+
+ warning_class = DeprecationWarning
+
+ def setUp(self):
+ super(IgnoreDeprecationWarningsMixin, self).setUp()
+ self.catch_warnings = warnings.catch_warnings()
+ self.catch_warnings.__enter__()
+ warnings.filterwarnings("ignore", category=self.warning_class)
+
+ def tearDown(self):
+ self.catch_warnings.__exit__(*sys.exc_info())
+ super(IgnoreDeprecationWarningsMixin, self).tearDown()
+
+
+class IgnorePendingDeprecationWarningsMixin(IgnoreDeprecationWarningsMixin):
+
+ warning_class = PendingDeprecationWarning
@@ -15,7 +15,7 @@
class _EnsureCsrfToken(CsrfViewMiddleware):
# We need this to behave just like the CsrfViewMiddleware, but not reject
- # requests.
+ # requests or log warnings.
def _reject(self, request, reason):
return None
View
@@ -27,12 +27,6 @@ account has :attr:`~django.contrib.auth.models.User.is_active` and
:attr:`~django.contrib.auth.models.User.is_staff` set to True. The admin site
only allows access to users with those two fields both set to True.
-How can I prevent the cache middleware from caching the admin site?
--------------------------------------------------------------------
-
-Set the :setting:`CACHE_MIDDLEWARE_ANONYMOUS_ONLY` setting to ``True``. See the
-:doc:`cache documentation </topics/cache>` for more information.
-
How do I automatically set a field's value to the user who last edited the object in the admin?
-----------------------------------------------------------------------------------------------
@@ -390,6 +390,8 @@ these changes.
``django.test.testcases.OutputChecker`` will be removed. Instead use the
doctest module from the Python standard library.
+* The ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting will be removed.
+
2.0
---
@@ -80,9 +80,10 @@ If a field has ``blank=False``, the field will be required.
.. attribute:: Field.choices
-An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this
-field. If this is given, the default form widget will be a select box with
-these choices instead of the standard text field.
+An iterable (e.g., a list or tuple) consisting itself of iterables of exactly
+two items (e.g. ``[(A, B), (A, B) ...]``) to use as choices for this field. If
+this is given, the default form widget will be a select box with these choices
+instead of the standard text field.
The first element in each tuple is the actual value to be stored, and the
second element is the human-readable name. For example::
@@ -889,7 +890,8 @@ The value ``0`` is accepted for backward compatibility reasons.
.. class:: PositiveSmallIntegerField([**options])
Like a :class:`PositiveIntegerField`, but only allows values under a certain
-(database-dependent) point.
+(database-dependent) point. Values up to 32767 are safe in all databases
+supported by Django.
``SlugField``
-------------
@@ -917,7 +919,8 @@ of some other value. You can do this automatically in the admin using
.. class:: SmallIntegerField([**options])
Like an :class:`IntegerField`, but only allows values under a certain
-(database-dependent) point.
+(database-dependent) point. Values from -32768 to 32767 are safe in all databases
+supported by Django.
``TextField``
-------------
@@ -280,15 +280,19 @@ CACHE_MIDDLEWARE_ANONYMOUS_ONLY
Default: ``False``
+.. deprecated:: 1.6
+
+ This setting was largely ineffective because of using cookies for sessions
+ and CSRF. See the :doc:`Django 1.6 release notes</releases/1.6>` for more
+ information.
+
If the value of this setting is ``True``, only anonymous requests (i.e., not
those made by a logged-in user) will be cached. Otherwise, the middleware
caches every page that doesn't have GET or POST parameters.
If you set the value of this setting to ``True``, you should make sure you've
activated ``AuthenticationMiddleware``.
-See :doc:`/topics/cache`.
-
.. setting:: CACHE_MIDDLEWARE_KEY_PREFIX
CACHE_MIDDLEWARE_KEY_PREFIX
View
@@ -238,6 +238,9 @@ Minor features
Meta option: ``localized_fields``. Fields included in this list will be localized
(by setting ``localize`` on the form field).
+* The ``choices`` argument to model fields now accepts an iterable of iterables
+ instead of requiring an iterable of lists or tuples.
+
Backwards incompatible changes in 1.6
=====================================
@@ -491,6 +494,11 @@ Miscellaneous
memcache backend no longer uses the default timeout, and now will
set-and-expire-immediately the value.
+* The ``django.contrib.flatpages`` app used to set custom HTTP headers for
+ debugging purposes. This functionality was not documented and made caching
+ ineffective so it has been removed, along with its generic implementation,
+ previously available in ``django.core.xheaders``.
+
Features deprecated in 1.6
==========================
@@ -561,6 +569,23 @@ If necessary, you can temporarily disable auto-escaping with
:func:`~django.utils.safestring.mark_safe` or :ttag:`{% autoescape off %}
<autoescape>`.
+``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``CacheMiddleware`` used to provide a way to cache requests only if they
+weren't made by a logged-in user. This mechanism was largely ineffective
+because the middleware correctly takes into account the ``Vary: Cookie`` HTTP
+header, and this header is being set on a variety of occasions, such as:
+
+* accessing the session, or
+* using CSRF protection, which is turned on by default, or
+* using a client-side library which sets cookies, like `Google Analytics`__.
+
+This makes the cache effectively work on a per-session basis regardless of the
+``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting.
+
+__ http://www.google.com/analytics/
+
``SEND_BROKEN_LINK_EMAILS`` setting
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
View
@@ -443,15 +443,9 @@ Then, add the following required settings to your Django settings file:
The cache middleware caches GET and HEAD responses with status 200, where the request
and response headers allow. Responses to requests for the same URL with different
query parameters are considered to be unique pages and are cached separately.
-Optionally, if the :setting:`CACHE_MIDDLEWARE_ANONYMOUS_ONLY`
-setting is ``True``, only anonymous requests (i.e., not those made by a
-logged-in user) will be cached. This is a simple and effective way of disabling
-caching for any user-specific pages (including Django's admin interface). Note
-that if you use :setting:`CACHE_MIDDLEWARE_ANONYMOUS_ONLY`, you should make
-sure you've activated ``AuthenticationMiddleware``. The cache middleware
-expects that a HEAD request is answered with the same response headers as
-the corresponding GET request; in which case it can return a cached GET
-response for HEAD request.
+The cache middleware expects that a HEAD request is answered with the same
+response headers as the corresponding GET request; in which case it can return
+a cached GET response for HEAD request.
Additionally, the cache middleware automatically sets a few headers in each
:class:`~django.http.HttpResponse`:
@@ -125,6 +125,17 @@ and the :setting:`SECRET_KEY` setting.
.. warning::
+ **If the :setting:`SECRET_KEY` is not kept secret, this can lead to
+ arbitrary remote code execution.**
+
+ An attacker in possession of the :setting:`SECRET_KEY` can not only
+ generate falsified session data, which your site will trust, but also
+ remotely execute arbitrary code, as the data is serialized using pickle.
+
+ If you use cookie-based sessions, pay extra care that your secret key is
+ always kept completely secret, for any system which might be remotely
+ accessible.
+
**The session data is signed but not encrypted**
When using the cookies backend the session data can be read by the client.
Oops, something went wrong.

0 comments on commit dc8814b

Please sign in to comment.