3

I am using Django 1.9. When I tried to add PermissionRequiredMixin to my class-based-view, it seems not to work as expected. I created a new user in a auth_group. This auth_group doesn't have any permission to any apps or models. This new user is not a superuser or admin user. But the app doesn't prevent this user from accessing to a particular view that needs permission_required.

Firstly, here is what I tried to make sure the user doesn't have permission:

user.get_all_permissions() # return set() - empty permission, which is correct.
user.is_superuser # return false, which is correct.
user.has_perm('myapp.add_something or even any words that make no sense')  # always return true, which is very weird.

The app has custom user model and also uses django-allauth as the AUTHENTICATION_BACKENDS. I am not sure if PermissionRequiredMixin will check user.has_perm() and it always return true so that's why checking permission doesn't work as expected?

# views.py
class My_View(PermissionRequiredMixin, View):
    permission_required = 'polls.can_vote'

    def get(self, request, *args, **kwargs):
        # do something...
        return render(request, "template.html", {})


# models.py - Custom User Model
class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    group = models.ManyToManyField(Group, through='UserGroupRelationship')
    .... 

# models.py - many-to-many relationship between user and group
class UserGroupRelationship(models.Model):
    user = models.ForeignKey("CustomUser") 
    user_group = models.ForeignKey(Group)

I also tried the old way to check permission in urls.py. It doesn't prevent user accessing either so I do not think that's the problem of using PermissionRequiredMixin.

urlpatterns = patterns('',

    (r'^vote/', permission_required('polls.can_vote')(VoteView.as_view())),
)
Joey
  • 2,732
  • 11
  • 43
  • 63

1 Answers1

3

After spending a few days on this problem, I eventually find out the cause.

When I looked into the source code about PermissionRequiredMixin, I found that PermissionRequiredMixin indeed checks user.has_perm(). When I tried to find the source code of has_perm(), I found that my codes (which is copied from the custom user model example from Django's document) contains the following overridden method...

def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

That's reason why user.has_perm('anything') always return true, which also affects the functionality of PermissionRequiredMixin. Therefore, if you are new to Django and try to copy some example codes from document, you need to be very careful about each line...

Joey
  • 2,732
  • 11
  • 43
  • 63
  • I searched for days too, thank god I found this. I cannot believe they do not explain this in the docs – diek Sep 18 '17 at 04:21