aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/mix/tasks/pleroma/database.ex23
-rw-r--r--lib/mix/tasks/pleroma/emoji.ex38
-rw-r--r--lib/pleroma/activity/queries.ex5
-rw-r--r--lib/pleroma/conversation.ex2
-rw-r--r--lib/pleroma/emoji/pack.ex2
-rw-r--r--lib/pleroma/http/adapter_helper/hackney.ex17
-rw-r--r--lib/pleroma/maintenance.ex37
-rw-r--r--lib/pleroma/notification.ex18
-rw-r--r--lib/pleroma/plugs/http_security_plug.ex82
-rw-r--r--lib/pleroma/user.ex27
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex27
-rw-r--r--lib/pleroma/web/activity_pub/builder.ex16
-rw-r--r--lib/pleroma/web/activity_pub/side_effects.ex7
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex10
-rw-r--r--lib/pleroma/web/admin_api/controllers/admin_api_controller.ex9
-rw-r--r--lib/pleroma/web/feed/user_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/account_controller.ex25
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex17
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/status_controller.ex4
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex12
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex2
-rw-r--r--lib/pleroma/web/streamer/streamer.ex2
-rw-r--r--lib/pleroma/workers/cron/clear_oauth_token_worker.ex2
-rw-r--r--lib/pleroma/workers/cron/digest_emails_worker.ex2
-rw-r--r--lib/pleroma/workers/cron/new_users_digest_worker.ex4
-rw-r--r--lib/pleroma/workers/cron/purge_expired_activities_worker.ex2
27 files changed, 265 insertions, 131 deletions
diff --git a/lib/mix/tasks/pleroma/database.ex b/lib/mix/tasks/pleroma/database.ex
index 778de162f..82e2abdcb 100644
--- a/lib/mix/tasks/pleroma/database.ex
+++ b/lib/mix/tasks/pleroma/database.ex
@@ -4,6 +4,7 @@
defmodule Mix.Tasks.Pleroma.Database do
alias Pleroma.Conversation
+ alias Pleroma.Maintenance
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
@@ -34,13 +35,7 @@ defmodule Mix.Tasks.Pleroma.Database do
)
if Keyword.get(options, :vacuum) do
- Logger.info("Runnning VACUUM FULL")
-
- Repo.query!(
- "vacuum full;",
- [],
- timeout: :infinity
- )
+ Maintenance.vacuum("full")
end
end
@@ -94,13 +89,7 @@ defmodule Mix.Tasks.Pleroma.Database do
|> Repo.delete_all(timeout: :infinity)
if Keyword.get(options, :vacuum) do
- Logger.info("Runnning VACUUM FULL")
-
- Repo.query!(
- "vacuum full;",
- [],
- timeout: :infinity
- )
+ Maintenance.vacuum("full")
end
end
@@ -135,4 +124,10 @@ defmodule Mix.Tasks.Pleroma.Database do
end)
|> Stream.run()
end
+
+ def run(["vacuum", args]) do
+ start_pleroma()
+
+ Maintenance.vacuum(args)
+ end
end
diff --git a/lib/mix/tasks/pleroma/emoji.ex b/lib/mix/tasks/pleroma/emoji.ex
index cdffa88b2..29a5fa99c 100644
--- a/lib/mix/tasks/pleroma/emoji.ex
+++ b/lib/mix/tasks/pleroma/emoji.ex
@@ -15,7 +15,7 @@ defmodule Mix.Tasks.Pleroma.Emoji do
{options, [], []} = parse_global_opts(args)
url_or_path = options[:manifest] || default_manifest()
- manifest = fetch_manifest(url_or_path)
+ manifest = fetch_and_decode(url_or_path)
Enum.each(manifest, fn {name, info} ->
to_print = [
@@ -42,12 +42,12 @@ defmodule Mix.Tasks.Pleroma.Emoji do
url_or_path = options[:manifest] || default_manifest()
- manifest = fetch_manifest(url_or_path)
+ manifest = fetch_and_decode(url_or_path)
for pack_name <- pack_names do
if Map.has_key?(manifest, pack_name) do
pack = manifest[pack_name]
- src_url = pack["src"]
+ src = pack["src"]
IO.puts(
IO.ANSI.format([
@@ -57,11 +57,11 @@ defmodule Mix.Tasks.Pleroma.Emoji do
:normal,
" from ",
:underline,
- src_url
+ src
])
)
- binary_archive = Tesla.get!(client(), src_url).body
+ {:ok, binary_archive} = fetch(src)
archive_sha = :crypto.hash(:sha256, binary_archive) |> Base.encode16()
sha_status_text = ["SHA256 of ", :bright, pack_name, :normal, " source file is ", :bright]
@@ -74,8 +74,8 @@ defmodule Mix.Tasks.Pleroma.Emoji do
raise "Bad SHA256 for #{pack_name}"
end
- # The url specified in files should be in the same directory
- files_url =
+ # The location specified in files should be in the same directory
+ files_loc =
url_or_path
|> Path.dirname()
|> Path.join(pack["files"])
@@ -88,11 +88,11 @@ defmodule Mix.Tasks.Pleroma.Emoji do
:normal,
" from ",
:underline,
- files_url
+ files_loc
])
)
- files = Tesla.get!(client(), files_url).body |> Jason.decode!()
+ files = fetch_and_decode(files_loc)
IO.puts(IO.ANSI.format(["Unpacking ", :bright, pack_name]))
@@ -237,16 +237,20 @@ defmodule Mix.Tasks.Pleroma.Emoji do
end
end
- defp fetch_manifest(from) do
- Jason.decode!(
- if String.starts_with?(from, "http") do
- Tesla.get!(client(), from).body
- else
- File.read!(from)
- end
- )
+ defp fetch_and_decode(from) do
+ with {:ok, json} <- fetch(from) do
+ Jason.decode!(json)
+ end
end
+ defp fetch("http" <> _ = from) do
+ with {:ok, %{body: body}} <- Tesla.get(client(), from) do
+ {:ok, body}
+ end
+ end
+
+ defp fetch(path), do: File.read(path)
+
defp parse_global_opts(args) do
OptionParser.parse(
args,
diff --git a/lib/pleroma/activity/queries.ex b/lib/pleroma/activity/queries.ex
index a34c20343..c99aae44b 100644
--- a/lib/pleroma/activity/queries.ex
+++ b/lib/pleroma/activity/queries.ex
@@ -24,10 +24,7 @@ defmodule Pleroma.Activity.Queries do
@spec by_actor(query, String.t()) :: query
def by_actor(query \\ Activity, actor) do
- from(
- activity in query,
- where: fragment("(?)->>'actor' = ?", activity.data, ^actor)
- )
+ from(a in query, where: a.actor == ^actor)
end
@spec by_author(query, User.t()) :: query
diff --git a/lib/pleroma/conversation.ex b/lib/pleroma/conversation.ex
index 37d455cfc..e76eb0087 100644
--- a/lib/pleroma/conversation.ex
+++ b/lib/pleroma/conversation.ex
@@ -63,7 +63,7 @@ defmodule Pleroma.Conversation do
ap_id when is_binary(ap_id) and byte_size(ap_id) > 0 <- object.data["context"] do
{:ok, conversation} = create_for_ap_id(ap_id)
- users = User.get_users_from_set(activity.recipients, false)
+ users = User.get_users_from_set(activity.recipients, local_only: false)
participations =
Enum.map(users, fn user ->
diff --git a/lib/pleroma/emoji/pack.ex b/lib/pleroma/emoji/pack.ex
index eb7d598c6..14a5185be 100644
--- a/lib/pleroma/emoji/pack.ex
+++ b/lib/pleroma/emoji/pack.ex
@@ -499,7 +499,7 @@ defmodule Pleroma.Emoji.Pack do
if Base.decode16!(sha) == :crypto.hash(:sha256, archive) do
{:ok, archive}
else
- {:error, :imvalid_checksum}
+ {:error, :invalid_checksum}
end
end
end
diff --git a/lib/pleroma/http/adapter_helper/hackney.ex b/lib/pleroma/http/adapter_helper/hackney.ex
index dcb4cac71..3972a03a9 100644
--- a/lib/pleroma/http/adapter_helper/hackney.ex
+++ b/lib/pleroma/http/adapter_helper/hackney.ex
@@ -22,22 +22,7 @@ defmodule Pleroma.HTTP.AdapterHelper.Hackney do
|> Pleroma.HTTP.AdapterHelper.maybe_add_proxy(proxy)
end
- defp add_scheme_opts(opts, %URI{scheme: "http"}), do: opts
-
- defp add_scheme_opts(opts, %URI{scheme: "https", host: host}) do
- ssl_opts = [
- ssl_options: [
- # Workaround for remote server certificate chain issues
- partial_chain: &:hackney_connect.partial_chain/1,
-
- # We don't support TLS v1.3 yet
- versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
- server_name_indication: to_charlist(host)
- ]
- ]
-
- Keyword.merge(opts, ssl_opts)
- end
+ defp add_scheme_opts(opts, _), do: opts
def after_request(_), do: :ok
end
diff --git a/lib/pleroma/maintenance.ex b/lib/pleroma/maintenance.ex
new file mode 100644
index 000000000..326c17825
--- /dev/null
+++ b/lib/pleroma/maintenance.ex
@@ -0,0 +1,37 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Maintenance do
+ alias Pleroma.Repo
+ require Logger
+
+ def vacuum(args) do
+ case args do
+ "analyze" ->
+ Logger.info("Runnning VACUUM ANALYZE.")
+
+ Repo.query!(
+ "vacuum analyze;",
+ [],
+ timeout: :infinity
+ )
+
+ "full" ->
+ Logger.info("Runnning VACUUM FULL.")
+
+ Logger.warn(
+ "Re-packing your entire database may take a while and will consume extra disk space during the process."
+ )
+
+ Repo.query!(
+ "vacuum full;",
+ [],
+ timeout: :infinity
+ )
+
+ _ ->
+ Logger.error("Error: invalid vacuum argument.")
+ end
+ end
+end
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 8aa9ed2d4..7eca55ac9 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -92,8 +92,9 @@ defmodule Pleroma.Notification do
|> join(:left, [n, a], object in Object,
on:
fragment(
- "(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)",
+ "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')",
object.data,
+ a.data,
a.data
)
)
@@ -224,18 +225,8 @@ defmodule Pleroma.Notification do
|> Marker.multi_set_last_read_id(user, "notifications")
|> Repo.transaction()
- Notification
+ for_user_query(user)
|> where([n], n.id in ^notification_ids)
- |> join(:inner, [n], activity in assoc(n, :activity))
- |> join(:left, [n, a], object in Object,
- on:
- fragment(
- "(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)",
- object.data,
- a.data
- )
- )
- |> preload([n, a, o], activity: {a, object: o})
|> Repo.all()
end
@@ -370,7 +361,8 @@ defmodule Pleroma.Notification do
when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact"] do
potential_receiver_ap_ids = get_potential_receiver_ap_ids(activity)
- potential_receivers = User.get_users_from_set(potential_receiver_ap_ids, local_only)
+ potential_receivers =
+ User.get_users_from_set(potential_receiver_ap_ids, local_only: local_only)
notification_enabled_ap_ids =
potential_receiver_ap_ids
diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex
index 6462797b6..6a339b32c 100644
--- a/lib/pleroma/plugs/http_security_plug.ex
+++ b/lib/pleroma/plugs/http_security_plug.ex
@@ -31,7 +31,7 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
{"x-content-type-options", "nosniff"},
{"referrer-policy", referrer_policy},
{"x-download-options", "noopen"},
- {"content-security-policy", csp_string() <> ";"}
+ {"content-security-policy", csp_string()}
]
if report_uri do
@@ -43,23 +43,46 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
]
}
- headers ++ [{"reply-to", Jason.encode!(report_group)}]
+ [{"reply-to", Jason.encode!(report_group)} | headers]
else
headers
end
end
+ static_csp_rules = [
+ "default-src 'none'",
+ "base-uri 'self'",
+ "frame-ancestors 'none'",
+ "style-src 'self' 'unsafe-inline'",
+ "font-src 'self'",
+ "manifest-src 'self'"
+ ]
+
+ @csp_start [Enum.join(static_csp_rules, ";") <> ";"]
+
defp csp_string do
scheme = Config.get([Pleroma.Web.Endpoint, :url])[:scheme]
static_url = Pleroma.Web.Endpoint.static_url()
websocket_url = Pleroma.Web.Endpoint.websocket_url()
report_uri = Config.get([:http_security, :report_uri])
- connect_src = "connect-src 'self' #{static_url} #{websocket_url}"
+ img_src = "img-src 'self' data: blob:"
+ media_src = "media-src 'self'"
+
+ {img_src, media_src} =
+ if Config.get([:media_proxy, :enabled]) &&
+ !Config.get([:media_proxy, :proxy_opts, :redirect_on_failure]) do
+ sources = get_proxy_and_attachment_sources()
+ {[img_src, sources], [media_src, sources]}
+ else
+ {[img_src, " https:"], [media_src, " https:"]}
+ end
+
+ connect_src = ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
connect_src =
if Pleroma.Config.get(:env) == :dev do
- connect_src <> " http://localhost:3035/"
+ [connect_src, " http://localhost:3035/"]
else
connect_src
end
@@ -71,27 +94,46 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
"script-src 'self'"
end
- main_part = [
- "default-src 'none'",
- "base-uri 'self'",
- "frame-ancestors 'none'",
- "img-src 'self' data: blob: https:",
- "media-src 'self' https:",
- "style-src 'self' 'unsafe-inline'",
- "font-src 'self'",
- "manifest-src 'self'",
- connect_src,
- script_src
- ]
+ report = if report_uri, do: ["report-uri ", report_uri, ";report-to csp-endpoint"]
+ insecure = if scheme == "https", do: "upgrade-insecure-requests"
+
+ @csp_start
+ |> add_csp_param(img_src)
+ |> add_csp_param(media_src)
+ |> add_csp_param(connect_src)
+ |> add_csp_param(script_src)
+ |> add_csp_param(insecure)
+ |> add_csp_param(report)
+ |> :erlang.iolist_to_binary()
+ end
+
+ defp get_proxy_and_attachment_sources do
+ media_proxy_whitelist =
+ Enum.reduce(Config.get([:media_proxy, :whitelist]), [], fn host, acc ->
+ add_source(acc, host)
+ end)
- report = if report_uri, do: ["report-uri #{report_uri}; report-to csp-endpoint"], else: []
+ upload_base_url =
+ if Config.get([Pleroma.Upload, :base_url]),
+ do: URI.parse(Config.get([Pleroma.Upload, :base_url])).host
- insecure = if scheme == "https", do: ["upgrade-insecure-requests"], else: []
+ s3_endpoint =
+ if Config.get([Pleroma.Upload, :uploader]) == Pleroma.Uploaders.S3,
+ do: URI.parse(Config.get([Pleroma.Uploaders.S3, :public_endpoint])).host
- (main_part ++ report ++ insecure)
- |> Enum.join("; ")
+ []
+ |> add_source(upload_base_url)
+ |> add_source(s3_endpoint)
+ |> add_source(media_proxy_whitelist)
end
+ defp add_source(iodata, nil), do: iodata
+ defp add_source(iodata, source), do: [[?\s, source] | iodata]
+
+ defp add_csp_param(csp_iodata, nil), do: csp_iodata
+
+ defp add_csp_param(csp_iodata, param), do: [[param, ?;] | csp_iodata]
+
def warn_if_disabled do
unless Config.get([:http_security, :enabled]) do
Logger.warn("
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index d2eeeb479..72ee2d58e 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -538,9 +538,10 @@ defmodule Pleroma.User do
|> delete_change(:also_known_as)
|> unique_constraint(:email)
|> validate_format(:email, @email_regex)
+ |> validate_inclusion(:actor_type, ["Person", "Service"])
end
- @spec update_as_admin(%User{}, map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
+ @spec update_as_admin(User.t(), map()) :: {:ok, User.t()} | {:error, Changeset.t()}
def update_as_admin(user, params) do
params = Map.put(params, "password_confirmation", params["password"])
changeset = update_as_admin_changeset(user, params)
@@ -561,7 +562,7 @@ defmodule Pleroma.User do
|> put_change(:password_reset_pending, false)
end
- @spec reset_password(User.t(), map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
+ @spec reset_password(User.t(), map()) :: {:ok, User.t()} | {:error, Changeset.t()}
def reset_password(%User{} = user, params) do
reset_password(user, user, params)
end
@@ -1208,8 +1209,9 @@ defmodule Pleroma.User do
def increment_unread_conversation_count(_, user), do: {:ok, user}
- @spec get_users_from_set([String.t()], boolean()) :: [User.t()]
- def get_users_from_set(ap_ids, local_only \\ true) do
+ @spec get_users_from_set([String.t()], keyword()) :: [User.t()]
+ def get_users_from_set(ap_ids, opts \\ []) do
+ local_only = Keyword.get(opts, :local_only, true)
criteria = %{ap_id: ap_ids, deactivated: false}
criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria
@@ -1618,12 +1620,19 @@ defmodule Pleroma.User do
def fetch_by_ap_id(ap_id), do: ActivityPub.make_user_from_ap_id(ap_id)
def get_or_fetch_by_ap_id(ap_id) do
- user = get_cached_by_ap_id(ap_id)
+ cached_user = get_cached_by_ap_id(ap_id)
- if !is_nil(user) and !needs_update?(user) do
- {:ok, user}
- else
- fetch_by_ap_id(ap_id)
+ maybe_fetched_user = needs_update?(cached_user) && fetch_by_ap_id(ap_id)
+
+ case {cached_user, maybe_fetched_user} do
+ {_, {:ok, %User{} = user}} ->
+ {:ok, user}
+
+ {%User{} = user, _} ->
+ {:ok, user}
+
+ _ ->
+ {:error, :not_found}
end
end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 2cea55285..b8a2873d8 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -538,14 +538,27 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Repo.one()
end
- @spec fetch_public_activities(map(), Pagination.type()) :: [Activity.t()]
- def fetch_public_activities(opts \\ %{}, pagination \\ :keyset) do
+ @spec fetch_public_or_unlisted_activities(map(), Pagination.type()) :: [Activity.t()]
+ def fetch_public_or_unlisted_activities(opts \\ %{}, pagination \\ :keyset) do
opts = Map.drop(opts, ["user"])
- [Constants.as_public()]
- |> fetch_activities_query(opts)
- |> restrict_unlisted()
- |> Pagination.fetch_paginated(opts, pagination)
+ query = fetch_activities_query([Constants.as_public()], opts)
+
+ query =
+ if opts["restrict_unlisted"] do
+ restrict_unlisted(query)
+ else
+ query
+ end
+
+ Pagination.fetch_paginated(query, opts, pagination)
+ end
+
+ @spec fetch_public_activities(map(), Pagination.type()) :: [Activity.t()]
+ def fetch_public_activities(opts \\ %{}, pagination \\ :keyset) do
+ opts
+ |> Map.put("restrict_unlisted", true)
+ |> fetch_public_or_unlisted_activities(pagination)
end
@valid_visibilities ~w[direct unlisted public private]
@@ -1145,7 +1158,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Activity.with_joined_object()
|> Object.with_joined_activity()
|> select([_like, object, activity], %{activity | object: object})
- |> order_by([like, _, _], desc: like.id)
+ |> order_by([like, _, _], desc_nulls_last: like.id)
|> Pagination.fetch_paginated(
Map.merge(params, %{"skip_order" => true}),
pagination,
diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex
index 7ece764f5..51b74414a 100644
--- a/lib/pleroma/web/activity_pub/builder.ex
+++ b/lib/pleroma/web/activity_pub/builder.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
alias Pleroma.Object
alias Pleroma.User
+ alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility
@@ -85,15 +86,20 @@ defmodule Pleroma.Web.ActivityPub.Builder do
end
end
+ @spec announce(User.t(), Object.t(), keyword()) :: {:ok, map(), keyword()}
def announce(actor, object, options \\ []) do
public? = Keyword.get(options, :public, false)
- to = [actor.follower_address, object.data["actor"]]
to =
- if public? do
- [Pleroma.Constants.as_public() | to]
- else
- to
+ cond do
+ actor.ap_id == Relay.relay_ap_id() ->
+ [actor.follower_address]
+
+ public? ->
+ [actor.follower_address, object.data["actor"], Pleroma.Constants.as_public()]
+
+ true ->
+ [actor.follower_address, object.data["actor"]]
end
{:ok,
diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex
index 7eae0c52c..fb6275450 100644
--- a/lib/pleroma/web/activity_pub/side_effects.ex
+++ b/lib/pleroma/web/activity_pub/side_effects.ex
@@ -33,11 +33,14 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
# - Stream out the announce
def handle(%{data: %{"type" => "Announce"}} = object, meta) do
announced_object = Object.get_by_ap_id(object.data["object"])
+ user = User.get_cached_by_ap_id(object.data["actor"])
Utils.add_announce_to_object(object, announced_object)
- Notification.create_notifications(object)
- ActivityPub.stream_out(object)
+ if !User.is_internal_user?(user) do
+ Notification.create_notifications(object)
+ ActivityPub.stream_out(object)
+ end
{:ok, object, meta}
end
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index d594c64f4..8443c284c 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -1045,10 +1045,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
Map.put(object, "tag", tags)
end
+ # TODO These should be added on our side on insertion, it doesn't make much
+ # sense to regenerate these all the time
def add_mention_tags(object) do
- {enabled_receivers, disabled_receivers} = Utils.get_notified_from_object(object)
- potential_receivers = enabled_receivers ++ disabled_receivers
- mentions = Enum.map(potential_receivers, &build_mention_tag/1)
+ to = object["to"] || []
+ cc = object["cc"] || []
+ mentioned = User.get_users_from_set(to ++ cc, local_only: false)
+
+ mentions = Enum.map(mentioned, &build_mention_tag/1)
tags = object["tag"] || []
Map.put(object, "tag", tags ++ mentions)
diff --git a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
index 6b1d64a2e..783203c07 100644
--- a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
@@ -693,7 +693,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
%{assigns: %{user: admin}} = conn,
%{"nickname" => nickname} = params
) do
- with {_, user} <- {:user, User.get_cached_by_nickname(nickname)},
+ with {_, %User{} = user} <- {:user, User.get_cached_by_nickname(nickname)},
{:ok, _user} <-
User.update_as_admin(user, params) do
ModerationLog.insert_log(%{
@@ -715,11 +715,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
json(conn, %{status: "success"})
else
{:error, changeset} ->
- {_, {error, _}} = Enum.at(changeset.errors, 0)
- json(conn, %{error: "New password #{error}."})
+ errors = Map.new(changeset.errors, fn {key, {error, _}} -> {key, error} end)
+
+ json(conn, %{errors: errors})
_ ->
- json(conn, %{error: "Unable to change password."})
+ json(conn, %{error: "Unable to update user."})
end
end
diff --git a/lib/pleroma/web/feed/user_controller.ex b/lib/pleroma/web/feed/user_controller.ex
index 1b72e23dc..5a6fc9de0 100644
--- a/lib/pleroma/web/feed/user_controller.ex
+++ b/lib/pleroma/web/feed/user_controller.ex
@@ -56,7 +56,7 @@ defmodule Pleroma.Web.Feed.UserController do
"actor_id" => user.ap_id
}
|> put_if_exist("max_id", params["max_id"])
- |> ActivityPub.fetch_public_activities()
+ |> ActivityPub.fetch_public_or_unlisted_activities()
conn
|> put_resp_content_type("application/#{format}+xml")
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
index 75512442d..97295a52f 100644
--- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -81,7 +81,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
plug(
RateLimiter,
- [name: :relation_id_action, params: ["id", "uri"]] when action in @relationship_actions
+ [name: :relation_id_action, params: [:id, :uri]] when action in @relationship_actions
)
plug(RateLimiter, [name: :relations_actions] when action in @relationship_actions)
@@ -139,9 +139,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
end
@doc "PATCH /api/v1/accounts/update_credentials"
- def update_credentials(%{assigns: %{user: original_user}, body_params: params} = conn, _params) do
- user = original_user
-
+ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _params) do
params =
params
|> Enum.filter(fn {_, value} -> not is_nil(value) end)
@@ -183,12 +181,31 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
changeset = User.update_changeset(user, user_params)
with {:ok, user} <- User.update_and_set_cache(changeset) do
+ user
+ |> build_update_activity_params()
+ |> ActivityPub.update()
+
render(conn, "show.json", user: user, for: user, with_pleroma_settings: true)
else
_e -> render_error(conn, :forbidden, "Invalid request")
end
end
+ # Hotfix, handling will be redone with the pipeline
+ defp build_update_activity_params(user) do
+ object =
+ Pleroma.Web.ActivityPub.UserView.render("user.json", user: user)
+ |> Map.delete("@context")
+
+ %{
+ local: true,
+ to: [user.follower_address],
+ cc: [],
+ object: object,
+ actor: user.ap_id
+ }
+ end
+
defp add_if_present(map, params, params_field, map_field, value_function \\ &{:ok, &1}) do
with true <- is_map(params),
true <- Map.has_key?(params, params_field),
diff --git a/lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex b/lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex
index f35ec3596..69f0e3846 100644
--- a/lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex
@@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationController do
@doc "GET /api/v1/conversations"
def index(%{assigns: %{user: user}} = conn, params) do
+ params = stringify_pagination_params(params)
participations = Participation.for_user_with_last_activity_id(user, params)
conn
@@ -36,4 +37,20 @@ defmodule Pleroma.Web.MastodonAPI.ConversationController do
render(conn, "participation.json", participation: participation, for: user)
end
end
+
+ defp stringify_pagination_params(params) do
+ atom_keys =
+ Pleroma.Pagination.page_keys()
+ |> Enum.map(&String.to_atom(&1))
+
+ str_keys =
+ params
+ |> Map.take(atom_keys)
+ |> Enum.map(fn {key, value} -> {to_string(key), value} end)
+ |> Enum.into(%{})
+
+ params
+ |> Map.delete(atom_keys)
+ |> Map.merge(str_keys)
+ end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
index 83d997abd..f20157a5f 100644
--- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
@@ -84,13 +84,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
plug(
RateLimiter,
- [name: :status_id_action, bucket_name: "status_id_action:reblog_unreblog", params: ["id"]]
+ [name: :status_id_action, bucket_name: "status_id_action:reblog_unreblog", params: [:id]]
when action in ~w(reblog unreblog)a
)
plug(
RateLimiter,
- [name: :status_id_action, bucket_name: "status_id_action:fav_unfav", params: ["id"]]
+ [name: :status_id_action, bucket_name: "status_id_action:fav_unfav", params: [:id]]
when action in ~w(favourite unfavourite)a
)
diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
index 958567510..f67f75430 100644
--- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
@@ -111,7 +111,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
else
activities =
params
- |> Map.put("type", ["Create", "Announce"])
+ |> Map.put("type", ["Create"])
|> Map.put("local_only", local_only)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index 45fffaad2..04c419d2f 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -182,12 +182,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
bot = user.actor_type in ["Application", "Service"]
emojis =
- Enum.map(user.emoji, fn {shortcode, url} ->
+ Enum.map(user.emoji, fn {shortcode, raw_url} ->
+ url = MediaProxy.url(raw_url)
+
%{
- "shortcode" => shortcode,
- "url" => url,
- "static_url" => url,
- "visible_in_picker" => false
+ shortcode: shortcode,
+ url: url,
+ static_url: url,
+ visible_in_picker: false
}
end)
diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex
index 2c53dcde1..d1efdeb5d 100644
--- a/lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex
@@ -106,7 +106,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackController do
|> put_status(:internal_server_error)
|> json(%{error: "The requested instance does not support sharing emoji packs"})
- {:error, :imvalid_checksum} ->
+ {:error, :invalid_checksum} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "SHA256 for the pack doesn't match the one sent by the server"})
diff --git a/lib/pleroma/web/streamer/streamer.ex b/lib/pleroma/web/streamer/streamer.ex
index 49a400df7..0cf41189b 100644
--- a/lib/pleroma/web/streamer/streamer.ex
+++ b/lib/pleroma/web/streamer/streamer.ex
@@ -136,7 +136,7 @@ defmodule Pleroma.Web.Streamer do
false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, item_host),
false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, parent_host),
true <- thread_containment(item, user),
- false <- CommonAPI.thread_muted?(user, item) do
+ false <- CommonAPI.thread_muted?(user, parent) do
false
else
_ -> true
diff --git a/lib/pleroma/workers/cron/clear_oauth_token_worker.ex b/lib/pleroma/workers/cron/clear_oauth_token_worker.ex
index 341eff054..a4c3b9516 100644
--- a/lib/pleroma/workers/cron/clear_oauth_token_worker.ex
+++ b/lib/pleroma/workers/cron/clear_oauth_token_worker.ex
@@ -16,6 +16,8 @@ defmodule Pleroma.Workers.Cron.ClearOauthTokenWorker do
def perform(_opts, _job) do
if Config.get([:oauth2, :clean_expired_tokens], false) do
Token.delete_expired_tokens()
+ else
+ :ok
end
end
end
diff --git a/lib/pleroma/workers/cron/digest_emails_worker.ex b/lib/pleroma/workers/cron/digest_emails_worker.ex
index dd13c3b17..7f09ff3cf 100644
--- a/lib/pleroma/workers/cron/digest_emails_worker.ex
+++ b/lib/pleroma/workers/cron/digest_emails_worker.ex
@@ -37,6 +37,8 @@ defmodule Pleroma.Workers.Cron.DigestEmailsWorker do
)
|> Repo.all()
|> send_emails
+ else
+ :ok
end
end
diff --git a/lib/pleroma/workers/cron/new_users_digest_worker.ex b/lib/pleroma/workers/cron/new_users_digest_worker.ex
index 9bd0a5621..5c816b3fe 100644
--- a/lib/pleroma/workers/cron/new_users_digest_worker.ex
+++ b/lib/pleroma/workers/cron/new_users_digest_worker.ex
@@ -55,7 +55,11 @@ defmodule Pleroma.Workers.Cron.NewUsersDigestWorker do
|> Repo.all()
|> Enum.map(&Pleroma.Emails.NewUsersDigestEmail.new_users(&1, users_and_statuses))
|> Enum.each(&Pleroma.Emails.Mailer.deliver/1)
+ else
+ :ok
end
+ else
+ :ok
end
end
end
diff --git a/lib/pleroma/workers/cron/purge_expired_activities_worker.ex b/lib/pleroma/workers/cron/purge_expired_activities_worker.ex
index b8953dd7f..84b3b84de 100644
--- a/lib/pleroma/workers/cron/purge_expired_activities_worker.ex
+++ b/lib/pleroma/workers/cron/purge_expired_activities_worker.ex
@@ -23,6 +23,8 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker do
def perform(_opts, _job) do
if Config.get([ActivityExpiration, :enabled]) do
Enum.each(ActivityExpiration.due_expirations(@interval), &delete_activity/1)
+ else
+ :ok
end
end