#10686: Add class name interpolation in Meta.permissions codenames
-------------------------------------+-------------------------------------
     Reporter:  faldridge            |                    Owner:  (none)
         Type:  New feature          |                   Status:  new
    Component:  Database layer       |                  Version:  dev
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  permissions          |             Triage Stage:  Accepted
  inheritance                        |
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Old description:

> I've got a patch for a slight behavior modification that I needed and
> that might be useful for others, and I wanted to collect some thoughts on
> it before writing up the regression tests and documentation changes.
>
> Twice now, I've come across a situation where the default Django behavior
> for inheriting permissions is inappropriate for my security model.
>
> Here's the situation: I have a permission on an abstract base model class
> that I want all child classes to inherit, and I want to then append
> specific permission(s) to one or more of the children.
>
> Example:
> {{{
> #!python
> class MyAppBaseModel(models.Model):
>     class Meta:
>         abstract = True
>         permissions = (("view_%(class)s", "Can view %(class)s"),)
>
> class ChildModel(MyAppBaseModel):
>     class Meta:
>         permissions =  (("foobar_childmodel", "Can foobar childmodel"),)
> }}}
>
> Two problems arise:
>     1.  Although permissions currently may be inherited, the Options
> class does not currently implement %(class)s replacement like the
> RelatedField class does, so my permissions end up actually being stored
> in the database with %(class)s in the name and codename.
>     2.  The way Meta attributes are currently processed in the ModelBase
> metaclass causes inherited permissions to be completely replaced if any
> explicit permissions are defined on the child class.  So instead of
> can_view and can_foobar on ChildModel, I only get can_foobar.
>

> This patch changes Django's behavior such that any explicit child class
> permissions would be appended to the inherited ones, rather than
> completely replacing them.
>
> Also, I've added a backwards-compatible flag to the Meta options,
> 'inherit_permissions'.  This flag would only be required in the case that
> one wanted Django's current behavior which is to discard base class
> permissions when explicit permissions are declared on the child class.
>
> Example:
> {{{
> #!python
> class MyAppBaseModel(models.Model):
>     class Meta:
>         abstract = True
>         permissions = (("view_%(class)s", "Can view %(class)s"),)
>
> class ChildModel(MyAppBaseModel):
>     class Meta:
>         permissions =  (("foobar_childmodel", "Can foobar childmodel"),)
>         inherit_permissions = False
> }}}
>
> This would result in ChildModel only having the can_foobar permission
> (Django's current behavior).  If you wanted to inherit/append the
> view_class
> permission instead (proposed behavior), you could set the attribute to
> True or leave it out entirely.
>
> This, of course, assumes that my desired behavior is what most other
> people would want.  I suspect, but am not certain that this is the case.
>
> Though a small change, I believe it requires a design decision.
>
> Thanks!

New description:



--

Comment (by [email protected]):

 Dear community,

 just picked this while figuring out how to build permission names
 dynamically.

 Here’s a new PR: https://github.com/django/django/pull/15936

 Open issues:

 * Tim Graham commented that the code may be [generating faulty
 
permissions](https://github.com/django/django/pull/6861#issuecomment-240427426).
 I checked the behavior in a dummy project, but cannot confirm. I struggled
 to write a test for this, because it needs real migrations, real data etc.
 in the database. Please let me know if there’s an example in the existing
 tests that I can check (the advanced testing docs don’t mention “defining
 a real model in a testcase” either)
 * Authors and version added are still missing – I’ll add this if it has a
 chance to get merged.
 * (Changed to `class` argument to `model_name´ – I believe this is more
 consistent with content types & auth

-- 
Ticket URL: <https://code.djangoproject.com/ticket/10686#comment:24>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018282f5a1a3-64ced2b0-33f1-413a-b238-12106f8f0ea6-000000%40eu-central-1.amazonses.com.

Reply via email to