Hi, as far as I understand the documentation[1], django's architecture supports object permissions, but external apps like django-rules or django-guardian are supposed to provide actual implementations.
I think this approach is great. However, I believe that there are some key points where django core should provide more tooling so that the external apps can concentrate more on building the actual authentication backends. # DefaultObjectBackend (#20218) ModelBackend always returns `False` if an object is passed. Many developers expect object permissions to be a superset of model permissions. A DefaultObjectBackend could be added that does exactly that. By implementing it as a separate backend it is fully optional and does not break backwards compatibility. ``` class DefaultObjectBackend: def authenticate(self, username, password): return None def get_user_permissions(self, user, obj=None): if obj is None: return set() return user.get_user_permissions() def get_group_permissions(self, user, obj=None): if obj is None: return set() return user.get_group_permissions() def get_all_permissions(self, user, obj=None): if obj is None: return set() return user.get_all_permissions() def has_perm(self, user, perm, obj=None): if obj is not None: return user.has_perm(perm) ``` # PermissionRequiredMixin.get_permission_object() Currently, external apps have to ship their own mixin because the default one does not support object permissions. A new method `get_permission_object()` could be added. This is what django-guardian does. However, in django core it should return None by default for backwards compatibility (In django-guardian it falls back to `get_object()`). ``` class PermissionRequiredMixin: … def get_permission_object(self): return None def has_permission(self): perms = self.get_permission_required() permission_object = self.get_permission_object() return self.request.user.has_perms(perms, obj=permission_object) ``` # has_perm template tag Just as with PermissionRequiredMixin, the current way to check for permissions in templates does not support object permissions. A new has_perm template tag could be added that simply calls `user.has_perm()`. This approach is used by django-rules. ``` @register.simple_tag def has_perm(perm, user, obj=None): return user.has_perm(perm, obj) ``` # Add a BaseBackend Currently, writing an authentication backend is not as straight-forward as it could be. I propose to add a BaseBackend that implements some sane defaults: ``` class BaseBackend: def authenticate(self, username, password): return None def get_user_permissions(self, user, obj=None): return set() def get_group_permissions(self, user, obj=None): return set() def get_all_permissions(self, user, obj=None): perms = set() perms.update(self.get_user_permissions(user, obj=obj)) perms.update(self.get_group_permissions(user, obj=obj)) return perms def has_perm(self, user, perm, obj=None): perms = self.get_all_permissions(user, obj=obj) return perm in perms ``` All of these changes can easily be implemented and have little to no backwards incompatibility. However, they would provide a much stronger base for object permission in core. I am not sure whether this is desired from either the core team or the developers of external authentication apps though. What do you think? Should I proceed writing pull requests for the proposed changes? tobias [1]: https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#handling-object-permissions -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at https://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/c50b1518-9f7c-d090-a40b-70995bf2f731%40posteo.de. For more options, visit https://groups.google.com/d/optout.