From 0f412cf6e68fcebda3e94b71b7f182af689748bf Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Mon, 24 Dec 2018 02:25:36 +0300 Subject: Create tombstone instead of object deletion --- lib/pleroma/activity.ex | 20 +++++++++++++++++++- lib/pleroma/object.ex | 22 ++++++++++++++++++++-- lib/pleroma/web/common_api/utils.ex | 7 ++++++- 3 files changed, 45 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 200addd6e..0845233ee 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -1,7 +1,7 @@ defmodule Pleroma.Activity do use Ecto.Schema alias Pleroma.{Repo, Activity, Notification} - import Ecto.Query + import Ecto.{Query, Changeset} # https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19 @mastodon_notification_types %{ @@ -103,4 +103,22 @@ defmodule Pleroma.Activity do end def mastodon_notification_type(%Activity{}), do: nil + + def get_tombstone(%Activity{data: data}, deleted \\ DateTime.utc_now()) do + %{ + id: data["id"], + context: data["context"], + type: "tombstone", + published: data["published"], + deleted: deleted + } + end + + def swap_data_with_tombstone(activity) do + tombstone = get_tombstone(activity) + + activity + |> change(%{data: tombstone}) + |> Repo.update() + end end diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 31c8dd5bd..436cf6d5d 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -62,9 +62,27 @@ defmodule Pleroma.Object do Object.change(%Object{}, %{data: %{"id" => context}}) end + def get_tombstone(%Object{data: data}, deleted \\ DateTime.utc_now()) do + %{ + id: data["id"], + type: "tombstone", + deleted: deleted + } + end + + def swap_data_with_tombstone(object) do + tombstone = get_tombstone(object) + + object + |> Object.change(%{data: tombstone}) + |> Repo.update() + end + def delete(%Object{data: %{"id" => id}} = object) do - with Repo.delete(object), - Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)), + with swap_data_with_tombstone(object), + Activity.all_non_create_by_object_ap_id_q(id) + |> Repo.all() + |> Enum.each(&Activity.swap_data_with_tombstone/1), {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do {:ok, object} end diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 142283684..d25fef6bc 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -69,7 +69,12 @@ defmodule Pleroma.Web.CommonAPI.Utils do mentioned_users = Enum.map(mentions, fn {_, %{ap_id: ap_id}} -> ap_id end) if inReplyTo do - {Enum.uniq([inReplyTo.data["actor"] | mentioned_users]), []} + to = + [inReplyTo.data["actor"] | mentioned_users] + |> Enum.uniq() + |> Enum.reject(&is_nil/1) + + {to, []} else {mentioned_users, []} end -- cgit v1.2.3 From 18a4cbb244dbc188f5a391626fb98e3a53571318 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Mon, 24 Dec 2018 20:09:18 +0300 Subject: Capitalize "tombstone" --- lib/pleroma/object.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 436cf6d5d..31f206c39 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -65,7 +65,7 @@ defmodule Pleroma.Object do def get_tombstone(%Object{data: data}, deleted \\ DateTime.utc_now()) do %{ id: data["id"], - type: "tombstone", + type: "Tombstone", deleted: deleted } end -- cgit v1.2.3 From 2bbec33c7112ede3f93a7d35e9d5f3ac5a31ce05 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Tue, 25 Dec 2018 00:29:13 +0300 Subject: Fix failing tests --- lib/pleroma/activity.ex | 15 +++++++++------ lib/pleroma/notification.ex | 10 +++++++--- lib/pleroma/web/activity_pub/transmogrifier.ex | 3 ++- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 0845233ee..be04363aa 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -108,17 +108,20 @@ defmodule Pleroma.Activity do %{ id: data["id"], context: data["context"], - type: "tombstone", + type: "Tombstone", published: data["published"], deleted: deleted } end def swap_data_with_tombstone(activity) do - tombstone = get_tombstone(activity) - - activity - |> change(%{data: tombstone}) - |> Repo.update() + with tombstone = get_tombstone(activity), + Notification.clear(activity), + {:ok, changed_activity} = + activity + |> change(%{data: tombstone}) + |> Repo.update() do + {:ok, changed_activity} + end end end diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 47f6b6ee7..457cba935 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -75,10 +75,14 @@ defmodule Pleroma.Notification do end end - def clear(user) do - query = from(n in Notification, where: n.user_id == ^user.id) + def clear(%User{} = user) do + from(n in Notification, where: n.user_id == ^user.id) + |> Repo.delete_all() + end - Repo.delete_all(query) + def clear(%Activity{} = activity) do + from(n in Notification, where: n.activity_id == ^activity.id) + |> Repo.delete_all() end def dismiss(%{id: user_id} = _user, id) do diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index e6af4b211..87514870d 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -586,7 +586,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) do - with false <- String.starts_with?(inReplyTo, "http"), + with false <- is_nil(inReplyTo), + false <- String.starts_with?(inReplyTo, "http"), {:ok, %{data: replied_to_object}} <- get_obj_helper(inReplyTo) do Map.put(object, "inReplyTo", replied_to_object["external_url"] || inReplyTo) else -- cgit v1.2.3 From f75f707f6cf07c66a23ddbbe80a9b782a1ecb6f8 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Tue, 25 Dec 2018 03:00:06 +0300 Subject: Revert Activity tombstones, add ObjectTombstone struct --- lib/pleroma/activity.ex | 23 +---------------------- lib/pleroma/object.ex | 21 ++++++++++----------- lib/pleroma/object_tombstone.ex | 4 ++++ 3 files changed, 15 insertions(+), 33 deletions(-) create mode 100644 lib/pleroma/object_tombstone.ex (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index be04363aa..200addd6e 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -1,7 +1,7 @@ defmodule Pleroma.Activity do use Ecto.Schema alias Pleroma.{Repo, Activity, Notification} - import Ecto.{Query, Changeset} + import Ecto.Query # https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19 @mastodon_notification_types %{ @@ -103,25 +103,4 @@ defmodule Pleroma.Activity do end def mastodon_notification_type(%Activity{}), do: nil - - def get_tombstone(%Activity{data: data}, deleted \\ DateTime.utc_now()) do - %{ - id: data["id"], - context: data["context"], - type: "Tombstone", - published: data["published"], - deleted: deleted - } - end - - def swap_data_with_tombstone(activity) do - with tombstone = get_tombstone(activity), - Notification.clear(activity), - {:ok, changed_activity} = - activity - |> change(%{data: tombstone}) - |> Repo.update() do - {:ok, changed_activity} - end - end end diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 31f206c39..5b1347b37 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -1,6 +1,6 @@ defmodule Pleroma.Object do use Ecto.Schema - alias Pleroma.{Repo, Object, User, Activity} + alias Pleroma.{Repo, Object, User, Activity, ObjectTombstone} import Ecto.{Query, Changeset} schema "objects" do @@ -62,16 +62,17 @@ defmodule Pleroma.Object do Object.change(%Object{}, %{data: %{"id" => context}}) end - def get_tombstone(%Object{data: data}, deleted \\ DateTime.utc_now()) do - %{ - id: data["id"], - type: "Tombstone", + def make_tombstone(%Object{data: %{"id" => id, "type" => type}}, deleted \\ DateTime.utc_now()) do + %ObjectTombstone{ + id: id, + formerType: type, deleted: deleted } + |> Map.from_struct() end - def swap_data_with_tombstone(object) do - tombstone = get_tombstone(object) + def swap_object_with_tombstone(object) do + tombstone = make_tombstone(object) object |> Object.change(%{data: tombstone}) @@ -79,10 +80,8 @@ defmodule Pleroma.Object do end def delete(%Object{data: %{"id" => id}} = object) do - with swap_data_with_tombstone(object), - Activity.all_non_create_by_object_ap_id_q(id) - |> Repo.all() - |> Enum.each(&Activity.swap_data_with_tombstone/1), + with {:ok, _obj} = swap_object_with_tombstone(object), + Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)), {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do {:ok, object} end diff --git a/lib/pleroma/object_tombstone.ex b/lib/pleroma/object_tombstone.ex new file mode 100644 index 000000000..64d836d3e --- /dev/null +++ b/lib/pleroma/object_tombstone.ex @@ -0,0 +1,4 @@ +defmodule Pleroma.ObjectTombstone do + @enforce_keys [:id, :formerType, :deleted] + defstruct [:id, :formerType, :deleted, type: "Tombstone"] +end -- cgit v1.2.3 From ca2e9ce9cc98f046ea2be0a9051cdf06d253d7f6 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Tue, 25 Dec 2018 03:44:48 +0300 Subject: Revert unneeded changes --- lib/pleroma/notification.ex | 7 +------ lib/pleroma/web/activity_pub/transmogrifier.ex | 3 +-- lib/pleroma/web/common_api/utils.ex | 7 +------ 3 files changed, 3 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 457cba935..47578d60e 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -75,16 +75,11 @@ defmodule Pleroma.Notification do end end - def clear(%User{} = user) do + def clear(user) do from(n in Notification, where: n.user_id == ^user.id) |> Repo.delete_all() end - def clear(%Activity{} = activity) do - from(n in Notification, where: n.activity_id == ^activity.id) - |> Repo.delete_all() - end - def dismiss(%{id: user_id} = _user, id) do notification = Repo.get(Notification, id) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 87514870d..e6af4b211 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -586,8 +586,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) do - with false <- is_nil(inReplyTo), - false <- String.starts_with?(inReplyTo, "http"), + with false <- String.starts_with?(inReplyTo, "http"), {:ok, %{data: replied_to_object}} <- get_obj_helper(inReplyTo) do Map.put(object, "inReplyTo", replied_to_object["external_url"] || inReplyTo) else diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index d25fef6bc..142283684 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -69,12 +69,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do mentioned_users = Enum.map(mentions, fn {_, %{ap_id: ap_id}} -> ap_id end) if inReplyTo do - to = - [inReplyTo.data["actor"] | mentioned_users] - |> Enum.uniq() - |> Enum.reject(&is_nil/1) - - {to, []} + {Enum.uniq([inReplyTo.data["actor"] | mentioned_users]), []} else {mentioned_users, []} end -- cgit v1.2.3 From 91724d160acc39585c37742204c59b91e59df569 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 25 Dec 2018 20:09:27 +0100 Subject: Reserve a few user names These are all names that are used for domain.com/:route routes or projected to be. --- lib/pleroma/user.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1f930479d..33f5e43fc 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -197,6 +197,7 @@ defmodule Pleroma.User do |> validate_confirmation(:password) |> unique_constraint(:email) |> unique_constraint(:nickname) + |> validate_exclusion(:nickname, Pleroma.Config.get([Pleroma.User, :restricted_nicknames])) |> validate_format(:nickname, local_nickname_regex()) |> validate_format(:email, @email_regex) |> validate_length(:bio, max: 1000) -- cgit v1.2.3 From 5811e65e67591b06238de66470c03744e0d83e2d Mon Sep 17 00:00:00 2001 From: lain Date: Wed, 26 Dec 2018 12:39:35 +0100 Subject: Add some hard limits on inserted activities. --- lib/pleroma/web/activity_pub/activity_pub.ex | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 188060780..8b2f764e4 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -56,10 +56,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end + defp check_remote_limit(%{"object" => %{"content" => content}}) do + limit = Pleroma.Config.get([:instance, :remote_limit]) + String.length(content) <= limit + end + + defp check_remote_limit(_), do: true + def insert(map, local \\ true) when is_map(map) do with nil <- Activity.normalize(map), map <- lazy_put_activity_defaults(map), :ok <- check_actor_is_active(map["actor"]), + {_, true} <- {:remote_limit_error, check_remote_limit(map)}, {:ok, map} <- MRF.filter(map), :ok <- insert_full_object(map) do {recipients, _, _} = get_recipients(map) -- cgit v1.2.3 From 551d80cc0186424d2c1653f917749adea16d9963 Mon Sep 17 00:00:00 2001 From: lain Date: Wed, 26 Dec 2018 12:46:16 +0100 Subject: Expose restricted names in nodeinfo. --- lib/pleroma/web/nodeinfo/nodeinfo_controller.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 1265d81c5..a992f75f6 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -138,7 +138,8 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do }, accountActivationRequired: Keyword.get(instance, :account_activation_required, false), invitesEnabled: Keyword.get(instance, :invites_enabled, false), - features: features + features: features, + restrictedNicknames: Pleroma.Config.get([Pleroma.User, :restricted_nicknames]) } } -- cgit v1.2.3 From 838c0242316545afa42384b8e50a401e54ad1405 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Thu, 27 Dec 2018 02:39:41 +0300 Subject: Treat any present value in "no_attachment_links" as true --- lib/pleroma/web/common_api/utils.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index b91cfc4bb..d9cc52e26 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -89,7 +89,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do ) do status |> format_input(mentions, tags, content_type) - |> maybe_add_attachments(attachments, no_attachment_links) + |> maybe_add_attachments(attachments, !!no_attachment_links) end def make_context(%Activity{data: %{"context" => context}}), do: context -- cgit v1.2.3 From e4562105e77dd2d580921a07f05907a63da1d826 Mon Sep 17 00:00:00 2001 From: Vyr Cossont <600-VyrCossont@users.noreply.git.pleroma.social> Date: Wed, 26 Dec 2018 21:30:01 -0800 Subject: Implement exclude_reblogs and include_rts --- lib/pleroma/web/activity_pub/activity_pub.ex | 7 +++++++ lib/pleroma/web/twitter_api/twitter_api_controller.ex | 9 +++++++++ 2 files changed, 16 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 188060780..2d4cc9f68 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -503,6 +503,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_replies(query, _), do: query + defp restrict_reblogs(query, %{"exclude_reblogs" => val}) when val == "true" or val == "1" do + from(activity in query, where: fragment("?->>'type' != 'Announce'", activity.data)) + end + + defp restrict_reblogs(query, _), do: query + # Only search through last 100_000 activities by default defp restrict_recent(query, %{"whole_db" => true}), do: query @@ -561,6 +567,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_media(opts) |> restrict_visibility(opts) |> restrict_replies(opts) + |> restrict_reblogs(opts) end def fetch_activities(recipients, opts \\ %{}) do diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index c25cb0876..7ae850d71 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -130,6 +130,15 @@ defmodule Pleroma.Web.TwitterAPI.Controller do def user_timeline(%{assigns: %{user: user}} = conn, params) do case TwitterAPI.get_user(user, params) do {:ok, target_user} -> + # Twitter and ActivityPub use a different name and sense for this parameter. + {include_rts, params} = Map.pop(params, "include_rts") + + params = + case include_rts do + x when x == "false" or x == "0" -> Map.put(params, "exclude_reblogs", "true") + _ -> params + end + activities = ActivityPub.fetch_user_activities(target_user, user, params) conn -- cgit v1.2.3 From be70272ab08356353ff3c2685dbb639477c2cdf4 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Thu, 27 Dec 2018 13:21:04 +0300 Subject: Treat only true and "true" as true --- lib/pleroma/web/common_api/common_api.ex | 2 +- lib/pleroma/web/common_api/utils.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 5e5821561..085a95172 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -102,7 +102,7 @@ defmodule Pleroma.Web.CommonAPI do attachments, tags, get_content_type(data["content_type"]), - data["no_attachment_links"] + Enum.member?([true, "true"], data["no_attachment_links"]) ), context <- make_context(inReplyTo), cw <- data["spoiler_text"], diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index d9cc52e26..b91cfc4bb 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -89,7 +89,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do ) do status |> format_input(mentions, tags, content_type) - |> maybe_add_attachments(attachments, !!no_attachment_links) + |> maybe_add_attachments(attachments, no_attachment_links) end def make_context(%Activity{data: %{"context" => context}}), do: context -- cgit v1.2.3 From e6aeb1d4a5c0e0e0e5e1e744b4062f7392ed0722 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Thu, 27 Dec 2018 15:46:18 +0300 Subject: [#471] Prevented rendering of inactive local accounts. --- lib/pleroma/user.ex | 2 ++ lib/pleroma/web/mastodon_api/views/account_view.ex | 22 ++++++++++++++- lib/pleroma/web/twitter_api/views/user_view.ex | 33 ++++++++++++++++++---- 3 files changed, 50 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1f930479d..b8a7a3fae 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -47,6 +47,8 @@ defmodule Pleroma.User do !Pleroma.Config.get([:instance, :account_activation_required]) end + def remote_or_auth_active?(%User{} = user), do: !user.local || auth_active?(user) + def superuser?(%User{} = user), do: user.info && User.Info.superuser?(user.info) def avatar_url(user) do diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index aaaae2035..ba72e3a10 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -11,10 +11,30 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do alias Pleroma.HTML def render("accounts.json", %{users: users} = opts) do - render_many(users, AccountView, "account.json", opts) + users + |> render_many(AccountView, "account.json", opts) + |> Enum.filter(&Enum.any?/1) end def render("account.json", %{user: user} = opts) do + for_user = opts[:for] + + allow_render = + User.remote_or_auth_active?(user) || + (for_user && (for_user.id == user.id || User.superuser?(for_user))) + + if allow_render do + render("valid_account.json", opts) + else + render("invalid_account.json", opts) + end + end + + def render("invalid_account.json", _opts) do + %{} + end + + def render("valid_account.json", %{user: user} = opts) do image = User.avatar_url(user) |> MediaProxy.url() header = User.banner_url(user) |> MediaProxy.url() user_info = User.user_info(user) diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index 6e489624f..41825f8f6 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -15,18 +15,39 @@ defmodule Pleroma.Web.TwitterAPI.UserView do end def render("index.json", %{users: users, for: user}) do - render_many(users, Pleroma.Web.TwitterAPI.UserView, "user.json", for: user) + users + |> render_many(Pleroma.Web.TwitterAPI.UserView, "user.json", for: user) + |> Enum.filter(&Enum.any?/1) end def render("user.json", %{user: user = %User{}} = assigns) do + for_user = assigns[:for] + + allow_render = + User.remote_or_auth_active?(user) || + (for_user && (for_user.id == user.id || User.superuser?(for_user))) + + if allow_render do + render("valid_user.json", assigns) + else + render("invalid_user.json", assigns) + end + end + + def render("invalid_user.json", _assigns) do + %{} + end + + def render("valid_user.json", %{user: user = %User{}} = assigns) do + for_user = assigns[:for] image = User.avatar_url(user) |> MediaProxy.url() {following, follows_you, statusnet_blocking} = - if assigns[:for] do + if for_user do { - User.following?(assigns[:for], user), - User.following?(user, assigns[:for]), - User.blocks?(assigns[:for], user) + User.following?(for_user, user), + User.following?(user, for_user), + User.blocks?(for_user, user) } else {false, false, false} @@ -51,7 +72,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do data = %{ "created_at" => user.inserted_at |> Utils.format_naive_asctime(), "description" => HTML.strip_tags((user.bio || "") |> String.replace("
", "\n")), - "description_html" => HTML.filter_tags(user.bio, User.html_filter_policy(assigns[:for])), + "description_html" => HTML.filter_tags(user.bio, User.html_filter_policy(for_user)), "favourites_count" => 0, "followers_count" => user_info[:follower_count], "following" => following, -- cgit v1.2.3 From d8cc96cb1f9e2a4e736f6830529e8aa9a5d289d8 Mon Sep 17 00:00:00 2001 From: Vyr Cossont <600-VyrCossont@users.noreply.git.pleroma.social> Date: Thu, 27 Dec 2018 22:43:40 -0800 Subject: Fix Twitter timelines for private instances --- lib/pleroma/web/twitter_api/twitter_api_controller.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 7ae850d71..92b7386da 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -662,7 +662,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do json_reply(conn, 403, json) end - def only_if_public_instance(conn = %{conn: %{assigns: %{user: _user}}}, _), do: conn + def only_if_public_instance(%{assigns: %{user: %User{}}} = conn, _), do: conn def only_if_public_instance(conn, _) do if Keyword.get(Application.get_env(:pleroma, :instance), :public) do -- cgit v1.2.3 From 0d1788ce44cf7bf50aa40e56988be0d2e315d2e1 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 28 Dec 2018 14:35:25 +0300 Subject: [#471] Factored out User.visible_for?/2. --- lib/pleroma/user.ex | 6 ++++++ lib/pleroma/web/mastodon_api/views/account_view.ex | 14 +++----------- lib/pleroma/web/twitter_api/views/user_view.ex | 14 +++----------- 3 files changed, 12 insertions(+), 22 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b8a7a3fae..7d97bf7e5 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -49,6 +49,12 @@ defmodule Pleroma.User do def remote_or_auth_active?(%User{} = user), do: !user.local || auth_active?(user) + def visible_for?(%User{} = user, for_user \\ nil) do + User.remote_or_auth_active?(user) || (for_user && for_user.id == user.id) || + User.superuser?(for_user) + end + + def superuser?(nil), do: false def superuser?(%User{} = user), do: user.info && User.Info.superuser?(user.info) def avatar_url(user) do diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index ba72e3a10..32cb1ac60 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -17,17 +17,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do end def render("account.json", %{user: user} = opts) do - for_user = opts[:for] - - allow_render = - User.remote_or_auth_active?(user) || - (for_user && (for_user.id == user.id || User.superuser?(for_user))) - - if allow_render do - render("valid_account.json", opts) - else - render("invalid_account.json", opts) - end + if User.visible_for?(user, opts[:for]), + do: render("valid_account.json", opts), + else: render("invalid_account.json", opts) end def render("invalid_account.json", _opts) do diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index 41825f8f6..890d4234e 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -21,17 +21,9 @@ defmodule Pleroma.Web.TwitterAPI.UserView do end def render("user.json", %{user: user = %User{}} = assigns) do - for_user = assigns[:for] - - allow_render = - User.remote_or_auth_active?(user) || - (for_user && (for_user.id == user.id || User.superuser?(for_user))) - - if allow_render do - render("valid_user.json", assigns) - else - render("invalid_user.json", assigns) - end + if User.visible_for?(user, assigns[:for]), + do: render("valid_user.json", assigns), + else: render("invalid_user.json", assigns) end def render("invalid_user.json", _assigns) do -- cgit v1.2.3 From 6e9a15b181fcca9e7485a61b1cce2e4ec6d46b78 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 28 Dec 2018 21:08:07 +0300 Subject: [#483] Blocked users export for TwitterAPI. --- lib/pleroma/user.ex | 3 +++ lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 6 ++---- lib/pleroma/web/router.ex | 1 + lib/pleroma/web/twitter_api/twitter_api_controller.ex | 8 ++++++++ 4 files changed, 14 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 33f5e43fc..b64ed74c4 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -649,6 +649,9 @@ defmodule Pleroma.User do end) end + def blocked_users(user), + do: Repo.all(from(u in User, where: u.ap_id in ^user.info.blocks)) + def block_domain(user, domain) do info_cng = user.info diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 22715bb76..663a0fa08 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -704,11 +704,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - # TODO: Use proper query def blocks(%{assigns: %{user: user}} = conn, _) do - with blocked_users <- user.info.blocks || [], - accounts <- Enum.map(blocked_users, fn ap_id -> User.get_cached_by_ap_id(ap_id) end) do - res = AccountView.render("accounts.json", users: accounts, for: user, as: :user) + with blocked_accounts <- User.blocked_users(user) do + res = AccountView.render("accounts.json", users: blocked_accounts, for: user, as: :user) json(conn, res) end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 7ec0cabb3..a7f78ba81 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -281,6 +281,7 @@ defmodule Pleroma.Web.Router do get("/statuses/followers", TwitterAPI.Controller, :followers) get("/statuses/friends", TwitterAPI.Controller, :friends) + get("/statuses/blocks", TwitterAPI.Controller, :blocks) get("/statuses/show/:id", TwitterAPI.Controller, :fetch_status) get("/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 7ae850d71..c11824afc 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -507,6 +507,14 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end end + def blocks(%{assigns: %{user: user}} = conn, _params) do + with blocked_users <- User.blocked_users(user) do + conn + |> put_view(UserView) + |> render("index.json", %{users: blocked_users, for: user}) + end + end + def friend_requests(conn, params) do with {:ok, user} <- TwitterAPI.get_user(conn.assigns[:user], params), {:ok, friend_requests} <- User.get_follow_requests(user) do -- cgit v1.2.3 From 0a41786624454d26fd966748735a8f2333bf4012 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 28 Dec 2018 22:47:42 +0300 Subject: [#467] Refactored valid / invalid user rendering. --- lib/pleroma/web/mastodon_api/views/account_view.ex | 80 ++++++++++------------ lib/pleroma/web/twitter_api/views/user_view.ex | 40 +++++------ 2 files changed, 56 insertions(+), 64 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 32cb1ac60..555383503 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -18,15 +18,48 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do def render("account.json", %{user: user} = opts) do if User.visible_for?(user, opts[:for]), - do: render("valid_account.json", opts), - else: render("invalid_account.json", opts) + do: do_render("account.json", opts), + else: %{} end - def render("invalid_account.json", _opts) do - %{} + def render("mention.json", %{user: user}) do + %{ + id: to_string(user.id), + acct: user.nickname, + username: username_from_nickname(user.nickname), + url: user.ap_id + } + end + + def render("relationship.json", %{user: user, target: target}) do + follow_activity = Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, target) + + requested = + if follow_activity do + follow_activity.data["state"] == "pending" + else + false + end + + %{ + id: to_string(target.id), + following: User.following?(user, target), + followed_by: User.following?(target, user), + blocking: User.blocks?(user, target), + muting: false, + muting_notifications: false, + requested: requested, + domain_blocking: false, + showing_reblogs: false, + endorsed: false + } end - def render("valid_account.json", %{user: user} = opts) do + def render("relationships.json", %{user: user, targets: targets}) do + render_many(targets, AccountView, "relationship.json", user: user, as: :target) + end + + defp do_render("account.json", %{user: user} = opts) do image = User.avatar_url(user) |> MediaProxy.url() header = User.banner_url(user) |> MediaProxy.url() user_info = User.user_info(user) @@ -84,43 +117,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do } end - def render("mention.json", %{user: user}) do - %{ - id: to_string(user.id), - acct: user.nickname, - username: username_from_nickname(user.nickname), - url: user.ap_id - } - end - - def render("relationship.json", %{user: user, target: target}) do - follow_activity = Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, target) - - requested = - if follow_activity do - follow_activity.data["state"] == "pending" - else - false - end - - %{ - id: to_string(target.id), - following: User.following?(user, target), - followed_by: User.following?(target, user), - blocking: User.blocks?(user, target), - muting: false, - muting_notifications: false, - requested: requested, - domain_blocking: false, - showing_reblogs: false, - endorsed: false - } - end - - def render("relationships.json", %{user: user, targets: targets}) do - render_many(targets, AccountView, "relationship.json", user: user, as: :target) - end - defp username_from_nickname(string) when is_binary(string) do hd(String.split(string, "@")) end diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index 890d4234e..ede3c0d25 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -22,15 +22,28 @@ defmodule Pleroma.Web.TwitterAPI.UserView do def render("user.json", %{user: user = %User{}} = assigns) do if User.visible_for?(user, assigns[:for]), - do: render("valid_user.json", assigns), - else: render("invalid_user.json", assigns) + do: do_render("user.json", assigns), + else: %{} end - def render("invalid_user.json", _assigns) do - %{} + def render("short.json", %{ + user: %User{ + nickname: nickname, + id: id, + ap_id: ap_id, + name: name + } + }) do + %{ + "fullname" => name, + "id" => id, + "ostatus_uri" => ap_id, + "profile_url" => ap_id, + "screen_name" => nickname + } end - def render("valid_user.json", %{user: user = %User{}} = assigns) do + defp do_render("user.json", %{user: user = %User{}} = assigns) do for_user = assigns[:for] image = User.avatar_url(user) |> MediaProxy.url() @@ -110,23 +123,6 @@ defmodule Pleroma.Web.TwitterAPI.UserView do end end - def render("short.json", %{ - user: %User{ - nickname: nickname, - id: id, - ap_id: ap_id, - name: name - } - }) do - %{ - "fullname" => name, - "id" => id, - "ostatus_uri" => ap_id, - "profile_url" => ap_id, - "screen_name" => nickname - } - end - defp image_url(%{"url" => [%{"href" => href} | _]}), do: href defp image_url(_), do: nil -- cgit v1.2.3 From 700661b761117e6673ad254877ebba902b9d751b Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 28 Dec 2018 23:01:03 +0300 Subject: [#483] Blocked users list import (TwitterAPI). --- lib/pleroma/web/router.ex | 1 + .../web/twitter_api/controllers/util_controller.ex | 31 ++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index a7f78ba81..43b04e508 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -137,6 +137,7 @@ defmodule Pleroma.Web.Router do scope "/api/pleroma", Pleroma.Web.TwitterAPI do pipe_through(:authenticated_api) + post("/blocks_import", UtilController, :blocks_import) post("/follow_import", UtilController, :follow_import) post("/change_password", UtilController, :change_password) post("/delete_account", UtilController, :delete_account) diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index c872aec2b..6a9325afe 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -242,9 +242,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do def follow_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do Task.start(fn -> - String.split(list) + follower = User.get_cached_by_ap_id(user.ap_id) + + list + |> String.split() |> Enum.map(fn account -> - with %User{} = follower <- User.get_cached_by_ap_id(user.ap_id), + with %User{} <- follower, %User{} = followed <- User.get_or_fetch(account), {:ok, follower} <- User.maybe_direct_follow(follower, followed) do ActivityPub.follow(follower, followed) @@ -257,6 +260,30 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do json(conn, "job started") end + def blocks_import(conn, %{"list" => %Plug.Upload{} = listfile}) do + blocks_import(conn, %{"list" => File.read!(listfile.path)}) + end + + def blocks_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do + Task.start(fn -> + blocker = User.get_cached_by_ap_id(user.ap_id) + + list + |> String.split() + |> Enum.map(fn account -> + with %User{} <- blocker, + %User{} = blocked <- User.get_or_fetch(account), + {:ok, blocker} <- User.block(blocker, blocked) do + ActivityPub.block(blocker, blocked) + else + err -> Logger.debug("blocks_import: blocking #{account} failed with #{inspect(err)}") + end + end) + end) + + json(conn, "job started") + end + def change_password(%{assigns: %{user: user}} = conn, params) do case CommonAPI.Utils.confirm_current_password(user, params["password"]) do {:ok, user} -> -- cgit v1.2.3 From 67b4297f4d4010ee1b66452af4cea094d2cab2c4 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Sat, 29 Dec 2018 12:02:37 +0300 Subject: [#483] Refactored blocks and follows import, added tests. --- lib/pleroma/user.ex | 37 +++++++++++++++++ .../web/twitter_api/controllers/util_controller.ex | 46 +++++----------------- 2 files changed, 47 insertions(+), 36 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b64ed74c4..558014760 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -13,6 +13,8 @@ defmodule Pleroma.User do alias Pleroma.Web.{OStatus, Websub, OAuth} alias Pleroma.Web.ActivityPub.{Utils, ActivityPub} + require Logger + @type t :: %__MODULE__{} @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ @@ -331,6 +333,24 @@ defmodule Pleroma.User do Enum.member?(follower.following, followed.follower_address) end + def follow_import(%User{} = follower, followed_identifiers) + when is_list(followed_identifiers) do + Enum.map( + followed_identifiers, + fn followed_identifier -> + with %User{} = followed <- get_or_fetch(followed_identifier), + {:ok, follower} <- maybe_direct_follow(follower, followed), + {:ok, _} <- ActivityPub.follow(follower, followed) do + followed + else + err -> + Logger.debug("follow_import failed for #{followed_identifier} with: #{inspect(err)}") + err + end + end + ) + end + def locked?(%User{} = user) do user.info.locked || false end @@ -596,6 +616,23 @@ defmodule Pleroma.User do Repo.all(q) end + def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do + Enum.map( + blocked_identifiers, + fn blocked_identifier -> + with %User{} = blocked <- get_or_fetch(blocked_identifier), + {:ok, blocker} <- block(blocker, blocked), + {:ok, _} <- ActivityPub.block(blocker, blocked) do + blocked + else + err -> + Logger.debug("blocks_import failed for #{blocked_identifier} with: #{inspect(err)}") + err + end + end + ) + end + def block(blocker, %User{ap_id: ap_id} = blocked) do # sever any follow relationships to prevent leaks per activitypub (Pleroma issue #213) blocker = diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 6a9325afe..87b8b71ba 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -240,48 +240,22 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do follow_import(conn, %{"list" => File.read!(listfile.path)}) end - def follow_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do - Task.start(fn -> - follower = User.get_cached_by_ap_id(user.ap_id) - - list - |> String.split() - |> Enum.map(fn account -> - with %User{} <- follower, - %User{} = followed <- User.get_or_fetch(account), - {:ok, follower} <- User.maybe_direct_follow(follower, followed) do - ActivityPub.follow(follower, followed) - else - err -> Logger.debug("follow_import: following #{account} failed with #{inspect(err)}") - end - end) - end) - - json(conn, "job started") + def follow_import(%{assigns: %{user: follower}} = conn, %{"list" => list}) do + with followed_identifiers <- String.split(list), + {:ok, _} = Task.start(fn -> User.follow_import(follower, followed_identifiers) end) do + json(conn, "job started") + end end def blocks_import(conn, %{"list" => %Plug.Upload{} = listfile}) do blocks_import(conn, %{"list" => File.read!(listfile.path)}) end - def blocks_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do - Task.start(fn -> - blocker = User.get_cached_by_ap_id(user.ap_id) - - list - |> String.split() - |> Enum.map(fn account -> - with %User{} <- blocker, - %User{} = blocked <- User.get_or_fetch(account), - {:ok, blocker} <- User.block(blocker, blocked) do - ActivityPub.block(blocker, blocked) - else - err -> Logger.debug("blocks_import: blocking #{account} failed with #{inspect(err)}") - end - end) - end) - - json(conn, "job started") + def blocks_import(%{assigns: %{user: blocker}} = conn, %{"list" => list}) do + with blocked_identifiers <- String.split(list), + {:ok, _} = Task.start(fn -> User.blocks_import(blocker, blocked_identifiers) end) do + json(conn, "job started") + end end def change_password(%{assigns: %{user: user}} = conn, params) do -- cgit v1.2.3 From b3574dccbbb9d24ed90f0a82627d18428aaa7a16 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Sat, 29 Dec 2018 12:15:46 +0300 Subject: [#483] User.get_by_nickname/1: allowed retrieving user by fully-qualified local nickname (@). --- lib/pleroma/user.ex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 558014760..d4a6b13fb 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -387,7 +387,11 @@ defmodule Pleroma.User do end def get_by_nickname(nickname) do - Repo.get_by(User, nickname: nickname) + Repo.get_by(User, nickname: nickname) || + if String.ends_with?(nickname, "@" <> Pleroma.Web.Endpoint.host()) do + [local_nickname, _] = String.split(nickname, "@") + Repo.get_by(User, nickname: local_nickname) + end end def get_by_nickname_or_email(nickname_or_email) do -- cgit v1.2.3 From 7bd49a32222045c34098f925fbd494461ab67ccd Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Sat, 29 Dec 2018 12:26:23 +0300 Subject: [#483] User.get_by_nickname/1: ensured case-insensitive matching for local FQN. Added tests. --- lib/pleroma/user.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index d4a6b13fb..1f6d4cc5e 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -388,7 +388,7 @@ defmodule Pleroma.User do def get_by_nickname(nickname) do Repo.get_by(User, nickname: nickname) || - if String.ends_with?(nickname, "@" <> Pleroma.Web.Endpoint.host()) do + if Regex.match?(~r(@#{Pleroma.Web.Endpoint.host()})i, nickname) do [local_nickname, _] = String.split(nickname, "@") Repo.get_by(User, nickname: local_nickname) end -- cgit v1.2.3 From 523848d1fd94cfefa0a81e585d5891135982f8c2 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Sat, 29 Dec 2018 12:48:54 +0300 Subject: Salmon# fixed publish an activity to remote accounts --- lib/pleroma/activity.ex | 2 ++ lib/pleroma/http/http.ex | 2 ++ lib/pleroma/web/salmon/salmon.ex | 18 ++++++++++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 34b665765..a14d1e8c6 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -7,6 +7,8 @@ defmodule Pleroma.Activity do alias Pleroma.{Repo, Activity, Notification} import Ecto.Query + @type t :: %__MODULE__{} + # https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19 @mastodon_notification_types %{ "Create" => "mention", diff --git a/lib/pleroma/http/http.ex b/lib/pleroma/http/http.ex index e572dfedf..32d9cf5aa 100644 --- a/lib/pleroma/http/http.ex +++ b/lib/pleroma/http/http.ex @@ -10,6 +10,8 @@ defmodule Pleroma.HTTP do alias Pleroma.HTTP.Connection alias Pleroma.HTTP.RequestBuilder, as: Builder + @type t :: __MODULE__ + @doc """ Builds and perform http request. diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex index 1dc514976..f7d2257eb 100644 --- a/lib/pleroma/web/salmon/salmon.ex +++ b/lib/pleroma/web/salmon/salmon.ex @@ -161,16 +161,21 @@ defmodule Pleroma.Web.Salmon do |> Enum.filter(fn user -> user && !user.local end) end - defp send_to_user(%{info: %{salmon: salmon}}, feed, poster) do + # push an activity to remote accounts + # + defp send_to_user(%{info: %{salmon: salmon}}, feed, poster), + do: send_to_user(salmon, feed, poster) + + defp send_to_user(url, feed, poster) when is_binary(url) do with {:ok, %{status: code}} <- poster.( - salmon, + url, feed, [{"Content-Type", "application/magic-envelope+xml"}] ) do - Logger.debug(fn -> "Pushed to #{salmon}, code #{code}" end) + Logger.debug(fn -> "Pushed to #{url}, code #{code}" end) else - e -> Logger.debug(fn -> "Pushing Salmon to #{salmon} failed, #{inspect(e)}" end) + e -> Logger.debug(fn -> "Pushing Salmon to #{url} failed, #{inspect(e)}" end) end end @@ -184,6 +189,11 @@ defmodule Pleroma.Web.Salmon do "Undo", "Delete" ] + + @doc """ + Publishes an activity to remote accounts + """ + @spec publish(User.t(), Pleroma.Activity.t(), Pleroma.HTTP.t()) :: none def publish(user, activity, poster \\ &@httpoison.post/3) def publish(%{info: %{keys: keys}} = user, %{data: %{"type" => type}} = activity, poster) -- cgit v1.2.3 From ab9cda315f2ee7b0a2a6e505eface5d7c65d50b4 Mon Sep 17 00:00:00 2001 From: spctrl Date: Sat, 29 Dec 2018 12:43:54 +0100 Subject: Change 'name' to 'instance_name' so option is used when running non-interactive --- lib/mix/tasks/pleroma/instance.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mix/tasks/pleroma/instance.ex b/lib/mix/tasks/pleroma/instance.ex index 1ef40671c..0a2c891c0 100644 --- a/lib/mix/tasks/pleroma/instance.ex +++ b/lib/mix/tasks/pleroma/instance.ex @@ -75,7 +75,7 @@ defmodule Mix.Tasks.Pleroma.Instance do name = Common.get_option( options, - :name, + :instance_name, "What is the name of your instance? (e.g. Pleroma/Soykaf)" ) -- cgit v1.2.3 From aa082ca7b6a64f6cfd509118f76a5c18492e07b9 Mon Sep 17 00:00:00 2001 From: sxsdv1 Date: Sat, 29 Dec 2018 18:01:15 +0100 Subject: Wire up stub routes for client calls of activitypub inbox/outbox Code style: remove wrapping function of outbox --- .../web/activity_pub/activity_pub_controller.ex | 36 ++++++++++++++++++---- lib/pleroma/web/router.ex | 21 +++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 7fd6a45f5..dfa7eb94b 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -93,19 +93,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end - def outbox(conn, %{"nickname" => nickname, "max_id" => max_id}) do + def outbox(conn, %{"nickname" => nickname} = params) do with %User{} = user <- User.get_cached_by_nickname(nickname), {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do conn |> put_resp_header("content-type", "application/activity+json") - |> json(UserView.render("outbox.json", %{user: user, max_id: max_id})) + |> json(UserView.render("outbox.json", %{user: user, max_id: params["max_id"]})) end end - def outbox(conn, %{"nickname" => nickname}) do - outbox(conn, %{"nickname" => nickname, "max_id" => nil}) - end - def inbox(%{assigns: %{valid_signature: true}} = conn, %{"nickname" => nickname} = params) do with %User{} = user <- User.get_cached_by_nickname(nickname), true <- Utils.recipient_in_message(user.ap_id, params), @@ -156,6 +152,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end + def read_inbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = params) do + if nickname == user.nickname do + Logger.info("read inbox #{inspect(params)}") + + conn + |> put_resp_header("content-type", "application/activity+json") + |> json("ok!") + else + conn + |> put_status(:forbidden) + |> json("can't read inbox of #{nickname} as #{user.nickname}") + end + end + + def update_outbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = params) do + if nickname == user.nickname do + Logger.info("update outbox #{inspect(params)}") + + conn + |> put_status(:created) + |> json("ok!") + else + conn + |> put_status(:forbidden) + |> json("can't update outbox of #{nickname} as #{user.nickname}") + end + end + def errors(conn, {:error, :not_found}) do conn |> put_status(404) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 43b04e508..33c573d46 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -412,6 +412,27 @@ defmodule Pleroma.Web.Router do get("/users/:nickname/outbox", ActivityPubController, :outbox) end + pipeline :activitypub_client do + plug(:accepts, ["activity+json"]) + plug(:fetch_session) + plug(Pleroma.Plugs.OAuthPlug) + plug(Pleroma.Plugs.BasicAuthDecoderPlug) + plug(Pleroma.Plugs.UserFetcherPlug) + plug(Pleroma.Plugs.SessionAuthenticationPlug) + plug(Pleroma.Plugs.LegacyAuthenticationPlug) + plug(Pleroma.Plugs.AuthenticationPlug) + plug(Pleroma.Plugs.UserEnabledPlug) + plug(Pleroma.Plugs.SetUserSessionIdPlug) + plug(Pleroma.Plugs.EnsureUserKeyPlug) + end + + scope "/", Pleroma.Web.ActivityPub do + pipe_through([:activitypub_client]) + + get("/users/:nickname/inbox", ActivityPubController, :read_inbox) + post("/users/:nickname/outbox", ActivityPubController, :update_outbox) + end + scope "/relay", Pleroma.Web.ActivityPub do pipe_through(:ap_relay) get("/", ActivityPubController, :relay) -- cgit v1.2.3 From 26dc2dddab6103a3e6e44a3c7ba097283302fc2a Mon Sep 17 00:00:00 2001 From: sxsdv1 Date: Sat, 29 Dec 2018 18:15:28 +0100 Subject: Implement ActivityPub inbox view More or less verbatim copied from the outbox template with only changes to the activities fetched and url reported --- .../web/activity_pub/activity_pub_controller.ex | 4 +- lib/pleroma/web/activity_pub/views/user_view.ex | 47 ++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index dfa7eb94b..9f083d0a5 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -154,11 +154,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do def read_inbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = params) do if nickname == user.nickname do - Logger.info("read inbox #{inspect(params)}") - conn |> put_resp_header("content-type", "application/activity+json") - |> json("ok!") + |> json(UserView.render("inbox.json", %{user: user, max_id: params["max_id"]})) else conn |> put_status(:forbidden) diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index f0c268755..439d834e4 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -176,6 +176,53 @@ defmodule Pleroma.Web.ActivityPub.UserView do end end + def render("inbox.json", %{user: user, max_id: max_qid}) do + params = %{ + "limit" => "10" + } + + params = + if max_qid != nil do + Map.put(params, "max_id", max_qid) + else + params + end + + activities = ActivityPub.fetch_activities([user.ap_id | user.following], params) + + min_id = Enum.at(Enum.reverse(activities), 0).id + max_id = Enum.at(activities, 0).id + + collection = + Enum.map(activities, fn act -> + {:ok, data} = Transmogrifier.prepare_outgoing(act.data) + data + end) + + iri = "#{user.ap_id}/inbox" + + page = %{ + "id" => "#{iri}?max_id=#{max_id}", + "type" => "OrderedCollectionPage", + "partOf" => iri, + "totalItems" => -1, + "orderedItems" => collection, + "next" => "#{iri}?max_id=#{min_id - 1}" + } + + if max_qid == nil do + %{ + "id" => iri, + "type" => "OrderedCollection", + "totalItems" => -1, + "first" => page + } + |> Map.merge(Utils.make_json_ld_header()) + else + page |> Map.merge(Utils.make_json_ld_header()) + end + end + def collection(collection, iri, page, show_items \\ true, total \\ nil) do offset = (page - 1) * 10 items = Enum.slice(collection, offset, 10) -- cgit v1.2.3 From 569bad821006add1719123f6e2830f23542921d2 Mon Sep 17 00:00:00 2001 From: sxsdv1 Date: Sat, 29 Dec 2018 18:21:45 +0100 Subject: Create activity when client posts to outbox --- .../web/activity_pub/activity_pub_controller.ex | 35 ++++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 9f083d0a5..dca74db73 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -4,11 +4,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do use Pleroma.Web, :controller - alias Pleroma.{User, Object} + alias Pleroma.{Activity, User, Object} alias Pleroma.Web.ActivityPub.{ObjectView, UserView} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.Federator require Logger @@ -166,11 +167,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do def update_outbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = params) do if nickname == user.nickname do - Logger.info("update outbox #{inspect(params)}") - - conn - |> put_status(:created) - |> json("ok!") + actor = user.ap_id() + + params = + params + |> Map.drop(["id"]) + |> Map.put("actor", actor) + |> Transmogrifier.fix_addressing() + + object = + params["object"] + |> Map.merge(Map.take(params, ["to", "cc"])) + |> Map.put("attributedTo", actor) + |> Transmogrifier.fix_object() + + with {:ok, %Activity{} = activity} <- + ActivityPub.create(%{ + to: params["to"], + actor: user, + context: object["context"], + object: object, + additional: Map.take(params, ["cc"]) + }) do + conn + |> put_status(:created) + |> put_resp_header("location", activity.data["id"]) + |> json(%{"id" => activity.data["id"]}) + end else conn |> put_status(:forbidden) -- cgit v1.2.3 From 1e781715c8a9c7f6e24838a5522b960250cffc1b Mon Sep 17 00:00:00 2001 From: sxsdv1 Date: Sat, 29 Dec 2018 18:22:40 +0100 Subject: Limit activity types accepted to outbox to only 'Create' --- lib/pleroma/web/activity_pub/activity_pub_controller.ex | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index dca74db73..f90132b4d 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -165,7 +165,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end - def update_outbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = params) do + def update_outbox( + %{assigns: %{user: user}} = conn, + %{"nickname" => nickname, "type" => "Create"} = params + ) do if nickname == user.nickname do actor = user.ap_id() -- cgit v1.2.3 From f40562b4e1ff213b88c8b6edf57431bfb1b804ac Mon Sep 17 00:00:00 2001 From: sxsdv1 Date: Sun, 30 Dec 2018 11:19:53 +0100 Subject: Respond with full activity to outbox post --- lib/pleroma/web/activity_pub/activity_pub_controller.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index f90132b4d..e41b14afc 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -195,7 +195,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do conn |> put_status(:created) |> put_resp_header("location", activity.data["id"]) - |> json(%{"id" => activity.data["id"]}) + |> json(activity.data) end else conn -- cgit v1.2.3