Opened 3 weeks ago

Closed 7 days ago

Last modified 7 days ago

#37361 closed Bug (fixed)

Permission renames do not apply to a chain of RenameModel operations

Reported by: Jacob Walls Owned by: Md. Saikat Islam
Component: contrib.auth Version: 6.1
Severity: Release blocker Keywords:
Cc: artirix1927 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

#27489 implemented renaming permissions as part of RenameModel migration operations, but did not support a chain of multiple operations.

For a chain of renames A -> B -> C, the database is queried for permissions on A, and then for permissions on B, but because all planned renames are applied to the database in a second loop, the query for permissions on B in the first loop finds nothing, so no second permission rename is done in the second loop.

To reproduce:

  1. Define Class A
  2. makemigrations
  3. migrate (this creates permissions)
  4. Rename A -> B
  5. makemigrations (answer "Y" to the rename prompt)
  6. Rename B -> C
  7. makemigrations (answer "Y" to the rename prompt)
  8. migrate -v2 (this renames permissions)

Expected: permissions in database end with "C"
Actual:

Renamed permission(s): myapp.add_a → add_b
Renamed permission(s): myapp.change_a → change_b
Renamed permission(s): myapp.delete_a → delete_b
Renamed permission(s): myapp.view_a → view_b
Adding permission 'Permission object (49)'
Adding permission 'Permission object (50)'
Adding permission 'Permission object (51)'
Adding permission 'Permission object (52)'
  1. migrate myapp zero
RuntimeError: 4 permission rename conflict(s) detected.

Bug in a040f555069971192220122555f187530d679d53.

Change History (8)

comment:1 by Md. Saikat Islam, 3 weeks ago

I was able to reproduce it on Django 6.2.dev20260902172522. I’ll take this ticket once it’s marked as accepted. Looking forward to someone marking it as accepted.

comment:2 by Md. Saikat Islam, 3 weeks ago

Owner: set to Md. Saikat Islam
Status: new → assigned

comment:3 by Md. Saikat Islam, 2 weeks ago

Has patch: set
Needs tests: set
Triage Stage: Unreviewed → Accepted

comment:4 by Md. Saikat Islam, 2 weeks ago

Looking forward to get reviews: ​https://github.com/django/django/pull/22018

comment:5 by Jacob Walls, 7 days ago

Patch needs improvement: set

comment:6 by Jacob Walls, 7 days ago

Needs tests: unset
Patch needs improvement: unset
Triage Stage: Accepted → Ready for checkin

Pushed changes to account for the fact that codename is only unique together with content_type. Also tested backwards migrations more fully. The new version is good to go in my opinion.

comment:7 by Jacob Walls <jacobtylerwalls@…>, 7 days ago

Resolution: → fixed
Status: assigned → closed

In 7847227a:

Fixed #37361 -- Fixed permission renames for chained RenameModel operations.

rename_permissions_after_model_rename() previously queried the database
for permissions during each rename step before saving the planned changes.
For chained RenameModel operations (e.g. A -> B -> C), intermediate
permissions (e.g. add_b) were not yet written to the database, causing
subsequent rename steps to not detect permissions.

rename_permissions_after_model_rename() now tracks permission codename
updates in memory across the sequence of RenameModel operations in the
migration plan.

An unlikely edge case is also handled to prevent renaming other
permissions sharing the same codename in a single app.

Co-authored-by: Jacob Walls <jacobtylerwalls@…>

comment:8 by Jacob Walls <jacobtylerwalls@…>, 7 days ago

In 25872ef:

[6.1.x] Fixed #37361 -- Fixed permission renames for chained RenameModel operations.

rename_permissions_after_model_rename() previously queried the database
for permissions during each rename step before saving the planned changes.
For chained RenameModel operations (e.g. A -> B -> C), intermediate
permissions (e.g. add_b) were not yet written to the database, causing
subsequent rename steps to not detect permissions.

rename_permissions_after_model_rename() now tracks permission codename
updates in memory across the sequence of RenameModel operations in the
migration plan.

An unlikely edge case is also handled to prevent renaming other
permissions sharing the same codename in a single app.

Co-authored-by: Jacob Walls <jacobtylerwalls@…>

Backport of 7847227a3fecde4b2a169552b84c60c6286b6025 from main.

Note: See TracTickets for help on using tickets.
Back to Top