ActivityPub Controller: Actually pass for_user to following/followers
views and give 403 errors when trying to request hidden follower pages when unauthenticated
This commit is contained in:
parent
1f6ac7680d
commit
97b79efbcd
3 changed files with 102 additions and 14 deletions
|
@ -103,43 +103,57 @@ def activity(conn, %{"uuid" => uuid}) do
|
|||
end
|
||||
end
|
||||
|
||||
def following(conn, %{"nickname" => nickname, "page" => page}) do
|
||||
def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "page" => page}) do
|
||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||
{:ok, user} <- User.ensure_keys_present(user) do
|
||||
{user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user),
|
||||
{:show_follows, true} <-
|
||||
{:show_follows, (for_user && for_user == user) || !user.info.hide_follows} do
|
||||
{page, _} = Integer.parse(page)
|
||||
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(UserView.render("following.json", %{user: user, page: page}))
|
||||
end
|
||||
end
|
||||
|
||||
def following(conn, %{"nickname" => nickname}) do
|
||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||
{:ok, user} <- User.ensure_keys_present(user) do
|
||||
|> json(UserView.render("following.json", %{user: user, page: page, for: for_user}))
|
||||
else
|
||||
{:show_follows, _} ->
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(UserView.render("following.json", %{user: user}))
|
||||
|> send_resp(403, "")
|
||||
end
|
||||
end
|
||||
|
||||
def followers(conn, %{"nickname" => nickname, "page" => page}) do
|
||||
def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) do
|
||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||
{:ok, user} <- User.ensure_keys_present(user) do
|
||||
{user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(UserView.render("following.json", %{user: user, for: for_user}))
|
||||
end
|
||||
end
|
||||
|
||||
def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "page" => page}) do
|
||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||
{user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user),
|
||||
{:show_followers, true} <-
|
||||
{:show_followers, (for_user && for_user == user) || !user.info.hide_followers} do
|
||||
{page, _} = Integer.parse(page)
|
||||
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(UserView.render("followers.json", %{user: user, page: page}))
|
||||
|> json(UserView.render("followers.json", %{user: user, page: page, for: for_user}))
|
||||
else
|
||||
{:show_followers, _} ->
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> send_resp(403, "")
|
||||
end
|
||||
end
|
||||
|
||||
def followers(conn, %{"nickname" => nickname}) do
|
||||
def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) do
|
||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||
{:ok, user} <- User.ensure_keys_present(user) do
|
||||
{user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(UserView.render("followers.json", %{user: user}))
|
||||
|> json(UserView.render("followers.json", %{user: user, for: for_user}))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -325,4 +339,17 @@ defp set_requester_reachable(%Plug.Conn{} = conn, _) do
|
|||
|
||||
conn
|
||||
end
|
||||
|
||||
defp ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do
|
||||
{:ok, new_user} = User.ensure_keys_present(user)
|
||||
|
||||
for_user =
|
||||
if new_user != user and match?(%User{}, for_user) do
|
||||
User.get_cached_by_nickname(for_user.nickname)
|
||||
else
|
||||
for_user
|
||||
end
|
||||
|
||||
{new_user, for_user}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -623,8 +623,6 @@ defmodule Pleroma.Web.Router do
|
|||
# XXX: not really ostatus
|
||||
pipe_through(:ostatus)
|
||||
|
||||
get("/users/:nickname/followers", ActivityPubController, :followers)
|
||||
get("/users/:nickname/following", ActivityPubController, :following)
|
||||
get("/users/:nickname/outbox", ActivityPubController, :outbox)
|
||||
get("/objects/:uuid/likes", ActivityPubController, :object_likes)
|
||||
end
|
||||
|
@ -656,6 +654,12 @@ defmodule Pleroma.Web.Router do
|
|||
pipe_through(:oauth_write)
|
||||
post("/users/:nickname/outbox", ActivityPubController, :update_outbox)
|
||||
end
|
||||
|
||||
scope [] do
|
||||
pipe_through(:oauth_read_or_public)
|
||||
get("/users/:nickname/followers", ActivityPubController, :followers)
|
||||
get("/users/:nickname/following", ActivityPubController, :following)
|
||||
end
|
||||
end
|
||||
|
||||
scope "/relay", Pleroma.Web.ActivityPub do
|
||||
|
|
|
@ -12,6 +12,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
alias Pleroma.Web.ActivityPub.ObjectView
|
||||
alias Pleroma.Web.ActivityPub.UserView
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
|
@ -564,6 +565,34 @@ test "it returns returns a uri if the user has 'hide_followers' set", %{conn: co
|
|||
assert is_binary(result["first"])
|
||||
end
|
||||
|
||||
test "it returns a 403 error on pages, if the user has 'hide_followers' set and the request is not authenticated",
|
||||
%{conn: conn} do
|
||||
user = insert(:user, %{info: %{hide_followers: true}})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/followers?page=1")
|
||||
|
||||
assert result.status == 403
|
||||
assert result.resp_body == ""
|
||||
end
|
||||
|
||||
test "it renders the page, if the user has 'hide_followers' set and the request is authenticated with the same user",
|
||||
%{conn: conn} do
|
||||
user = insert(:user, %{info: %{hide_followers: true}})
|
||||
other_user = insert(:user)
|
||||
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user.nickname}/followers?page=1")
|
||||
|> json_response(200)
|
||||
|
||||
assert result["totalItems"] == 1
|
||||
assert result["orderedItems"] == [other_user.ap_id]
|
||||
end
|
||||
|
||||
test "it works for more than 10 users", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
|
@ -618,6 +647,34 @@ test "it returns a uri if the user has 'hide_follows' set", %{conn: conn} do
|
|||
assert is_binary(result["first"])
|
||||
end
|
||||
|
||||
test "it returns a 403 error on pages, if the user has 'hide_follows' set and the request is not authenticated",
|
||||
%{conn: conn} do
|
||||
user = insert(:user, %{info: %{hide_follows: true}})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/following?page=1")
|
||||
|
||||
assert result.status == 403
|
||||
assert result.resp_body == ""
|
||||
end
|
||||
|
||||
test "it renders the page, if the user has 'hide_follows' set and the request is authenticated with the same user",
|
||||
%{conn: conn} do
|
||||
user = insert(:user, %{info: %{hide_follows: true}})
|
||||
other_user = insert(:user)
|
||||
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user.nickname}/following?page=1")
|
||||
|> json_response(200)
|
||||
|
||||
assert result["totalItems"] == 1
|
||||
assert result["orderedItems"] == [other_user.ap_id]
|
||||
end
|
||||
|
||||
test "it works for more than 10 users", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
Loading…
Reference in a new issue