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