예제 #1
0
    def visible_posts(self, request):
        print("visible_posts endpoint hit")
        xUser = request.META.get("HTTP_X_REQUEST_USER_ID")
        page = int(request.query_params.get("page", 0)) + 1 # Must offset page by 1
        if page < 1:
            return Response({
                "query": "posts",
                "message": "Page number must be positive",
                "success": False
            }, status=400)
        size = int(request.query_params.get("size", DEFAULT_POST_PAGE_SIZE))
        if size < 0 or size > 100:
            return Response({
                "query": "posts",
                "message": "Size was invalid",
                "success": False
            }, status=400)

        # Only return public posts if the user isn't authenticated
        if request.user.is_anonymous:
            posts = Posts.objects.all().filter(visibility__in=["PUBLIC"], unlisted=False)
        elif ServerUtil.is_server(request.user):
            sUtil = ServerUtil(user=request.user)
            if not sUtil.is_valid():
                return Response("This shouldn't happen, server=server!", status=500)
            elif not xUser:
                print("No xUser specified, sending all public posts")
                posts = Posts.objects.all().filter(visibility__in=["PUBLIC"])
            elif not sUtil.author_from_this_server(xUser):
                return Response("You're trying to access posts for a user that doesn't belong to you. user: "******" server: " + sUtil.get_base_url(), status=400)
            else:
                followedByXUser = Follow.objects.values_list("followed", flat=True).filter(follower=xUser)
                friendsOfXUser = Follow.objects.values_list("follower", flat=True).filter(followed=xUser, follower__in=followedByXUser)
                friends = []
                friends += sUtil.get_friends_of(xUser.split("/author/")[1])
                friends += friendsOfXUser
                friends = list(set(friends))
                foafs = []
                foafs += friends
                for friend in friends:
                    print("friend of", xUser, ":", friend)
                    # First check if it's an external user
                    sUtil = ServerUtil(authorUrl=friend)
                    if sUtil.is_valid():
                        foafs += sUtil.get_friends_of(friend.split("/author/")[1])
                    else: # it's not external (local), or we don't have that node anymore
                        peopleFollowedByFriend = Follow.objects.values_list("followed", flat=True).filter(follower=friend)
                        friendFriends = Follow.objects.values_list("follower", flat=True).filter(followed=friend, follower__in=peopleFollowedByFriend)
                        foafs += friendFriends
                baseUrl = get_host_url()
                foafs = list(set(foafs))
                friends = [get_author_id(x) for x in friends if x.startswith(baseUrl)]
                foafs = [get_author_id(x) for x in foafs if x.startswith(baseUrl)]
                posts = Posts.objects.all().filter(visibility="PUBLIC", unlisted=False)
                posts |= Posts.objects.all().filter(visibility="FRIENDS", author_id__in=friends, unlisted=False)
                posts |= Posts.objects.all().filter(visibility="FOAF", author_id__in=foafs, unlisted=False)
                posts |= Posts.objects.all().filter(visibility="PRIVATE", visibleTo__contains=[xUser], unlisted=False)
        else:
            requestingAuthor = request.user.author.id # Should be guaranteed because not anon
            # Get direct friends and FOAFs into a dictionary
            requesterFriends = {}
            requesterFOAFs = {}
            for friend in get_friends_from_pk(requestingAuthor):
                #friend = friend.split("/")[-1] # these are actually "urls", so grab the uuid
                requesterFriends[friend] = True
            for friend in requesterFriends:
                for foaf in get_friends(friend):
                    #friend = friend.split("/")[-1] # these are actually "urls", so grab the uuid
                    # Ensure we don't add direct friends as an FOAF
                    if not requesterFriends.get(foaf, False):
                        requesterFOAFs[foaf] = True
            try:
                # Grab the requesting user's posts
                posts = Posts.objects.all().filter(author=requestingAuthor, unlisted=False)
                # Grab all public posts
                posts |= Posts.objects.all().filter(visibility__in=["PUBLIC"], unlisted=False)

                host_url = get_host_url()
                # Grab posts from direct friends
                for friend in requesterFriends:
                    if not friend.startswith(host_url): continue
                    posts |= Posts.objects.all().filter(author=get_author_id(friend), visibility__in=["FRIENDS", "FOAF", "SERVERONLY"], unlisted=False)

                # Posts from FOAFs
                for friend in requesterFOAFs:
                    if not friend.startswith(host_url): continue
                    posts |= Posts.objects.all().filter(author=get_author_id(friend), visibility__in=["FOAF"], unlisted=False)

                # PRIVATE posts that the author can see
                posts |= Posts.objects.all().filter(visibility="PRIVATE", visibleTo__contains=[get_author_url(str(requestingAuthor))], unlisted=False)
            except:
                print("got except!")
                return Response(status=500)

        pages = Paginator(posts, size)
        current_page = pages.page(page)
        posts = PostsSerializer(current_page, many=True)

        response = {
            "query": "posts",
            "count": pages.count,
            "size": size,
            "posts": posts.data
        }
        add_page_details_to_response(request, response, current_page, page - 1)
        return Response(response, status=200)
예제 #2
0
    def handle_friend_request_response(self, request, pk):
        try:
            author = Author.objects.get(pk=pk)
            if ((not request.user.is_authenticated) or request.user.author != author):
                return Response({
                    "query": "friendrequest",
                    "success": False,
                    "message": "You must be authenticated as the requested user to perform this action."
                }, status=status.HTTP_403_FORBIDDEN)
        except:
            return Response({
                "query": "friendrequest",
                "success": False,
                "message": "Invalid author ID specified"
            }, status=404)

        try:
            message = "The request body could not be parsed"
            body = request.data
            success, message, friend_request, friend_data = validate_friend_request_response(body, pk)
        except:
            return Response({
                "query": "friendrequest",
                "success": False,
                "message": message
            }, status=400)

        if not success:
            return Response({
                "query": "friendrequest",
                "success": False,
                "message": message
            }, status=400)
        if not friend_request:
            return Response({
                "query": "friendrequest",
                "success": False,
                "message": "Could not find a friend request from the specified author"
            }, status=404)

        # check if this is an external friendship
        localAuthorUrl = get_author_url(pk)
        if localAuthorUrl.split("/author/")[0] != friend_data["url"].split("/author/")[0]:
            xServerAuthorUrl = friend_data["url"]
            xServerBody = {
                "query": "friendrequest",
                "friend": friend_data,
                "author": {
                    "displayName": author.displayName,
                    "host": localAuthorUrl.split("/author/")[0],
                    "id": localAuthorUrl,
                    "url": localAuthorUrl
                }
            }
            print(xServerBody)
            server = ServerUtil(authorUrl=xServerAuthorUrl)
            # if we fail to notify the external server we can't proceed with the friendship
            if not server.is_valid() or not server.notify_server_of_friendship(xServerBody):
                return Response({
                    "query": "friendrequest",
                    "success": False,
                    "message": "Failed to notify external server."
                }, status=500)

        if (body["approve"]):
            Follow.objects.create(follower=get_author_url(pk), followed=friend_data["url"])
        friend_request.delete()
        response = {
            "message": message,
            "success": success,
            "query": "friendrequest"
        }
        return Response(response, status=200)