Check perms in list views
This commit is contained in:
		| @@ -92,6 +92,12 @@ class ListItem(CollectionItemMixin, BookWyrmModel): | |||||||
|                 notification_type="ADD", |                 notification_type="ADD", | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|  |     def raise_not_deletable(self, viewer): | ||||||
|  |         """the associated user OR the list owner can delete""" | ||||||
|  |         if self.book_list.user == viewer: | ||||||
|  |             return | ||||||
|  |         super().raise_not_deletable(viewer) | ||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|         """A book may only be placed into a list once, |         """A book may only be placed into a list once, | ||||||
|         and each order in the list may be used only once""" |         and each order in the list may be used only once""" | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ from typing import Optional | |||||||
| from urllib.parse import urlencode | from urllib.parse import urlencode | ||||||
|  |  | ||||||
| from django.contrib.auth.decorators import login_required | from django.contrib.auth.decorators import login_required | ||||||
| from django.core.exceptions import PermissionDenied |  | ||||||
| from django.core.paginator import Paginator | from django.core.paginator import Paginator | ||||||
| from django.db import IntegrityError, transaction | from django.db import IntegrityError, transaction | ||||||
| from django.db.models import Avg, Count, DecimalField, Q, Max | from django.db.models import Avg, Count, DecimalField, Q, Max | ||||||
| @@ -270,8 +269,7 @@ def delete_list(request, list_id): | |||||||
|     book_list = get_object_or_404(models.List, id=list_id) |     book_list = get_object_or_404(models.List, id=list_id) | ||||||
|  |  | ||||||
|     # only the owner or a moderator can delete a list |     # only the owner or a moderator can delete a list | ||||||
|     if book_list.user != request.user and not request.user.has_perm("moderate_post"): |     book_list.raise_not_editable(request.user) | ||||||
|         raise PermissionDenied |  | ||||||
|  |  | ||||||
|     book_list.delete() |     book_list.delete() | ||||||
|     return redirect("lists") |     return redirect("lists") | ||||||
| @@ -334,13 +332,11 @@ def remove_book(request, list_id): | |||||||
|     with transaction.atomic(): |     with transaction.atomic(): | ||||||
|         book_list = get_object_or_404(models.List, id=list_id) |         book_list = get_object_or_404(models.List, id=list_id) | ||||||
|         item = get_object_or_404(models.ListItem, id=request.POST.get("item")) |         item = get_object_or_404(models.ListItem, id=request.POST.get("item")) | ||||||
|  |         item.raise_not_deletable(request.user) | ||||||
|         if not book_list.user == request.user and not item.user == request.user: |  | ||||||
|             return HttpResponseNotFound() |  | ||||||
|  |  | ||||||
|         deleted_order = item.order |         deleted_order = item.order | ||||||
|         item.delete() |         item.delete() | ||||||
|     normalize_book_list_ordering(book_list.id, start=deleted_order) |         normalize_book_list_ordering(book_list.id, start=deleted_order) | ||||||
|     return redirect("list", list_id) |     return redirect("list", list_id) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -351,34 +347,34 @@ def set_book_position(request, list_item_id): | |||||||
|     Action for when the list user manually specifies a list position, takes |     Action for when the list user manually specifies a list position, takes | ||||||
|     special care with the unique ordering per list. |     special care with the unique ordering per list. | ||||||
|     """ |     """ | ||||||
|  |     list_item = get_object_or_404(models.ListItem, id=list_item_id) | ||||||
|  |     list_item.list.raise_not_editable(request.user) | ||||||
|  |     try: | ||||||
|  |         int_position = int(request.POST.get("position")) | ||||||
|  |     except ValueError: | ||||||
|  |         return HttpResponseBadRequest( | ||||||
|  |             "bad value for position. should be an integer" | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |     if int_position < 1: | ||||||
|  |         return HttpResponseBadRequest("position cannot be less than 1") | ||||||
|  |  | ||||||
|  |     book_list = list_item.book_list | ||||||
|  |  | ||||||
|  |     # the max position to which a book may be set is the highest order for | ||||||
|  |     # books which are approved | ||||||
|  |     order_max = book_list.listitem_set.filter(approved=True).aggregate( | ||||||
|  |         Max("order") | ||||||
|  |     )["order__max"] | ||||||
|  |  | ||||||
|  |     int_position = min(int_position, order_max) | ||||||
|  |  | ||||||
|  |     original_order = list_item.order | ||||||
|  |     if original_order == int_position: | ||||||
|  |         # no change | ||||||
|  |         return HttpResponse(status=204) | ||||||
|  |  | ||||||
|     with transaction.atomic(): |     with transaction.atomic(): | ||||||
|         list_item = get_object_or_404(models.ListItem, id=list_item_id) |  | ||||||
|         try: |  | ||||||
|             int_position = int(request.POST.get("position")) |  | ||||||
|         except ValueError: |  | ||||||
|             return HttpResponseBadRequest( |  | ||||||
|                 "bad value for position. should be an integer" |  | ||||||
|             ) |  | ||||||
|  |  | ||||||
|         if int_position < 1: |  | ||||||
|             return HttpResponseBadRequest("position cannot be less than 1") |  | ||||||
|  |  | ||||||
|         book_list = list_item.book_list |  | ||||||
|  |  | ||||||
|         # the max position to which a book may be set is the highest order for |  | ||||||
|         # books which are approved |  | ||||||
|         order_max = book_list.listitem_set.filter(approved=True).aggregate( |  | ||||||
|             Max("order") |  | ||||||
|         )["order__max"] |  | ||||||
|  |  | ||||||
|         int_position = min(int_position, order_max) |  | ||||||
|  |  | ||||||
|         if request.user not in (book_list.user, list_item.user): |  | ||||||
|             return HttpResponseNotFound() |  | ||||||
|  |  | ||||||
|         original_order = list_item.order |  | ||||||
|         if original_order == int_position: |  | ||||||
|             return HttpResponse(status=204) |  | ||||||
|         if original_order > int_position: |         if original_order > int_position: | ||||||
|             list_item.order = -1 |             list_item.order = -1 | ||||||
|             list_item.save() |             list_item.save() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user