Loading django/contrib/admin/options.py +3 −1 Original line number Diff line number Diff line Loading @@ -485,8 +485,10 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): ) for related_object in related_objects: related_model = related_object.related_model remote_field = related_object.field.rel if (any(issubclass(model, related_model) for model in registered_models) and related_object.field.rel.get_related_field() == field): hasattr(remote_field, 'get_related_field') and remote_field.get_related_field() == field): return True return False Loading docs/releases/1.8.6.txt +3 −0 Original line number Diff line number Diff line Loading @@ -48,3 +48,6 @@ Bugfixes * Fixed a regression in ``URLValidator`` that allowed URLs with consecutive dots in the domain section (like ``http://example..com/``) to pass (:ticket:`25620`). * Fixed a crash with ``GenericRelation`` and ``BaseModelAdmin.to_field_allowed`` (:ticket:`25622`). tests/admin_views/admin.py +15 −12 Original line number Diff line number Diff line Loading @@ -30,18 +30,19 @@ from .models import ( EmptyModelHidden, EmptyModelMixin, EmptyModelVisible, ExplicitlyProvidedPK, ExternalSubscriber, Fabric, FancyDoodad, FieldOverridePost, FilteredManager, FooAccount, FoodDelivery, FunkyTag, Gadget, Gallery, Grommet, ImplicitlyGeneratedPK, Ingredient, InlineReference, InlineReferer, Inquisition, Language, Link, MainPrepopulated, ModelWithStringPrimaryKey, NotReferenced, OldSubscriber, OtherStory, Paper, Parent, ParentWithDependentChildren, Person, Persona, Picture, Pizza, Plot, PlotDetails, PluggableSearchPerson, Podcast, Post, PrePopulatedPost, PrePopulatedPostLargeSlug, PrePopulatedSubPost, Promo, Question, Recipe, Recommendation, Recommender, ReferencedByInline, ReferencedByParent, RelatedPrepopulated, Report, Reservation, Restaurant, RowLevelChangePermissionModel, Section, ShortMessage, Simple, Sketch, State, Story, StumpJoke, Subscriber, SuperVillain, Telegram, Thing, Topping, UnchangeableObject, UndeletableObject, UnorderedObject, UserMessenger, Villain, Vodcast, Whatsit, Widget, Worker, WorkHour, GenRelReference, Grommet, ImplicitlyGeneratedPK, Ingredient, InlineReference, InlineReferer, Inquisition, Language, Link, MainPrepopulated, ModelWithStringPrimaryKey, NotReferenced, OldSubscriber, OtherStory, Paper, Parent, ParentWithDependentChildren, Person, Persona, Picture, Pizza, Plot, PlotDetails, PluggableSearchPerson, Podcast, Post, PrePopulatedPost, PrePopulatedPostLargeSlug, PrePopulatedSubPost, Promo, Question, Recipe, Recommendation, Recommender, ReferencedByGenRel, ReferencedByInline, ReferencedByParent, RelatedPrepopulated, Report, Reservation, Restaurant, RowLevelChangePermissionModel, Section, ShortMessage, Simple, Sketch, State, Story, StumpJoke, Subscriber, SuperVillain, Telegram, Thing, Topping, UnchangeableObject, UndeletableObject, UnorderedObject, UserMessenger, Villain, Vodcast, Whatsit, Widget, Worker, WorkHour, ) Loading Loading @@ -932,6 +933,8 @@ site.register(ReferencedByParent) site.register(ChildOfReferer) site.register(ReferencedByInline) site.register(InlineReferer, InlineRefererAdmin) site.register(ReferencedByGenRel) site.register(GenRelReference) # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. # That way we cover all four cases: Loading tests/admin_views/models.py +11 −0 Original line number Diff line number Diff line Loading @@ -891,3 +891,14 @@ class ExplicitlyProvidedPK(models.Model): class ImplicitlyGeneratedPK(models.Model): name = models.IntegerField(unique=True) # Models for #25622 class ReferencedByGenRel(models.Model): content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') class GenRelReference(models.Model): references = GenericRelation(ReferencedByGenRel) tests/admin_views/tests.py +8 −0 Original line number Diff line number Diff line Loading @@ -640,6 +640,14 @@ class AdminViewBasicTest(AdminViewBasicTestCase): response = self.client.get(reverse('admin:admin_views_referencedbyinline_changelist'), {TO_FIELD_VAR: 'name'}) self.assertEqual(response.status_code, 200) # #25622 - Specifying a field of a model only referred by a generic # relation should raise DisallowedModelAdminToField. url = reverse('admin:admin_views_referencedbygenrel_changelist') with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: response = self.client.get(url, {TO_FIELD_VAR: 'object_id'}) self.assertEqual(response.status_code, 400) self.assertEqual(len(calls), 1) # We also want to prevent the add, change, and delete views from # leaking a disallowed field value. with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: Loading Loading
django/contrib/admin/options.py +3 −1 Original line number Diff line number Diff line Loading @@ -485,8 +485,10 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): ) for related_object in related_objects: related_model = related_object.related_model remote_field = related_object.field.rel if (any(issubclass(model, related_model) for model in registered_models) and related_object.field.rel.get_related_field() == field): hasattr(remote_field, 'get_related_field') and remote_field.get_related_field() == field): return True return False Loading
docs/releases/1.8.6.txt +3 −0 Original line number Diff line number Diff line Loading @@ -48,3 +48,6 @@ Bugfixes * Fixed a regression in ``URLValidator`` that allowed URLs with consecutive dots in the domain section (like ``http://example..com/``) to pass (:ticket:`25620`). * Fixed a crash with ``GenericRelation`` and ``BaseModelAdmin.to_field_allowed`` (:ticket:`25622`).
tests/admin_views/admin.py +15 −12 Original line number Diff line number Diff line Loading @@ -30,18 +30,19 @@ from .models import ( EmptyModelHidden, EmptyModelMixin, EmptyModelVisible, ExplicitlyProvidedPK, ExternalSubscriber, Fabric, FancyDoodad, FieldOverridePost, FilteredManager, FooAccount, FoodDelivery, FunkyTag, Gadget, Gallery, Grommet, ImplicitlyGeneratedPK, Ingredient, InlineReference, InlineReferer, Inquisition, Language, Link, MainPrepopulated, ModelWithStringPrimaryKey, NotReferenced, OldSubscriber, OtherStory, Paper, Parent, ParentWithDependentChildren, Person, Persona, Picture, Pizza, Plot, PlotDetails, PluggableSearchPerson, Podcast, Post, PrePopulatedPost, PrePopulatedPostLargeSlug, PrePopulatedSubPost, Promo, Question, Recipe, Recommendation, Recommender, ReferencedByInline, ReferencedByParent, RelatedPrepopulated, Report, Reservation, Restaurant, RowLevelChangePermissionModel, Section, ShortMessage, Simple, Sketch, State, Story, StumpJoke, Subscriber, SuperVillain, Telegram, Thing, Topping, UnchangeableObject, UndeletableObject, UnorderedObject, UserMessenger, Villain, Vodcast, Whatsit, Widget, Worker, WorkHour, GenRelReference, Grommet, ImplicitlyGeneratedPK, Ingredient, InlineReference, InlineReferer, Inquisition, Language, Link, MainPrepopulated, ModelWithStringPrimaryKey, NotReferenced, OldSubscriber, OtherStory, Paper, Parent, ParentWithDependentChildren, Person, Persona, Picture, Pizza, Plot, PlotDetails, PluggableSearchPerson, Podcast, Post, PrePopulatedPost, PrePopulatedPostLargeSlug, PrePopulatedSubPost, Promo, Question, Recipe, Recommendation, Recommender, ReferencedByGenRel, ReferencedByInline, ReferencedByParent, RelatedPrepopulated, Report, Reservation, Restaurant, RowLevelChangePermissionModel, Section, ShortMessage, Simple, Sketch, State, Story, StumpJoke, Subscriber, SuperVillain, Telegram, Thing, Topping, UnchangeableObject, UndeletableObject, UnorderedObject, UserMessenger, Villain, Vodcast, Whatsit, Widget, Worker, WorkHour, ) Loading Loading @@ -932,6 +933,8 @@ site.register(ReferencedByParent) site.register(ChildOfReferer) site.register(ReferencedByInline) site.register(InlineReferer, InlineRefererAdmin) site.register(ReferencedByGenRel) site.register(GenRelReference) # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. # That way we cover all four cases: Loading
tests/admin_views/models.py +11 −0 Original line number Diff line number Diff line Loading @@ -891,3 +891,14 @@ class ExplicitlyProvidedPK(models.Model): class ImplicitlyGeneratedPK(models.Model): name = models.IntegerField(unique=True) # Models for #25622 class ReferencedByGenRel(models.Model): content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') class GenRelReference(models.Model): references = GenericRelation(ReferencedByGenRel)
tests/admin_views/tests.py +8 −0 Original line number Diff line number Diff line Loading @@ -640,6 +640,14 @@ class AdminViewBasicTest(AdminViewBasicTestCase): response = self.client.get(reverse('admin:admin_views_referencedbyinline_changelist'), {TO_FIELD_VAR: 'name'}) self.assertEqual(response.status_code, 200) # #25622 - Specifying a field of a model only referred by a generic # relation should raise DisallowedModelAdminToField. url = reverse('admin:admin_views_referencedbygenrel_changelist') with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: response = self.client.get(url, {TO_FIELD_VAR: 'object_id'}) self.assertEqual(response.status_code, 400) self.assertEqual(len(calls), 1) # We also want to prevent the add, change, and delete views from # leaking a disallowed field value. with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: Loading