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)
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)