Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into no-async-clear-config
This commit is contained in:
commit
18ab36d70c
@ -1,6 +1,7 @@
|
|||||||
image: git.pleroma.social:5050/pleroma/pleroma/ci-base
|
image: git.pleroma.social:5050/pleroma/pleroma/ci-base
|
||||||
|
|
||||||
variables: &global_variables
|
variables: &global_variables
|
||||||
|
# Only used for the release
|
||||||
ELIXIR_VER: 1.12.3
|
ELIXIR_VER: 1.12.3
|
||||||
POSTGRES_DB: pleroma_test
|
POSTGRES_DB: pleroma_test
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
@ -319,8 +320,9 @@ amd64:
|
|||||||
- deps
|
- deps
|
||||||
variables: &release-variables
|
variables: &release-variables
|
||||||
MIX_ENV: prod
|
MIX_ENV: prod
|
||||||
|
VIX_COMPILATION_MODE: PLATFORM_PROVIDED_LIBVIPS
|
||||||
before_script: &before-release
|
before_script: &before-release
|
||||||
- apt-get update && apt-get install -y cmake libmagic-dev
|
- apt-get update && apt-get install -y cmake libmagic-dev libvips-dev erlang-dev
|
||||||
- echo "import Config" > config/prod.secret.exs
|
- echo "import Config" > config/prod.secret.exs
|
||||||
- mix local.hex --force
|
- mix local.hex --force
|
||||||
- mix local.rebar --force
|
- mix local.rebar --force
|
||||||
@ -341,7 +343,7 @@ amd64-musl:
|
|||||||
cache: *release-cache
|
cache: *release-cache
|
||||||
variables: *release-variables
|
variables: *release-variables
|
||||||
before_script: &before-release-musl
|
before_script: &before-release-musl
|
||||||
- apk add git build-base cmake file-dev openssl
|
- apk add git build-base cmake file-dev openssl vips-dev
|
||||||
- echo "import Config" > config/prod.secret.exs
|
- echo "import Config" > config/prod.secret.exs
|
||||||
- mix local.hex --force
|
- mix local.hex --force
|
||||||
- mix local.rebar --force
|
- mix local.rebar --force
|
||||||
|
1
changelog.d/authorize-interaction.add
Normal file
1
changelog.d/authorize-interaction.add
Normal file
@ -0,0 +1 @@
|
|||||||
|
Support /authorize-interaction route used by Mastodon
|
0
changelog.d/build-release-with-local-libvips.skip
Normal file
0
changelog.d/build-release-with-local-libvips.skip
Normal file
1
changelog.d/optimistic-inbox.change
Normal file
1
changelog.d/optimistic-inbox.change
Normal file
@ -0,0 +1 @@
|
|||||||
|
Optimistic Inbox reduces the processing overhead of incoming activities without instantly verifiable signatures.
|
@ -2136,7 +2136,7 @@ defmodule Pleroma.User do
|
|||||||
def public_key(_), do: {:error, "key not found"}
|
def public_key(_), do: {:error, "key not found"}
|
||||||
|
|
||||||
def get_public_key_for_ap_id(ap_id) do
|
def get_public_key_for_ap_id(ap_id) do
|
||||||
with {:ok, %User{} = user} <- get_or_fetch_by_ap_id(ap_id),
|
with %User{} = user <- get_cached_by_ap_id(ap_id),
|
||||||
{:ok, public_key} <- public_key(user) do
|
{:ok, public_key} <- public_key(user) do
|
||||||
{:ok, public_key}
|
{:ok, public_key}
|
||||||
else
|
else
|
||||||
|
@ -287,10 +287,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||||||
json(conn, "ok")
|
json(conn, "ok")
|
||||||
end
|
end
|
||||||
|
|
||||||
def inbox(%{assigns: %{valid_signature: false}} = conn, _params) do
|
def inbox(%{assigns: %{valid_signature: false}, req_headers: req_headers} = conn, params) do
|
||||||
conn
|
Federator.incoming_ap_doc(%{req_headers: req_headers, params: params})
|
||||||
|> put_status(:bad_request)
|
json(conn, "ok")
|
||||||
|> json("Invalid HTTP Signature")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# POST /relay/inbox -or- POST /internal/fetch/inbox
|
# POST /relay/inbox -or- POST /internal/fetch/inbox
|
||||||
|
@ -35,6 +35,17 @@ defmodule Pleroma.Web.Federator do
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Client API
|
# Client API
|
||||||
|
def incoming_ap_doc(%{params: params, req_headers: req_headers}) do
|
||||||
|
ReceiverWorker.enqueue(
|
||||||
|
"incoming_ap_doc",
|
||||||
|
%{"req_headers" => req_headers, "params" => params, "timeout" => :timer.seconds(20)},
|
||||||
|
priority: 2
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def incoming_ap_doc(%{"type" => "Delete"} = params) do
|
||||||
|
ReceiverWorker.enqueue("incoming_ap_doc", %{"params" => params}, priority: 3)
|
||||||
|
end
|
||||||
|
|
||||||
def incoming_ap_doc(params) do
|
def incoming_ap_doc(params) do
|
||||||
ReceiverWorker.enqueue("incoming_ap_doc", %{"params" => params})
|
ReceiverWorker.enqueue("incoming_ap_doc", %{"params" => params})
|
||||||
|
@ -471,6 +471,8 @@ defmodule Pleroma.Web.Router do
|
|||||||
get("/main/ostatus", UtilController, :show_subscribe_form)
|
get("/main/ostatus", UtilController, :show_subscribe_form)
|
||||||
get("/ostatus_subscribe", RemoteFollowController, :follow)
|
get("/ostatus_subscribe", RemoteFollowController, :follow)
|
||||||
post("/ostatus_subscribe", RemoteFollowController, :do_follow)
|
post("/ostatus_subscribe", RemoteFollowController, :do_follow)
|
||||||
|
|
||||||
|
get("/authorize_interaction", RemoteFollowController, :authorize_interaction)
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
|
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
|
||||||
|
@ -121,6 +121,13 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
|
|||||||
render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."})
|
render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# GET /authorize_interaction
|
||||||
|
#
|
||||||
|
def authorize_interaction(conn, %{"uri" => uri}) do
|
||||||
|
conn
|
||||||
|
|> redirect(to: Routes.remote_follow_path(conn, :follow, %{acct: uri}))
|
||||||
|
end
|
||||||
|
|
||||||
defp handle_follow_error(conn, {:mfa_token, followee, _} = _) do
|
defp handle_follow_error(conn, {:mfa_token, followee, _} = _) do
|
||||||
render(conn, "follow_login.html", %{error: "Wrong username or password", followee: followee})
|
render(conn, "follow_login.html", %{error: "Wrong username or password", followee: followee})
|
||||||
end
|
end
|
||||||
|
@ -3,24 +3,56 @@
|
|||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Workers.ReceiverWorker do
|
defmodule Pleroma.Workers.ReceiverWorker do
|
||||||
|
alias Pleroma.Signature
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.Federator
|
alias Pleroma.Web.Federator
|
||||||
|
|
||||||
use Pleroma.Workers.WorkerHelper, queue: "federator_incoming"
|
use Pleroma.Workers.WorkerHelper, queue: "federator_incoming"
|
||||||
|
|
||||||
@impl Oban.Worker
|
@impl Oban.Worker
|
||||||
|
|
||||||
|
def perform(%Job{
|
||||||
|
args: %{"op" => "incoming_ap_doc", "req_headers" => req_headers, "params" => params}
|
||||||
|
}) do
|
||||||
|
# Oban's serialization converts our tuple headers to lists.
|
||||||
|
# Revert it for the signature validation.
|
||||||
|
req_headers = Enum.into(req_headers, [], &List.to_tuple(&1))
|
||||||
|
|
||||||
|
conn_data = %{params: params, req_headers: req_headers}
|
||||||
|
|
||||||
|
with {:ok, %User{} = _actor} <- User.get_or_fetch_by_ap_id(conn_data.params["actor"]),
|
||||||
|
{:ok, _public_key} <- Signature.refetch_public_key(conn_data),
|
||||||
|
{:signature, true} <- {:signature, HTTPSignatures.validate_conn(conn_data)},
|
||||||
|
{:ok, res} <- Federator.perform(:incoming_ap_doc, params) do
|
||||||
|
{:ok, res}
|
||||||
|
else
|
||||||
|
e -> process_errors(e)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def perform(%Job{args: %{"op" => "incoming_ap_doc", "params" => params}}) do
|
def perform(%Job{args: %{"op" => "incoming_ap_doc", "params" => params}}) do
|
||||||
with {:ok, res} <- Federator.perform(:incoming_ap_doc, params) do
|
with {:ok, res} <- Federator.perform(:incoming_ap_doc, params) do
|
||||||
{:ok, res}
|
{:ok, res}
|
||||||
else
|
else
|
||||||
|
e -> process_errors(e)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl Oban.Worker
|
||||||
|
def timeout(%_{args: %{"timeout" => timeout}}), do: timeout
|
||||||
|
|
||||||
|
def timeout(_job), do: :timer.seconds(5)
|
||||||
|
|
||||||
|
defp process_errors(errors) do
|
||||||
|
case errors do
|
||||||
{:error, :origin_containment_failed} -> {:cancel, :origin_containment_failed}
|
{:error, :origin_containment_failed} -> {:cancel, :origin_containment_failed}
|
||||||
{:error, :already_present} -> {:cancel, :already_present}
|
{:error, :already_present} -> {:cancel, :already_present}
|
||||||
{:error, {:validate_object, reason}} -> {:cancel, reason}
|
{:error, {:validate_object, reason}} -> {:cancel, reason}
|
||||||
{:error, {:error, {:validate, reason}}} -> {:cancel, reason}
|
{:error, {:error, {:validate, reason}}} -> {:cancel, reason}
|
||||||
{:error, {:reject, reason}} -> {:cancel, reason}
|
{:error, {:reject, reason}} -> {:cancel, reason}
|
||||||
|
{:signature, false} -> {:cancel, :invalid_signature}
|
||||||
|
{:error, {:error, reason = "Object has been deleted"}} -> {:cancel, reason}
|
||||||
e -> e
|
e -> e
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl Oban.Worker
|
|
||||||
def timeout(_job), do: :timer.seconds(5)
|
|
||||||
end
|
end
|
||||||
|
2
mix.exs
2
mix.exs
@ -181,7 +181,7 @@ defmodule Pleroma.Mixfile do
|
|||||||
{:majic, "~> 1.0"},
|
{:majic, "~> 1.0"},
|
||||||
{:open_api_spex, "~> 3.16"},
|
{:open_api_spex, "~> 3.16"},
|
||||||
{:ecto_psql_extras, "~> 0.6"},
|
{:ecto_psql_extras, "~> 0.6"},
|
||||||
{:vix, "~> 0.25.0"},
|
{:vix, "~> 0.26.0"},
|
||||||
{:elixir_make, "~> 0.7.7", override: true},
|
{:elixir_make, "~> 0.7.7", override: true},
|
||||||
{:blurhash, "~> 0.1.0", hex: :rinpatch_blurhash},
|
{:blurhash, "~> 0.1.0", hex: :rinpatch_blurhash},
|
||||||
|
|
||||||
|
2
mix.lock
2
mix.lock
@ -137,7 +137,7 @@
|
|||||||
"ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"},
|
"ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"},
|
||||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||||
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
|
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
|
||||||
"vix": {:hex, :vix, "0.25.0", "b294ca3140c0357b262d86e9966949949844282b81923bb990668c1ee5a35337", [:make, :mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:cc_precompiler, "~> 0.1.4 or ~> 0.2", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.7.3 or ~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:kino, "~> 0.7", [hex: :kino, repo: "hexpm", optional: true]}], "hexpm", "be09c96982978bc2d0c501a73e0b65ba58ec94c1afb94e3617029d6ce7ae8c3f"},
|
"vix": {:hex, :vix, "0.26.0", "027f10b6969b759318be84bd0bd8c88af877445e4e41cf96a0460392cea5399c", [:make, :mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:cc_precompiler, "~> 0.1.4 or ~> 0.2", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.7.3 or ~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:kino, "~> 0.7", [hex: :kino, repo: "hexpm", optional: true]}], "hexpm", "71b0a79ae7f199cacfc8e679b0e4ba25ee47dc02e182c5b9097efb29fbe14efd"},
|
||||||
"web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"},
|
"web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"},
|
||||||
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
||||||
"websock_adapter": {:hex, :websock_adapter, "0.5.5", "9dfeee8269b27e958a65b3e235b7e447769f66b5b5925385f5a569269164a210", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "4b977ba4a01918acbf77045ff88de7f6972c2a009213c515a445c48f224ffce9"},
|
"websock_adapter": {:hex, :websock_adapter, "0.5.5", "9dfeee8269b27e958a65b3e235b7e447769f66b5b5925385f5a569269164a210", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "4b977ba4a01918acbf77045ff88de7f6972c2a009213c515a445c48f224ffce9"},
|
||||||
|
@ -43,10 +43,7 @@ defmodule Pleroma.SignatureTest do
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error when not found user" do
|
test "it returns error when not found user" do
|
||||||
assert capture_log(fn ->
|
assert Signature.fetch_public_key(make_fake_conn("https://test-ap-id")) == {:error, :error}
|
||||||
assert Signature.fetch_public_key(make_fake_conn("https://test-ap-id")) ==
|
|
||||||
{:error, :error}
|
|
||||||
end) =~ "[error] Could not decode user"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error if public key is nil" do
|
test "it returns error if public key is nil" do
|
||||||
|
@ -1951,8 +1951,8 @@ defmodule Pleroma.UserTest do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_public_key_for_ap_id fetches a user that's not in the db" do
|
test "get_public_key_for_ap_id returns correctly for user that's not in the db" do
|
||||||
assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
|
assert :error = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "per-user rich-text filtering" do
|
describe "per-user rich-text filtering" do
|
||||||
|
@ -89,6 +89,7 @@ defmodule Pleroma.Web.Plugs.FrontendStaticPlugTest do
|
|||||||
"api",
|
"api",
|
||||||
"main",
|
"main",
|
||||||
"ostatus_subscribe",
|
"ostatus_subscribe",
|
||||||
|
"authorize_interaction",
|
||||||
"oauth",
|
"oauth",
|
||||||
"objects",
|
"objects",
|
||||||
"activities",
|
"activities",
|
||||||
|
@ -460,4 +460,38 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
|
|||||||
assert avatar_url == "#{Pleroma.Web.Endpoint.url()}/localuser/avatar.png"
|
assert avatar_url == "#{Pleroma.Web.Endpoint.url()}/localuser/avatar.png"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "GET /authorize_interaction - authorize_interaction/2" do
|
||||||
|
test "redirects to /ostatus_subscribe", %{conn: conn} do
|
||||||
|
Tesla.Mock.mock(fn
|
||||||
|
%{method: :get, url: "https://mastodon.social/users/emelie"} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
headers: [{"content-type", "application/activity+json"}],
|
||||||
|
body: File.read!("test/fixtures/tesla_mock/emelie.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
%{method: :get, url: "https://mastodon.social/users/emelie/collections/featured"} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
headers: [{"content-type", "application/activity+json"}],
|
||||||
|
body:
|
||||||
|
File.read!("test/fixtures/users_mock/masto_featured.json")
|
||||||
|
|> String.replace("{{domain}}", "mastodon.social")
|
||||||
|
|> String.replace("{{nickname}}", "emelie")
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> get(
|
||||||
|
remote_follow_path(conn, :authorize_interaction, %{
|
||||||
|
uri: "https://mastodon.social/users/emelie"
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
assert redirected_to(conn) ==
|
||||||
|
remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"})
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user