7e404946e4
Refactored permission check for REST API viewsets. Removed old PermissionMixin. Cleaned up several views.py files.
197 lines
6.0 KiB
Python
197 lines
6.0 KiB
Python
from django.contrib.auth import login as auth_login
|
|
from django.contrib.auth import logout as auth_logout
|
|
from django.contrib.auth.forms import AuthenticationForm
|
|
from django.utils.translation import ugettext as _
|
|
from django.utils.translation import ugettext_lazy
|
|
from rest_framework import status
|
|
|
|
from openslides.core.config import config
|
|
from openslides.utils.rest_api import ModelViewSet, Response, detail_route
|
|
from openslides.utils.views import APIView, PDFView
|
|
|
|
from .models import Group, User
|
|
from .pdf import users_passwords_to_pdf, users_to_pdf
|
|
from .serializers import (
|
|
GroupSerializer,
|
|
UserFullSerializer,
|
|
UserShortSerializer,
|
|
)
|
|
|
|
|
|
# Viewsets for the REST API
|
|
|
|
class UserViewSet(ModelViewSet):
|
|
"""
|
|
API endpoint for users.
|
|
|
|
There are the following views: list, retrieve, create, partial_update,
|
|
update, destroy and reset_password.
|
|
"""
|
|
queryset = User.objects.all()
|
|
|
|
def check_view_permissions(self):
|
|
"""
|
|
Returns True if the user has required permissions.
|
|
"""
|
|
if self.action in ('list', 'retrieve'):
|
|
result = self.request.user.has_perm('users.can_see_name')
|
|
elif self.action in ('create', 'partial_update', 'update', 'destroy', 'reset_password'):
|
|
result = (self.request.user.has_perm('users.can_see_name') and
|
|
self.request.user.has_perm('users.can_see_extra_data') and
|
|
self.request.user.has_perm('users.can_manage'))
|
|
else:
|
|
result = False
|
|
return result
|
|
|
|
def get_serializer_class(self):
|
|
"""
|
|
Returns different serializer classes with respect to action and user's
|
|
permissions.
|
|
"""
|
|
if (self.action in ('create', 'partial_update', 'update') or
|
|
self.request.user.has_perm('users.can_see_extra_data')):
|
|
# Return the UserFullSerializer for edit requests or for
|
|
# list/retrieve requests of users with more permissions.
|
|
serializer_class = UserFullSerializer
|
|
else:
|
|
serializer_class = UserShortSerializer
|
|
return serializer_class
|
|
|
|
@detail_route(methods=['post'])
|
|
def reset_password(self, request, pk=None):
|
|
"""
|
|
View to reset the password (using the default password).
|
|
"""
|
|
user = self.get_object()
|
|
user.set_password(user.default_password)
|
|
user.save()
|
|
return Response({'detail': _('Password successfully reset.')})
|
|
|
|
|
|
class GroupViewSet(ModelViewSet):
|
|
"""
|
|
API endpoint for groups.
|
|
|
|
There are the following views: list, retrieve, create, partial_update,
|
|
update and destroy.
|
|
"""
|
|
queryset = Group.objects.all()
|
|
serializer_class = GroupSerializer
|
|
|
|
def check_view_permissions(self):
|
|
"""
|
|
Returns True if the user has required permissions.
|
|
"""
|
|
if self.action in ('list', 'retrieve'):
|
|
# Every authenticated user can list or retrieve groups.
|
|
# Anonymous users can do so if they are enabled.
|
|
result = self.request.user.is_authenticated() or config['general_system_enable_anonymous']
|
|
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
|
|
# Users with all app permissions can edit groups.
|
|
result = (self.request.user.has_perm('users.can_see_name') and
|
|
self.request.user.has_perm('users.can_see_extra_data') and
|
|
self.request.user.has_perm('users.can_manage'))
|
|
else:
|
|
# Deny request in any other case.
|
|
result = False
|
|
return result
|
|
|
|
def destroy(self, request, *args, **kwargs):
|
|
"""
|
|
Protects builtin groups 'Anonymous' (pk=1) and 'Registered' (pk=2)
|
|
from being deleted.
|
|
"""
|
|
instance = self.get_object()
|
|
if instance.pk in (1, 2):
|
|
self.permission_denied(request)
|
|
self.perform_destroy(instance)
|
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
|
|
|
|
|
# Special API views
|
|
|
|
class UserLoginView(APIView):
|
|
"""
|
|
Login the user via Ajax.
|
|
"""
|
|
http_method_names = ['post']
|
|
|
|
def post(self, *args, **kwargs):
|
|
form = AuthenticationForm(self.request, data=self.request.data)
|
|
if form.is_valid():
|
|
self.user = form.get_user()
|
|
auth_login(self.request, self.user)
|
|
self.success = True
|
|
else:
|
|
self.success = False
|
|
return super().post(*args, **kwargs)
|
|
|
|
def get_context_data(self, **context):
|
|
context['success'] = self.success
|
|
if self.success:
|
|
context['user_id'] = self.user.pk
|
|
return super().get_context_data(**context)
|
|
|
|
|
|
class UserLogoutView(APIView):
|
|
"""
|
|
Logout the user via Ajax.
|
|
"""
|
|
http_method_names = ['post']
|
|
|
|
def post(self, *args, **kwargs):
|
|
auth_logout(self.request)
|
|
return super().post(*args, **kwargs)
|
|
|
|
|
|
class WhoAmIView(APIView):
|
|
"""
|
|
Returns the id of the requesting user.
|
|
"""
|
|
http_method_names = ['get']
|
|
|
|
def get_context_data(self, **context):
|
|
"""
|
|
Appends the user id into the context.
|
|
|
|
Uses None for the anonymous user.
|
|
"""
|
|
return super().get_context_data(
|
|
user_id=self.request.user.pk,
|
|
**context)
|
|
|
|
|
|
# Views to generate PDFs
|
|
|
|
class UsersListPDF(PDFView):
|
|
"""
|
|
Generate the userliste as PDF.
|
|
"""
|
|
required_permission = 'users.can_see_extra_data'
|
|
filename = ugettext_lazy("user-list")
|
|
document_title = ugettext_lazy('List of Users')
|
|
|
|
def append_to_pdf(self, pdf):
|
|
"""
|
|
Append PDF objects.
|
|
"""
|
|
users_to_pdf(pdf)
|
|
|
|
|
|
class UsersPasswordsPDF(PDFView):
|
|
"""
|
|
Generate the access data welcome paper for all users as PDF.
|
|
"""
|
|
required_permission = 'users.can_manage'
|
|
filename = ugettext_lazy("User-access-data")
|
|
top_space = 0
|
|
|
|
def build_document(self, pdf_document, story):
|
|
pdf_document.build(story)
|
|
|
|
def append_to_pdf(self, pdf):
|
|
"""
|
|
Append PDF objects.
|
|
"""
|
|
users_passwords_to_pdf(pdf)
|