mirror of
https://github.com/pinry/pinry.git
synced 2026-01-16 04:02:05 +01:00
Feature: Add Private property for Pin and read proection
Now the private pin should only be viewed by owner.
This commit is contained in:
@@ -83,6 +83,7 @@ class Board(models.Model):
|
||||
|
||||
class Pin(models.Model):
|
||||
submitter = models.ForeignKey(User)
|
||||
private = models.BooleanField(default=False, blank=False)
|
||||
url = models.CharField(null=True, blank=True, max_length=256)
|
||||
referer = models.CharField(null=True, blank=True, max_length=256)
|
||||
description = models.TextField(blank=True, null=True)
|
||||
|
||||
@@ -21,6 +21,19 @@ class IsOwnerOrReadOnly(permissions.IsAuthenticatedOrReadOnly):
|
||||
return getattr(obj, self.__owner_field_name) == request.user
|
||||
|
||||
|
||||
class OwnerOnlyIfPrivate(permissions.BasePermission):
|
||||
def __init__(self, owner_field_name="owner"):
|
||||
self.__owner_field_name = owner_field_name
|
||||
|
||||
def __call__(self):
|
||||
return self
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
if getattr(obj, "private"):
|
||||
return request.user == getattr(obj, self.__owner_field_name)
|
||||
return True
|
||||
|
||||
|
||||
class OwnerOnly(permissions.IsAuthenticatedOrReadOnly):
|
||||
|
||||
def has_permission(self, request, view):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from taggit.models import Tag
|
||||
@@ -9,6 +10,14 @@ from django_images.models import Thumbnail
|
||||
from users.serializers import UserSerializer
|
||||
|
||||
|
||||
def filter_private_pin(request, query):
|
||||
if request.user.is_authenticated:
|
||||
query = query.exclude(~Q(submitter=request.user), private=True)
|
||||
else:
|
||||
query = query.exclude(private=True)
|
||||
return query.select_related('image', 'submitter')
|
||||
|
||||
|
||||
class ThumbnailSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Thumbnail
|
||||
@@ -164,7 +173,9 @@ class BoardSerializer(serializers.HyperlinkedModelSerializer):
|
||||
}
|
||||
|
||||
submitter = UserSerializer(read_only=True)
|
||||
pins_detail = PinSerializer(source="pins", many=True, read_only=True)
|
||||
pins_detail = serializers.SerializerMethodField(
|
||||
read_only=True,
|
||||
)
|
||||
pins = serializers.HyperlinkedRelatedField(
|
||||
write_only=True,
|
||||
queryset=Pin.objects.all(),
|
||||
@@ -187,6 +198,12 @@ class BoardSerializer(serializers.HyperlinkedModelSerializer):
|
||||
help_text="only patch method works for this field"
|
||||
)
|
||||
|
||||
def get_pins_detail(self, instance):
|
||||
query = instance.pins.all()
|
||||
request = self.context['request']
|
||||
query = filter_private_pin(request, query)
|
||||
return [PinSerializer(pin, context=self.context).data for pin in query]
|
||||
|
||||
@staticmethod
|
||||
def _get_list(pins_id):
|
||||
return tuple(Pin.objects.filter(id__in=pins_id))
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from django.db.models import Q
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
@@ -8,7 +9,8 @@ from taggit.models import Tag
|
||||
|
||||
from core import serializers as api
|
||||
from core.models import Image, Pin, Board
|
||||
from core.permissions import IsOwnerOrReadOnly
|
||||
from core.permissions import IsOwnerOrReadOnly, OwnerOnlyIfPrivate
|
||||
from core.serializers import filter_private_pin
|
||||
|
||||
|
||||
class ImageViewSet(mixins.CreateModelMixin, GenericViewSet):
|
||||
@@ -20,13 +22,17 @@ class ImageViewSet(mixins.CreateModelMixin, GenericViewSet):
|
||||
|
||||
|
||||
class PinViewSet(viewsets.ModelViewSet):
|
||||
queryset = Pin.objects.all().select_related('image', 'submitter')
|
||||
serializer_class = api.PinSerializer
|
||||
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
|
||||
filter_fields = ("submitter__username", 'tags__name', )
|
||||
ordering_fields = ('-id', )
|
||||
ordering = ('-id', )
|
||||
permission_classes = [IsOwnerOrReadOnly("submitter"), ]
|
||||
permission_classes = [IsOwnerOrReadOnly("submitter"), OwnerOnlyIfPrivate("submitter")]
|
||||
|
||||
def get_queryset(self):
|
||||
query = Pin.objects.all()
|
||||
request = self.request
|
||||
return filter_private_pin(request, query)
|
||||
|
||||
|
||||
class BoardViewSet(viewsets.ModelViewSet):
|
||||
@@ -67,7 +73,7 @@ class TagAutoCompleteViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
|
||||
|
||||
|
||||
drf_router = routers.DefaultRouter()
|
||||
drf_router.register(r'pins', PinViewSet)
|
||||
drf_router.register(r'pins', PinViewSet, basename="pin")
|
||||
drf_router.register(r'images', ImageViewSet)
|
||||
drf_router.register(r'boards', BoardViewSet)
|
||||
drf_router.register(r'tags-auto-complete', TagAutoCompleteViewSet)
|
||||
|
||||
Reference in New Issue
Block a user