[#1560] Ensured authentication or enabled federation for federation-related routes. New tests + tests refactoring.
This commit is contained in:
parent
027714b519
commit
5fc92deef3
|
@ -15,9 +15,24 @@ def call(%{assigns: %{user: %User{}}} = conn, _) do
|
|||
conn
|
||||
end
|
||||
|
||||
def call(conn, _) do
|
||||
def call(conn, options) do
|
||||
perform =
|
||||
cond do
|
||||
options[:if_func] -> options[:if_func].()
|
||||
options[:unless_func] -> !options[:unless_func].()
|
||||
true -> true
|
||||
end
|
||||
|
||||
if perform do
|
||||
fail(conn)
|
||||
else
|
||||
conn
|
||||
end
|
||||
end
|
||||
|
||||
def fail(conn) do
|
||||
conn
|
||||
|> render_error(:forbidden, "Invalid credentials.")
|
||||
|> halt
|
||||
|> halt()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,7 +19,7 @@ def call(conn, _opts) do
|
|||
|
||||
def federating?, do: Pleroma.Config.get([:instance, :federating])
|
||||
|
||||
def fail(conn) do
|
||||
defp fail(conn) do
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> Phoenix.Controller.put_view(Pleroma.Web.ErrorView)
|
||||
|
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
alias Pleroma.Delivery
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Fetcher
|
||||
alias Pleroma.Plugs.EnsureAuthenticatedPlug
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||
|
@ -25,18 +26,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
|
||||
action_fallback(:errors)
|
||||
|
||||
# Note: some of the following actions (like :update_inbox) may be server-to-server as well
|
||||
@client_to_server_actions [
|
||||
:whoami,
|
||||
:read_inbox,
|
||||
:outbox,
|
||||
:update_outbox,
|
||||
:upload_media,
|
||||
:followers,
|
||||
:following
|
||||
]
|
||||
@federating_only_actions [:internal_fetch, :relay, :relay_following, :relay_followers]
|
||||
|
||||
plug(FederatingPlug when action not in @client_to_server_actions)
|
||||
plug(FederatingPlug when action in @federating_only_actions)
|
||||
|
||||
plug(
|
||||
EnsureAuthenticatedPlug,
|
||||
[unless_func: &FederatingPlug.federating?/0] when action not in @federating_only_actions
|
||||
)
|
||||
|
||||
plug(
|
||||
EnsureAuthenticatedPlug
|
||||
when action in [:read_inbox, :update_outbox, :whoami, :upload_media, :following, :followers]
|
||||
)
|
||||
|
||||
plug(
|
||||
Pleroma.Plugs.Cache,
|
||||
|
@ -47,7 +49,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
plug(:set_requester_reachable when action in [:inbox])
|
||||
plug(:relay_active? when action in [:relay])
|
||||
|
||||
def relay_active?(conn, _) do
|
||||
defp relay_active?(conn, _) do
|
||||
if Pleroma.Config.get([:instance, :allow_relay]) do
|
||||
conn
|
||||
else
|
||||
|
@ -140,14 +142,12 @@ defp set_cache_ttl_for(conn, entity) do
|
|||
end
|
||||
|
||||
# GET /relay/following
|
||||
def following(%{assigns: %{relay: true}} = conn, _params) do
|
||||
if FederatingPlug.federating?() do
|
||||
def relay_following(conn, _params) do
|
||||
with %{halted: false} = conn <- FederatingPlug.call(conn, []) do
|
||||
conn
|
||||
|> put_resp_content_type("application/activity+json")
|
||||
|> put_view(UserView)
|
||||
|> render("following.json", %{user: Relay.get_actor()})
|
||||
else
|
||||
FederatingPlug.fail(conn)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -181,14 +181,12 @@ def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) d
|
|||
end
|
||||
|
||||
# GET /relay/followers
|
||||
def followers(%{assigns: %{relay: true}} = conn, _params) do
|
||||
if FederatingPlug.federating?() do
|
||||
def relay_followers(conn, _params) do
|
||||
with %{halted: false} = conn <- FederatingPlug.call(conn, []) do
|
||||
conn
|
||||
|> put_resp_content_type("application/activity+json")
|
||||
|> put_view(UserView)
|
||||
|> render("followers.json", %{user: Relay.get_actor()})
|
||||
else
|
||||
FederatingPlug.fail(conn)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -221,13 +219,16 @@ def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) d
|
|||
end
|
||||
end
|
||||
|
||||
def outbox(conn, %{"nickname" => nickname, "page" => page?} = params)
|
||||
def outbox(
|
||||
%{assigns: %{user: for_user}} = conn,
|
||||
%{"nickname" => nickname, "page" => page?} = params
|
||||
)
|
||||
when page? in [true, "true"] do
|
||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||
{:ok, user} <- User.ensure_keys_present(user) do
|
||||
activities =
|
||||
if params["max_id"] do
|
||||
ActivityPub.fetch_user_activities(user, nil, %{
|
||||
ActivityPub.fetch_user_activities(user, for_user, %{
|
||||
"max_id" => params["max_id"],
|
||||
# This is a hack because postgres generates inefficient queries when filtering by
|
||||
# 'Answer', poll votes will be hidden by the visibility filter in this case anyway
|
||||
|
@ -235,7 +236,7 @@ def outbox(conn, %{"nickname" => nickname, "page" => page?} = params)
|
|||
"limit" => 10
|
||||
})
|
||||
else
|
||||
ActivityPub.fetch_user_activities(user, nil, %{
|
||||
ActivityPub.fetch_user_activities(user, for_user, %{
|
||||
"limit" => 10,
|
||||
"include_poll_votes" => true
|
||||
})
|
||||
|
@ -298,7 +299,8 @@ defp post_inbox_relayed_create(conn, params) do
|
|||
defp post_inbox_fallback(conn, params) do
|
||||
headers = Enum.into(conn.req_headers, %{})
|
||||
|
||||
if String.contains?(headers["signature"], params["actor"]) do
|
||||
if headers["signature"] && params["actor"] &&
|
||||
String.contains?(headers["signature"], params["actor"]) do
|
||||
Logger.debug(
|
||||
"Signature validation error for: #{params["actor"]}, make sure you are forwarding the HTTP Host header!"
|
||||
)
|
||||
|
@ -306,7 +308,9 @@ defp post_inbox_fallback(conn, params) do
|
|||
Logger.debug(inspect(conn.req_headers))
|
||||
end
|
||||
|
||||
json(conn, dgettext("errors", "error"))
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json(dgettext("errors", "error"))
|
||||
end
|
||||
|
||||
defp represent_service_actor(%User{} = user, conn) do
|
||||
|
@ -340,8 +344,6 @@ def whoami(%{assigns: %{user: %User{} = user}} = conn, _params) do
|
|||
|> render("user.json", %{user: user})
|
||||
end
|
||||
|
||||
def whoami(_conn, _params), do: {:error, :not_found}
|
||||
|
||||
def read_inbox(
|
||||
%{assigns: %{user: %User{nickname: nickname} = user}} = conn,
|
||||
%{"nickname" => nickname, "page" => page?} = params
|
||||
|
@ -377,14 +379,6 @@ def read_inbox(%{assigns: %{user: %User{nickname: nickname} = user}} = conn, %{
|
|||
end
|
||||
end
|
||||
|
||||
def read_inbox(%{assigns: %{user: nil}} = conn, %{"nickname" => nickname}) do
|
||||
err = dgettext("errors", "can't read inbox of %{nickname}", nickname: nickname)
|
||||
|
||||
conn
|
||||
|> put_status(:forbidden)
|
||||
|> json(err)
|
||||
end
|
||||
|
||||
def read_inbox(%{assigns: %{user: %User{nickname: as_nickname}}} = conn, %{
|
||||
"nickname" => nickname
|
||||
}) do
|
||||
|
@ -399,7 +393,7 @@ def read_inbox(%{assigns: %{user: %User{nickname: as_nickname}}} = conn, %{
|
|||
|> json(err)
|
||||
end
|
||||
|
||||
def handle_user_activity(%User{} = user, %{"type" => "Create"} = params) do
|
||||
defp handle_user_activity(%User{} = user, %{"type" => "Create"} = params) do
|
||||
object =
|
||||
params["object"]
|
||||
|> Map.merge(Map.take(params, ["to", "cc"]))
|
||||
|
@ -415,7 +409,7 @@ def handle_user_activity(%User{} = user, %{"type" => "Create"} = params) do
|
|||
})
|
||||
end
|
||||
|
||||
def handle_user_activity(%User{} = user, %{"type" => "Delete"} = params) do
|
||||
defp handle_user_activity(%User{} = user, %{"type" => "Delete"} = params) do
|
||||
with %Object{} = object <- Object.normalize(params["object"]),
|
||||
true <- user.is_moderator || user.ap_id == object.data["actor"],
|
||||
{:ok, delete} <- ActivityPub.delete(object) do
|
||||
|
@ -425,7 +419,7 @@ def handle_user_activity(%User{} = user, %{"type" => "Delete"} = params) do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_user_activity(%User{} = user, %{"type" => "Like"} = params) do
|
||||
defp handle_user_activity(%User{} = user, %{"type" => "Like"} = params) do
|
||||
with %Object{} = object <- Object.normalize(params["object"]),
|
||||
{:ok, activity, _object} <- ActivityPub.like(user, object) do
|
||||
{:ok, activity}
|
||||
|
@ -434,7 +428,7 @@ def handle_user_activity(%User{} = user, %{"type" => "Like"} = params) do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_user_activity(_, _) do
|
||||
defp handle_user_activity(_, _) do
|
||||
{:error, dgettext("errors", "Unhandled activity type")}
|
||||
end
|
||||
|
||||
|
@ -475,13 +469,13 @@ def update_outbox(%{assigns: %{user: %User{} = user}} = conn, %{"nickname" => ni
|
|||
|> json(err)
|
||||
end
|
||||
|
||||
def errors(conn, {:error, :not_found}) do
|
||||
defp errors(conn, {:error, :not_found}) do
|
||||
conn
|
||||
|> put_status(:not_found)
|
||||
|> json(dgettext("errors", "Not found"))
|
||||
end
|
||||
|
||||
def errors(conn, _e) do
|
||||
defp errors(conn, _e) do
|
||||
conn
|
||||
|> put_status(:internal_server_error)
|
||||
|> json(dgettext("errors", "error"))
|
||||
|
|
|
@ -25,7 +25,12 @@ def feed_redirect(%{assigns: %{format: "html"}} = conn, %{"nickname" => nickname
|
|||
|
||||
def feed_redirect(%{assigns: %{format: format}} = conn, _params)
|
||||
when format in ["json", "activity+json"] do
|
||||
ActivityPubController.call(conn, :user)
|
||||
with %{halted: false} = conn <-
|
||||
Pleroma.Plugs.EnsureAuthenticatedPlug.call(conn,
|
||||
unless_func: &Pleroma.Web.FederatingPlug.federating?/0
|
||||
) do
|
||||
ActivityPubController.call(conn, :user)
|
||||
end
|
||||
end
|
||||
|
||||
def feed_redirect(conn, %{"nickname" => nickname}) do
|
||||
|
|
|
@ -16,7 +16,9 @@ defmodule Pleroma.Web.OStatus.OStatusController do
|
|||
alias Pleroma.Web.Metadata.PlayerView
|
||||
alias Pleroma.Web.Router
|
||||
|
||||
plug(Pleroma.Web.FederatingPlug)
|
||||
plug(Pleroma.Plugs.EnsureAuthenticatedPlug,
|
||||
unless_func: &Pleroma.Web.FederatingPlug.federating?/0
|
||||
)
|
||||
|
||||
plug(
|
||||
RateLimiter,
|
||||
|
@ -137,13 +139,13 @@ def notice_player(conn, %{"id" => id}) do
|
|||
end
|
||||
end
|
||||
|
||||
def errors(conn, {:error, :not_found}) do
|
||||
defp errors(conn, {:error, :not_found}) do
|
||||
render_error(conn, :not_found, "Not found")
|
||||
end
|
||||
|
||||
def errors(conn, {:fetch_user, nil}), do: errors(conn, {:error, :not_found})
|
||||
defp errors(conn, {:fetch_user, nil}), do: errors(conn, {:error, :not_found})
|
||||
|
||||
def errors(conn, _) do
|
||||
defp errors(conn, _) do
|
||||
render_error(conn, :internal_server_error, "Something went wrong")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -570,7 +570,6 @@ defmodule Pleroma.Web.Router do
|
|||
plug(Pleroma.Plugs.EnsureUserKeyPlug)
|
||||
end
|
||||
|
||||
# Note: propagate _any_ updates to `@client_to_server_actions` in `ActivityPubController`
|
||||
scope "/", Pleroma.Web.ActivityPub do
|
||||
pipe_through([:activitypub_client])
|
||||
|
||||
|
@ -600,8 +599,8 @@ defmodule Pleroma.Web.Router do
|
|||
post("/inbox", ActivityPubController, :inbox)
|
||||
end
|
||||
|
||||
get("/following", ActivityPubController, :following, assigns: %{relay: true})
|
||||
get("/followers", ActivityPubController, :followers, assigns: %{relay: true})
|
||||
get("/following", ActivityPubController, :relay_following)
|
||||
get("/followers", ActivityPubController, :relay_followers)
|
||||
end
|
||||
|
||||
scope "/internal/fetch", Pleroma.Web.ActivityPub do
|
||||
|
|
|
@ -8,24 +8,62 @@ defmodule Pleroma.Plugs.EnsureAuthenticatedPlugTest do
|
|||
alias Pleroma.Plugs.EnsureAuthenticatedPlug
|
||||
alias Pleroma.User
|
||||
|
||||
test "it halts if no user is assigned", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> EnsureAuthenticatedPlug.call(%{})
|
||||
describe "without :if_func / :unless_func options" do
|
||||
test "it halts if user is NOT assigned", %{conn: conn} do
|
||||
conn = EnsureAuthenticatedPlug.call(conn, %{})
|
||||
|
||||
assert conn.status == 403
|
||||
assert conn.halted == true
|
||||
assert conn.status == 403
|
||||
assert conn.halted == true
|
||||
end
|
||||
|
||||
test "it continues if a user is assigned", %{conn: conn} do
|
||||
conn = assign(conn, :user, %User{})
|
||||
ret_conn = EnsureAuthenticatedPlug.call(conn, %{})
|
||||
|
||||
assert ret_conn == conn
|
||||
end
|
||||
end
|
||||
|
||||
test "it continues if a user is assigned", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, %User{})
|
||||
describe "with :if_func / :unless_func options" do
|
||||
setup do
|
||||
%{
|
||||
true_fn: fn -> true end,
|
||||
false_fn: fn -> false end
|
||||
}
|
||||
end
|
||||
|
||||
ret_conn =
|
||||
conn
|
||||
|> EnsureAuthenticatedPlug.call(%{})
|
||||
test "it continues if a user is assigned", %{conn: conn, true_fn: true_fn, false_fn: false_fn} do
|
||||
conn = assign(conn, :user, %User{})
|
||||
assert EnsureAuthenticatedPlug.call(conn, if_func: true_fn) == conn
|
||||
assert EnsureAuthenticatedPlug.call(conn, if_func: false_fn) == conn
|
||||
assert EnsureAuthenticatedPlug.call(conn, unless_func: true_fn) == conn
|
||||
assert EnsureAuthenticatedPlug.call(conn, unless_func: false_fn) == conn
|
||||
end
|
||||
|
||||
assert ret_conn == conn
|
||||
test "it continues if a user is NOT assigned but :if_func evaluates to `false`",
|
||||
%{conn: conn, false_fn: false_fn} do
|
||||
assert EnsureAuthenticatedPlug.call(conn, if_func: false_fn) == conn
|
||||
end
|
||||
|
||||
test "it continues if a user is NOT assigned but :unless_func evaluates to `true`",
|
||||
%{conn: conn, true_fn: true_fn} do
|
||||
assert EnsureAuthenticatedPlug.call(conn, unless_func: true_fn) == conn
|
||||
end
|
||||
|
||||
test "it halts if a user is NOT assigned and :if_func evaluates to `true`",
|
||||
%{conn: conn, true_fn: true_fn} do
|
||||
conn = EnsureAuthenticatedPlug.call(conn, if_func: true_fn)
|
||||
|
||||
assert conn.status == 403
|
||||
assert conn.halted == true
|
||||
end
|
||||
|
||||
test "it halts if a user is NOT assigned and :unless_func evaluates to `false`",
|
||||
%{conn: conn, false_fn: false_fn} do
|
||||
conn = EnsureAuthenticatedPlug.call(conn, unless_func: false_fn)
|
||||
|
||||
assert conn.status == 403
|
||||
assert conn.halted == true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,6 +48,25 @@ defp oauth_access(scopes, opts \\ []) do
|
|||
|
||||
%{user: user, token: token, conn: conn}
|
||||
end
|
||||
|
||||
defp ensure_federating_or_authenticated(conn, url, user) do
|
||||
Pleroma.Config.put([:instance, :federating], false)
|
||||
|
||||
conn
|
||||
|> get(url)
|
||||
|> response(403)
|
||||
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get(url)
|
||||
|> response(200)
|
||||
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
|
||||
conn
|
||||
|> get(url)
|
||||
|> response(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
|
||||
import Pleroma.Factory
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Delivery
|
||||
alias Pleroma.Instances
|
||||
alias Pleroma.Object
|
||||
|
@ -25,8 +26,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
:ok
|
||||
end
|
||||
|
||||
clear_config_all([:instance, :federating]) do
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
clear_config([:instance, :federating]) do
|
||||
Config.put([:instance, :federating], true)
|
||||
end
|
||||
|
||||
describe "/relay" do
|
||||
|
@ -42,12 +43,21 @@ test "with the relay active, it returns the relay user", %{conn: conn} do
|
|||
end
|
||||
|
||||
test "with the relay disabled, it returns 404", %{conn: conn} do
|
||||
Pleroma.Config.put([:instance, :allow_relay], false)
|
||||
Config.put([:instance, :allow_relay], false)
|
||||
|
||||
conn
|
||||
|> get(activity_pub_path(conn, :relay))
|
||||
|> json_response(404)
|
||||
|> assert
|
||||
end
|
||||
|
||||
test "on non-federating instance, it returns 404", %{conn: conn} do
|
||||
Config.put([:instance, :federating], false)
|
||||
user = insert(:user)
|
||||
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get(activity_pub_path(conn, :relay))
|
||||
|> json_response(404)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -60,6 +70,16 @@ test "it returns the internal fetch user", %{conn: conn} do
|
|||
|
||||
assert res["id"] =~ "/fetch"
|
||||
end
|
||||
|
||||
test "on non-federating instance, it returns 404", %{conn: conn} do
|
||||
Config.put([:instance, :federating], false)
|
||||
user = insert(:user)
|
||||
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get(activity_pub_path(conn, :internal_fetch))
|
||||
|> json_response(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/users/:nickname" do
|
||||
|
@ -123,9 +143,34 @@ test "it returns 404 for remote users", %{
|
|||
|
||||
assert json_response(conn, 404)
|
||||
end
|
||||
|
||||
test "it returns error when user is not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/users/jimm")
|
||||
|> json_response(404)
|
||||
|
||||
assert response == "Not found"
|
||||
end
|
||||
|
||||
test "it requires authentication if instance is NOT federating", %{
|
||||
conn: conn
|
||||
} do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
put_req_header(
|
||||
conn,
|
||||
"accept",
|
||||
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
|
||||
)
|
||||
|
||||
ensure_federating_or_authenticated(conn, "/users/#{user.nickname}.json", user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/object/:uuid" do
|
||||
describe "/objects/:uuid" do
|
||||
test "it returns a json representation of the object with accept application/json", %{
|
||||
conn: conn
|
||||
} do
|
||||
|
@ -236,6 +281,18 @@ test "cached purged after object deletion", %{conn: conn} do
|
|||
|
||||
assert "Not found" == json_response(conn2, :not_found)
|
||||
end
|
||||
|
||||
test "it requires authentication if instance is NOT federating", %{
|
||||
conn: conn
|
||||
} do
|
||||
user = insert(:user)
|
||||
note = insert(:note)
|
||||
uuid = String.split(note.data["id"], "/") |> List.last()
|
||||
|
||||
conn = put_req_header(conn, "accept", "application/activity+json")
|
||||
|
||||
ensure_federating_or_authenticated(conn, "/objects/#{uuid}", user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/activities/:uuid" do
|
||||
|
@ -307,6 +364,18 @@ test "cached purged after activity deletion", %{conn: conn} do
|
|||
|
||||
assert "Not found" == json_response(conn2, :not_found)
|
||||
end
|
||||
|
||||
test "it requires authentication if instance is NOT federating", %{
|
||||
conn: conn
|
||||
} do
|
||||
user = insert(:user)
|
||||
activity = insert(:note_activity)
|
||||
uuid = String.split(activity.data["id"], "/") |> List.last()
|
||||
|
||||
conn = put_req_header(conn, "accept", "application/activity+json")
|
||||
|
||||
ensure_federating_or_authenticated(conn, "/activities/#{uuid}", user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/inbox" do
|
||||
|
@ -341,6 +410,34 @@ test "it clears `unreachable` federation status of the sender", %{conn: conn} do
|
|||
assert "ok" == json_response(conn, 200)
|
||||
assert Instances.reachable?(sender_url)
|
||||
end
|
||||
|
||||
test "without valid signature, " <>
|
||||
"it only accepts Create activities and requires enabled federation",
|
||||
%{conn: conn} do
|
||||
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
|
||||
non_create_data = File.read!("test/fixtures/mastodon-announce.json") |> Poison.decode!()
|
||||
|
||||
conn = put_req_header(conn, "content-type", "application/activity+json")
|
||||
|
||||
Config.put([:instance, :federating], false)
|
||||
|
||||
conn
|
||||
|> post("/inbox", data)
|
||||
|> json_response(403)
|
||||
|
||||
conn
|
||||
|> post("/inbox", non_create_data)
|
||||
|> json_response(403)
|
||||
|
||||
Config.put([:instance, :federating], true)
|
||||
|
||||
ret_conn = post(conn, "/inbox", data)
|
||||
assert "ok" == json_response(ret_conn, 200)
|
||||
|
||||
conn
|
||||
|> post("/inbox", non_create_data)
|
||||
|> json_response(400)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/users/:nickname/inbox" do
|
||||
|
@ -479,22 +576,11 @@ test "it accepts messages from actors that are followed by the user", %{
|
|||
|
||||
test "it rejects reads from other users", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
otheruser = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, otheruser)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/inbox")
|
||||
|
||||
assert json_response(conn, 403)
|
||||
end
|
||||
|
||||
test "it doesn't crash without an authenticated user", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, other_user)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/inbox")
|
||||
|
||||
|
@ -575,14 +661,30 @@ test "it removes all follower collections but actor's", %{conn: conn} do
|
|||
refute recipient.follower_address in activity.data["cc"]
|
||||
refute recipient.follower_address in activity.data["to"]
|
||||
end
|
||||
|
||||
test "it requires authentication", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
conn = put_req_header(conn, "accept", "application/activity+json")
|
||||
|
||||
ret_conn = get(conn, "/users/#{user.nickname}/inbox")
|
||||
assert json_response(ret_conn, 403)
|
||||
|
||||
ret_conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user.nickname}/inbox")
|
||||
|
||||
assert json_response(ret_conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /users/:nickname/outbox" do
|
||||
test "it will not bomb when there is no activity", %{conn: conn} do
|
||||
test "it returns 200 even if there're no activities", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/outbox")
|
||||
|
||||
|
@ -597,6 +699,7 @@ test "it returns a note activity in a collection", %{conn: conn} do
|
|||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/outbox?page=true")
|
||||
|
||||
|
@ -609,26 +712,38 @@ test "it returns an announce activity in a collection", %{conn: conn} do
|
|||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/outbox?page=true")
|
||||
|
||||
assert response(conn, 200) =~ announce_activity.data["object"]
|
||||
end
|
||||
|
||||
test "it requires authentication if instance is NOT federating", %{
|
||||
conn: conn
|
||||
} do
|
||||
user = insert(:user)
|
||||
conn = put_req_header(conn, "accept", "application/activity+json")
|
||||
|
||||
ensure_federating_or_authenticated(conn, "/users/#{user.nickname}/outbox", user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /users/:nickname/outbox" do
|
||||
test "it rejects posts from other users", %{conn: conn} do
|
||||
test "it rejects posts from other users / unauuthenticated users", %{conn: conn} do
|
||||
data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
|
||||
user = insert(:user)
|
||||
otheruser = insert(:user)
|
||||
other_user = insert(:user)
|
||||
conn = put_req_header(conn, "content-type", "application/activity+json")
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, otheruser)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{user.nickname}/outbox", data)
|
||||
conn
|
||||
|> post("/users/#{user.nickname}/outbox", data)
|
||||
|> json_response(403)
|
||||
|
||||
assert json_response(conn, 403)
|
||||
conn
|
||||
|> assign(:user, other_user)
|
||||
|> post("/users/#{user.nickname}/outbox", data)
|
||||
|> json_response(403)
|
||||
end
|
||||
|
||||
test "it inserts an incoming create activity into the database", %{conn: conn} do
|
||||
|
@ -743,24 +858,42 @@ test "it returns relay followers", %{conn: conn} do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> assign(:relay, true)
|
||||
|> get("/relay/followers")
|
||||
|> json_response(200)
|
||||
|
||||
assert result["first"]["orderedItems"] == [user.ap_id]
|
||||
end
|
||||
|
||||
test "on non-federating instance, it returns 404", %{conn: conn} do
|
||||
Config.put([:instance, :federating], false)
|
||||
user = insert(:user)
|
||||
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/relay/followers")
|
||||
|> json_response(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/relay/following" do
|
||||
test "it returns relay following", %{conn: conn} do
|
||||
result =
|
||||
conn
|
||||
|> assign(:relay, true)
|
||||
|> get("/relay/following")
|
||||
|> json_response(200)
|
||||
|
||||
assert result["first"]["orderedItems"] == []
|
||||
end
|
||||
|
||||
test "on non-federating instance, it returns 404", %{conn: conn} do
|
||||
Config.put([:instance, :federating], false)
|
||||
user = insert(:user)
|
||||
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/relay/following")
|
||||
|> json_response(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/users/:nickname/followers" do
|
||||
|
@ -771,6 +904,7 @@ test "it returns the followers in a collection", %{conn: conn} do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user_two)
|
||||
|> get("/users/#{user_two.nickname}/followers")
|
||||
|> json_response(200)
|
||||
|
||||
|
@ -784,19 +918,22 @@ test "it returns a uri if the user has 'hide_followers' set", %{conn: conn} do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user_two.nickname}/followers")
|
||||
|> json_response(200)
|
||||
|
||||
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",
|
||||
test "it returns a 403 error on pages, if the user has 'hide_followers' set and the request is from another user",
|
||||
%{conn: conn} do
|
||||
user = insert(:user, hide_followers: true)
|
||||
user = insert(:user)
|
||||
other_user = insert(:user, hide_followers: true)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/followers?page=1")
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{other_user.nickname}/followers?page=1")
|
||||
|
||||
assert result.status == 403
|
||||
assert result.resp_body == ""
|
||||
|
@ -828,6 +965,7 @@ test "it works for more than 10 users", %{conn: conn} do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user.nickname}/followers")
|
||||
|> json_response(200)
|
||||
|
||||
|
@ -837,12 +975,21 @@ test "it works for more than 10 users", %{conn: conn} do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user.nickname}/followers?page=2")
|
||||
|> json_response(200)
|
||||
|
||||
assert length(result["orderedItems"]) == 5
|
||||
assert result["totalItems"] == 15
|
||||
end
|
||||
|
||||
test "returns 403 if requester is not logged in", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/followers")
|
||||
|> json_response(403)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/users/:nickname/following" do
|
||||
|
@ -853,6 +1000,7 @@ test "it returns the following in a collection", %{conn: conn} do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user.nickname}/following")
|
||||
|> json_response(200)
|
||||
|
||||
|
@ -860,25 +1008,28 @@ test "it returns the following in a collection", %{conn: conn} do
|
|||
end
|
||||
|
||||
test "it returns a uri if the user has 'hide_follows' set", %{conn: conn} do
|
||||
user = insert(:user, hide_follows: true)
|
||||
user_two = insert(:user)
|
||||
user = insert(:user)
|
||||
user_two = insert(:user, hide_follows: true)
|
||||
User.follow(user, user_two)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/following")
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user_two.nickname}/following")
|
||||
|> json_response(200)
|
||||
|
||||
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",
|
||||
test "it returns a 403 error on pages, if the user has 'hide_follows' set and the request is from another user",
|
||||
%{conn: conn} do
|
||||
user = insert(:user, hide_follows: true)
|
||||
user = insert(:user)
|
||||
user_two = insert(:user, hide_follows: true)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/following?page=1")
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user_two.nickname}/following?page=1")
|
||||
|
||||
assert result.status == 403
|
||||
assert result.resp_body == ""
|
||||
|
@ -911,6 +1062,7 @@ test "it works for more than 10 users", %{conn: conn} do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user.nickname}/following")
|
||||
|> json_response(200)
|
||||
|
||||
|
@ -920,12 +1072,21 @@ test "it works for more than 10 users", %{conn: conn} do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/users/#{user.nickname}/following?page=2")
|
||||
|> json_response(200)
|
||||
|
||||
assert length(result["orderedItems"]) == 5
|
||||
assert result["totalItems"] == 15
|
||||
end
|
||||
|
||||
test "returns 403 if requester is not logged in", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/following")
|
||||
|> json_response(403)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delivery tracking" do
|
||||
|
@ -1011,7 +1172,7 @@ test "it tracks a signed activity fetch when the json is cached", %{conn: conn}
|
|||
end
|
||||
|
||||
describe "Additional ActivityPub C2S endpoints" do
|
||||
test "/api/ap/whoami", %{conn: conn} do
|
||||
test "GET /api/ap/whoami", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
|
@ -1022,12 +1183,16 @@ test "/api/ap/whoami", %{conn: conn} do
|
|||
user = User.get_cached_by_id(user.id)
|
||||
|
||||
assert UserView.render("user.json", %{user: user}) == json_response(conn, 200)
|
||||
|
||||
conn
|
||||
|> get("/api/ap/whoami")
|
||||
|> json_response(403)
|
||||
end
|
||||
|
||||
clear_config([:media_proxy])
|
||||
clear_config([Pleroma.Upload])
|
||||
|
||||
test "uploadMedia", %{conn: conn} do
|
||||
test "POST /api/ap/upload_media", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
desc = "Description of the image"
|
||||
|
@ -1047,67 +1212,10 @@ test "uploadMedia", %{conn: conn} do
|
|||
assert object["name"] == desc
|
||||
assert object["type"] == "Document"
|
||||
assert object["actor"] == user.ap_id
|
||||
end
|
||||
end
|
||||
|
||||
describe "when instance is not federating," do
|
||||
clear_config([:instance, :federating]) do
|
||||
Pleroma.Config.put([:instance, :federating], false)
|
||||
end
|
||||
|
||||
test "returns 404 for GET routes", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
conn = put_req_header(conn, "accept", "application/json")
|
||||
|
||||
get_uris = [
|
||||
"/users/#{user.nickname}",
|
||||
"/internal/fetch",
|
||||
"/relay",
|
||||
"/relay/following",
|
||||
"/relay/followers"
|
||||
]
|
||||
|
||||
for get_uri <- get_uris do
|
||||
conn
|
||||
|> get(get_uri)
|
||||
|> json_response(404)
|
||||
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get(get_uri)
|
||||
|> json_response(404)
|
||||
end
|
||||
end
|
||||
|
||||
test "returns 404 for activity-related POST routes", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:valid_signature, true)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|
||||
post_activity_data =
|
||||
"test/fixtures/mastodon-post-activity.json"
|
||||
|> File.read!()
|
||||
|> Poison.decode!()
|
||||
|
||||
post_activity_uris = [
|
||||
"/inbox",
|
||||
"/relay/inbox",
|
||||
"/users/#{user.nickname}/inbox"
|
||||
]
|
||||
|
||||
for post_activity_uri <- post_activity_uris do
|
||||
conn
|
||||
|> post(post_activity_uri, post_activity_data)
|
||||
|> json_response(404)
|
||||
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post(post_activity_uri, post_activity_data)
|
||||
|> json_response(404)
|
||||
end
|
||||
conn
|
||||
|> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
|
||||
|> json_response(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
alias Pleroma.Object
|
||||
alias Pleroma.User
|
||||
|
||||
clear_config_all([:instance, :federating]) do
|
||||
clear_config([:instance, :federating]) do
|
||||
Config.put([:instance, :federating], true)
|
||||
end
|
||||
|
||||
|
@ -82,160 +82,9 @@ test "returns 404 for a missing feed", %{conn: conn} do
|
|||
end
|
||||
end
|
||||
|
||||
# Note: see ActivityPubControllerTest for JSON format tests
|
||||
describe "feed_redirect" do
|
||||
test "undefined format. it redirects to feed", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/xml")
|
||||
|> get("/users/#{user.nickname}")
|
||||
|> response(302)
|
||||
|
||||
assert response ==
|
||||
"<html><body>You are being <a href=\"#{Pleroma.Web.base_url()}/users/#{
|
||||
user.nickname
|
||||
}/feed.atom\">redirected</a>.</body></html>"
|
||||
end
|
||||
|
||||
test "undefined format. it returns error when user not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/xml")
|
||||
|> get(user_feed_path(conn, :feed, "jimm"))
|
||||
|> response(404)
|
||||
|
||||
assert response == ~S({"error":"Not found"})
|
||||
end
|
||||
|
||||
test "activity+json format. it redirects on actual feed of user", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}")
|
||||
|> json_response(200)
|
||||
|
||||
assert response["endpoints"] == %{
|
||||
"oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize",
|
||||
"oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps",
|
||||
"oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token",
|
||||
"sharedInbox" => "#{Pleroma.Web.base_url()}/inbox",
|
||||
"uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media"
|
||||
}
|
||||
|
||||
assert response["@context"] == [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"http://localhost:4001/schemas/litepub-0.1.jsonld",
|
||||
%{"@language" => "und"}
|
||||
]
|
||||
|
||||
assert Map.take(response, [
|
||||
"followers",
|
||||
"following",
|
||||
"id",
|
||||
"inbox",
|
||||
"manuallyApprovesFollowers",
|
||||
"name",
|
||||
"outbox",
|
||||
"preferredUsername",
|
||||
"summary",
|
||||
"tag",
|
||||
"type",
|
||||
"url"
|
||||
]) == %{
|
||||
"followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers",
|
||||
"following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following",
|
||||
"id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}",
|
||||
"inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox",
|
||||
"manuallyApprovesFollowers" => false,
|
||||
"name" => user.name,
|
||||
"outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox",
|
||||
"preferredUsername" => user.nickname,
|
||||
"summary" => user.bio,
|
||||
"tag" => [],
|
||||
"type" => "Person",
|
||||
"url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
|
||||
}
|
||||
end
|
||||
|
||||
test "activity+json format. it returns error whe use not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/jimm")
|
||||
|> json_response(404)
|
||||
|
||||
assert response == "Not found"
|
||||
end
|
||||
|
||||
test "json format. it redirects on actual feed of user", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/users/#{user.nickname}")
|
||||
|> json_response(200)
|
||||
|
||||
assert response["endpoints"] == %{
|
||||
"oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize",
|
||||
"oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps",
|
||||
"oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token",
|
||||
"sharedInbox" => "#{Pleroma.Web.base_url()}/inbox",
|
||||
"uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media"
|
||||
}
|
||||
|
||||
assert response["@context"] == [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"http://localhost:4001/schemas/litepub-0.1.jsonld",
|
||||
%{"@language" => "und"}
|
||||
]
|
||||
|
||||
assert Map.take(response, [
|
||||
"followers",
|
||||
"following",
|
||||
"id",
|
||||
"inbox",
|
||||
"manuallyApprovesFollowers",
|
||||
"name",
|
||||
"outbox",
|
||||
"preferredUsername",
|
||||
"summary",
|
||||
"tag",
|
||||
"type",
|
||||
"url"
|
||||
]) == %{
|
||||
"followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers",
|
||||
"following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following",
|
||||
"id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}",
|
||||
"inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox",
|
||||
"manuallyApprovesFollowers" => false,
|
||||
"name" => user.name,
|
||||
"outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox",
|
||||
"preferredUsername" => user.nickname,
|
||||
"summary" => user.bio,
|
||||
"tag" => [],
|
||||
"type" => "Person",
|
||||
"url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
|
||||
}
|
||||
end
|
||||
|
||||
test "json format. it returns error whe use not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/users/jimm")
|
||||
|> json_response(404)
|
||||
|
||||
assert response == "Not found"
|
||||
end
|
||||
|
||||
test "html format. it redirects on actual feed of user", %{conn: conn} do
|
||||
test "with html format, it redirects to user feed", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
||||
|
||||
|
@ -251,7 +100,7 @@ test "html format. it redirects on actual feed of user", %{conn: conn} do
|
|||
).resp_body
|
||||
end
|
||||
|
||||
test "html format. it returns error when user not found", %{conn: conn} do
|
||||
test "with html format, it returns error when user is not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> get("/users/jimm")
|
||||
|
@ -259,30 +108,30 @@ test "html format. it returns error when user not found", %{conn: conn} do
|
|||
|
||||
assert response == %{"error" => "Not found"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "feed_redirect (depending on federation enabled state)" do
|
||||
setup %{conn: conn} do
|
||||
user = insert(:user)
|
||||
conn = put_req_header(conn, "accept", "application/json")
|
||||
test "with non-html / non-json format, it redirects to user feed in atom format", %{
|
||||
conn: conn
|
||||
} do
|
||||
note_activity = insert(:note_activity)
|
||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
||||
|
||||
%{conn: conn, user: user}
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/xml")
|
||||
|> get("/users/#{user.nickname}")
|
||||
|
||||
assert conn.status == 302
|
||||
assert redirected_to(conn) == "#{Pleroma.Web.base_url()}/users/#{user.nickname}/feed.atom"
|
||||
end
|
||||
|
||||
clear_config([:instance, :federating])
|
||||
test "with non-html / non-json format, it returns error when user is not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/xml")
|
||||
|> get(user_feed_path(conn, :feed, "jimm"))
|
||||
|> response(404)
|
||||
|
||||
test "renders if instance is federating", %{conn: conn, user: user} do
|
||||
Config.put([:instance, :federating], true)
|
||||
|
||||
conn = get(conn, "/users/#{user.nickname}")
|
||||
assert json_response(conn, 200)
|
||||
end
|
||||
|
||||
test "renders 404 if instance is NOT federating", %{conn: conn, user: user} do
|
||||
Config.put([:instance, :federating], false)
|
||||
|
||||
conn = get(conn, "/users/#{user.nickname}")
|
||||
assert json_response(conn, 404)
|
||||
assert response == ~S({"error":"Not found"})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -52,9 +52,8 @@ test "redirects on valid url when filename invalidated", %{conn: conn} do
|
|||
url = Pleroma.Web.MediaProxy.encode_url("https://google.fn/test.png")
|
||||
invalid_url = String.replace(url, "test.png", "test-file.png")
|
||||
response = get(conn, invalid_url)
|
||||
html = "<html><body>You are being <a href=\"#{url}\">redirected</a>.</body></html>"
|
||||
assert response.status == 302
|
||||
assert response.resp_body == html
|
||||
assert redirected_to(response) == url
|
||||
end
|
||||
|
||||
test "it performs ReverseProxy.call when signature valid", %{conn: conn} do
|
||||
|
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
|
|||
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
@ -16,22 +17,24 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
|
|||
:ok
|
||||
end
|
||||
|
||||
clear_config_all([:instance, :federating]) do
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
clear_config([:instance, :federating]) do
|
||||
Config.put([:instance, :federating], true)
|
||||
end
|
||||
|
||||
describe "GET object/2" do
|
||||
# Note: see ActivityPubControllerTest for JSON format tests
|
||||
describe "GET /objects/:uuid (text/html)" do
|
||||
setup %{conn: conn} do
|
||||
conn = put_req_header(conn, "accept", "text/html")
|
||||
%{conn: conn}
|
||||
end
|
||||
|
||||
test "redirects to /notice/id for html format", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
object = Object.normalize(note_activity)
|
||||
[_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
|
||||
url = "/objects/#{uuid}"
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get(url)
|
||||
|
||||
conn = get(conn, url)
|
||||
assert redirected_to(conn) == "/notice/#{note_activity.id}"
|
||||
end
|
||||
|
||||
|
@ -45,23 +48,25 @@ test "404s on private objects", %{conn: conn} do
|
|||
|> response(404)
|
||||
end
|
||||
|
||||
test "404s on nonexisting objects", %{conn: conn} do
|
||||
test "404s on non-existing objects", %{conn: conn} do
|
||||
conn
|
||||
|> get("/objects/123")
|
||||
|> response(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET activity/2" do
|
||||
# Note: see ActivityPubControllerTest for JSON format tests
|
||||
describe "GET /activities/:uuid (text/html)" do
|
||||
setup %{conn: conn} do
|
||||
conn = put_req_header(conn, "accept", "text/html")
|
||||
%{conn: conn}
|
||||
end
|
||||
|
||||
test "redirects to /notice/id for html format", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
[_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"]))
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/activities/#{uuid}")
|
||||
|
||||
conn = get(conn, "/activities/#{uuid}")
|
||||
assert redirected_to(conn) == "/notice/#{note_activity.id}"
|
||||
end
|
||||
|
||||
|
@ -79,19 +84,6 @@ test "404s on nonexistent activities", %{conn: conn} do
|
|||
|> get("/activities/123")
|
||||
|> response(404)
|
||||
end
|
||||
|
||||
test "gets an activity in AS2 format", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
[_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"]))
|
||||
url = "/activities/#{uuid}"
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get(url)
|
||||
|
||||
assert json_response(conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET notice/2" do
|
||||
|
@ -170,7 +162,7 @@ test "404s a private notice", %{conn: conn} do
|
|||
assert response(conn, 404)
|
||||
end
|
||||
|
||||
test "404s a nonexisting notice", %{conn: conn} do
|
||||
test "404s a non-existing notice", %{conn: conn} do
|
||||
url = "/notice/123"
|
||||
|
||||
conn =
|
||||
|
@ -179,10 +171,21 @@ test "404s a nonexisting notice", %{conn: conn} do
|
|||
|
||||
assert response(conn, 404)
|
||||
end
|
||||
|
||||
test "it requires authentication if instance is NOT federating", %{
|
||||
conn: conn
|
||||
} do
|
||||
user = insert(:user)
|
||||
note_activity = insert(:note_activity)
|
||||
|
||||
conn = put_req_header(conn, "accept", "text/html")
|
||||
|
||||
ensure_federating_or_authenticated(conn, "/notice/#{note_activity.id}", user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /notice/:id/embed_player" do
|
||||
test "render embed player", %{conn: conn} do
|
||||
setup do
|
||||
note_activity = insert(:note_activity)
|
||||
object = Pleroma.Object.normalize(note_activity)
|
||||
|
||||
|
@ -204,9 +207,11 @@ test "render embed player", %{conn: conn} do
|
|||
|> Ecto.Changeset.change(data: object_data)
|
||||
|> Pleroma.Repo.update()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> get("/notice/#{note_activity.id}/embed_player")
|
||||
%{note_activity: note_activity}
|
||||
end
|
||||
|
||||
test "renders embed player", %{conn: conn, note_activity: note_activity} do
|
||||
conn = get(conn, "/notice/#{note_activity.id}/embed_player")
|
||||
|
||||
assert Plug.Conn.get_resp_header(conn, "x-frame-options") == ["ALLOW"]
|
||||
|
||||
|
@ -272,38 +277,19 @@ test "404s when attachment isn't audio or video", %{conn: conn} do
|
|||
|> Ecto.Changeset.change(data: object_data)
|
||||
|> Pleroma.Repo.update()
|
||||
|
||||
assert conn
|
||||
|> get("/notice/#{note_activity.id}/embed_player")
|
||||
|> response(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when instance is not federating," do
|
||||
clear_config([:instance, :federating]) do
|
||||
Pleroma.Config.put([:instance, :federating], false)
|
||||
conn
|
||||
|> get("/notice/#{note_activity.id}/embed_player")
|
||||
|> response(404)
|
||||
end
|
||||
|
||||
test "returns 404 for GET routes", %{conn: conn} do
|
||||
conn = put_req_header(conn, "accept", "application/json")
|
||||
test "it requires authentication if instance is NOT federating", %{
|
||||
conn: conn,
|
||||
note_activity: note_activity
|
||||
} do
|
||||
user = insert(:user)
|
||||
conn = put_req_header(conn, "accept", "text/html")
|
||||
|
||||
note_activity = insert(:note_activity, local: true)
|
||||
[_, activity_uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"]))
|
||||
|
||||
object = Object.normalize(note_activity)
|
||||
[_, object_uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
|
||||
|
||||
get_uris = [
|
||||
"/activities/#{activity_uuid}",
|
||||
"/objects/#{object_uuid}",
|
||||
"/notice/#{note_activity.id}",
|
||||
"/notice/#{note_activity.id}/embed_player"
|
||||
]
|
||||
|
||||
for get_uri <- get_uris do
|
||||
conn
|
||||
|> get(get_uri)
|
||||
|> json_response(404)
|
||||
end
|
||||
ensure_federating_or_authenticated(conn, "/notice/#{note_activity.id}/embed_player", user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue