Merge branch 'develop' into rename/pleroma_activity_consistency

This commit is contained in:
lain 2019-01-23 13:05:58 +01:00
commit 2de208817c
17 changed files with 324 additions and 20 deletions

View file

@ -36,6 +36,10 @@ defmodule Pleroma.Activity do
)
end
def get_by_id(id) do
Repo.get(Activity, id)
end
def by_object_ap_id(ap_id) do
from(
activity in Activity,

View file

@ -275,11 +275,24 @@ defmodule Pleroma.ReverseProxy do
defp build_resp_cache_headers(headers, _opts) do
has_cache? = Enum.any?(headers, fn {k, _} -> k in @resp_cache_headers end)
has_cache_control? = List.keymember?(headers, "cache-control", 0)
if has_cache? do
headers
else
List.keystore(headers, "cache-control", 0, {"cache-control", @default_cache_control_header})
cond do
has_cache? && has_cache_control? ->
headers
has_cache? ->
# There's caching header present but no cache-control -- we need to explicitely override it to public
# as Plug defaults to "max-age=0, private, must-revalidate"
List.keystore(headers, "cache-control", 0, {"cache-control", "public"})
true ->
List.keystore(
headers,
"cache-control",
0,
{"cache-control", @default_cache_control_header}
)
end
end

View file

@ -27,18 +27,47 @@ defmodule Pleroma.Uploaders.Uploader do
This allows to correctly proxy or redirect requests to the backend, while allowing to migrate backends without breaking any URL.
* `{url, url :: String.t}` to bypass `get_file/2` and use the `url` directly in the activity.
* `{:error, String.t}` error information if the file failed to be saved to the backend.
* `:wait_callback` will wait for an http post request at `/api/pleroma/upload_callback/:upload_path` and call the uploader's `http_callback/3` method.
"""
@type file_spec :: {:file | :url, String.t()}
@callback put_file(Pleroma.Upload.t()) ::
:ok | {:ok, {:file | :url, String.t()}} | {:error, String.t()}
:ok | {:ok, file_spec()} | {:error, String.t()} | :wait_callback
@callback http_callback(Plug.Conn.t(), Map.t()) ::
{:ok, Plug.Conn.t()}
| {:ok, Plug.Conn.t(), file_spec()}
| {:error, Plug.Conn.t(), String.t()}
@optional_callbacks http_callback: 2
@spec put_file(module(), Pleroma.Upload.t()) :: {:ok, file_spec()} | {:error, String.t()}
@spec put_file(module(), Pleroma.Upload.t()) ::
{:ok, {:file | :url, String.t()}} | {:error, String.t()}
def put_file(uploader, upload) do
case uploader.put_file(upload) do
:ok -> {:ok, {:file, upload.path}}
other -> other
:wait_callback -> handle_callback(uploader, upload)
{:ok, _} = ok -> ok
{:error, _} = error -> error
end
end
defp handle_callback(uploader, upload) do
:global.register_name({__MODULE__, upload.path}, self())
receive do
{__MODULE__, pid, conn, params} ->
case uploader.http_callback(conn, params) do
{:ok, conn, ok} ->
send(pid, {__MODULE__, conn})
{:ok, ok}
{:error, conn, error} ->
send(pid, {__MODULE__, conn})
{:error, error}
end
after
30_000 -> {:error, "Uploader callback timeout"}
end
end
end

View file

@ -901,7 +901,7 @@ defmodule Pleroma.User do
def active_local_user_query do
from(
u in local_user_query(),
where: fragment("?->'deactivated' @> 'false'", u.info)
where: fragment("not (?->'deactivated' @> 'true')", u.info)
)
end

View file

@ -140,8 +140,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
additional
),
{:ok, activity} <- insert(create_data, local),
:ok <- maybe_federate(activity),
{:ok, _actor} <- User.increase_note_count(actor) do
# Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info
{:ok, _actor} <- User.increase_note_count(actor),
:ok <- maybe_federate(activity) do
{:ok, activity}
end
end
@ -288,8 +289,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
with {:ok, _} <- Object.delete(object),
{:ok, activity} <- insert(data, local),
:ok <- maybe_federate(activity),
{:ok, _actor} <- User.decrease_note_count(user) do
# Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info
{:ok, _actor} <- User.decrease_note_count(user),
:ok <- maybe_federate(activity) do
{:ok, activity}
end
end
@ -802,11 +804,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false
def is_public?(%Object{data: data}), do: is_public?(data)
def is_public?(%Activity{data: data}), do: is_public?(data)
def is_public?(%{"directMessage" => true}), do: false
def is_public?(data) do
"https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || []))
end
def is_private?(activity) do
!is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers"))
end
def is_direct?(%Activity{data: %{"directMessage" => true}}), do: true
def is_direct?(%Object{data: %{"directMessage" => true}}), do: true
def is_direct?(activity) do
!is_public?(activity) && !is_private?(activity)
end
def visible_for_user?(activity, nil) do
is_public?(activity)
end

View file

@ -93,12 +93,47 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end
def fix_addressing(map) do
map
def fix_explicit_addressing(%{"to" => to, "cc" => cc} = object, explicit_mentions) do
explicit_to =
to
|> Enum.filter(fn x -> x in explicit_mentions end)
explicit_cc =
to
|> Enum.filter(fn x -> x not in explicit_mentions end)
final_cc =
(cc ++ explicit_cc)
|> Enum.uniq()
object
|> Map.put("to", explicit_to)
|> Map.put("cc", final_cc)
end
def fix_explicit_addressing(object, _explicit_mentions), do: object
# if directMessage flag is set to true, leave the addressing alone
def fix_explicit_addressing(%{"directMessage" => true} = object), do: object
def fix_explicit_addressing(object) do
explicit_mentions =
object
|> Utils.determine_explicit_mentions()
explicit_mentions = explicit_mentions ++ ["https://www.w3.org/ns/activitystreams#Public"]
object
|> fix_explicit_addressing(explicit_mentions)
end
def fix_addressing(object) do
object
|> fix_addressing_list("to")
|> fix_addressing_list("cc")
|> fix_addressing_list("bto")
|> fix_addressing_list("bcc")
|> fix_explicit_addressing
end
def fix_actor(%{"attributedTo" => actor} = object) do
@ -348,6 +383,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
additional:
Map.take(data, [
"cc",
"directMessage",
"id"
])
}

View file

@ -25,6 +25,20 @@ defmodule Pleroma.Web.ActivityPub.Utils do
Map.put(params, "actor", get_ap_id(params["actor"]))
end
def determine_explicit_mentions(%{"tag" => tag} = _object) when is_list(tag) do
tag
|> Enum.filter(fn x -> is_map(x) end)
|> Enum.filter(fn x -> x["type"] == "Mention" end)
|> Enum.map(fn x -> x["href"] end)
end
def determine_explicit_mentions(%{"tag" => tag} = object) when is_map(tag) do
Map.put(object, "tag", [tag])
|> determine_explicit_mentions()
end
def determine_explicit_mentions(_), do: []
defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll
defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll
defp recipient_in_collection(_, _), do: false

View file

@ -143,7 +143,7 @@ defmodule Pleroma.Web.CommonAPI do
actor: user,
context: context,
object: object,
additional: %{"cc" => cc}
additional: %{"cc" => cc, "directMessage" => visibility == "direct"}
})
res

View file

@ -231,6 +231,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
Enum.any?(to, &String.contains?(&1, "/followers")) ->
"private"
length(cc) > 0 ->
"private"
true ->
"direct"
end

View file

@ -107,6 +107,11 @@ defmodule Pleroma.Web.Router do
get("/captcha", UtilController, :captcha)
end
scope "/api/pleroma", Pleroma.Web do
pipe_through(:pleroma_api)
post("/uploader_callback/:upload_path", UploaderController, :callback)
end
scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
pipe_through(:admin_api)
delete("/user", AdminAPIController, :user_delete)

View file

@ -0,0 +1,25 @@
defmodule Pleroma.Web.UploaderController do
use Pleroma.Web, :controller
alias Pleroma.Uploaders.Uploader
def callback(conn, params = %{"upload_path" => upload_path}) do
process_callback(conn, :global.whereis_name({Uploader, upload_path}), params)
end
def callbacks(conn, _) do
send_resp(conn, 400, "bad request")
end
defp process_callback(conn, pid, params) when is_pid(pid) do
send(pid, {Uploader, self(), conn, params})
receive do
{Uploader, conn} -> conn
end
end
defp process_callback(conn, _, _) do
send_resp(conn, 400, "bad request")
end
end