mirror of https://github.com/django/django.git
Fixed #23601 -- Ensured view exists in URLconf before importing it in admindocs.
This commit is contained in:
parent
a24cf21722
commit
2f16ff5a6c
|
@ -143,10 +143,11 @@ class ViewDetailView(BaseAdminDocsView):
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
view = self.kwargs['view']
|
view = self.kwargs['view']
|
||||||
mod, func = urlresolvers.get_mod_func(view)
|
urlconf = urlresolvers.get_urlconf()
|
||||||
try:
|
if urlresolvers.get_resolver(urlconf)._is_callback(view):
|
||||||
|
mod, func = urlresolvers.get_mod_func(view)
|
||||||
view_func = getattr(import_module(mod), func)
|
view_func = getattr(import_module(mod), func)
|
||||||
except (ImportError, AttributeError):
|
else:
|
||||||
raise Http404
|
raise Http404
|
||||||
title, body, metadata = utils.parse_docstring(view_func.__doc__)
|
title, body, metadata = utils.parse_docstring(view_func.__doc__)
|
||||||
if title:
|
if title:
|
||||||
|
|
|
@ -353,6 +353,11 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
self._populate()
|
self._populate()
|
||||||
return self._app_dict[language_code]
|
return self._app_dict[language_code]
|
||||||
|
|
||||||
|
def _is_callback(self, name):
|
||||||
|
if not self._populated:
|
||||||
|
self._populate()
|
||||||
|
return name in self._callback_strs
|
||||||
|
|
||||||
def resolve(self, path):
|
def resolve(self, path):
|
||||||
path = force_text(path) # path may be a reverse_lazy object
|
path = force_text(path) # path may be a reverse_lazy object
|
||||||
tried = []
|
tried = []
|
||||||
|
@ -430,7 +435,7 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
|
|
||||||
original_lookup = lookup_view
|
original_lookup = lookup_view
|
||||||
try:
|
try:
|
||||||
if lookup_view in self._callback_strs:
|
if self._is_callback(lookup_view):
|
||||||
lookup_view = get_callable(lookup_view, True)
|
lookup_view = get_callable(lookup_view, True)
|
||||||
except (ImportError, AttributeError) as e:
|
except (ImportError, AttributeError) as e:
|
||||||
raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e))
|
raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e))
|
||||||
|
|
|
@ -76,6 +76,14 @@ Minor features
|
||||||
<django.contrib.admin.ModelAdmin.show_full_result_count>` to control whether
|
<django.contrib.admin.ModelAdmin.show_full_result_count>` to control whether
|
||||||
or not the full count of objects should be displayed on a filtered admin page.
|
or not the full count of objects should be displayed on a filtered admin page.
|
||||||
|
|
||||||
|
:mod:`django.contrib.admindocs`
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
* The view to browse view details now checks if the view specified in the URL
|
||||||
|
exists in the URLconf. Previously it was possible to import arbitrary
|
||||||
|
packages from the Python path. This was not considered a security issue
|
||||||
|
because ``admindocs`` is only accessible to staff users.
|
||||||
|
|
||||||
:mod:`django.contrib.auth`
|
:mod:`django.contrib.auth`
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -84,6 +85,16 @@ class AdminDocViewTests(AdminDocsTestCase):
|
||||||
# View docstring
|
# View docstring
|
||||||
self.assertContains(response, 'Base view for admindocs views.')
|
self.assertContains(response, 'Base view for admindocs views.')
|
||||||
|
|
||||||
|
def test_view_detail_illegal_import(self):
|
||||||
|
"""
|
||||||
|
#23601 - Ensure the view exists in the URLconf.
|
||||||
|
"""
|
||||||
|
response = self.client.get(
|
||||||
|
reverse('django-admindocs-views-detail',
|
||||||
|
args=['urlpatterns_reverse.nonimported_module.view']))
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
self.assertNotIn("urlpatterns_reverse.nonimported_module", sys.modules)
|
||||||
|
|
||||||
def test_model_index(self):
|
def test_model_index(self):
|
||||||
response = self.client.get(reverse('django-admindocs-models-index'))
|
response = self.client.get(reverse('django-admindocs-models-index'))
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
|
|
Loading…
Reference in New Issue