aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2020-06-22 12:37:10 +0000
committerlain <lain@soykaf.club>2020-06-22 12:37:10 +0000
commit59bdef0c337f1892282e245c5a236680af8e0318 (patch)
treece4c3c2a39e88a805caa124e5b40324b923ba88b
parent31489bc864c92c9f4b891373f34f0a9e3d8e32ff (diff)
parent0321a3e07814c3f225f19e0372b69a7813cef15e (diff)
downloadpleroma-59bdef0c337f1892282e245c5a236680af8e0318.tar.gz
Merge branch 'feature/1739-account-endpoints' into 'develop'
account visibility in masto api Closes #1739 See merge request pleroma/pleroma!2488
-rw-r--r--lib/pleroma/user.ex59
-rw-r--r--lib/pleroma/web/api_spec/operations/account_operation.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/account_controller.ex18
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex2
-rw-r--r--test/user_test.exs10
-rw-r--r--test/web/mastodon_api/controllers/account_controller_test.exs59
6 files changed, 106 insertions, 44 deletions
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index ae4f96aac..1d70a37ef 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -263,37 +263,60 @@ defmodule Pleroma.User do
def account_status(%User{password_reset_pending: true}), do: :password_reset_pending
def account_status(%User{confirmation_pending: true}) do
- case Config.get([:instance, :account_activation_required]) do
- true -> :confirmation_pending
- _ -> :active
+ if Config.get([:instance, :account_activation_required]) do
+ :confirmation_pending
+ else
+ :active
end
end
def account_status(%User{}), do: :active
- @spec visible_for?(User.t(), User.t() | nil) :: boolean()
- def visible_for?(user, for_user \\ nil)
+ @spec visible_for(User.t(), User.t() | nil) ::
+ :visible
+ | :invisible
+ | :restricted_unauthenticated
+ | :deactivated
+ | :confirmation_pending
+ def visible_for(user, for_user \\ nil)
- def visible_for?(%User{invisible: true}, _), do: false
+ def visible_for(%User{invisible: true}, _), do: :invisible
- def visible_for?(%User{id: user_id}, %User{id: user_id}), do: true
+ def visible_for(%User{id: user_id}, %User{id: user_id}), do: :visible
- def visible_for?(%User{local: local} = user, nil) do
- cfg_key =
- if local,
- do: :local,
- else: :remote
+ def visible_for(%User{} = user, nil) do
+ if restrict_unauthenticated?(user) do
+ :restrict_unauthenticated
+ else
+ visible_account_status(user)
+ end
+ end
- if Config.get([:restrict_unauthenticated, :profiles, cfg_key]),
- do: false,
- else: account_status(user) == :active
+ def visible_for(%User{} = user, for_user) do
+ if superuser?(for_user) do
+ :visible
+ else
+ visible_account_status(user)
+ end
end
- def visible_for?(%User{} = user, for_user) do
- account_status(user) == :active || superuser?(for_user)
+ def visible_for(_, _), do: :invisible
+
+ defp restrict_unauthenticated?(%User{local: local}) do
+ config_key = if local, do: :local, else: :remote
+
+ Config.get([:restrict_unauthenticated, :profiles, config_key], false)
end
- def visible_for?(_, _), do: false
+ defp visible_account_status(user) do
+ status = account_status(user)
+
+ if status in [:active, :password_reset_pending] do
+ :visible
+ else
+ status
+ end
+ end
@spec superuser?(User.t()) :: boolean()
def superuser?(%User{local: true, is_admin: true}), do: true
diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex
index 20572f8ea..9bde8fc0d 100644
--- a/lib/pleroma/web/api_spec/operations/account_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/account_operation.ex
@@ -102,6 +102,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
responses: %{
200 => Operation.response("Account", "application/json", Account),
+ 401 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError)
}
}
@@ -142,6 +143,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
] ++ pagination_params(),
responses: %{
200 => Operation.response("Statuses", "application/json", array_of_statuses()),
+ 401 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError)
}
}
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
index adbbac624..d50e7c5dd 100644
--- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -234,17 +234,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
@doc "GET /api/v1/accounts/:id"
def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id}) do
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user),
- true <- User.visible_for?(user, for_user) do
+ :visible <- User.visible_for(user, for_user) do
render(conn, "show.json", user: user, for: for_user)
else
- _e -> render_error(conn, :not_found, "Can't find user")
+ error -> user_visibility_error(conn, error)
end
end
@doc "GET /api/v1/accounts/:id/statuses"
def statuses(%{assigns: %{user: reading_user}} = conn, params) do
with %User{} = user <- User.get_cached_by_nickname_or_id(params.id, for: reading_user),
- true <- User.visible_for?(user, reading_user) do
+ :visible <- User.visible_for(user, reading_user) do
params =
params
|> Map.delete(:tagged)
@@ -261,7 +261,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
as: :activity
)
else
- _e -> render_error(conn, :not_found, "Can't find user")
+ error -> user_visibility_error(conn, error)
+ end
+ end
+
+ defp user_visibility_error(conn, error) do
+ case error do
+ :restrict_unauthenticated ->
+ render_error(conn, :unauthorized, "This API requires an authenticated user")
+
+ _ ->
+ render_error(conn, :not_found, "Can't find user")
end
end
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index 6c40b8ccd..a6e64b4ab 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -35,7 +35,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
end
def render("show.json", %{user: user} = opts) do
- if User.visible_for?(user, opts[:for]) do
+ if User.visible_for(user, opts[:for]) == :visible do
do_render("show.json", opts)
else
%{}
diff --git a/test/user_test.exs b/test/user_test.exs
index 98c79da4f..311b6c683 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -1342,11 +1342,11 @@ defmodule Pleroma.UserTest do
end
end
- describe "visible_for?/2" do
+ describe "visible_for/2" do
test "returns true when the account is itself" do
user = insert(:user, local: true)
- assert User.visible_for?(user, user)
+ assert User.visible_for(user, user) == :visible
end
test "returns false when the account is unauthenticated and auth is required" do
@@ -1355,14 +1355,14 @@ defmodule Pleroma.UserTest do
user = insert(:user, local: true, confirmation_pending: true)
other_user = insert(:user, local: true)
- refute User.visible_for?(user, other_user)
+ refute User.visible_for(user, other_user) == :visible
end
test "returns true when the account is unauthenticated and auth is not required" do
user = insert(:user, local: true, confirmation_pending: true)
other_user = insert(:user, local: true)
- assert User.visible_for?(user, other_user)
+ assert User.visible_for(user, other_user) == :visible
end
test "returns true when the account is unauthenticated and being viewed by a privileged account (auth required)" do
@@ -1371,7 +1371,7 @@ defmodule Pleroma.UserTest do
user = insert(:user, local: true, confirmation_pending: true)
other_user = insert(:user, local: true, is_admin: true)
- assert User.visible_for?(user, other_user)
+ assert User.visible_for(user, other_user) == :visible
end
end
diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs
index 2343a9d2d..ebfcedd01 100644
--- a/test/web/mastodon_api/controllers/account_controller_test.exs
+++ b/test/web/mastodon_api/controllers/account_controller_test.exs
@@ -127,6 +127,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/accounts/internal.fetch")
|> json_response_and_validate_schema(404)
end
+
+ test "returns 404 for deactivated user", %{conn: conn} do
+ user = insert(:user, deactivated: true)
+
+ assert %{"error" => "Can't find user"} =
+ conn
+ |> get("/api/v1/accounts/#{user.id}")
+ |> json_response_and_validate_schema(:not_found)
+ end
end
defp local_and_remote_users do
@@ -143,15 +152,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- assert %{"error" => "Can't find user"} ==
+ assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}")
- |> json_response_and_validate_schema(:not_found)
+ |> json_response_and_validate_schema(:unauthorized)
- assert %{"error" => "Can't find user"} ==
+ assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}")
- |> json_response_and_validate_schema(:not_found)
+ |> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do
@@ -173,8 +182,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
- assert json_response_and_validate_schema(res_conn, :not_found) == %{
- "error" => "Can't find user"
+ assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
+ "error" => "This API requires an authenticated user"
}
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
@@ -203,8 +212,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
- assert json_response_and_validate_schema(res_conn, :not_found) == %{
- "error" => "Can't find user"
+ assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
+ "error" => "This API requires an authenticated user"
}
end
@@ -249,6 +258,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert id == announce.id
end
+ test "deactivated user", %{conn: conn} do
+ user = insert(:user, deactivated: true)
+
+ assert %{"error" => "Can't find user"} ==
+ conn
+ |> get("/api/v1/accounts/#{user.id}/statuses")
+ |> json_response_and_validate_schema(:not_found)
+ end
+
+ test "returns 404 when user is invisible", %{conn: conn} do
+ user = insert(:user, %{invisible: true})
+
+ assert %{"error" => "Can't find user"} =
+ conn
+ |> get("/api/v1/accounts/#{user.id}")
+ |> json_response_and_validate_schema(404)
+ end
+
test "respects blocks", %{user: user_one, conn: conn} do
user_two = insert(:user)
user_three = insert(:user)
@@ -430,15 +457,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- assert %{"error" => "Can't find user"} ==
+ assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}/statuses")
- |> json_response_and_validate_schema(:not_found)
+ |> json_response_and_validate_schema(:unauthorized)
- assert %{"error" => "Can't find user"} ==
+ assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}/statuses")
- |> json_response_and_validate_schema(:not_found)
+ |> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do
@@ -459,10 +486,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- assert %{"error" => "Can't find user"} ==
+ assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}/statuses")
- |> json_response_and_validate_schema(:not_found)
+ |> json_response_and_validate_schema(:unauthorized)
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
assert length(json_response_and_validate_schema(res_conn, 200)) == 1
@@ -489,10 +516,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
assert length(json_response_and_validate_schema(res_conn, 200)) == 1
- assert %{"error" => "Can't find user"} ==
+ assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}/statuses")
- |> json_response_and_validate_schema(:not_found)
+ |> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do