from django.views import View from django.views.generic.edit import CreateView from django.views.generic.detail import SingleObjectMixin from django.contrib import messages from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.shortcuts import redirect from django.urls import reverse_lazy from lostplaces_app.models import Place class IsAuthenticated(LoginRequiredMixin, View): ''' A view mixin that checks wether a user is loged in or not. If the user is not logged in, he gets redirected to the login page. ''' login_url = reverse_lazy('login') permission_denied_message = 'Please login to proceed' def handle_no_permission(self): messages.error(self.request, self.permission_denied_message) return super().handle_no_permission() class IsPlaceSubmitter(UserPassesTestMixin, View): ''' A view mixin that checks wethe a user is the submitter of a place Throws 403 if the user is not. The subclass has to provide a get_place method, wich returns the place to check. ''' place_submitter_error_message = None def get_place(self): pass def test_func(self): """ Check if user is eligible to modify place. """ if not hasattr(self.request, 'user'): return False if self.request.user.is_superuser: return True # Check if currently logged in user was the submitter place_obj = self.get_place() if place_obj and hasattr(place_obj, 'submitted_by') and self.request.user.explorer == place_obj.submitted_by: return True if self.place_submitter_error_message: messages.error(self.request, self.place_submitter_error_message) return False class PlaceAssetCreateView(IsAuthenticated, SuccessMessageMixin, CreateView): model = None fields = [] template_name = '' success_message = '' def get(self, request, place_id, *args, **kwargs): self.place = Place.objects.get(pk=place_id) return super().get(request, *args, **kwargs) def post(self, request, place_id, *args, **kwargs): self.place = Place.objects.get(pk=place_id) response = super().post(request, *args, **kwargs) self.object.place = self.place self.object.submitted_by = request.user.explorer self.object.save() return response def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['place'] = self.place return context def get_success_url(self): return reverse_lazy('place_detail', kwargs={'pk': self.place.id}) class PlaceAssetDeleteView(IsAuthenticated, IsPlaceSubmitter, SingleObjectMixin, View): model = None success_message = '' permission_denied_message = '' def get_place(self): place_id = self.get_object().place.id return Place.objects.get(pk=place_id) def test_func(self): can_edit_place = super().test_func() if can_edit_place: return True if self.get_object().submitted_by == self.request.user.explorer: return True messages.error(self.request, self.permission_denied_message) return False def get(self, request, *args, **kwargs): place_id = self.get_object().place.id self.get_object().delete() messages.success(self.request, self.success_message) return redirect(reverse_lazy('place_detail', kwargs={'pk': place_id}))