Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#32236 closed Cleanup/optimization (wontfix)

LoginRequiredMixin and PermissionRequiredMixin could use UserPassesTestMixin

Reported by: Jaap Roes Owned by: Jerin Peter George
Component: contrib.auth Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Currently django.contrib.auth.mixins defines LoginRequiredMixin and PermissionRequiredMixin as subclasses of AccessMixin.

It also defines an abstract UserPassesTestMixin that requires an implementation of test_func (or get_test_func).
Both LoginRequiredMixin and PermissionRequiredMixin perform tests on the current user and could be implemented subclasses of UserPassesTestMixin with an implementation of test_func (or get_test_func). That way they can re-use the dispatch logic in UserPassesTestMixin.

i.e.:

class LoginRequiredMixin(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.is_authenticated


class PermissionRequiredMixin(UserPassesTestMixin):
    """Verify that the current user has all specified permissions."""
    permission_required = None

    def get_permission_required(self):
        """
        Override this method to override the permission_required attribute.
        Must return an iterable.
        """
        if self.permission_required is None:
            raise ImproperlyConfigured(
                '{0} is missing the permission_required attribute. Define {0}.permission_required, or override '
                '{0}.get_permission_required().'.format(self.__class__.__name__)
            )
        if isinstance(self.permission_required, str):
            perms = (self.permission_required,)
        else:
            perms = self.permission_required
        return perms

    def has_permission(self):
        """
        Override this method to customize the way permissions are checked.
        """
        perms = self.get_permission_required()
        return self.request.user.has_perms(perms)

    def get_test_func(self):
        return self.has_permission

Change History (7)

comment:1 by Mariusz Felisiak, 4 years ago

Triage Stage: UnreviewedAccepted

comment:2 by Jerin Peter George, 4 years ago

Owner: changed from nobody to Jerin Peter George
Status: newassigned

comment:3 by Jerin Peter George, 4 years ago

Has patch: set
Version 0, edited 4 years ago by Jerin Peter George (next)

comment:4 by Jerin Peter George, 4 years ago

I would like to write the related docs, but I wish to know whether my implementations are okay or not.

comment:5 by Mariusz Felisiak, 4 years ago

Patch needs improvement: set

comment:6 by Mariusz Felisiak, 4 years ago

Has patch: unset
Patch needs improvement: unset
Resolution: wontfix
Status: assignedclosed

Unfortunately, due to the way UserPassesTestMixin is implemented, you cannot stack them in your inheritance list, so LoginRequiredMixin/PermissionRequiredMixin cannot subclass it, see Stacking UserPassesTestMixin.

comment:7 by Jaap Roes, 4 years ago

Oh wow, I didn't realize this was a known flaw in the design of UserPassesTestMixin, sorry for the noise.

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