Beispiel #1
0
 def get_permissions(self):
     if self.action not in ['update', 'partial_update', 'destroy']:
         return [AllowAny()]
     return [IsAuthenticated()]
Beispiel #2
0
class StoryViewSet(viewsets.GenericViewSet):
    queryset = Story.objects.all()
    serializer_class = StorySerializer
    permission_classes = (IsAuthenticated(), )

    cache_story_page1_key = 'story:list-1'
    cache_story_main_key = 'story:main'
    cache_story_trending_key = 'story:trending'
    cache_timeout = 60
    cache_timeout_long = 600

    def get_serializer_class(self):
        if self.action in ('list', 'main', 'trending'):
            return SimpleStorySerializer
        elif self.action in ('comment', 'comment_list'):
            return CommentSerializer
        return self.serializer_class

    def get_permissions(self):
        if self.action in ('retrieve', 'list', 'comment_list', 'main',
                           'trending'):
            return (AllowAny(), )
        elif self.request.method.lower() == 'options':
            return (AllowAny(), )  # Allow CORS preflight request
        return self.permission_classes

    def get_pagination_class(self):
        if self.action in ('comment', 'comment_list'):
            return CommentPagination
        return StoryPagination

    pagination_class = property(fget=get_pagination_class)

    def create(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def update(self, request, pk=None):
        story = self.get_object()
        if story.writer != request.user:
            return Response({'error': "You can't edit others' story"},
                            status=status.HTTP_403_FORBIDDEN)
        serializer = self.get_serializer(story,
                                         data=request.data,
                                         partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.update(story, serializer.validated_data)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        story = self.get_object()
        if story.published or story.writer == request.user:
            return Response(self.get_serializer(story).data)
        return Response({'error': "This story is not published yet"},
                        status=status.HTTP_404_NOT_FOUND)

    def list(self, request):
        queryset = self.get_queryset(). \
            filter(published=True). \
            order_by('-published_at'). \
            defer('body'). \
            select_related('writer'). \
            prefetch_related('writer__userprofile')
        is_cacheable = True
        if 'title' in request.query_params:
            title = request.query_params.get('title')
            queryset = queryset.filter(title__icontains=title)
            is_cacheable = False
        if 'tag' in request.query_params:
            return Response({'error': 'tag query is not implemented'},
                            status=status.HTTP_501_NOT_IMPLEMENTED)
            # is_cacheable = False
        if is_cacheable:
            queryset = queryset.filter(main_order=None, trending_order=None)
        if is_cacheable and request.query_params.get('page', 1) in (1, '1'):
            cached_data = cache.get(self.cache_story_page1_key)
            if cached_data is None:
                page = self.paginate_queryset(queryset)
                assert page is not None
                serializer = self.get_serializer(page, many=True)
                response = self.get_paginated_response(serializer.data)
                data = response.data
                cache.set(self.cache_story_page1_key,
                          data,
                          timeout=self.cache_timeout)
                return response
            else:
                data = cached_data
                return Response(data)

        page = self.paginate_queryset(queryset)
        assert page is not None
        serializer = self.get_serializer(page, many=True)

        return self.get_paginated_response(serializer.data)

    @action(methods=['GET'], detail=False)
    def main(self, request):
        cached_data = cache.get(self.cache_story_main_key)
        if cached_data is None:
            queryset = self.get_queryset(). \
                filter(published=True). \
                filter(main_order__gte=1, main_order__lte=5). \
                order_by('main_order'). \
                defer('body'). \
                select_related('writer'). \
                prefetch_related('writer__userprofile')
            data = self.get_serializer(queryset, many=True).data
            cache.set(self.cache_story_main_key,
                      data,
                      timeout=self.cache_timeout_long)
        else:
            data = cached_data
        return Response(data)

    @action(methods=['GET'], detail=False)
    def trending(self, request):
        cached_data = cache.get(self.cache_story_trending_key)
        if cached_data is None:
            queryset = self.get_queryset(). \
                filter(published=True). \
                filter(trending_order__gte=1, trending_order__lte=6). \
                order_by('trending_order'). \
                defer('body'). \
                select_related('writer'). \
                prefetch_related('writer__userprofile')
            data = self.get_serializer(queryset, many=True).data
            cache.set(self.cache_story_trending_key,
                      data,
                      timeout=self.cache_timeout_long)
        else:
            data = cached_data
        return Response(data)

    @action(methods=['POST'], detail=True)
    def publish(self, request, pk=None):
        story = self.get_object()
        if story.writer != request.user:
            return Response({'error': "You can't publish others' story"},
                            status=status.HTTP_403_FORBIDDEN)
        if story.published:
            story.published_at = None
            story.published = False
        else:
            story.published_at = timezone.now()
            story.published = True
        story.save()
        return Response(self.get_serializer(story).data)

    def destroy(self, request, pk=None):
        story = self.get_object()
        if story.writer != request.user:
            return Response({'error': "You can't delete others' story"},
                            status=status.HTTP_403_FORBIDDEN)
        story.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    @action(methods=['POST', 'PUT', 'DELETE'], detail=True)
    def comment(self, request, pk=None):
        if pk is None:
            return Response({'error': "Primary key is required"},
                            status=status.HTTP_400_BAD_REQUEST)

        story = self.get_queryset().only('published').get(pk=pk)
        if not story.published:
            return Response({'error': "This story is not published yet"},
                            status=status.HTTP_404_NOT_FOUND)

        if request.method == 'POST':
            serializer = CommentSerializer(data=request.data,
                                           context={
                                               'story': story,
                                               'user': request.user
                                           })
            serializer.is_valid(raise_exception=True)
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        else:  # When method is PUT or DELETE
            if 'id' not in request.query_params:
                return Response({'error': "comment id is required"},
                                status=status.HTTP_400_BAD_REQUEST)
            try:
                comment = story.comments.get(id=request.query_params.get('id'))
            except StoryComment.DoesNotExist:
                return Response(
                    {
                        'error':
                        "Comments with this id do not exist in this story."
                    },
                    status=status.HTTP_400_BAD_REQUEST)
            if comment.writer != request.user:
                return Response({'error': "This is not your comment"},
                                status=status.HTTP_403_FORBIDDEN)

            if request.method == 'PUT':
                serializer = self.get_serializer(comment,
                                                 data=request.data,
                                                 partial=True)
                serializer.is_valid(raise_exception=True)
                serializer.update(comment, serializer.validated_data)
                return Response(serializer.data)

            elif request.method == 'DELETE':
                comment.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)

    @comment.mapping.get
    def comment_list(self, request, pk=None):
        story = self.get_queryset().only('published').get(pk=pk)
        if not story.published:
            return Response({'error': "This story is not published yet"},
                            status=status.HTTP_404_NOT_FOUND)

        queryset = story.comments.all(). \
            order_by('created_at'). \
            select_related('writer'). \
            select_related('writer__userprofile')

        page = self.paginate_queryset(queryset)
        assert page is not None
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)
Beispiel #3
0
 def has_permission(self, request, view):
     if IsAuthenticated().has_permission(
             request, view) and request.method in self.SAFE_METHODS:
         return True
     return IsAdminUser().has_permission(request, view)
Beispiel #4
0
 def get_permissions(self):
     if self.action == 'list':
         return [AllowAny()]
     return [IsAuthenticated()]
 def get_permissions(self):
     if self.action in ['create', 'update', 'partial_update', 'destroy']:
         return [IsAuthenticated(), IsAdminUser()]
     return []
Beispiel #6
0
 def get_permissions(self):
     if self.action in ['create', 'update', 'destroy']:
         return [IsAdminUser()]
     if self.action in ['list', 'retrieve']:
         return [IsAuthenticated()]
     return [IsAdminUser()]
Beispiel #7
0
 def get_permissions(self):
     permissions = super().get_permissions()
     if self.request.method in ["POST", "DELETE", "PUT", "PATCH"]:
         permissions.append(IsAuthenticated())
     return permissions
Beispiel #8
0
 def get_permissions(self):
     if self.action == "create":
         return [IsAuthenticated()]
     return super().get_permissions()
Beispiel #9
0
 def get_permissions(self):
     if self.action == "list":
         return [IsAuthenticated()]
     if self.action == "retrieve":
         return [IsAuthenticated(), UserIsSelf()]
     if self.action == "update":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "create":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "create_multiple":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "reset_password":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "reset_password_multiple":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "set_inactive":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "set_inactive_multiple":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "set_active":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "set_active_multiple":
         return [IsAuthenticated(), UserIsSuperUser()]
     if self.action == "set_avatar":
         return [IsAuthenticated(), UserIsSelf()]
     if self.action == "remove_avatar":
         return [IsAuthenticated(), UserIsSelf()]
     if self.action == "get_face_list":
         return [IsAuthenticated()]
     if self.action == "set_face":
         return [IsAuthenticated(), UserIsSelf()]
     if self.action == "get_info_self":
         return [IsAuthenticated()]
     if self.action == "change_password_admin":
         return [IsAuthenticated(), UserIsSuperUser()]
     return []
Beispiel #10
0
 def get_permissions(self):
     if self.request.method == "GET":
         return AllowAny(),
     else:
         return IsAuthenticated(),
Beispiel #11
0
 def get_permissions(self):
     if self.action in ("make", ):
         return (IsAuthenticated(), )
     return (AllowAny(), )
Beispiel #12
0
 def get_permissions(self):
     if self.method in ('get', 'post'):
         return [IsAuthenticated()]
     return [HasStoreProfile()]
Beispiel #13
0
 def get_permissions(self):
     """获取权限"""
     if self.is_action:
         return [IsAdminUser(), IsAuthenticated()]
     else:
         return []
Beispiel #14
0
    def has_permission(self, request, view):
        if not IsAuthenticated().has_permission(request, view):
            return False

        return (UserProjectsListing().has_permission(request, view)
                or PublicDetailPrivateListing().has_permission(request, view))
Beispiel #15
0
 def get_permissions(self):
     if self.action == 'create' and self.action == 'retrieve':
         return (AllowAny(),)
     else:
         #return (AllowAny(),)
         return (IsAuthenticated(),UserPermission())
Beispiel #16
0
 def get_permissions(self):
     if self.action == "check_old_email":
         return [IsAuthenticated()]
     if self.action == "send_old_email_captcha":
         return [IsAuthenticated()]
     if self.action == "confirm_old_email_captcha":
         return [IsAuthenticated()]
     if self.action == "change_mobile":
         return [IsAuthenticated()]
     if self.action == "change_password":
         return [IsAuthenticated()]
     if self.action == "send_new_email_captcha":
         return [IsAuthenticated()]
     if self.action == "change_email":
         return [IsAuthenticated()]
     if self.action == "check_account_password":
         return [IsAuthenticated()]
     if self.action == "send_bind_email_captcha":
         return [IsAuthenticated()]
     if self.action == "bind_email":
         return [IsAuthenticated()]
     return [IsAuthenticated()]
Beispiel #17
0
 def get_permissions(self):
     if self.request.method == 'GET':
         return [AllowAny(), ]
     else :
         return [IsAuthenticated(), ]
Beispiel #18
0
 def get_permissions(self):
     request_method = self.request.method
     if request_method == 'POST':
         return (IsAdminUser(), IsVerified())
     else:
         return (IsAuthenticated(), IsVerified())
Beispiel #19
0
 def get_permissions(self):
     if self.action == 'destroy':
         return [IsAuthenticated()]
     else:
         return []
Beispiel #20
0
 def get_permissions(self):
     if self.action in self.allowed_actions:
         return (AllowAny(),)
     if self.action in self.auth_actions or self.request.method in self.auth_methods:
         return (IsAuthenticated(),)
     return super(Users, self).get_permissions()
Beispiel #21
0
 def get_permissions(self):
     if self.authenticate_permission_path and (
             get_end_url_path(self.request.path) in self.authenticate_permission_path):
         return [IsAuthenticated()]
     return super().get_permissions()
Beispiel #22
0
 def get_permissions(self):
     # Anyone can view tweets but only authenticated user can do other things
     if self.action == 'list':
         return [AllowAny()]
     return [IsAuthenticated()]
Beispiel #23
0
class UserViewSet(viewsets.GenericViewSet):
    queryset = User.objects.all()
    permission_classes = (IsAuthenticated(),)

    def get_permissions(self):
        if self.action in ("create", "login", "retrieve"):
            return (AllowAny(),)
        return self.permission_classes

    def get_serializer_class(self):
        if self.action in ("create", "update"):
            return UserSerializer
        return UserProfileSerializer

    @transaction.atomic
    def create_github_user(self, request):
        github_data = get_github_data(request.data.get("github_token"))
        if github_data is None or github_data.get("id") is None:
            return Response(
                {"message": "Invalid github token"}, status=status.HTTP_400_BAD_REQUEST
            )
        github_id = int(github_data["id"])
        if UserProfile.objects.filter(github_id=github_id).exists():
            return Response(
                {"message": "User already signed up"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        user = User.objects.create_user(
            username=f"{GITHUB}_{github_id}",
            password="******",
            email=github_data.get("email", ""),
        )
        request_data = request.data.copy()
        request_data["nickname"] = github_data["login"]
        request_data["github_id"] = github_id
        request_data["user_id"] = user.id
        Token.objects.create(user=user)
        serializer = UserProfileProduceSerializer(data=request_data)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        data = UserProfileSerializer(user.profile).data
        data["token"] = user.auth_token.key
        return Response(data, status=status.HTTP_201_CREATED)

    def create(self, request):
        request_data = request.data.copy()

        github_token = request_data.get("github_token")

        if github_token is not None:
            return self.create_github_user(request)

        request_data.pop("github_id", None)
        serializer = self.get_serializer(data=request_data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        data = UserProfileSerializer(user.profile).data
        data["token"] = user.auth_token.key
        return Response(data, status=status.HTTP_201_CREATED)

    @action(detail=False, methods=["PUT"])
    def login(self, request):
        username = request.data.get("username")
        password = request.data.get("password")
        github_token = request.data.get("github_token")

        if github_token is None or github_token == "":
            if username is None or len(username) > MAX_LENGTH:
                return Response(
                    {"message": "Authentication failed"},
                    status=status.HTTP_403_FORBIDDEN,
                )
            user = authenticate(request, username=username, password=password)
        else:
            github_data = get_github_data(github_token)
            try:
                user = UserProfile.objects.get(github_id=github_data.get("id")).user
            except (UserProfile.DoesNotExist, AttributeError):
                return self.create_github_user(request)
        if user and user.is_active:
            data = self.get_serializer(user.profile).data
            token, created = Token.objects.get_or_create(user=user)
            data["token"] = token.key
            return Response(data)

        return Response(
            {"message": "Authentication failed"}, status=status.HTTP_403_FORBIDDEN
        )

    @action(detail=False, methods=["POST"])
    def logout(self, request):
        try:
            request.user.auth_token.delete()
        except (AttributeError, ObjectDoesNotExist):
            return Response(
                {"message:token not exist"}, status=status.HTTP_400_BAD_REQUEST
            )
        return Response({})

    def retrieve(self, request, pk=None):
        if pk == "me":
            if not request.user.is_authenticated:
                return Response(
                    {"message": "Invalid Token"}, status=status.HTTP_401_UNAUTHORIZED
                )
            user = request.user
        else:
            try:
                user = User.objects.get(pk=pk, is_active=True)
            except (User.DoesNotExist, ValueError):
                return Response(
                    {"message": "There is no user with that id"},
                    status=status.HTTP_404_NOT_FOUND,
                )

        return Response(self.get_serializer(user.profile).data)

    def update(self, request, pk=None):
        if pk != "me":
            return Response(
                {"message": "Not allowed to edit user not me"},
                status=status.HTTP_403_FORBIDDEN,
            )

        user = request.user
        data = request.data

        serializer = self.get_serializer(user, data=data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        data = UserProfileSerializer(user.profile).data
        return Response(data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None):
        if pk != "me":
            return Response(
                {"message": "Not allowed to edit user not me or this user"},
                status=status.HTTP_403_FORBIDDEN,
            )

        user = request.user
        if user.is_active:
            user.is_active = False
            user.save()
            logout(request)
            return Response({}, status=status.HTTP_200_OK)
        else:
            return Response({}, status=status.HTTP_204_NO_CONTENT)
Beispiel #24
0
 def get_permissions(self):
     if self.request.method not in permissions.SAFE_METHODS:
         permission_classes = [IsAuthorOfPost]
         return [permission() for permission in permission_classes]
     return [IsAuthenticated()]
Beispiel #25
0
 def get_permissions(self):
     if self.action in ['list', 'retrieve']:
         return [AllowAny()]
     return [IsAuthenticated()]
Beispiel #26
0
 def has_permission(self, request, view) -> list:
     if request.method == "GET" and not request.user.is_anonymous:
         return [IsAuthenticated()]
     elif request.method == "POST":
         return [AllowAny()]
     return []
Beispiel #27
0
 def get_permissions(self):
     """Authenticate, unless you are creating a user"""
     return [AllowAny()] if self.action == "create" else [IsAuthenticated()]
Beispiel #28
0
class ArticleViewSet(viewsets.GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    permission_classes = (IsAuthenticated(), )
    pagination_class = CursorSetPagination

    def get_permissions(self):
        return self.permission_classes

    def create(self, request):

        user = request.user
        title = request.data.get('title')
        articles = Article.objects.filter(article_writer_id=user, title=title)

        if articles.exists():
            return Response(
                {"error": "article with same writer and title is invalid."},
                status=status.HTTP_400_BAD_REQUEST)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(article_writer=user)

        data = serializer.data

        return Response(data, status=status.HTTP_201_CREATED)

    def update(self, request, pk=None):

        user = request.user
        article = get_object_or_404(Article, pk=pk)

        if user != article.article_writer:
            return Response({"error": "Can't update other User's article"},
                            status=status.HTTP_403_FORBIDDEN)

        serializer = self.get_serializer(article,
                                         data=request.data,
                                         partial=True)

        serializer.is_valid(raise_exception=True)

        serializer.update(article, serializer.validated_data)

        return Response(serializer.data)

    def retrieve(self, request, pk=None):

        article = get_object_or_404(Article, pk=pk)

        return Response(self.get_serializer(article).data)

    def list(self, request):

        title = self.request.query_params.get('title')
        articles = self.get_queryset()

        if title:
            articles = articles.filter(title__icontains=title)

        data = ArticleSerializer(articles, many=True).data

        return Response(data)

    def destroy(self, request, pk=None):
        user = request.user
        article = get_object_or_404(Article, pk=pk)

        if user != article.article_writer:
            return Response({"error": "Can't delete other User's article"},
                            status=status.HTTP_403_FORBIDDEN)

        article.delete()

        return Response({"message": "Successfully deleted."})

    @transaction.atomic
    @action(methods=['post'], detail=True)
    def like(self, request, pk=None):
        user = request.user
        article = get_object_or_404(Article, pk=pk)
        check = user.like_article.filter(article=article)

        if check:
            LikeArticle.objects.get(user=user, article=article).delete()
            article.like_count = LikeArticle.objects.filter(
                article=article).count()
            article.save()

            return Response("You Unliked this article.",
                            status=status.HTTP_200_OK)

        else:
            LikeArticle.objects.create(user=user, article=article)
            article.like_count = LikeArticle.objects.filter(
                article=article).count()
            article.save()

            return Response("You liked this article.",
                            status=status.HTTP_200_OK)

    @transaction.atomic
    @action(methods=['POST'], detail=True, url_path='comment_write')
    def comment_write(self, request, pk=None):

        article = get_object_or_404(Article, pk=pk)
        user = request.user

        serializer = CommentSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(comment_writer=user, article=article)
        data = serializer.data

        return Response(data, status=status.HTTP_201_CREATED)

    @action(methods=['GET'], detail=True, url_path='comment_list')
    def comment_list(self, request, pk=None):

        qp_contents = self.request.query_params.get('contents')

        article = get_object_or_404(Article, pk=pk)
        comments = article.comment.get_queryset()

        if qp_contents:
            comments = comments.filter(contents__icontains=qp_contents)

        return Response(CommentSerializer(comments, many=True).data)

    @action(methods=['GET'],
            detail=True,
            url_path='comment/(?P<comment_pk>[^/.]+)')
    def comment_retrieve(self, request, comment_pk, pk=None):

        article = get_object_or_404(Article, pk=pk)
        comment = get_object_or_404(article.comment, pk=comment_pk)

        return Response(CommentSerializer(comment).data)

    @action(methods=['PUT'],
            detail=True,
            url_path='comment_update/(?P<comment_pk>[^/.]+)')
    def comment_update(self, request, comment_pk, pk=None):
        user = request.user
        article = get_object_or_404(Article, pk=pk)
        comment = get_object_or_404(article.comment, pk=comment_pk)

        if user != comment.comment_writer:
            return Response({"error": "Can't Update other User's comment"},
                            status=status.HTTP_403_FORBIDDEN)

        serializer = CommentSerializer(comment,
                                       data=request.data,
                                       partial=True)

        serializer.is_valid(raise_exception=True)

        serializer.update(comment, serializer.validated_data)

        return Response(serializer.data)

    @action(methods=['DELETE'],
            detail=True,
            url_path='comment_delete/(?P<comment_pk>[^/.]+)')
    def comment_delete(self, request, comment_pk, pk=None):
        user = request.user
        article = get_object_or_404(Article, pk=pk)
        comment = get_object_or_404(article.comment, pk=comment_pk)

        if user != comment.comment_writer:
            return Response({"error": "Can't delete other User's comment"},
                            status=status.HTTP_403_FORBIDDEN)

        comment.delete()

        return Response({"message": "Successfully deleted."})