diff --git a/core/serializers.py b/core/serializers.py index 41a20e7..12f6ed9 100644 --- a/core/serializers.py +++ b/core/serializers.py @@ -8,6 +8,7 @@ from core.models import Image, Board from core.models import Pin from django_images.models import Thumbnail from users.serializers import UserSerializer +from users.models import User def filter_private_pin(request, query): @@ -219,8 +220,14 @@ class BoardSerializer(serializers.HyperlinkedModelSerializer): return PinSerializer(pin, context=self.context).data @staticmethod - def _get_list(pins_id): - return tuple(Pin.objects.filter(id__in=pins_id)) + def _get_list(pins_id, submitter: User): + pins = Pin.objects.filter(id__in=pins_id) + valid_pins = [] + for pin in pins: + if pin.private and pin.submitter != submitter: + continue + valid_pins.append(pin) + return valid_pins def update(self, instance: Board, validated_data): pins_to_add = validated_data.pop("pins_to_add", []) @@ -237,11 +244,11 @@ class BoardSerializer(serializers.HyperlinkedModelSerializer): changed = False if pins_to_add: changed = True - for pin in self._get_list(pins_to_add): + for pin in self._get_list(pins_to_add, instance.submitter): instance.pins.add(pin) if pins_to_remove: changed = True - for pin in self._get_list(pins_to_remove): + for pin in self._get_list(pins_to_remove, instance.submitter): instance.pins.remove(pin) if changed: instance.save() diff --git a/core/tests/api.py b/core/tests/api.py index 20144b6..ac1c960 100644 --- a/core/tests/api.py +++ b/core/tests/api.py @@ -53,6 +53,13 @@ class BoardPrivacyTests(APITestCase): def tearDown(self): _teardown_models() + def _create_pin_with_non_owner(self, private): + image = create_image() + pin = create_pin(self.non_owner, image=image, tags=[]) + pin.private = private + pin.save() + return pin + def test_should_non_owner_and_anonymous_user_has_no_permission_to_list_private_board(self): resp = self.client.get(self.boards_url) self.assertEqual(len(resp.json()), 0, resp.json()) @@ -79,6 +86,30 @@ class BoardPrivacyTests(APITestCase): resp = self.client.get(self.board_url) self.assertEqual(resp.status_code, 200) + def test_should_owner_has_no_permission_to_add_private_pin_of_other_user_to_board(self): + self.client.login(username=self.owner.username, password='password') + + private_pin_of_other_user = self._create_pin_with_non_owner(True) + + resp = self.client.patch(self.board_url, data={"pins_to_add": [private_pin_of_other_user.id, ]}) + self.assertEqual(resp.status_code, 200) + + resp = self.client.get(self.board_url) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.json()['total_pins'], 0, resp.json()) + + def test_should_owner_has_permission_to_add_non_private_pin_of_other_user_to_board(self): + self.client.login(username=self.owner.username, password='password') + + private_pin_of_other_user = self._create_pin_with_non_owner(False) + + resp = self.client.patch(self.board_url, data={"pins_to_add": [private_pin_of_other_user.id, ]}) + self.assertEqual(resp.status_code, 200) + + resp = self.client.get(self.board_url) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.json()['total_pins'], 1, resp.json()) + class PinPrivacyTests(APITestCase):