# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
use Pleroma.Web.ConnCase
+ alias Pleroma.Config
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
import Pleroma.Factory
describe "account fetching" do
+ setup do: clear_config([:instance, :limit_to_local_content])
+
test "works by id" do
user = insert(:user)
end
test "works by nickname for remote users" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
- Pleroma.Config.put([:instance, :limit_to_local_content], false)
+ Config.put([:instance, :limit_to_local_content], false)
user = insert(:user, nickname: "user@example.com", local: false)
conn =
build_conn()
|> get("/api/v1/accounts/#{user.nickname}")
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert %{"id" => id} = json_response(conn, 200)
assert id == user.id
end
test "respects limit_to_local_content == :all for remote user nicknames" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
- Pleroma.Config.put([:instance, :limit_to_local_content], :all)
+ Config.put([:instance, :limit_to_local_content], :all)
user = insert(:user, nickname: "user@example.com", local: false)
build_conn()
|> get("/api/v1/accounts/#{user.nickname}")
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert json_response(conn, 404)
end
test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
- Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
+ Config.put([:instance, :limit_to_local_content], :unauthenticated)
user = insert(:user, nickname: "user@example.com", local: false)
reading_user = insert(:user)
|> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"]))
|> get("/api/v1/accounts/#{user.nickname}")
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert %{"id" => id} = json_response(conn, 200)
assert id == user.id
end
end
end
+ defp local_and_remote_users do
+ local = insert(:user)
+ remote = insert(:user, local: false)
+ {:ok, local: local, remote: remote}
+ end
+
+ describe "user fetching with restrict unauthenticated profiles for local and remote" do
+ setup do: local_and_remote_users()
+
+ setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
+
+ setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
+
+ test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}")
+
+ assert json_response(res_conn, :not_found) == %{
+ "error" => "Can't find user"
+ }
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
+
+ assert json_response(res_conn, :not_found) == %{
+ "error" => "Can't find user"
+ }
+ end
+
+ test "if user is authenticated", %{local: local, remote: remote} do
+ %{conn: conn} = oauth_access(["read"])
+
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}")
+ assert %{"id" => _} = json_response(res_conn, 200)
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
+ assert %{"id" => _} = json_response(res_conn, 200)
+ end
+ end
+
+ describe "user fetching with restrict unauthenticated profiles for local" do
+ setup do: local_and_remote_users()
+
+ setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
+
+ test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}")
+
+ assert json_response(res_conn, :not_found) == %{
+ "error" => "Can't find user"
+ }
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
+ assert %{"id" => _} = json_response(res_conn, 200)
+ end
+
+ test "if user is authenticated", %{local: local, remote: remote} do
+ %{conn: conn} = oauth_access(["read"])
+
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}")
+ assert %{"id" => _} = json_response(res_conn, 200)
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
+ assert %{"id" => _} = json_response(res_conn, 200)
+ end
+ end
+
+ describe "user fetching with restrict unauthenticated profiles for remote" do
+ setup do: local_and_remote_users()
+
+ setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
+
+ test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}")
+ assert %{"id" => _} = json_response(res_conn, 200)
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
+
+ assert json_response(res_conn, :not_found) == %{
+ "error" => "Can't find user"
+ }
+ end
+
+ test "if user is authenticated", %{local: local, remote: remote} do
+ %{conn: conn} = oauth_access(["read"])
+
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}")
+ assert %{"id" => _} = json_response(res_conn, 200)
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
+ assert %{"id" => _} = json_response(res_conn, 200)
+ end
+ end
+
describe "user timelines" do
setup do: oauth_access(["read:statuses"])
end
end
+ defp local_and_remote_activities(%{local: local, remote: remote}) do
+ insert(:note_activity, user: local)
+ insert(:note_activity, user: remote, local: false)
+
+ :ok
+ end
+
+ describe "statuses with restrict unauthenticated profiles for local and remote" do
+ setup do: local_and_remote_users()
+ setup :local_and_remote_activities
+
+ setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
+
+ setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
+
+ test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
+
+ assert json_response(res_conn, :not_found) == %{
+ "error" => "Can't find user"
+ }
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
+
+ assert json_response(res_conn, :not_found) == %{
+ "error" => "Can't find user"
+ }
+ end
+
+ test "if user is authenticated", %{local: local, remote: remote} do
+ %{conn: conn} = oauth_access(["read"])
+
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
+ assert length(json_response(res_conn, 200)) == 1
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
+ assert length(json_response(res_conn, 200)) == 1
+ end
+ end
+
+ describe "statuses with restrict unauthenticated profiles for local" do
+ setup do: local_and_remote_users()
+ setup :local_and_remote_activities
+
+ setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
+
+ test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
+
+ assert json_response(res_conn, :not_found) == %{
+ "error" => "Can't find user"
+ }
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
+ assert length(json_response(res_conn, 200)) == 1
+ end
+
+ test "if user is authenticated", %{local: local, remote: remote} do
+ %{conn: conn} = oauth_access(["read"])
+
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
+ assert length(json_response(res_conn, 200)) == 1
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
+ assert length(json_response(res_conn, 200)) == 1
+ end
+ end
+
+ describe "statuses with restrict unauthenticated profiles for remote" do
+ setup do: local_and_remote_users()
+ setup :local_and_remote_activities
+
+ setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
+
+ test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
+ assert length(json_response(res_conn, 200)) == 1
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
+
+ assert json_response(res_conn, :not_found) == %{
+ "error" => "Can't find user"
+ }
+ end
+
+ test "if user is authenticated", %{local: local, remote: remote} do
+ %{conn: conn} = oauth_access(["read"])
+
+ res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
+ assert length(json_response(res_conn, 200)) == 1
+
+ res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
+ assert length(json_response(res_conn, 200)) == 1
+ end
+ end
+
describe "followers" do
setup do: oauth_access(["read:accounts"])
[valid_params: valid_params]
end
+ setup do: clear_config([:instance, :account_activation_required])
+
test "Account registration via Application", %{conn: conn} do
conn =
- post(conn, "/api/v1/apps", %{
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/apps", %{
client_name: "client_name",
redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
scopes: "read, write, follow"
assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"}
end
- test "rate limit", %{conn: conn} do
- Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], true)
+ test "returns bad_request if missing required params", %{
+ conn: conn,
+ valid_params: valid_params
+ } do
+ app_token = insert(:oauth_token, user: nil)
+
+ conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
+
+ res = post(conn, "/api/v1/accounts", valid_params)
+ assert json_response(res, 200)
+
+ [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
+ |> Stream.zip(Map.delete(valid_params, :email))
+ |> Enum.each(fn {ip, {attr, _}} ->
+ res =
+ conn
+ |> Map.put(:remote_ip, ip)
+ |> post("/api/v1/accounts", Map.delete(valid_params, attr))
+ |> json_response(400)
+
+ assert res == %{"error" => "Missing parameters"}
+ end)
+ end
+
+ setup do: clear_config([:instance, :account_activation_required])
+
+ test "returns bad_request if missing email params when :account_activation_required is enabled",
+ %{conn: conn, valid_params: valid_params} do
+ Pleroma.Config.put([:instance, :account_activation_required], true)
+
+ app_token = insert(:oauth_token, user: nil)
+ conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
+
+ res =
+ conn
+ |> Map.put(:remote_ip, {127, 0, 0, 5})
+ |> post("/api/v1/accounts", Map.delete(valid_params, :email))
+
+ assert json_response(res, 400) == %{"error" => "Missing parameters"}
+
+ res =
+ conn
+ |> Map.put(:remote_ip, {127, 0, 0, 6})
+ |> post("/api/v1/accounts", Map.put(valid_params, :email, ""))
+
+ assert json_response(res, 400) == %{"error" => "{\"email\":[\"can't be blank\"]}"}
+ end
+
+ test "allow registration without an email", %{conn: conn, valid_params: valid_params} do
+ app_token = insert(:oauth_token, user: nil)
+ conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
+
+ res =
+ conn
+ |> Map.put(:remote_ip, {127, 0, 0, 7})
+ |> post("/api/v1/accounts", Map.delete(valid_params, :email))
+
+ assert json_response(res, 200)
+ end
+
+ test "allow registration with an empty email", %{conn: conn, valid_params: valid_params} do
+ app_token = insert(:oauth_token, user: nil)
+ conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
+
+ res =
+ conn
+ |> Map.put(:remote_ip, {127, 0, 0, 8})
+ |> post("/api/v1/accounts", Map.put(valid_params, :email, ""))
+
+ assert json_response(res, 200)
+ end
+
+ test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do
+ conn = put_req_header(conn, "authorization", "Bearer " <> "invalid-token")
+
+ res = post(conn, "/api/v1/accounts", valid_params)
+ assert json_response(res, 403) == %{"error" => "Invalid credentials"}
+ end
+ end
+
+ describe "create account by app / rate limit" do
+ setup do: clear_config([:rate_limit, :app_account_creation], {10_000, 2})
+
+ test "respects rate limit setting", %{conn: conn} do
app_token = insert(:oauth_token, user: nil)
conn =
|> put_req_header("authorization", "Bearer " <> app_token.token)
|> Map.put(:remote_ip, {15, 15, 15, 15})
- for i <- 1..5 do
+ for i <- 1..2 do
conn =
post(conn, "/api/v1/accounts", %{
username: "#{i}lain",
assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"}
end
-
- test "returns bad_request if missing required params", %{
- conn: conn,
- valid_params: valid_params
- } do
- app_token = insert(:oauth_token, user: nil)
-
- conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
-
- res = post(conn, "/api/v1/accounts", valid_params)
- assert json_response(res, 200)
-
- [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
- |> Stream.zip(valid_params)
- |> Enum.each(fn {ip, {attr, _}} ->
- res =
- conn
- |> Map.put(:remote_ip, ip)
- |> post("/api/v1/accounts", Map.delete(valid_params, attr))
- |> json_response(400)
-
- assert res == %{"error" => "Missing parameters"}
- end)
- end
-
- test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do
- conn = put_req_header(conn, "authorization", "Bearer " <> "invalid-token")
-
- res = post(conn, "/api/v1/accounts", valid_params)
- assert json_response(res, 403) == %{"error" => "Invalid credentials"}
- end
end
describe "GET /api/v1/accounts/:id/lists - account_lists" do