lambdalisue/django-inspectional-registration

Permissions bug prevents non-superusers from accepting/rejecting/activating registrations

coredumperror opened this issue · 3 comments

I have a Group called 'Admin', to which I have given every Registration related permission. However, my User, which is part of the Admin group, but not marked as a superuser, gets a PermissionDenied error whenever he tries to accept a user registration.

I traced the code, and determined that this is the fault of the RegistrationAdmin.has_accept_permission() method. Because it passes obj into the call to request.user.has_perm('registration.accept_registration', obj), Django's django.contrib.auth.backends.ModelBackend class automatically treats the user as having no permissions at all. Here are the relevant methods in ModelBackend:

def get_all_permissions(self, user_obj, obj=None):
    if user_obj.is_anonymous() or obj is not None:
        return set()
    if not hasattr(user_obj, '_perm_cache'):
        user_obj._perm_cache = set("%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related())
        user_obj._perm_cache.update(self.get_group_permissions(user_obj))
    return user_obj._perm_cache

def has_perm(self, user_obj, perm, obj=None):
    if not user_obj.is_active:
        return False
    return perm in self.get_all_permissions(user_obj, obj)

Notice that get_all_permissions() automatically returns an empty set when obj is not None. This is because Django's default permissions system doesn't support object-level permissions. It only supports Model-level permissions.

The fix for this is to stop passing obj into request.user.has_perm() in all three RegistrationAdmin.has_*_permission() methods.

Please fix this as soon as possible, as this is a showstopper bug for my site.

Thanks for the detail. The problem was fixed 3dbfc89

I was stupid... 94f64ee

Heh, I have totally done that before. "It's such a simple change! I'll just type it out and push it off."