Skip to content

Authorization

Theory

Authorization is the definition of the rights of individual users. Let's take a look at the admin interface for the Groups model. Groups combine users with permissions to manage specific "parts" of the database. You can also directly connect users with permissions. The administrator panel allows you to log into it

  • Administrator who can perform any operation on the data

  • Personnel who can perform the operations for which they are authorized

From the model level, in addition to the default permissions, we can add our own. Own rights do not have the default service in the administrator panel.

Checking permissions

In normal views, we can also check the permissions of each user. When checking user permissions, we are not interested to which group the user belongs, but whether any group to which it belongs has certain permissions. We don't have to worry about this relationship, because this check will be done by Django - we just need to declare what permission we want. We can check whether the user has certain rights

  • Decorator @permission_required

  • Mixin PermissionRequiredMixin

Let's check the user's permissions when manipulating the movie entry. The expected permission should be put as a string in a static variable permission_required

from django.contrib.auth.mixins import (
  LoginRequiredMixin, PermissionRequiredMixin
)


class MovieCreateView(PermissionRequiredMixin, CreateView):
  template_name = 'form.html'
  form_class = MovieForm
  success_url = reverse_lazy('viewer:movie_list')
  permission_required = 'viewer.add_movie'


class MovieUpdateView(PermissionRequiredMixin, UpdateView):
  template_name = 'form.html'
  model = Movie
  form_class = MovieForm
  success_url = reverse_lazy('viewer:movie_list')
  permission_required = 'viewer.change_movie'


class MovieDeleteView(PermissionRequiredMixin, DeleteView):
  template_name = 'movie_confirm_delete.html'
  model = Movie
  success_url = reverse_lazy('viewer:movie_list')
  permission_required = 'viewer.delete_movie'

Authorization test

Django also provides us with tools to perform any authorization test. They are

  • Decorator @user_passes_test

  • Mixin UserPassesTestMixin

In the case of destructive operations, we should additionally check whether we are really dealing with the staff or the administrator. For this, in addition to inheritance, we need to implement the test_func function. Since the staff is checked in two views, this test should be excluded for the StaffRequiredMixin admix we created.

from django.contrib.auth.mixins import (
  LoginRequiredMixin, PermissionRequiredMixin, UserPassesTestMixin
)
class StaffRequiredMixin(UserPassesTestMixin):
  def test_func(self):
    return self.request.user.is_staff


class MovieListView(ListView):
  template_name = 'movie_list.html'
  model = Movie


class MovieUpdateView(
  StaffRequiredMixin, PermissionRequiredMixin, UpdateView
):
  template_name = 'form.html'
  model = Movie
  form_class = MovieForm
  success_url = reverse_lazy('viewer:movie_list')
  permission_required = 'viewer.change_movie'


class MovieDeleteView(
  StaffRequiredMixin, PermissionRequiredMixin, DeleteView
):

  template_name = 'movie_confirm_delete.html'
  model = Movie
  success_url = reverse_lazy('viewer:movie_list')
  permission_required = 'viewer.delete_movie'

  def test_func(self):
    return super().test_func() and self.request.user.is_superuser

Practical Notes

  • The permissions are verified automatically by the administrator panel

  • On the side of the website we create, we have to check them ourselves!

  • The administrator has all rights in any situation, even if he does not belong to the group