Opened 12 years ago
Closed 12 years ago
#21056 closed Cleanup/optimization (fixed)
AdminSite app_list may be reverse()'d into an invalid URL endpoint
| Reported by: | Owned by: | ||
|---|---|---|---|
| Component: | contrib.admin | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Because of the way the regular expression for the app_index view is set, it allows pretty much anything to be reversed to a valid URL, even if that URL will generate a 404 when visited. This is in contrast to any of the views defined in the ModelAdmin's own get_urls, because they are included by way of the app_label for that ModelAdmin's Model class, and are usually resolved using the named url which is a combination of the app label + model name.
>>> from django.core.urlresolvers import reverse
>>> reverse('admin:index') # this is ok!
'/admin/'
>>> reverse('admin:app_list', kwargs={'app_label': 'auth'}) # this is ok!
'/admin/auth/'
>>> reverse('admin:app_list', kwargs={'app_label': 'test_anything_is_allowed'}) # chances are this isn't right.
'/admin/test_anything_is_allowed/'
As the registry already maintains a list of ModelAdmins, it would probably be reasonably simple to iterate over those and get all distinct app labels, and compile one regex that ORs them altogether, reducing the ability to accidentally create invalid links.
Change History (7)
comment:1 by , 12 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:2 by , 12 years ago
comment:3 by , 12 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:4 by , 12 years ago
| Owner: | removed |
|---|---|
| Status: | assigned → new |
comment:5 by , 12 years ago
As Dan has removed himself, but verified the problem [thanks!], I've whipped up a first pass at fixing it; Pull request is here, tested locally using:
PYTHONPATH=..:$PYTHONPATH python ./runtests.py --settings=test_sqlite
Essentially it saves the app labels until it's mounted the various individual modeladmins, and then compiles a regex of the form: ^(?P<app_label>app1|app2|app3|app4)/$ so that only those which are valid are resolvable. It also stops the app index being registered if there aren't any apps mounted, though I cannot imagine a reasonable scenario in which that is the case.
comment:6 by , 12 years ago
| Has patch: | set |
|---|
comment:7 by , 12 years ago
| Owner: | set to |
|---|---|
| Resolution: | → fixed |
| Status: | new → closed |
I can confirm this issue. Very straightforward to reproduce this issue.