aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/plugs/set_format_plug.ex24
-rw-r--r--lib/pleroma/signature.ex15
-rw-r--r--lib/pleroma/upload.ex9
-rw-r--r--lib/pleroma/user.ex32
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex23
-rw-r--r--lib/pleroma/web/activity_pub/publisher.ex8
-rw-r--r--lib/pleroma/web/activity_pub/visibility.ex13
-rw-r--r--lib/pleroma/web/admin_api/admin_api_controller.ex19
-rw-r--r--lib/pleroma/web/admin_api/config.ex14
-rw-r--r--lib/pleroma/web/common_api/utils.ex7
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex6
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex2
-rw-r--r--lib/pleroma/web/rich_media/parser.ex1
-rw-r--r--lib/pleroma/web/router.ex14
-rw-r--r--lib/pleroma/web/streamer.ex5
-rw-r--r--lib/pleroma/web/web_finger/web_finger.ex3
-rw-r--r--lib/pleroma/web/web_finger/web_finger_controller.ex43
17 files changed, 168 insertions, 70 deletions
diff --git a/lib/pleroma/plugs/set_format_plug.ex b/lib/pleroma/plugs/set_format_plug.ex
new file mode 100644
index 000000000..5ca741c64
--- /dev/null
+++ b/lib/pleroma/plugs/set_format_plug.ex
@@ -0,0 +1,24 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Plugs.SetFormatPlug do
+ import Plug.Conn, only: [assign: 3, fetch_query_params: 1]
+
+ def init(_), do: nil
+
+ def call(conn, _) do
+ case get_format(conn) do
+ nil -> conn
+ format -> assign(conn, :format, format)
+ end
+ end
+
+ defp get_format(conn) do
+ conn.private[:phoenix_format] ||
+ case fetch_query_params(conn) do
+ %{query_params: %{"_format" => format}} -> format
+ _ -> nil
+ end
+ end
+end
diff --git a/lib/pleroma/signature.ex b/lib/pleroma/signature.ex
index 2a0823ecf..0bf49fd7c 100644
--- a/lib/pleroma/signature.ex
+++ b/lib/pleroma/signature.ex
@@ -10,9 +10,18 @@ defmodule Pleroma.Signature do
alias Pleroma.Web.ActivityPub.ActivityPub
def key_id_to_actor_id(key_id) do
- URI.parse(key_id)
- |> Map.put(:fragment, nil)
- |> URI.to_string()
+ uri =
+ URI.parse(key_id)
+ |> Map.put(:fragment, nil)
+
+ uri =
+ if String.ends_with?(uri.path, "/publickey") do
+ Map.put(uri, :path, String.replace(uri.path, "/publickey", ""))
+ else
+ uri
+ end
+
+ URI.to_string(uri)
end
def fetch_public_key(conn) do
diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex
index c47d65241..9f0adde5b 100644
--- a/lib/pleroma/upload.ex
+++ b/lib/pleroma/upload.ex
@@ -228,7 +228,14 @@ defmodule Pleroma.Upload do
""
end
- [base_url, "media", path]
+ prefix =
+ if is_nil(Pleroma.Config.get([__MODULE__, :base_url])) do
+ "media"
+ else
+ ""
+ end
+
+ [base_url, prefix, path]
|> Path.join()
end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index a3f6add28..974f6df18 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -586,12 +586,23 @@ defmodule Pleroma.User do
@spec get_followers_query(User.t()) :: Ecto.Query.t()
def get_followers_query(user), do: get_followers_query(user, nil)
+ @spec get_followers(User.t(), pos_integer()) :: {:ok, list(User.t())}
def get_followers(user, page \\ nil) do
q = get_followers_query(user, page)
{:ok, Repo.all(q)}
end
+ @spec get_external_followers(User.t(), pos_integer()) :: {:ok, list(User.t())}
+ def get_external_followers(user, page \\ nil) do
+ q =
+ user
+ |> get_followers_query(page)
+ |> User.Query.build(%{external: true})
+
+ {:ok, Repo.all(q)}
+ end
+
def get_followers_ids(user, page \\ nil) do
q = get_followers_query(user, page)
@@ -871,17 +882,26 @@ defmodule Pleroma.User do
def muted_notifications?(user, %{ap_id: ap_id}),
do: Enum.member?(user.info.muted_notifications, ap_id)
- def blocks?(%User{info: info} = _user, %{ap_id: ap_id}) do
- blocks = info.blocks
+ def blocks?(%User{} = user, %User{} = target) do
+ blocks_ap_id?(user, target) || blocks_domain?(user, target)
+ end
- domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(info.domain_blocks)
+ def blocks?(nil, _), do: false
- %{host: host} = URI.parse(ap_id)
+ def blocks_ap_id?(%User{} = user, %User{} = target) do
+ Enum.member?(user.info.blocks, target.ap_id)
+ end
- Enum.member?(blocks, ap_id) ||
- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, host)
+ def blocks_ap_id?(_, _), do: false
+
+ def blocks_domain?(%User{} = user, %User{} = target) do
+ domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.info.domain_blocks)
+ %{host: host} = URI.parse(target.ap_id)
+ Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, host)
end
+ def blocks_domain?(_, _), do: false
+
def subscribed_to?(user, %{ap_id: ap_id}) do
with %User{} = target <- get_cached_by_ap_id(ap_id) do
Enum.member?(target.info.subscribers, user.ap_id)
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 31397b09f..a42c50875 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -631,17 +631,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Map.put("pinned_activity_ids", user.info.pinned_activities)
recipients =
- if reading_user do
- ["https://www.w3.org/ns/activitystreams#Public"] ++
- [reading_user.ap_id | reading_user.following]
- else
- ["https://www.w3.org/ns/activitystreams#Public"]
- end
+ user_activities_recipients(%{
+ "godmode" => params["godmode"],
+ "reading_user" => reading_user
+ })
fetch_activities(recipients, params)
|> Enum.reverse()
end
+ defp user_activities_recipients(%{"godmode" => true}) do
+ []
+ end
+
+ defp user_activities_recipients(%{"reading_user" => reading_user}) do
+ if reading_user do
+ ["https://www.w3.org/ns/activitystreams#Public"] ++
+ [reading_user.ap_id | reading_user.following]
+ else
+ ["https://www.w3.org/ns/activitystreams#Public"]
+ end
+ end
+
defp restrict_since(query, %{"since_id" => ""}), do: query
defp restrict_since(query, %{"since_id" => since_id}) do
diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex
index 0bbe6ee80..016d78216 100644
--- a/lib/pleroma/web/activity_pub/publisher.ex
+++ b/lib/pleroma/web/activity_pub/publisher.ex
@@ -97,13 +97,13 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
end
end
+ @spec recipients(User.t(), Activity.t()) :: list(User.t()) | []
defp recipients(actor, activity) do
- followers =
+ {:ok, followers} =
if actor.follower_address in activity.recipients do
- {:ok, followers} = User.get_followers(actor)
- Enum.filter(followers, &(!&1.local))
+ User.get_external_followers(actor)
else
- []
+ {:ok, []}
end
Pleroma.Web.Salmon.remote_users(actor, activity) ++ followers
diff --git a/lib/pleroma/web/activity_pub/visibility.ex b/lib/pleroma/web/activity_pub/visibility.ex
index 2666edc7c..097fceb08 100644
--- a/lib/pleroma/web/activity_pub/visibility.ex
+++ b/lib/pleroma/web/activity_pub/visibility.ex
@@ -8,14 +8,14 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
alias Pleroma.Repo
alias Pleroma.User
+ @public "https://www.w3.org/ns/activitystreams#Public"
+
+ @spec is_public?(Object.t() | Activity.t() | map()) :: boolean()
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_public?(data), do: @public in (data["to"] ++ (data["cc"] || []))
def is_private?(activity) do
with false <- is_public?(activity),
@@ -69,15 +69,14 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
end
def get_visibility(object) do
- public = "https://www.w3.org/ns/activitystreams#Public"
to = object.data["to"] || []
cc = object.data["cc"] || []
cond do
- public in to ->
+ @public in to ->
"public"
- public in cc ->
+ @public in cc ->
"unlisted"
# this should use the sql for the object's activity
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex
index 811be1eff..1ae5acd91 100644
--- a/lib/pleroma/web/admin_api/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/admin_api_controller.ex
@@ -82,6 +82,25 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
end
end
+ def list_user_statuses(conn, %{"nickname" => nickname} = params) do
+ godmode = params["godmode"] == "true" || params["godmode"] == true
+
+ with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
+ {_, page_size} = page_params(params)
+
+ activities =
+ ActivityPub.fetch_user_activities(user, nil, %{
+ "limit" => page_size,
+ "godmode" => godmode
+ })
+
+ conn
+ |> json(StatusView.render("index.json", %{activities: activities, as: :activity}))
+ else
+ _ -> {:error, :not_found}
+ end
+ end
+
def user_toggle_activation(conn, %{"nickname" => nickname}) do
user = User.get_cached_by_nickname(nickname)
diff --git a/lib/pleroma/web/admin_api/config.ex b/lib/pleroma/web/admin_api/config.ex
index b4eb8e002..dde05ea7b 100644
--- a/lib/pleroma/web/admin_api/config.ex
+++ b/lib/pleroma/web/admin_api/config.ex
@@ -84,6 +84,7 @@ defmodule Pleroma.Web.AdminAPI.Config do
end
defp do_convert({:dispatch, [entity]}), do: %{"tuple" => [":dispatch", [inspect(entity)]]}
+ defp do_convert({:partial_chain, entity}), do: %{"tuple" => [":partial_chain", inspect(entity)]}
defp do_convert(entity) when is_tuple(entity),
do: %{"tuple" => do_convert(Tuple.to_list(entity))}
@@ -113,11 +114,15 @@ defmodule Pleroma.Web.AdminAPI.Config do
defp do_transform(%Regex{} = entity) when is_map(entity), do: entity
defp do_transform(%{"tuple" => [":dispatch", [entity]]}) do
- cleaned_string = String.replace(entity, ~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "")
- {dispatch_settings, []} = Code.eval_string(cleaned_string, [], requires: [], macros: [])
+ {dispatch_settings, []} = do_eval(entity)
{:dispatch, [dispatch_settings]}
end
+ defp do_transform(%{"tuple" => [":partial_chain", entity]}) do
+ {partial_chain, []} = do_eval(entity)
+ {:partial_chain, partial_chain}
+ end
+
defp do_transform(%{"tuple" => entity}) do
Enum.reduce(entity, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end)
end
@@ -149,4 +154,9 @@ defmodule Pleroma.Web.AdminAPI.Config do
do: String.to_existing_atom("Elixir." <> value),
else: value
end
+
+ defp do_eval(entity) do
+ cleaned_string = String.replace(entity, ~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "")
+ Code.eval_string(cleaned_string, [], requires: [], macros: [])
+ end
end
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index fcc000969..94462c3dd 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -439,6 +439,13 @@ defmodule Pleroma.Web.CommonAPI.Utils do
def maybe_notify_mentioned_recipients(recipients, _), do: recipients
+ # Do not notify subscribers if author is making a reply
+ def maybe_notify_subscribers(recipients, %Activity{
+ object: %Object{data: %{"inReplyTo" => _ap_id}}
+ }) do
+ recipients
+ end
+
def maybe_notify_subscribers(
recipients,
%Activity{data: %{"actor" => actor, "type" => type}} = activity
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index befb35c26..b2b06eeb9 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -50,13 +50,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
id: to_string(target.id),
following: User.following?(user, target),
followed_by: User.following?(target, user),
- blocking: User.blocks?(user, target),
- blocked_by: User.blocks?(target, user),
+ blocking: User.blocks_ap_id?(user, target),
+ blocked_by: User.blocks_ap_id?(target, user),
muting: User.mutes?(user, target),
muting_notifications: User.muted_notifications?(user, target),
subscribing: User.subscribed_to?(user, target),
requested: requested,
- domain_blocking: false,
+ domain_blocking: User.blocks_domain?(user, target),
showing_reblogs: User.showing_reblogs?(user, target),
endorsed: false
}
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index de9425959..80df9b2ac 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -222,7 +222,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
if user.local do
Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, activity)
else
- object.data["external_url"] || object.data["id"]
+ object.data["url"] || object.data["external_url"] || object.data["id"]
end
%{
diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex
index 185156375..f5f9e358c 100644
--- a/lib/pleroma/web/rich_media/parser.ex
+++ b/lib/pleroma/web/rich_media/parser.ex
@@ -82,6 +82,7 @@ defmodule Pleroma.Web.RichMedia.Parser do
html
|> maybe_parse()
+ |> Map.put(:url, url)
|> clean_parsed_data()
|> check_parsed_data()
rescue
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index a33b5ddd7..a9f3826fc 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -154,22 +154,12 @@ defmodule Pleroma.Web.Router do
post("/users/follow", AdminAPIController, :user_follow)
post("/users/unfollow", AdminAPIController, :user_unfollow)
- # TODO: to be removed at version 1.0
- delete("/user", AdminAPIController, :user_delete)
- post("/user", AdminAPIController, :user_create)
-
delete("/users", AdminAPIController, :user_delete)
post("/users", AdminAPIController, :user_create)
patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation)
put("/users/tag", AdminAPIController, :tag_users)
delete("/users/tag", AdminAPIController, :untag_users)
- # TODO: to be removed at version 1.0
- get("/permission_group/:nickname", AdminAPIController, :right_get)
- get("/permission_group/:nickname/:permission_group", AdminAPIController, :right_get)
- post("/permission_group/:nickname/:permission_group", AdminAPIController, :right_add)
- delete("/permission_group/:nickname/:permission_group", AdminAPIController, :right_delete)
-
get("/users/:nickname/permission_group", AdminAPIController, :right_get)
get("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_get)
post("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_add)
@@ -190,13 +180,11 @@ defmodule Pleroma.Web.Router do
post("/users/revoke_invite", AdminAPIController, :revoke_invite)
post("/users/email_invite", AdminAPIController, :email_invite)
- # TODO: to be removed at version 1.0
- get("/password_reset", AdminAPIController, :get_password_reset)
-
get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset)
get("/users", AdminAPIController, :list_users)
get("/users/:nickname", AdminAPIController, :user_show)
+ get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses)
get("/reports", AdminAPIController, :list_reports)
get("/reports/:id", AdminAPIController, :report_show)
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index 86e2dc4dd..9ee331030 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -234,10 +234,15 @@ defmodule Pleroma.Web.Streamer do
blocks = user.info.blocks || []
mutes = user.info.mutes || []
reblog_mutes = user.info.muted_reblogs || []
+ domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.info.domain_blocks)
with parent when not is_nil(parent) <- Object.normalize(item),
true <- Enum.all?([blocks, mutes, reblog_mutes], &(item.actor not in &1)),
true <- Enum.all?([blocks, mutes], &(parent.data["actor"] not in &1)),
+ %{host: item_host} <- URI.parse(item.actor),
+ %{host: parent_host} <- URI.parse(parent.data["actor"]),
+ 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) do
true
else
diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex
index ad3884c0e..ecb39ee50 100644
--- a/lib/pleroma/web/web_finger/web_finger.ex
+++ b/lib/pleroma/web/web_finger/web_finger.ex
@@ -193,6 +193,7 @@ defmodule Pleroma.Web.WebFinger do
end
end
+ @spec finger(String.t()) :: {:ok, map()} | {:error, any()}
def finger(account) do
account = String.trim_leading(account, "@")
@@ -226,8 +227,6 @@ defmodule Pleroma.Web.WebFinger do
else
with {:ok, doc} <- Jason.decode(body) do
webfinger_from_json(doc)
- else
- {:error, e} -> e
end
end
else
diff --git a/lib/pleroma/web/web_finger/web_finger_controller.ex b/lib/pleroma/web/web_finger/web_finger_controller.ex
index b77c75ec5..896eb15f9 100644
--- a/lib/pleroma/web/web_finger/web_finger_controller.ex
+++ b/lib/pleroma/web/web_finger/web_finger_controller.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.WebFinger.WebFingerController do
alias Pleroma.Web.WebFinger
+ plug(Pleroma.Plugs.SetFormatPlug)
plug(Pleroma.Web.FederatingPlug)
def host_meta(conn, _params) do
@@ -17,30 +18,28 @@ defmodule Pleroma.Web.WebFinger.WebFingerController do
|> send_resp(200, xml)
end
- def webfinger(conn, %{"resource" => resource}) do
- case get_format(conn) do
- n when n in ["xml", "xrd+xml"] ->
- with {:ok, response} <- WebFinger.webfinger(resource, "XML") do
- conn
- |> put_resp_content_type("application/xrd+xml")
- |> send_resp(200, response)
- else
- _e -> send_resp(conn, 404, "Couldn't find user")
- end
-
- n when n in ["json", "jrd+json"] ->
- with {:ok, response} <- WebFinger.webfinger(resource, "JSON") do
- json(conn, response)
- else
- _e -> send_resp(conn, 404, "Couldn't find user")
- end
-
- _ ->
- send_resp(conn, 404, "Unsupported format")
+ def webfinger(%{assigns: %{format: format}} = conn, %{"resource" => resource})
+ when format in ["xml", "xrd+xml"] do
+ with {:ok, response} <- WebFinger.webfinger(resource, "XML") do
+ conn
+ |> put_resp_content_type("application/xrd+xml")
+ |> send_resp(200, response)
+ else
+ _e -> send_resp(conn, 404, "Couldn't find user")
end
end
- def webfinger(conn, _params) do
- send_resp(conn, 400, "Bad Request")
+ def webfinger(%{assigns: %{format: format}} = conn, %{"resource" => resource})
+ when format in ["json", "jrd+json"] do
+ with {:ok, response} <- WebFinger.webfinger(resource, "JSON") do
+ json(conn, response)
+ else
+ _e ->
+ conn
+ |> put_status(404)
+ |> json("Couldn't find user")
+ end
end
+
+ def webfinger(conn, _params), do: send_resp(conn, 400, "Bad Request")
end