Created
June 9, 2011 20:41
-
-
Save ulope/1017687 to your computer and use it in GitHub Desktop.
django #15552 patch v1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From cccb047c79211bfa3f89760a206009f706168728 Mon Sep 17 00:00:00 2001 | |
From: Ulrich Petri <[email protected]> | |
Date: Thu, 9 Jun 2011 22:38:33 +0200 | |
Subject: [PATCH] Refactored settings.LOGIN_URL, LOGIN_REDIRECT_URL to use the logic from django.shortcuts.redirect (i.e. allow view names in LOGIN_URL, et. al.) | |
--- | |
django/contrib/auth/decorators.py | 5 ++- | |
django/contrib/auth/tests/decorators.py | 2 +- | |
django/contrib/auth/views.py | 13 +++++--- | |
django/shortcuts/__init__.py | 19 +---------- | |
django/utils/url.py | 33 ++++++++++++++++++++ | |
.../comment_tests/tests/__init__.py | 2 +- | |
.../regressiontests/comment_tests/urls_default.py | 9 +++++ | |
tests/runtests.py | 2 +- | |
8 files changed, 58 insertions(+), 27 deletions(-) | |
create mode 100644 django/utils/url.py | |
create mode 100644 tests/regressiontests/comment_tests/urls_default.py | |
diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py | |
index 00a6bce..c0aa1c4 100644 | |
--- a/django/contrib/auth/decorators.py | |
+++ b/django/contrib/auth/decorators.py | |
@@ -3,6 +3,7 @@ from functools import wraps | |
from django.conf import settings | |
from django.contrib.auth import REDIRECT_FIELD_NAME | |
from django.utils.decorators import available_attrs | |
+from django.utils.url import resolve_url | |
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): | |
@@ -20,8 +21,8 @@ def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIE | |
path = request.build_absolute_uri() | |
# If the login url is the same scheme and net location then just | |
# use the path as the "next" url. | |
- login_scheme, login_netloc = urlparse.urlparse(login_url or | |
- settings.LOGIN_URL)[:2] | |
+ login_scheme, login_netloc = urlparse.urlparse( | |
+ resolve_url(login_url or settings.LOGIN_URL))[:2] | |
current_scheme, current_netloc = urlparse.urlparse(path)[:2] | |
if ((not login_scheme or login_scheme == current_scheme) and | |
(not login_netloc or login_netloc == current_netloc)): | |
diff --git a/django/contrib/auth/tests/decorators.py b/django/contrib/auth/tests/decorators.py | |
index bd3f011..dd41a32 100644 | |
--- a/django/contrib/auth/tests/decorators.py | |
+++ b/django/contrib/auth/tests/decorators.py | |
@@ -25,7 +25,7 @@ class LoginRequiredTestCase(AuthViewsTestCase): | |
pass | |
login_required(normal_view) | |
- def testLoginRequired(self, view_url='/login_required/', login_url=settings.LOGIN_URL): | |
+ def testLoginRequired(self, view_url='/login_required/', login_url="/login/"): | |
""" | |
Check that login_required works on a simple view wrapped in a | |
login_required decorator. | |
diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py | |
index 4995f89..8d63177 100644 | |
--- a/django/contrib/auth/views.py | |
+++ b/django/contrib/auth/views.py | |
@@ -6,6 +6,7 @@ from django.http import HttpResponseRedirect, QueryDict | |
from django.template.response import TemplateResponse | |
from django.utils.http import base36_to_int | |
from django.utils.translation import ugettext as _ | |
+from django.utils.url import resolve_url | |
from django.views.decorators.debug import sensitive_post_parameters | |
from django.views.decorators.cache import never_cache | |
from django.views.decorators.csrf import csrf_protect | |
@@ -34,16 +35,16 @@ def login(request, template_name='registration/login.html', | |
if request.method == "POST": | |
form = authentication_form(data=request.POST) | |
if form.is_valid(): | |
- netloc = urlparse.urlparse(redirect_to)[1] | |
- | |
# Use default setting if redirect_to is empty | |
if not redirect_to: | |
redirect_to = settings.LOGIN_REDIRECT_URL | |
+ redirect_to = resolve_url(redirect_to) | |
+ netloc = urlparse.urlparse(redirect_to)[1] | |
# Heavier security check -- don't allow redirection to a different | |
# host. | |
- elif netloc and netloc != request.get_host(): | |
- redirect_to = settings.LOGIN_REDIRECT_URL | |
+ if netloc and netloc != request.get_host(): | |
+ redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) | |
# Okay, security checks complete. Log the user in. | |
auth_login(request, form.get_user()) | |
@@ -106,6 +107,7 @@ def logout_then_login(request, login_url=None, current_app=None, extra_context=N | |
""" | |
if not login_url: | |
login_url = settings.LOGIN_URL | |
+ login_url = resolve_url(login_url) | |
return logout(request, login_url, current_app=current_app, extra_context=extra_context) | |
def redirect_to_login(next, login_url=None, | |
@@ -115,6 +117,7 @@ def redirect_to_login(next, login_url=None, | |
""" | |
if not login_url: | |
login_url = settings.LOGIN_URL | |
+ login_url = resolve_url(login_url) | |
login_url_parts = list(urlparse.urlparse(login_url)) | |
if redirect_field_name: | |
@@ -223,7 +226,7 @@ def password_reset_complete(request, | |
template_name='registration/password_reset_complete.html', | |
current_app=None, extra_context=None): | |
context = { | |
- 'login_url': settings.LOGIN_URL | |
+ 'login_url': resolve_url(settings.LOGIN_URL) | |
} | |
if extra_context is not None: | |
context.update(extra_context) | |
diff --git a/django/shortcuts/__init__.py b/django/shortcuts/__init__.py | |
index 9f97cae..4dc74d3 100644 | |
--- a/django/shortcuts/__init__.py | |
+++ b/django/shortcuts/__init__.py | |
@@ -10,6 +10,7 @@ from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect | |
from django.db.models.manager import Manager | |
from django.db.models.query import QuerySet | |
from django.core import urlresolvers | |
+from django.utils.url import resolve_url | |
def render_to_response(*args, **kwargs): | |
""" | |
@@ -66,23 +67,7 @@ def redirect(to, *args, **kwargs): | |
else: | |
redirect_class = HttpResponseRedirect | |
- # If it's a model, use get_absolute_url() | |
- if hasattr(to, 'get_absolute_url'): | |
- return redirect_class(to.get_absolute_url()) | |
- | |
- # Next try a reverse URL resolution. | |
- try: | |
- return redirect_class(urlresolvers.reverse(to, args=args, kwargs=kwargs)) | |
- except urlresolvers.NoReverseMatch: | |
- # If this is a callable, re-raise. | |
- if callable(to): | |
- raise | |
- # If this doesn't "feel" like a URL, re-raise. | |
- if '/' not in to and '.' not in to: | |
- raise | |
- | |
- # Finally, fall back and assume it's a URL | |
- return redirect_class(to) | |
+ return redirect_class(resolve_url(to, *args, **kwargs)) | |
def _get_queryset(klass): | |
""" | |
diff --git a/django/utils/url.py b/django/utils/url.py | |
new file mode 100644 | |
index 0000000..f7d0e0b | |
--- /dev/null | |
+++ b/django/utils/url.py | |
@@ -0,0 +1,33 @@ | |
+from django.core import urlresolvers | |
+ | |
+def resolve_url(to, *args, **kwargs): | |
+ """ | |
+ Returns an URL apropriate for the arguments | |
+ passed. | |
+ | |
+ The arguments could be: | |
+ | |
+ * A model: the model's `get_absolute_url()` function will be called. | |
+ | |
+ * A view name, possibly with arguments: `urlresolvers.reverse()` will | |
+ be used to reverse-resolve the name. | |
+ | |
+ * A URL, which will be returned as-is. | |
+ """ | |
+ # If it's a model, use get_absolute_url() | |
+ if hasattr(to, 'get_absolute_url'): | |
+ return to.get_absolute_url() | |
+ | |
+ # Next try a reverse URL resolution. | |
+ try: | |
+ return urlresolvers.reverse(to, args=args, kwargs=kwargs) | |
+ except urlresolvers.NoReverseMatch: | |
+ # If this is a callable, re-raise. | |
+ if callable(to): | |
+ raise | |
+ # If this doesn't "feel" like a URL, re-raise. | |
+ if '/' not in to and '.' not in to: | |
+ raise | |
+ | |
+ # Finally, fall back and assume it's a URL | |
+ return to | |
diff --git a/tests/regressiontests/comment_tests/tests/__init__.py b/tests/regressiontests/comment_tests/tests/__init__.py | |
index 88c6f33..7fc5e29 100644 | |
--- a/tests/regressiontests/comment_tests/tests/__init__.py | |
+++ b/tests/regressiontests/comment_tests/tests/__init__.py | |
@@ -12,7 +12,7 @@ CT = ContentType.objects.get_for_model | |
# Helper base class for comment tests that need data. | |
class CommentTestCase(TestCase): | |
fixtures = ["comment_tests"] | |
- urls = 'django.contrib.comments.urls' | |
+ urls = 'regressiontests.comment_tests.urls_default' | |
def createSomeComments(self): | |
# Two anonymous comments on two different objects | |
diff --git a/tests/regressiontests/comment_tests/urls_default.py b/tests/regressiontests/comment_tests/urls_default.py | |
new file mode 100644 | |
index 0000000..bfce8ff | |
--- /dev/null | |
+++ b/tests/regressiontests/comment_tests/urls_default.py | |
@@ -0,0 +1,9 @@ | |
+from django.conf.urls.defaults import * | |
+ | |
+urlpatterns = patterns('', | |
+ (r'^', include('django.contrib.comments.urls')), | |
+ | |
+ # Provide the auth system login and logout views | |
+ (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}), | |
+ (r'^accounts/logout/$', 'django.contrib.auth.views.logout'), | |
+) | |
diff --git a/tests/runtests.py b/tests/runtests.py | |
index 6da3299..77c9281 100755 | |
--- a/tests/runtests.py | |
+++ b/tests/runtests.py | |
@@ -113,7 +113,7 @@ def setup(verbosity, test_labels): | |
settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), TEST_TEMPLATE_DIR),) | |
settings.USE_I18N = True | |
settings.LANGUAGE_CODE = 'en' | |
- settings.LOGIN_URL = '/accounts/login/' | |
+ settings.LOGIN_URL = 'django.contrib.auth.views.login' | |
settings.MIDDLEWARE_CLASSES = ( | |
'django.contrib.sessions.middleware.SessionMiddleware', | |
'django.contrib.auth.middleware.AuthenticationMiddleware', | |
-- | |
1.7.0.2+GitX |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment