mirror of
https://github.com/django/django.git
synced 2025-06-05 11:39:13 +00:00
added change that checks permissions when displaying url for recent changes
This commit is contained in:
parent
519087819e
commit
d8cb58ada8
@ -31,10 +31,10 @@
|
|||||||
{% for entry in admin_log %}
|
{% for entry in admin_log %}
|
||||||
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
|
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
|
||||||
<span class="visually-hidden">{% if entry.is_addition %}{% translate 'Added:' %}{% elif entry.is_change %}{% translate 'Changed:' %}{% elif entry.is_deletion %}{% translate 'Deleted:' %}{% endif %}</span>
|
<span class="visually-hidden">{% if entry.is_addition %}{% translate 'Added:' %}{% elif entry.is_change %}{% translate 'Changed:' %}{% elif entry.is_deletion %}{% translate 'Deleted:' %}{% endif %}</span>
|
||||||
{% if entry.is_deletion or not entry.get_admin_url %}
|
{% if entry.is_deletion or not entry.url %}
|
||||||
{{ entry.object_repr }}
|
{{ entry.object_repr }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
|
<a href="{{ entry.url }}">{{ entry.object_repr }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br>
|
<br>
|
||||||
{% if entry.content_type %}
|
{% if entry.content_type %}
|
||||||
|
@ -19,7 +19,22 @@ class AdminLogNode(template.Node):
|
|||||||
if not user_id.isdigit():
|
if not user_id.isdigit():
|
||||||
user_id = context[self.user].pk
|
user_id = context[self.user].pk
|
||||||
entries = entries.filter(user__pk=user_id)
|
entries = entries.filter(user__pk=user_id)
|
||||||
context[self.varname] = entries[: int(self.limit)]
|
filtered_context = entries.select_related("content_type", "user")[
|
||||||
|
: int(self.limit)
|
||||||
|
]
|
||||||
|
for entry in filtered_context:
|
||||||
|
content_type = entry.content_type
|
||||||
|
if not content_type:
|
||||||
|
entry.url = entry.get_admin_url()
|
||||||
|
continue
|
||||||
|
user = entry.user
|
||||||
|
view_permission_name = f"{content_type.app_label}.view_{content_type.model}"
|
||||||
|
user_has_permission = user.has_perm(view_permission_name)
|
||||||
|
if user_has_permission:
|
||||||
|
entry.url = entry.get_admin_url()
|
||||||
|
else:
|
||||||
|
entry.url = None
|
||||||
|
context[self.varname] = filtered_context
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
from django.contrib.admin.models import ADDITION, CHANGE, DELETION, LogEntry
|
from django.contrib.admin.models import ADDITION, CHANGE, DELETION, LogEntry
|
||||||
from django.contrib.admin.utils import quote
|
from django.contrib.admin.utils import quote
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User, Permission
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.test import TestCase, override_settings
|
from django.test import TestCase, override_settings
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@ -351,6 +351,32 @@ class LogEntryTests(TestCase):
|
|||||||
counted_presence_after = response.content.count(should_contain)
|
counted_presence_after = response.content.count(should_contain)
|
||||||
self.assertEqual(counted_presence_before - 1, counted_presence_after)
|
self.assertEqual(counted_presence_before - 1, counted_presence_after)
|
||||||
|
|
||||||
|
def test_recent_actions_user_lacks_view_permission(self):
|
||||||
|
# No permission to view articles. Log is a span with no link.
|
||||||
|
response = self.client.get(reverse("admin:index"))
|
||||||
|
should_contain = """<span class="mini quiet">Article</span>"""
|
||||||
|
self.assertContains(response, should_contain)
|
||||||
|
|
||||||
|
# Add permission to view articles. Log is a link.
|
||||||
|
logentry = LogEntry.objects.get(content_type__model__iexact="article")
|
||||||
|
view_permission_name = f"{logentry.content_type.app_label}.view_{logentry.content_type.model}"
|
||||||
|
view_article_permission = Permission.objects.create(
|
||||||
|
name=f"Can view {logentry.content_type.model}",
|
||||||
|
content_type=logentry.content_type,
|
||||||
|
codename=view_permission_name,
|
||||||
|
)
|
||||||
|
self.user.user_permissions.add(view_article_permission)
|
||||||
|
|
||||||
|
response = self.client.get(reverse("admin:index"))
|
||||||
|
expected_log_entry_link = reverse(
|
||||||
|
"admin:admin_utils_article_change", args=(quote(self.a1.pk),)
|
||||||
|
)
|
||||||
|
should_contain = """<a href="%s">%s</a>""" % (
|
||||||
|
escape(expected_log_entry_link),
|
||||||
|
escape(repr(self.a1)),
|
||||||
|
)
|
||||||
|
self.assertContains(response, should_contain)
|
||||||
|
|
||||||
def test_proxy_model_content_type_is_used_for_log_entries(self):
|
def test_proxy_model_content_type_is_used_for_log_entries(self):
|
||||||
"""
|
"""
|
||||||
Log entries for proxy models should have the proxy model's contenttype
|
Log entries for proxy models should have the proxy model's contenttype
|
||||||
|
Loading…
x
Reference in New Issue
Block a user