I feel like the interface for authentication backends is unnecessarily
complex: Basically, you only need authenticate() and has_perm(), but
currently the interface also includes get_group_permissions(),
get_all_permissions(), and has_module_perms().

The architecture is like this: User inherits from PermissionMixin which
implements the methods get_group_permissions(), get_all_permissions(),
has_perm(), has_perms(), and has_module_perms().

All of these methods basically just call the corresponding methods on
the authentication backends, if available. has_perms() is the only
exception, as it is just a shortcut to call has_perm() multiple times.

I believe that has_perm() is vastly more important than
get_*_permissions(). Still, I can understand that the latter exist. What
I find confusing is that there is no get_user_permissions() in this
interface. Whithout its counterpart, get_group_permissions() seems
pretty much useless to me. Also note that the separation between user
and group permissions may not be applicable with custom backends.

Another issue is that developers can easily end up with inconsistent
backends: There is no guarantee that get_all_permissions() will return a
superset of get_group_permissions(). There is also no guarantee that
has_perm() will be equivalent to `perm in get_all_permissions()`.

Then there is the issue of has_module_perms(). As far as I understand,
this should have been called has_app_perms(). It is used in
contrib.admin where it makes a lot of sense, but I don't really see how
it could be useful anywhere else.

I looked at some popular backends to see how they are implemented:

The default ModelBackend implements get_user_permissions() and
get_group_permissions(). get_all_permissions() joins their results and
has_perm() and has_module_perms() call get_all_permissions(). The
results of get_all_permissions() are cached.

django-guardian works pretty much the same. However, even though the
mechanism is the same, get_group_permissions() is not exposed in the
interface. has_module_perms() is missing.

django-rules only implements has_perm(). get_*_permissions() are
missing. has_module_perms() exists, but it is just an alias to
has_perm().

I guess the benefits of simplifying the interface do not justify
breaking changes for most of these issues. However, I think there are
two changes that could significantly improve the situation:

-   Either add get_user_permissions() or remove get_group_permissions()
-   Add default implementations for get_all_permissions() and
    has_perm(), either in PermissionMixin or in a new BaseBackend class.

Any thoughts?

tobias

-- 
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/9eb25389-d59e-1f6c-4b50-d1c7a986f923%40posteo.de.
For more options, visit https://groups.google.com/d/optout.

Reply via email to