Merge branch 'develop' into feature/expire-mutes

This commit is contained in:
Roman Chvanikov 2020-09-20 19:27:27 +03:00
commit 4987ee6256
113 changed files with 4510 additions and 348 deletions

View file

@ -22,6 +22,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
}
}
setup do: clear_config([:media_proxy, :enabled], true)
test "it prefetches media proxy URIs" do
with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
MediaProxyWarmingPolicy.filter(@message)

View file

@ -26,7 +26,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.MRF,
[],
[filter: fn o -> {:ok, o} end]
[pipeline_filter: fn o, m -> {:ok, o, m} end]
},
{
Pleroma.Web.ActivityPub.ActivityPub,
@ -51,7 +51,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
refute called(Pleroma.Web.Federator.publish(activity))
@ -68,7 +68,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.MRF,
[],
[filter: fn o -> {:ok, o} end]
[pipeline_filter: fn o, m -> {:ok, o, m} end]
},
{
Pleroma.Web.ActivityPub.ActivityPub,
@ -93,7 +93,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
assert_called(Pleroma.Web.Federator.publish(activity))
@ -109,7 +109,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.MRF,
[],
[filter: fn o -> {:ok, o} end]
[pipeline_filter: fn o, m -> {:ok, o, m} end]
},
{
Pleroma.Web.ActivityPub.ActivityPub,
@ -131,7 +131,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
end
@ -148,7 +148,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.MRF,
[],
[filter: fn o -> {:ok, o} end]
[pipeline_filter: fn o, m -> {:ok, o, m} end]
},
{
Pleroma.Web.ActivityPub.ActivityPub,
@ -170,7 +170,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
end

View file

@ -1510,6 +1510,56 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end
describe "GET /api/pleroma/admin/users/:nickname/chats" do
setup do
user = insert(:user)
recipients = insert_list(3, :user)
Enum.each(recipients, fn recipient ->
CommonAPI.post_chat_message(user, recipient, "yo")
end)
%{user: user}
end
test "renders user's chats", %{conn: conn, user: user} do
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/chats")
assert json_response(conn, 200) |> length() == 3
end
end
describe "GET /api/pleroma/admin/users/:nickname/chats unauthorized" do
setup do
user = insert(:user)
recipient = insert(:user)
CommonAPI.post_chat_message(user, recipient, "yo")
%{conn: conn} = oauth_access(["read:chats"])
%{conn: conn, user: user}
end
test "returns 403", %{conn: conn, user: user} do
conn
|> get("/api/pleroma/admin/users/#{user.nickname}/chats")
|> json_response(403)
end
end
describe "GET /api/pleroma/admin/users/:nickname/chats unauthenticated" do
setup do
user = insert(:user)
recipient = insert(:user)
CommonAPI.post_chat_message(user, recipient, "yo")
%{conn: build_conn(), user: user}
end
test "returns 403", %{conn: conn, user: user} do
conn
|> get("/api/pleroma/admin/users/#{user.nickname}/chats")
|> json_response(403)
end
end
describe "GET /api/pleroma/admin/moderation_log" do
setup do
moderator = insert(:user, is_moderator: true)

View file

@ -0,0 +1,219 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Config
alias Pleroma.ModerationLog
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Web.CommonAPI
defp admin_setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "DELETE /api/pleroma/admin/chats/:id/messages/:message_id" do
setup do: admin_setup()
test "it deletes a message from the chat", %{conn: conn, admin: admin} do
user = insert(:user)
recipient = insert(:user)
{:ok, message} =
CommonAPI.post_chat_message(user, recipient, "Hello darkness my old friend")
object = Object.normalize(message, false)
chat = Chat.get(user.id, recipient.ap_id)
recipient_chat = Chat.get(recipient.id, user.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
recipient_cm_ref = MessageReference.for_chat_and_object(recipient_chat, object)
result =
conn
|> put_req_header("content-type", "application/json")
|> delete("/api/pleroma/admin/chats/#{chat.id}/messages/#{cm_ref.id}")
|> json_response_and_validate_schema(200)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deleted chat message ##{cm_ref.id}"
assert result["id"] == cm_ref.id
refute MessageReference.get_by_id(cm_ref.id)
refute MessageReference.get_by_id(recipient_cm_ref.id)
assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id)
end
end
describe "GET /api/pleroma/admin/chats/:id/messages" do
setup do: admin_setup()
test "it paginates", %{conn: conn} do
user = insert(:user)
recipient = insert(:user)
Enum.each(1..30, fn _ ->
{:ok, _} = CommonAPI.post_chat_message(user, recipient, "hey")
end)
chat = Chat.get(user.id, recipient.ap_id)
result =
conn
|> get("/api/pleroma/admin/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(200)
assert length(result) == 20
result =
conn
|> get("/api/pleroma/admin/chats/#{chat.id}/messages?max_id=#{List.last(result)["id"]}")
|> json_response_and_validate_schema(200)
assert length(result) == 10
end
test "it returns the messages for a given chat", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
third_user = insert(:user)
{:ok, _} = CommonAPI.post_chat_message(user, other_user, "hey")
{:ok, _} = CommonAPI.post_chat_message(user, third_user, "hey")
{:ok, _} = CommonAPI.post_chat_message(user, other_user, "how are you?")
{:ok, _} = CommonAPI.post_chat_message(other_user, user, "fine, how about you?")
chat = Chat.get(user.id, other_user.ap_id)
result =
conn
|> get("/api/pleroma/admin/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(200)
result
|> Enum.each(fn message ->
assert message["chat_id"] == chat.id |> to_string()
end)
assert length(result) == 3
end
end
describe "GET /api/pleroma/admin/chats/:id" do
setup do: admin_setup()
test "it returns a chat", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> get("/api/pleroma/admin/chats/#{chat.id}")
|> json_response_and_validate_schema(200)
assert result["id"] == to_string(chat.id)
assert %{} = result["sender"]
assert %{} = result["receiver"]
refute result["account"]
end
end
describe "unauthorized chat moderation" do
setup do
user = insert(:user)
recipient = insert(:user)
{:ok, message} = CommonAPI.post_chat_message(user, recipient, "Yo")
object = Object.normalize(message, false)
chat = Chat.get(user.id, recipient.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
%{conn: conn} = oauth_access(["read:chats", "write:chats"])
%{conn: conn, chat: chat, cm_ref: cm_ref}
end
test "DELETE /api/pleroma/admin/chats/:id/messages/:message_id", %{
conn: conn,
chat: chat,
cm_ref: cm_ref
} do
conn
|> put_req_header("content-type", "application/json")
|> delete("/api/pleroma/admin/chats/#{chat.id}/messages/#{cm_ref.id}")
|> json_response(403)
assert MessageReference.get_by_id(cm_ref.id) == cm_ref
end
test "GET /api/pleroma/admin/chats/:id/messages", %{conn: conn, chat: chat} do
conn
|> get("/api/pleroma/admin/chats/#{chat.id}/messages")
|> json_response(403)
end
test "GET /api/pleroma/admin/chats/:id", %{conn: conn, chat: chat} do
conn
|> get("/api/pleroma/admin/chats/#{chat.id}")
|> json_response(403)
end
end
describe "unauthenticated chat moderation" do
setup do
user = insert(:user)
recipient = insert(:user)
{:ok, message} = CommonAPI.post_chat_message(user, recipient, "Yo")
object = Object.normalize(message, false)
chat = Chat.get(user.id, recipient.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
%{conn: build_conn(), chat: chat, cm_ref: cm_ref}
end
test "DELETE /api/pleroma/admin/chats/:id/messages/:message_id", %{
conn: conn,
chat: chat,
cm_ref: cm_ref
} do
conn
|> put_req_header("content-type", "application/json")
|> delete("/api/pleroma/admin/chats/#{chat.id}/messages/#{cm_ref.id}")
|> json_response(403)
assert MessageReference.get_by_id(cm_ref.id) == cm_ref
end
test "GET /api/pleroma/admin/chats/:id/messages", %{conn: conn, chat: chat} do
conn
|> get("/api/pleroma/admin/chats/#{chat.id}/messages")
|> json_response(403)
end
test "GET /api/pleroma/admin/chats/:id", %{conn: conn, chat: chat} do
conn
|> get("/api/pleroma/admin/chats/#{chat.id}")
|> json_response(403)
end
end
end

View file

@ -0,0 +1,106 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.InstanceDocumentControllerTest do
use Pleroma.Web.ConnCase, async: true
import Pleroma.Factory
alias Pleroma.Config
@dir "test/tmp/instance_static"
@default_instance_panel ~s(<p>Welcome to <a href="https://pleroma.social" target="_blank">Pleroma!</a></p>)
setup do
File.mkdir_p!(@dir)
on_exit(fn -> File.rm_rf(@dir) end)
end
setup do: clear_config([:instance, :static_dir], @dir)
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "GET /api/pleroma/admin/instance_document/:name" do
test "return the instance document url", %{conn: conn} do
conn = get(conn, "/api/pleroma/admin/instance_document/instance-panel")
assert content = html_response(conn, 200)
assert String.contains?(content, @default_instance_panel)
end
test "it returns 403 if requested by a non-admin" do
non_admin_user = insert(:user)
token = insert(:oauth_token, user: non_admin_user)
conn =
build_conn()
|> assign(:user, non_admin_user)
|> assign(:token, token)
|> get("/api/pleroma/admin/instance_document/instance-panel")
assert json_response(conn, :forbidden)
end
test "it returns 404 if the instance document with the given name doesn't exist", %{
conn: conn
} do
conn = get(conn, "/api/pleroma/admin/instance_document/1234")
assert json_response_and_validate_schema(conn, 404)
end
end
describe "PATCH /api/pleroma/admin/instance_document/:name" do
test "uploads the instance document", %{conn: conn} do
image = %Plug.Upload{
content_type: "text/html",
path: Path.absname("test/fixtures/custom_instance_panel.html"),
filename: "custom_instance_panel.html"
}
conn =
conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/admin/instance_document/instance-panel", %{
"file" => image
})
assert %{"url" => url} = json_response_and_validate_schema(conn, 200)
index = get(build_conn(), url)
assert html_response(index, 200) == "<h2>Custom instance panel</h2>"
end
end
describe "DELETE /api/pleroma/admin/instance_document/:name" do
test "deletes the instance document", %{conn: conn} do
File.mkdir!(@dir <> "/instance/")
File.write!(@dir <> "/instance/panel.html", "Custom instance panel")
conn_resp =
conn
|> get("/api/pleroma/admin/instance_document/instance-panel")
assert html_response(conn_resp, 200) == "Custom instance panel"
conn
|> delete("/api/pleroma/admin/instance_document/instance-panel")
|> json_response_and_validate_schema(200)
conn_resp =
conn
|> get("/api/pleroma/admin/instance_document/instance-panel")
assert content = html_response(conn_resp, 200)
assert String.contains?(content, @default_instance_panel)
end
end
end

View file

@ -177,5 +177,14 @@ defmodule Pleroma.Web.AdminAPI.SearchTest do
assert total == 3
assert count == 1
end
test "it returns non-discoverable users" do
insert(:user)
insert(:user, discoverable: false)
{:ok, _results, total} = Search.user()
assert total == 2
end
end
end

View file

@ -217,6 +217,17 @@ defmodule Pleroma.Web.CommonAPITest do
assert message == :content_too_long
end
test "it reject messages via MRF" do
clear_config([:mrf_keyword, :reject], ["GNO"])
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
author = insert(:user)
recipient = insert(:user)
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
CommonAPI.post_chat_message(author, recipient, "GNO/Linux")
end
end
describe "unblocking" do
@ -1209,4 +1220,24 @@ defmodule Pleroma.Web.CommonAPITest do
assert Visibility.get_visibility(activity) == "private"
end
end
describe "get_user/1" do
test "gets user by ap_id" do
user = insert(:user)
assert CommonAPI.get_user(user.ap_id) == user
end
test "gets user by guessed nickname" do
user = insert(:user, ap_id: "", nickname: "mario@mushroom.kingdom")
assert CommonAPI.get_user("https://mushroom.kingdom/users/mario") == user
end
test "fallback" do
assert %User{
name: "",
ap_id: "",
nickname: "erroruser@example.com"
} = CommonAPI.get_user("")
end
end
end

View file

@ -0,0 +1,124 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.FedSockets.FedRegistryTest do
use ExUnit.Case
alias Pleroma.Web.FedSockets
alias Pleroma.Web.FedSockets.FedRegistry
alias Pleroma.Web.FedSockets.SocketInfo
@good_domain "http://good.domain"
@good_domain_origin "good.domain:80"
setup do
start_supervised({Pleroma.Web.FedSockets.Supervisor, []})
build_test_socket(@good_domain)
Process.sleep(10)
:ok
end
describe "add_fed_socket/1 without conflicting sockets" do
test "can be added" do
Process.sleep(10)
assert {:ok, %SocketInfo{origin: origin}} = FedRegistry.get_fed_socket(@good_domain_origin)
assert origin == "good.domain:80"
end
test "multiple origins can be added" do
build_test_socket("http://anothergood.domain")
Process.sleep(10)
assert {:ok, %SocketInfo{origin: origin_1}} =
FedRegistry.get_fed_socket(@good_domain_origin)
assert {:ok, %SocketInfo{origin: origin_2}} =
FedRegistry.get_fed_socket("anothergood.domain:80")
assert origin_1 == "good.domain:80"
assert origin_2 == "anothergood.domain:80"
assert FedRegistry.list_all() |> Enum.count() == 2
end
end
describe "add_fed_socket/1 when duplicate sockets conflict" do
setup do
build_test_socket(@good_domain)
build_test_socket(@good_domain)
Process.sleep(10)
:ok
end
test "will be ignored" do
assert {:ok, %SocketInfo{origin: origin, pid: pid_one}} =
FedRegistry.get_fed_socket(@good_domain_origin)
assert origin == "good.domain:80"
assert FedRegistry.list_all() |> Enum.count() == 1
end
test "the newer process will be closed" do
pid_two = build_test_socket(@good_domain)
assert {:ok, %SocketInfo{origin: origin, pid: pid_one}} =
FedRegistry.get_fed_socket(@good_domain_origin)
assert origin == "good.domain:80"
Process.sleep(10)
refute Process.alive?(pid_two)
assert FedRegistry.list_all() |> Enum.count() == 1
end
end
describe "get_fed_socket/1" do
test "returns missing for unknown hosts" do
assert {:error, :missing} = FedRegistry.get_fed_socket("not_a_dmoain")
end
test "returns rejected for hosts previously rejected" do
"rejected.domain:80"
|> FedSockets.uri_for_origin()
|> FedRegistry.set_host_rejected()
assert {:error, :rejected} = FedRegistry.get_fed_socket("rejected.domain:80")
end
test "can retrieve a previously added SocketInfo" do
build_test_socket(@good_domain)
Process.sleep(10)
assert {:ok, %SocketInfo{origin: origin}} = FedRegistry.get_fed_socket(@good_domain_origin)
assert origin == "good.domain:80"
end
test "removes references to SocketInfos when the process crashes" do
assert {:ok, %SocketInfo{origin: origin, pid: pid}} =
FedRegistry.get_fed_socket(@good_domain_origin)
assert origin == "good.domain:80"
Process.exit(pid, :testing)
Process.sleep(100)
assert {:error, :missing} = FedRegistry.get_fed_socket(@good_domain_origin)
end
end
def build_test_socket(uri) do
Kernel.spawn(fn -> fed_socket_almost(uri) end)
end
def fed_socket_almost(origin) do
FedRegistry.add_fed_socket(origin)
receive do
:close ->
:ok
after
5_000 -> :timeout
end
end
end

View file

@ -0,0 +1,67 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.FedSockets.FetchRegistryTest do
use ExUnit.Case
alias Pleroma.Web.FedSockets.FetchRegistry
alias Pleroma.Web.FedSockets.FetchRegistry.FetchRegistryData
@json_message "hello"
@json_reply "hello back"
setup do
start_supervised(
{Pleroma.Web.FedSockets.Supervisor,
[
ping_interval: 8,
connection_duration: 15,
rejection_duration: 5,
fed_socket_fetches: [default: 10, interval: 10]
]}
)
:ok
end
test "fetches can be stored" do
uuid = FetchRegistry.register_fetch(@json_message)
assert {:error, :waiting} = FetchRegistry.check_fetch(uuid)
end
test "fetches can return" do
uuid = FetchRegistry.register_fetch(@json_message)
task = Task.async(fn -> FetchRegistry.register_fetch_received(uuid, @json_reply) end)
assert {:error, :waiting} = FetchRegistry.check_fetch(uuid)
Task.await(task)
assert {:ok, %FetchRegistryData{received_json: received_json}} =
FetchRegistry.check_fetch(uuid)
assert received_json == @json_reply
end
test "fetches are deleted once popped from stack" do
uuid = FetchRegistry.register_fetch(@json_message)
task = Task.async(fn -> FetchRegistry.register_fetch_received(uuid, @json_reply) end)
Task.await(task)
assert {:ok, %FetchRegistryData{received_json: received_json}} =
FetchRegistry.check_fetch(uuid)
assert received_json == @json_reply
assert {:ok, @json_reply} = FetchRegistry.pop_fetch(uuid)
assert {:error, :missing} = FetchRegistry.check_fetch(uuid)
end
test "fetches can time out" do
uuid = FetchRegistry.register_fetch(@json_message)
assert {:error, :waiting} = FetchRegistry.check_fetch(uuid)
Process.sleep(500)
assert {:error, :missing} = FetchRegistry.check_fetch(uuid)
end
end

View file

@ -0,0 +1,118 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.FedSockets.SocketInfoTest do
use ExUnit.Case
alias Pleroma.Web.FedSockets
alias Pleroma.Web.FedSockets.SocketInfo
describe "uri_for_origin" do
test "provides the fed_socket URL given the origin information" do
endpoint = "example.com:4000"
assert FedSockets.uri_for_origin(endpoint) =~ "ws://"
assert FedSockets.uri_for_origin(endpoint) =~ endpoint
end
end
describe "origin" do
test "will provide the origin field given a url" do
endpoint = "example.com:4000"
assert SocketInfo.origin("ws://#{endpoint}") == endpoint
assert SocketInfo.origin("http://#{endpoint}") == endpoint
assert SocketInfo.origin("https://#{endpoint}") == endpoint
end
test "will proide the origin field given a uri" do
endpoint = "example.com:4000"
uri = URI.parse("http://#{endpoint}")
assert SocketInfo.origin(uri) == endpoint
end
end
describe "touch" do
test "will update the TTL" do
endpoint = "example.com:4000"
socket = SocketInfo.build("ws://#{endpoint}")
Process.sleep(2)
touched_socket = SocketInfo.touch(socket)
assert socket.connected_until < touched_socket.connected_until
end
end
describe "expired?" do
setup do
start_supervised(
{Pleroma.Web.FedSockets.Supervisor,
[
ping_interval: 8,
connection_duration: 5,
rejection_duration: 5,
fed_socket_rejections: [lazy: true]
]}
)
:ok
end
test "tests if the TTL is exceeded" do
endpoint = "example.com:4000"
socket = SocketInfo.build("ws://#{endpoint}")
refute SocketInfo.expired?(socket)
Process.sleep(10)
assert SocketInfo.expired?(socket)
end
end
describe "creating outgoing connection records" do
test "can be passed a string" do
assert %{conn_pid: :pid, origin: _origin} = SocketInfo.build("example.com:4000", :pid)
end
test "can be passed a URI" do
uri = URI.parse("http://example.com:4000")
assert %{conn_pid: :pid, origin: origin} = SocketInfo.build(uri, :pid)
assert origin =~ "example.com:4000"
end
test "will include the port number" do
assert %{conn_pid: :pid, origin: origin} = SocketInfo.build("http://example.com:4000", :pid)
assert origin =~ ":4000"
end
test "will provide the port if missing" do
assert %{conn_pid: :pid, origin: "example.com:80"} =
SocketInfo.build("http://example.com", :pid)
assert %{conn_pid: :pid, origin: "example.com:443"} =
SocketInfo.build("https://example.com", :pid)
end
end
describe "creating incoming connection records" do
test "can be passed a string" do
assert %{pid: _, origin: _origin} = SocketInfo.build("example.com:4000")
end
test "can be passed a URI" do
uri = URI.parse("example.com:4000")
assert %{pid: _, origin: _origin} = SocketInfo.build(uri)
end
test "will include the port number" do
assert %{pid: _, origin: origin} = SocketInfo.build("http://example.com:4000")
assert origin =~ ":4000"
end
test "will provide the port if missing" do
assert %{pid: _, origin: "example.com:80"} = SocketInfo.build("http://example.com")
assert %{pid: _, origin: "example.com:443"} = SocketInfo.build("https://example.com")
end
end
end

View file

@ -5,6 +5,7 @@
defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
use Pleroma.DataCase
alias Pleroma.Config
alias Pleroma.User
alias Pleroma.UserRelationship
alias Pleroma.Web.CommonAPI
@ -68,7 +69,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
sensitive: false,
pleroma: %{
actor_type: "Person",
discoverable: false
discoverable: true
},
fields: []
},
@ -166,7 +167,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
sensitive: false,
pleroma: %{
actor_type: "Service",
discoverable: false
discoverable: true
},
fields: []
},
@ -540,8 +541,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
end
end
test "uses mediaproxy urls when it's enabled" do
test "uses mediaproxy urls when it's enabled (regardless of media preview proxy state)" do
clear_config([:media_proxy, :enabled], true)
clear_config([:media_preview_proxy, :enabled])
user =
insert(:user,
@ -550,20 +552,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
emoji: %{"joker_smile" => "https://evil.website/society.png"}
)
AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|> Enum.all?(fn
{key, url} when key in [:avatar, :avatar_static, :header, :header_static] ->
String.starts_with?(url, Pleroma.Web.base_url())
with media_preview_enabled <- [false, true] do
Config.put([:media_preview_proxy, :enabled], media_preview_enabled)
{:emojis, emojis} ->
Enum.all?(emojis, fn %{url: url, static_url: static_url} ->
String.starts_with?(url, Pleroma.Web.base_url()) &&
String.starts_with?(static_url, Pleroma.Web.base_url())
end)
AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|> Enum.all?(fn
{key, url} when key in [:avatar, :avatar_static, :header, :header_static] ->
String.starts_with?(url, Pleroma.Web.base_url())
_ ->
true
end)
|> assert()
{:emojis, emojis} ->
Enum.all?(emojis, fn %{url: url, static_url: static_url} ->
String.starts_with?(url, Pleroma.Web.base_url()) &&
String.starts_with?(static_url, Pleroma.Web.base_url())
end)
_ ->
true
end)
|> assert()
end
end
end

View file

@ -8,34 +8,34 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
import Mock
alias Pleroma.Web.MediaProxy
alias Pleroma.Web.MediaProxy.MediaProxyController
alias Plug.Conn
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
test "it returns 404 when MediaProxy disabled", %{conn: conn} do
clear_config([:media_proxy, :enabled], false)
assert %Conn{
status: 404,
resp_body: "Not Found"
} = get(conn, "/proxy/hhgfh/eeeee")
assert %Conn{
status: 404,
resp_body: "Not Found"
} = get(conn, "/proxy/hhgfh/eeee/fff")
end
describe "" do
describe "Media Proxy" do
setup do
clear_config([:media_proxy, :enabled], true)
clear_config([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
[url: MediaProxy.encode_url("https://google.fn/test.png")]
end
test "it returns 404 when disabled", %{conn: conn} do
clear_config([:media_proxy, :enabled], false)
assert %Conn{
status: 404,
resp_body: "Not Found"
} = get(conn, "/proxy/hhgfh/eeeee")
assert %Conn{
status: 404,
resp_body: "Not Found"
} = get(conn, "/proxy/hhgfh/eeee/fff")
end
test "it returns 403 for invalid signature", %{conn: conn, url: url} do
Pleroma.Config.put([Pleroma.Web.Endpoint, :secret_key_base], "000")
%{path: path} = URI.parse(url)
@ -56,7 +56,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
} = get(conn, "/proxy/hhgfh/eeee/fff")
end
test "redirects on valid url when filename is invalidated", %{conn: conn, url: url} do
test "redirects to valid url when filename is invalidated", %{conn: conn, url: url} do
invalid_url = String.replace(url, "test.png", "test-file.png")
response = get(conn, invalid_url)
assert response.status == 302
@ -80,42 +80,248 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
end
end
describe "filename_matches/3" do
test "preserves the encoded or decoded path" do
assert MediaProxyController.filename_matches(
%{"filename" => "/Hello world.jpg"},
"/Hello world.jpg",
"http://pleroma.social/Hello world.jpg"
) == :ok
describe "Media Preview Proxy" do
setup do
clear_config([:media_proxy, :enabled], true)
clear_config([:media_preview_proxy, :enabled], true)
clear_config([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
assert MediaProxyController.filename_matches(
%{"filename" => "/Hello%20world.jpg"},
"/Hello%20world.jpg",
"http://pleroma.social/Hello%20world.jpg"
) == :ok
original_url = "https://google.fn/test.png"
assert MediaProxyController.filename_matches(
%{"filename" => "/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"},
"/my%2Flong%2Furl%2F2019%2F07%2FS.jpg",
"http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"
) == :ok
assert MediaProxyController.filename_matches(
%{"filename" => "/my%2Flong%2Furl%2F2019%2F07%2FS.jp"},
"/my%2Flong%2Furl%2F2019%2F07%2FS.jp",
"http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"
) == {:wrong_filename, "my%2Flong%2Furl%2F2019%2F07%2FS.jpg"}
[
url: MediaProxy.encode_preview_url(original_url),
media_proxy_url: MediaProxy.encode_url(original_url)
]
end
test "encoded url are tried to match for proxy as `conn.request_path` encodes the url" do
# conn.request_path will return encoded url
request_path = "/ANALYSE-DAI-_-LE-STABLECOIN-100-D%C3%89CENTRALIS%C3%89-BQ.jpg"
test "returns 404 when media proxy is disabled", %{conn: conn} do
clear_config([:media_proxy, :enabled], false)
assert MediaProxyController.filename_matches(
true,
request_path,
"https://mydomain.com/uploads/2019/07/ANALYSE-DAI-_-LE-STABLECOIN-100-DÉCENTRALISÉ-BQ.jpg"
) == :ok
assert %Conn{
status: 404,
resp_body: "Not Found"
} = get(conn, "/proxy/preview/hhgfh/eeeee")
assert %Conn{
status: 404,
resp_body: "Not Found"
} = get(conn, "/proxy/preview/hhgfh/fff")
end
test "returns 404 when disabled", %{conn: conn} do
clear_config([:media_preview_proxy, :enabled], false)
assert %Conn{
status: 404,
resp_body: "Not Found"
} = get(conn, "/proxy/preview/hhgfh/eeeee")
assert %Conn{
status: 404,
resp_body: "Not Found"
} = get(conn, "/proxy/preview/hhgfh/fff")
end
test "it returns 403 for invalid signature", %{conn: conn, url: url} do
Pleroma.Config.put([Pleroma.Web.Endpoint, :secret_key_base], "000")
%{path: path} = URI.parse(url)
assert %Conn{
status: 403,
resp_body: "Forbidden"
} = get(conn, path)
assert %Conn{
status: 403,
resp_body: "Forbidden"
} = get(conn, "/proxy/preview/hhgfh/eeee")
assert %Conn{
status: 403,
resp_body: "Forbidden"
} = get(conn, "/proxy/preview/hhgfh/eeee/fff")
end
test "redirects to valid url when filename is invalidated", %{conn: conn, url: url} do
invalid_url = String.replace(url, "test.png", "test-file.png")
response = get(conn, invalid_url)
assert response.status == 302
assert redirected_to(response) == url
end
test "responds with 424 Failed Dependency if HEAD request to media proxy fails", %{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{status: 500, body: ""}
end)
response = get(conn, url)
assert response.status == 424
assert response.resp_body == "Can't fetch HTTP headers (HTTP 500)."
end
test "redirects to media proxy URI on unsupported content type", %{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]}
end)
response = get(conn, url)
assert response.status == 302
assert redirected_to(response) == media_proxy_url
end
test "with `static=true` and GIF image preview requested, responds with JPEG image", %{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
# Setting a high :min_content_length to ensure this scenario is not affected by its logic
clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000)
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{
status: 200,
body: "",
headers: [{"content-type", "image/gif"}, {"content-length", "1001718"}]
}
%{method: :get, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.gif")}
end)
response = get(conn, url <> "?static=true")
assert response.status == 200
assert Conn.get_resp_header(response, "content-type") == ["image/jpeg"]
assert response.resp_body != ""
end
test "with GIF image preview requested and no `static` param, redirects to media proxy URI",
%{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]}
end)
response = get(conn, url)
assert response.status == 302
assert redirected_to(response) == media_proxy_url
end
test "with `static` param and non-GIF image preview requested, " <>
"redirects to media preview proxy URI without `static` param",
%{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
end)
response = get(conn, url <> "?static=true")
assert response.status == 302
assert redirected_to(response) == url
end
test "with :min_content_length setting not matched by Content-Length header, " <>
"redirects to media proxy URI",
%{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
clear_config([:media_preview_proxy, :min_content_length], 100_000)
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{
status: 200,
body: "",
headers: [{"content-type", "image/gif"}, {"content-length", "5000"}]
}
end)
response = get(conn, url)
assert response.status == 302
assert redirected_to(response) == media_proxy_url
end
test "thumbnails PNG images into PNG", %{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]}
%{method: :get, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.png")}
end)
response = get(conn, url)
assert response.status == 200
assert Conn.get_resp_header(response, "content-type") == ["image/png"]
assert response.resp_body != ""
end
test "thumbnails JPEG images into JPEG", %{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
%{method: :get, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
end)
response = get(conn, url)
assert response.status == 200
assert Conn.get_resp_header(response, "content-type") == ["image/jpeg"]
assert response.resp_body != ""
end
test "redirects to media proxy URI in case of thumbnailing error", %{
conn: conn,
url: url,
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
%{method: :get, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "<html><body>error</body></html>"}
end)
response = get(conn, url)
assert response.status == 302
assert redirected_to(response) == media_proxy_url
end
end
end

View file

@ -6,9 +6,16 @@ defmodule Pleroma.Web.MediaProxyTest do
use ExUnit.Case
use Pleroma.Tests.Helpers
alias Pleroma.Config
alias Pleroma.Web.Endpoint
alias Pleroma.Web.MediaProxy
defp decode_result(encoded) do
[_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
{:ok, decoded} = MediaProxy.decode_url(sig, base64)
decoded
end
describe "when enabled" do
setup do: clear_config([:media_proxy, :enabled], true)
@ -35,7 +42,7 @@ defmodule Pleroma.Web.MediaProxyTest do
assert String.starts_with?(
encoded,
Pleroma.Config.get([:media_proxy, :base_url], Pleroma.Web.base_url())
Config.get([:media_proxy, :base_url], Pleroma.Web.base_url())
)
assert String.ends_with?(encoded, "/logo.png")
@ -75,6 +82,64 @@ defmodule Pleroma.Web.MediaProxyTest do
assert MediaProxy.decode_url(sig, base64) == {:error, :invalid_signature}
end
def test_verify_request_path_and_url(request_path, url, expected_result) do
assert MediaProxy.verify_request_path_and_url(request_path, url) == expected_result
assert MediaProxy.verify_request_path_and_url(
%Plug.Conn{
params: %{"filename" => Path.basename(request_path)},
request_path: request_path
},
url
) == expected_result
end
test "if first arg of `verify_request_path_and_url/2` is a Plug.Conn without \"filename\" " <>
"parameter, `verify_request_path_and_url/2` returns :ok " do
assert MediaProxy.verify_request_path_and_url(
%Plug.Conn{params: %{}, request_path: "/some/path"},
"https://instance.com/file.jpg"
) == :ok
assert MediaProxy.verify_request_path_and_url(
%Plug.Conn{params: %{}, request_path: "/path/to/file.jpg"},
"https://instance.com/file.jpg"
) == :ok
end
test "`verify_request_path_and_url/2` preserves the encoded or decoded path" do
test_verify_request_path_and_url(
"/Hello world.jpg",
"http://pleroma.social/Hello world.jpg",
:ok
)
test_verify_request_path_and_url(
"/Hello%20world.jpg",
"http://pleroma.social/Hello%20world.jpg",
:ok
)
test_verify_request_path_and_url(
"/my%2Flong%2Furl%2F2019%2F07%2FS.jpg",
"http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg",
:ok
)
test_verify_request_path_and_url(
# Note: `conn.request_path` returns encoded url
"/ANALYSE-DAI-_-LE-STABLECOIN-100-D%C3%89CENTRALIS%C3%89-BQ.jpg",
"https://mydomain.com/uploads/2019/07/ANALYSE-DAI-_-LE-STABLECOIN-100-DÉCENTRALISÉ-BQ.jpg",
:ok
)
test_verify_request_path_and_url(
"/my%2Flong%2Furl%2F2019%2F07%2FS",
"http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg",
{:wrong_filename, "my%2Flong%2Furl%2F2019%2F07%2FS.jpg"}
)
end
test "uses the configured base_url" do
base_url = "https://cache.pleroma.social"
clear_config([:media_proxy, :base_url], base_url)
@ -124,12 +189,6 @@ defmodule Pleroma.Web.MediaProxyTest do
end
end
defp decode_result(encoded) do
[_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
{:ok, decoded} = MediaProxy.decode_url(sig, base64)
decoded
end
describe "whitelist" do
setup do: clear_config([:media_proxy, :enabled], true)

View file

@ -16,7 +16,14 @@ defmodule Pleroma.Web.MetadataTest do
end
test "for local user" do
user = insert(:user)
user = insert(:user, discoverable: false)
assert Pleroma.Web.Metadata.build_tags(%{user: user}) =~
"<meta content=\"noindex, noarchive\" name=\"robots\">"
end
test "for local user set to discoverable" do
user = insert(:user, discoverable: true)
refute Pleroma.Web.Metadata.build_tags(%{user: user}) =~
"<meta content=\"noindex, noarchive\" name=\"robots\">"
@ -24,11 +31,19 @@ defmodule Pleroma.Web.MetadataTest do
end
describe "no metadata for private instances" do
test "for local user" do
test "for local user set to discoverable" do
clear_config([:instance, :public], false)
user = insert(:user, bio: "This is my secret fedi account bio")
user = insert(:user, bio: "This is my secret fedi account bio", discoverable: true)
assert "" = Pleroma.Web.Metadata.build_tags(%{user: user})
end
test "search exclusion metadata is included" do
clear_config([:instance, :public], false)
user = insert(:user, bio: "This is my secret fedi account bio", discoverable: false)
assert ~s(<meta content="noindex, noarchive" name="robots">) ==
Pleroma.Web.Metadata.build_tags(%{user: user})
end
end
end

View file

@ -14,8 +14,14 @@ defmodule Pleroma.Web.Metadata.Providers.RestrictIndexingTest do
test "for local user" do
assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{
user: %Pleroma.User{local: true}
user: %Pleroma.User{local: true, discoverable: true}
}) == []
end
test "for local user when discoverable is false" do
assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{
user: %Pleroma.User{local: true, discoverable: false}
}) == [{:meta, [name: "robots", content: "noindex, noarchive"], []}]
end
end
end

View file

@ -100,7 +100,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
|> post("/api/v1/pleroma/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(400)
assert result
assert %{"error" => "no_content"} == result
end
test "it works with an attachment", %{conn: conn, user: user} do
@ -126,6 +126,23 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
assert result["attachment"]
end
test "gets MRF reason when rejected", %{conn: conn, user: user} do
clear_config([:mrf_keyword, :reject], ["GNO"])
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "GNO/Linux"})
|> json_response_and_validate_schema(422)
assert %{"error" => "[KeywordPolicy] Matches with rejected keyword"} == result
end
end
describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do

View file

@ -12,7 +12,9 @@ defmodule Pleroma.Web.Push.ImplTest do
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Push.Impl
alias Pleroma.Web.Push.Subscription
alias Pleroma.Web.WebPushHttpClientMock
import Mock
import Pleroma.Factory
setup do
@ -78,6 +80,22 @@ defmodule Pleroma.Web.Push.ImplTest do
assert Impl.push_message(@message, @sub, @api_key, %Subscription{}) == :ok
end
test_with_mock "uses WebPushHttpClientMock as an HTTP client", WebPushHttpClientMock,
post: fn _, _, _ -> {:ok, %{status_code: 200}} end do
Impl.push_message(@message, @sub, @api_key, %Subscription{})
assert_called(WebPushHttpClientMock.post("https://example.com/example/1234", :_, :_))
end
test_with_mock "uses Pleroma.HTTP as an HTTP client", Pleroma.HTTP,
post: fn _, _, _ -> {:ok, %{status_code: 200}} end do
client = Application.get_env(:web_push_encryption, :http_client)
on_exit(fn -> Application.put_env(:web_push_encryption, :http_client, client) end)
Application.put_env(:web_push_encryption, :http_client, Pleroma.HTTP)
Impl.push_message(@message, @sub, @api_key, %Subscription{})
assert_called(Pleroma.HTTP.post("https://example.com/example/1234", :_, :_))
end
@tag capture_log: true
test "fail message sending" do
assert Impl.push_message(