Opened 4 days ago
Last modified 4 days ago
#36843 closed Bug
RenamePermission might operate on unrelated models — at Initial Version
| Reported by: | Jacob Walls | Owned by: | |
|---|---|---|---|
| Component: | contrib.auth | Version: | 6.0 |
| Severity: | Release blocker | Keywords: | |
| Cc: | Artyom Kotovskiy | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
As of Django 6.0 (#27489), when a migration contains a RenameModel operation, ephemeral RenamePermission operations are injected to sync the name & codename of the model's permission records.
As mentioned in https://github.com/django/django/pull/20339#discussion_r2653481704, we discovered that the ephemeral operation might operate on unrelated models owing to its use of model__icontains:
ctypes = ContentType.objects.using(db).filter( app_label=self.app_label, model__icontains=old_model.lower() ) for permission in Permission.objects.using(db).filter( content_type_id__in=ctypes.values("id") ):
To reproduce:
- Have
SongandSongProfilemodels, assign a view permission onSongProfileto a user - Rename
SongtoSon, migrate RenamePermissionadjusts the four permissions on each model (8 perms total) to all have "son" in the name & codename- Permissions are now missing for
SongProfile, so they get regenerated by the post_migrate handler - existing user/group assignments (e.g. the one created above) are now pointing to the wrong permission ("add_son" with a content type pointing to
SongProfile)
Unlike #36793, which hinged on the existence of stale records causing conflicts (possibly from reapplying or reversing migrations in environments that had stale permissions before Django 6), this scenario doesn't involve any duplicates, and the models in step 2 don't need to be the same as step 1, just have common substrings. I reused a model for convenience, but the point is that an unrelated model's permissions are being affected.
Suggesting to revert of f02b49d2f3bf84f5225de920ca510149f1f9f1da and that we address the issues identified in https://github.com/django/django/pull/20481 (which was a first pass at identifying & fixing) with more breathing room in a future version.