From a494508320d2e2650a2c09ae53b212b8c1ab7bd3 Mon Sep 17 00:00:00 2001 From: Greizgh Date: Sat, 27 Oct 2018 14:31:51 +0200 Subject: Cleanup postgresql setup script Drop unused CREATEDB privilege. Do not try to handle multiple run. --- lib/mix/tasks/sample_psql.eex | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/sample_psql.eex b/lib/mix/tasks/sample_psql.eex index bc22f166c..b6f57948b 100644 --- a/lib/mix/tasks/sample_psql.eex +++ b/lib/mix/tasks/sample_psql.eex @@ -1,8 +1,5 @@ -CREATE USER pleroma WITH ENCRYPTED PASSWORD '<%= dbpass %>' CREATEDB; --- in case someone runs this second time accidentally -ALTER USER pleroma WITH ENCRYPTED PASSWORD '<%= dbpass %>' CREATEDB; -CREATE DATABASE pleroma_dev; -ALTER DATABASE pleroma_dev OWNER TO pleroma; +CREATE USER pleroma WITH ENCRYPTED PASSWORD '<%= dbpass %>'; +CREATE DATABASE pleroma_dev OWNER pleroma; \c pleroma_dev; --Extensions made by ecto.migrate that need superuser access CREATE EXTENSION IF NOT EXISTS citext; -- cgit v1.2.3 From 72ea54de6e74084d69594c544bcddcc0a991603a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 28 Oct 2018 05:45:33 +0000 Subject: activitypub: fix possible false positives with broken thread filtering --- lib/pleroma/web/activity_pub/activity_pub.ex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 173ca688d..4b8b6eb52 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -793,9 +793,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do # child def entire_thread_visible_for_user?( - %Activity{data: %{"object" => %{"inReplyTo" => _parent_id}}} = tail, + %Activity{data: %{"object" => %{"inReplyTo" => parent_id}}} = tail, user - ) do + ) + when is_binary(parent_id) do parent = Activity.get_in_reply_to_activity(tail) visible_for_user?(tail, user) && entire_thread_visible_for_user?(parent, user) end -- cgit v1.2.3 From 69192f36ff617d237481c401850171bf79a2f547 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 28 Oct 2018 19:47:56 +0000 Subject: mix tasks: add new task to unsubscribe all users from, and then ban a remote user (e.g. followbots) --- lib/mix/tasks/unsubscribe_user.ex | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 lib/mix/tasks/unsubscribe_user.ex (limited to 'lib') diff --git a/lib/mix/tasks/unsubscribe_user.ex b/lib/mix/tasks/unsubscribe_user.ex new file mode 100644 index 000000000..bb72634b6 --- /dev/null +++ b/lib/mix/tasks/unsubscribe_user.ex @@ -0,0 +1,32 @@ +defmodule Mix.Tasks.UnsubscribeUser do + use Mix.Task + alias Pleroma.{User, Repo} + require Logger + + @shortdoc "Unsubscribe all users from a target and then deactivate them" + def run([nickname]) do + Mix.Task.run("app.start") + + with %User{} = user <- User.get_by_nickname(nickname) do + Logger.info("Deactivating #{user.nickname}") + User.deactivate(user) + + {:ok, friends} = User.get_friends(user) + + Enum.each(friends, fn friend -> + user = Repo.get(User, user.id) + + Logger.info("Unsubscribing #{friend.nickname} from #{user.nickname}") + User.unfollow(user, friend) + end) + + :timer.sleep(500) + + user = Repo.get(User, user.id) + + if length(user.following) == 0 do + Logger.info("Successfully unsubscribed all followers from #{user.nickname}") + end + end + end +end -- cgit v1.2.3 From 5c6ec2d9fc0bd9e6b49906ea58f163264c37a54e Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 15:19:32 +0000 Subject: twitter/mastodon api: always use mediaproxy URLs in attachments if using local media, the mediaproxy will not replace the URL anyway. --- lib/pleroma/web/mastodon_api/views/status_view.ex | 6 +++--- lib/pleroma/web/twitter_api/twitter_api.ex | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 8ffaf8466..80e80c8f5 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -166,7 +166,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do def render("attachment.json", %{attachment: attachment}) do [attachment_url | _] = attachment["url"] media_type = attachment_url["mediaType"] || attachment_url["mimeType"] || "image" - href = attachment_url["href"] + href = attachment_url["href"] |> MediaProxy.url() type = cond do @@ -180,9 +180,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do %{ id: to_string(attachment["id"] || hash_id), - url: MediaProxy.url(href), + url: href, remote_url: href, - preview_url: MediaProxy.url(href), + preview_url: href, text_url: href, type: type, description: attachment["name"] diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 3747285da..cb483df9d 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -3,6 +3,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.TwitterAPI.UserView alias Pleroma.Web.{OStatus, CommonAPI} + alias Pleroma.Web.MediaProxy import Ecto.Query @instance Application.get_env(:pleroma, :instance) @@ -97,7 +98,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do {:ok, object} = ActivityPub.upload(file) url = List.first(object.data["url"]) - href = url["href"] + href = url["href"] |> MediaProxy.url() type = url["mediaType"] case format do -- cgit v1.2.3 From fa483cd7c211ba7d755d307f095bde31efdb81d4 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 16:29:46 +0000 Subject: upload: add new optional argument designating an upload size limit --- lib/pleroma/upload.ex | 111 ++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 48 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index f188a5f32..2293ff54e 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -4,61 +4,76 @@ defmodule Pleroma.Upload do @storage_backend Application.get_env(:pleroma, Pleroma.Upload) |> Keyword.fetch!(:uploader) - def store(%Plug.Upload{} = file, should_dedupe) do + def check_file_size(path, nil), do: true + + def check_file_size(path, size_limit) do + {:ok, %{size: size}} = File.stat(path) + size <= size_limit + end + + def store(file, should_dedupe, size_limit \\ nil) + + def store(%Plug.Upload{} = file, should_dedupe, size_limit) do content_type = get_content_type(file.path) - uuid = get_uuid(file, should_dedupe) - name = get_name(file, uuid, content_type, should_dedupe) - - strip_exif_data(content_type, file.path) - - {:ok, url_path} = - @storage_backend.put_file(name, uuid, file.path, content_type, should_dedupe) - - %{ - "type" => "Document", - "url" => [ - %{ - "type" => "Link", - "mediaType" => content_type, - "href" => url_path - } - ], - "name" => name - } + with uuid <- get_uuid(file, should_dedupe), + name <- get_name(file, uuid, content_type, should_dedupe), + true <- check_file_size(file.path, size_limit) do + strip_exif_data(content_type, file.path) + + {:ok, url_path} = + @storage_backend.put_file(name, uuid, file.path, content_type, should_dedupe) + + %{ + "type" => "Document", + "url" => [ + %{ + "type" => "Link", + "mediaType" => content_type, + "href" => url_path + } + ], + "name" => name + } + else + _e -> nil + end end - def store(%{"img" => "data:image/" <> image_data}, should_dedupe) do + def store(%{"img" => "data:image/" <> image_data}, should_dedupe, size_limit) do parsed = Regex.named_captures(~r/(?jpeg|png|gif);base64,(?.*)/, image_data) data = Base.decode64!(parsed["data"], ignore: :whitespace) - tmp_path = tempfile_for_image(data) - - uuid = UUID.generate() - - content_type = get_content_type(tmp_path) - strip_exif_data(content_type, tmp_path) - - name = - create_name( - String.downcase(Base.encode16(:crypto.hash(:sha256, data))), - parsed["filetype"], - content_type - ) - - {:ok, url_path} = @storage_backend.put_file(name, uuid, tmp_path, content_type, should_dedupe) - - %{ - "type" => "Image", - "url" => [ - %{ - "type" => "Link", - "mediaType" => content_type, - "href" => url_path - } - ], - "name" => name - } + with tmp_path <- tempfile_for_image(data), + uuid <- UUID.generate(), + true <- check_file_size(tmp_path, size_limit) do + content_type = get_content_type(tmp_path) + strip_exif_data(content_type, tmp_path) + + name = + create_name( + String.downcase(Base.encode16(:crypto.hash(:sha256, data))), + parsed["filetype"], + content_type + ) + + {:ok, url_path} = + @storage_backend.put_file(name, uuid, tmp_path, content_type, should_dedupe) + + %{ + "type" => "Image", + "url" => [ + %{ + "type" => "Link", + "mediaType" => content_type, + "href" => url_path + } + ], + "name" => name + } + else + _e -> nil + end end @doc """ -- cgit v1.2.3 From 167d3789a5a334859dfb9bf1612bdfc993032667 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 16:30:12 +0000 Subject: activitypub: upload: pass through an upload limit if one is provided --- lib/pleroma/web/activity_pub/activity_pub.ex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 4b8b6eb52..537b99f31 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -575,9 +575,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> Enum.reverse() end - def upload(file) do - data = Upload.store(file, Application.get_env(:pleroma, :instance)[:dedupe_media]) - Repo.insert(%Object{data: data}) + def upload(file, size_limit \\ nil) do + with data <- + Upload.store(file, Application.get_env(:pleroma, :instance)[:dedupe_media], size_limit), + false <- is_nil(data) do + Repo.insert(%Object{data: data}) + end end def user_data_from_user_object(data) do -- cgit v1.2.3 From e12489e2fee6d757e432aadf2c49dbd10c70eef2 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 16:36:51 +0000 Subject: twitter api: enforce upload limits for avatars, banners and backgrounds --- lib/pleroma/web/twitter_api/twitter_api_controller.ex | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (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 4fc32b50c..7153a2bd6 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -263,7 +263,11 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def update_avatar(%{assigns: %{user: user}} = conn, params) do - {:ok, object} = ActivityPub.upload(params) + upload_limit = + Application.get_env(:pleroma, :instance) + |> Keyword.fetch(:avatar_upload_limit) + + {:ok, object} = ActivityPub.upload(params, upload_limit) change = Changeset.change(user, %{avatar: object.data}) {:ok, user} = User.update_and_set_cache(change) CommonAPI.update(user) @@ -272,7 +276,11 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def update_banner(%{assigns: %{user: user}} = conn, params) do - with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}), + upload_limit = + Application.get_env(:pleroma, :instance) + |> Keyword.fetch(:banner_upload_limit) + + with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, upload_limit), new_info <- Map.put(user.info, "banner", object.data), change <- User.info_changeset(user, %{info: new_info}), {:ok, user} <- User.update_and_set_cache(change) do @@ -286,7 +294,11 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def update_background(%{assigns: %{user: user}} = conn, params) do - with {:ok, object} <- ActivityPub.upload(params), + upload_limit = + Application.get_env(:pleroma, :instance) + |> Keyword.fetch(:background_upload_limit) + + with {:ok, object} <- ActivityPub.upload(params, upload_limit), new_info <- Map.put(user.info, "background", object.data), change <- User.info_changeset(user, %{info: new_info}), {:ok, _user} <- User.update_and_set_cache(change) do -- cgit v1.2.3 From 181f3bb56a0bc0211ddd2e8f215d93973222b405 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 16:39:00 +0000 Subject: mastodon api: enforce upload limits for avatars and banners --- lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index bc7558cb8..e03027be7 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -35,6 +35,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def update_credentials(%{assigns: %{user: user}} = conn, params) do original_user = user + avatar_upload_limit = + Application.get_env(:pleroma, :instance) + |> Keyword.fetch(:avatar_upload_limit) + + banner_upload_limit = + Application.get_env(:pleroma, :instance) + |> Keyword.fetch(:banner_upload_limit) + params = if bio = params["note"] do Map.put(params, "bio", bio) @@ -52,7 +60,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do user = if avatar = params["avatar"] do with %Plug.Upload{} <- avatar, - {:ok, object} <- ActivityPub.upload(avatar), + {:ok, object} <- ActivityPub.upload(avatar, avatar_upload_limit), change = Ecto.Changeset.change(user, %{avatar: object.data}), {:ok, user} = User.update_and_set_cache(change) do user @@ -66,7 +74,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do user = if banner = params["header"] do with %Plug.Upload{} <- banner, - {:ok, object} <- ActivityPub.upload(banner), + {:ok, object} <- ActivityPub.upload(banner, banner_upload_limit), new_info <- Map.put(user.info, "banner", object.data), change <- User.info_changeset(user, %{info: new_info}), {:ok, user} <- User.update_and_set_cache(change) do -- cgit v1.2.3 From 784b3a615d57e7b77b1ec2cafe27ae59281cbc6b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 17:26:15 +0000 Subject: utils: fix another possible leak with private S3 backends using mediaproxy same rationale as the other mediaproxy changes --- lib/pleroma/web/common_api/utils.ex | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 4cbbd0c7d..ed1fe1ad9 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -2,6 +2,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do alias Pleroma.{Repo, Object, Formatter, Activity} alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.Endpoint + alias Pleroma.Web.MediaProxy alias Pleroma.User alias Calendar.Strftime alias Comeonin.Pbkdf2 @@ -90,6 +91,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do Enum.map(attachments, fn %{"url" => [%{"href" => href} | _]} -> name = URI.decode(Path.basename(href)) + href = MediaProxy.url(href) "#{shortname(name)}" _ -> -- cgit v1.2.3 From f407831120318dcd8fa5b31f39137cdb1ee87519 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 17:59:24 +0000 Subject: common api: prefer formatting attachments using the attachment's name instead of URI --- lib/pleroma/web/common_api/utils.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index ed1fe1ad9..2a5a2cc15 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -89,8 +89,8 @@ defmodule Pleroma.Web.CommonAPI.Utils do def add_attachments(text, attachments) do attachment_text = Enum.map(attachments, fn - %{"url" => [%{"href" => href} | _]} -> - name = URI.decode(Path.basename(href)) + %{"url" => [%{"href" => href} | _]} = attachment -> + name = attachment["name"] || URI.decode(Path.basename(href)) href = MediaProxy.url(href) "#{shortname(name)}" -- cgit v1.2.3 From 36825932eb04d9db3e2d24b02368d7dd709dea23 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 18:00:59 +0000 Subject: s3 uploader: add new feature to force public attachment URIs to go through media proxy --- lib/pleroma/uploaders/s3.ex | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/uploaders/s3.ex b/lib/pleroma/uploaders/s3.ex index 87322753d..40a836460 100644 --- a/lib/pleroma/uploaders/s3.ex +++ b/lib/pleroma/uploaders/s3.ex @@ -1,10 +1,13 @@ defmodule Pleroma.Uploaders.S3 do + alias Pleroma.Web.MediaProxy + @behaviour Pleroma.Uploaders.Uploader def put_file(name, uuid, path, content_type, _should_dedupe) do settings = Application.get_env(:pleroma, Pleroma.Uploaders.S3) bucket = Keyword.fetch!(settings, :bucket) public_endpoint = Keyword.fetch!(settings, :public_endpoint) + force_media_proxy = Keyword.fetch!(settings, :force_media_proxy) {:ok, file_data} = File.read(path) @@ -19,7 +22,16 @@ defmodule Pleroma.Uploaders.S3 do ]) |> ExAws.request() - {:ok, "#{public_endpoint}/#{bucket}/#{s3_name}"} + url_base = "#{public_endpoint}/#{bucket}/#{s3_name}" + + public_url = + if force_media_proxy do + MediaProxy.url(url_base) + else + url_base + end + + {:ok, public_url} end defp encode(name) do -- cgit v1.2.3 From 676c97b8c7c79c6f96fce1366fc79c73a251ec4f Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 29 Oct 2018 20:07:52 +0000 Subject: nodeinfo: expose configured upload limits --- lib/pleroma/web/nodeinfo/nodeinfo_controller.ex | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 59b0ce3e1..5446179cb 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -113,6 +113,12 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do staffAccounts: staff_accounts, federation: federation_response, postFormats: Keyword.get(instance, :allowed_post_formats), + uploadLimits: %{ + general: Keyword.get(instance, :upload_limit), + avatar: Keyword.get(instance, :avatar_upload_limit), + banner: Keyword.get(instance, :banner_upload_limit), + background: Keyword.get(instance, :background_upload_limit) + }, features: features } } -- cgit v1.2.3 From b92e38d2d4c05da19b00162d7ca35f1905b44a80 Mon Sep 17 00:00:00 2001 From: scarlett Date: Mon, 29 Oct 2018 23:08:56 +0000 Subject: Add user reactivation task. --- lib/mix/tasks/deactivate_user.ex | 2 +- lib/mix/tasks/reactivate_user.ex | 13 +++++++++++++ lib/pleroma/user.ex | 4 ++-- lib/pleroma/web/activity_pub/activity_pub.ex | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 lib/mix/tasks/reactivate_user.ex (limited to 'lib') diff --git a/lib/mix/tasks/deactivate_user.ex b/lib/mix/tasks/deactivate_user.ex index 96b3db6e4..f18541787 100644 --- a/lib/mix/tasks/deactivate_user.ex +++ b/lib/mix/tasks/deactivate_user.ex @@ -2,7 +2,7 @@ defmodule Mix.Tasks.DeactivateUser do use Mix.Task alias Pleroma.User - @shortdoc "Toggle deactivation status for a user" + @shortdoc "Deactivate a user" def run([nickname]) do Mix.Task.run("app.start") diff --git a/lib/mix/tasks/reactivate_user.ex b/lib/mix/tasks/reactivate_user.ex new file mode 100644 index 000000000..40bd068ea --- /dev/null +++ b/lib/mix/tasks/reactivate_user.ex @@ -0,0 +1,13 @@ +defmodule Mix.Tasks.ReactivateUser do + use Mix.Task + alias Pleroma.User + + @shortdoc "Reactivate a user" + def run([nickname]) do + Mix.Task.run("app.start") + + with user <- User.get_by_nickname(nickname) do + User.deactivate(user, false) + end + end +end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 0c9fa559a..bb5b91c61 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -622,8 +622,8 @@ defmodule Pleroma.User do ) end - def deactivate(%User{} = user) do - new_info = Map.put(user.info, "deactivated", true) + def deactivate(%User{} = user, status \\ true) do + new_info = Map.put(user.info, "deactivated", status) cs = User.info_changeset(user, %{info: new_info}) update_and_set_cache(cs) end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 537b99f31..5a81f6fa2 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -44,7 +44,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp check_actor_is_active(actor) do if not is_nil(actor) do with user <- User.get_cached_by_ap_id(actor), - nil <- user.info["deactivated"] do + false <- !!user.info["deactivated"] do :ok else _e -> :reject -- cgit v1.2.3 From 795634c90f2cabbf366b9caf8fa6efd2870c1cb6 Mon Sep 17 00:00:00 2001 From: scarlett Date: Tue, 30 Oct 2018 21:40:06 +0000 Subject: Allow use of the `abbr` HTML tag. --- lib/pleroma/html.ex | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index a7338eac3..00b26963d 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -91,6 +91,8 @@ defmodule Pleroma.HTML.Scrubber.Default do Meta.allow_tag_with_uri_attributes("a", ["href"], @valid_schemes) Meta.allow_tag_with_these_attributes("a", ["name", "title"]) + Meta.allow_tag_with_these_attributes("abbr", ["title"]) + Meta.allow_tag_with_these_attributes("b", []) Meta.allow_tag_with_these_attributes("blockquote", []) Meta.allow_tag_with_these_attributes("br", []) -- cgit v1.2.3 From 47f76bf4b1ad314eb139ba4e79dc37732324ad36 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Wed, 31 Oct 2018 22:29:49 +0000 Subject: common api: allow self-liking objects mastodon allows this, for whatever reason. closes #347. --- lib/pleroma/web/common_api/common_api.ex | 2 -- 1 file changed, 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 f8fef219f..8f47bb127 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -36,7 +36,6 @@ defmodule Pleroma.Web.CommonAPI do def favorite(id_or_ap_id, user) do with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), - false <- activity.data["actor"] == user.ap_id, object <- Object.normalize(activity.data["object"]["id"]) do ActivityPub.like(user, object) else @@ -47,7 +46,6 @@ defmodule Pleroma.Web.CommonAPI do def unfavorite(id_or_ap_id, user) do with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), - false <- activity.data["actor"] == user.ap_id, object <- Object.normalize(activity.data["object"]["id"]) do ActivityPub.unlike(user, object) else -- cgit v1.2.3 From 558e6a84d6750cc245e6656ab12e9e8bbb4f256c Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 1 Nov 2018 06:52:01 +0100 Subject: =?UTF-8?q?[Pleroma.Web.CommonAPI]:=20Delete=20post=20cache=20entr?= =?UTF-8?q?y=20when=20it=E2=80=99s=20deleted?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes: https://git.pleroma.social/pleroma/pleroma/issues/346 --- lib/pleroma/web/common_api/common_api.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 8f47bb127..8607cb6b3 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -9,7 +9,8 @@ defmodule Pleroma.Web.CommonAPI do with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id), %Object{} = object <- Object.normalize(object_id), true <- user.info["is_moderator"] || user.ap_id == object.data["actor"], - {:ok, delete} <- ActivityPub.delete(object) do + {:ok, delete} <- ActivityPub.delete(object), + {:ok, true} <- Cachex.del(:user_cache, "object:#{object_id}") do {:ok, delete} end end -- cgit v1.2.3 From c4e43da63e03f66fd2feaa192c4d8192bbc3451c Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 07:28:48 +0000 Subject: object: add safe object deletion function --- lib/pleroma/object.ex | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 1bcff5a7b..8f96fd8fb 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} + alias Pleroma.{Repo, Object, Activity} import Ecto.{Query, Changeset} schema "objects" do @@ -52,4 +52,12 @@ defmodule Pleroma.Object do def context_mapping(context) do Object.change(%Object{}, %{data: %{"id" => context}}) 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)), + {:ok, true} <- Cachex.del(:user_cache, "object:#{id}") do + :ok + end + end end -- cgit v1.2.3 From 2bf358d7b47f3c2dda91b0ac638b6a068fb40a4c Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 07:29:12 +0000 Subject: activitypub: use Object.delete() instead of mutating the database and cache directly --- lib/pleroma/web/activity_pub/activity_pub.ex | 3 +-- lib/pleroma/web/common_api/common_api.ex | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 5a81f6fa2..48ae36ebd 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -273,8 +273,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do "to" => [user.follower_address, "https://www.w3.org/ns/activitystreams#Public"] } - with Repo.delete(object), - Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)), + with Object.delete(object), {:ok, activity} <- insert(data, local), :ok <- maybe_federate(activity), {:ok, _actor} <- User.decrease_note_count(user) do diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 8607cb6b3..8f47bb127 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -9,8 +9,7 @@ defmodule Pleroma.Web.CommonAPI do with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id), %Object{} = object <- Object.normalize(object_id), true <- user.info["is_moderator"] || user.ap_id == object.data["actor"], - {:ok, delete} <- ActivityPub.delete(object), - {:ok, true} <- Cachex.del(:user_cache, "object:#{object_id}") do + {:ok, delete} <- ActivityPub.delete(object) do {:ok, delete} end end -- cgit v1.2.3 From 10f3958468e24ba49178a19435b189a6be0dabfb Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 07:47:50 +0000 Subject: object: return the deleted object as well --- lib/pleroma/object.ex | 2 +- lib/pleroma/web/activity_pub/activity_pub.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 8f96fd8fb..fddf38450 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -57,7 +57,7 @@ defmodule Pleroma.Object do with Repo.delete(object), Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)), {:ok, true} <- Cachex.del(:user_cache, "object:#{id}") do - :ok + {:ok, object} end end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 48ae36ebd..32c14995f 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -273,7 +273,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do "to" => [user.follower_address, "https://www.w3.org/ns/activitystreams#Public"] } - with Object.delete(object), + with {:ok, _} <- Object.delete(object), {:ok, activity} <- insert(data, local), :ok <- maybe_federate(activity), {:ok, _actor} <- User.decrease_note_count(user) do -- cgit v1.2.3 From 2c3bfd7f76c2154ada70f1167023752e06ee595f Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 07:52:58 +0000 Subject: user: delete user_info data in User.invalidate_cache() --- 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 bb5b91c61..f724f8a5b 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -295,6 +295,7 @@ defmodule Pleroma.User do def invalidate_cache(user) do Cachex.del(:user_cache, "ap_id:#{user.ap_id}") Cachex.del(:user_cache, "nickname:#{user.nickname}") + Cachex.del(:user_cache, "user_info:#{user.id}") end def get_cached_by_ap_id(ap_id) do -- cgit v1.2.3 From f584a603f95f95c7c8d2c1897b24b5c7399f4f74 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 07:56:21 +0000 Subject: user: make User.delete() return data consistent with Object.delete() --- lib/mix/tasks/rm_user.ex | 2 +- lib/pleroma/user.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/rm_user.ex b/lib/mix/tasks/rm_user.ex index 27521b745..b7c922d6c 100644 --- a/lib/mix/tasks/rm_user.ex +++ b/lib/mix/tasks/rm_user.ex @@ -7,7 +7,7 @@ defmodule Mix.Tasks.RmUser do Mix.Task.run("app.start") with %User{local: true} = user <- User.get_by_nickname(nickname) do - User.delete(user) + {:ok, _} = User.delete(user) end end end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index f724f8a5b..b2f59ab6b 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -657,7 +657,7 @@ defmodule Pleroma.User do end end) - :ok + {:ok, user} end def html_filter_policy(%User{info: %{"no_rich_text" => true}}) do -- cgit v1.2.3 From 2b3a40d0383f2ea79c1704c7700ff4d3e5f3c17a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 08:30:10 +0000 Subject: object: split object_cache from user_cache --- lib/pleroma/application.ex | 30 +++++++++++++++++++++++------- lib/pleroma/object.ex | 4 ++-- 2 files changed, 25 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index a89728471..a6b921b45 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -16,14 +16,30 @@ defmodule Pleroma.Application do supervisor(Pleroma.Web.Endpoint, []), # Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3) # worker(Pleroma.Worker, [arg1, arg2, arg3]), - worker(Cachex, [ - :user_cache, + worker( + Cachex, [ - default_ttl: 25000, - ttl_interval: 1000, - limit: 2500 - ] - ]), + :user_cache, + [ + default_ttl: 25000, + ttl_interval: 1000, + limit: 2500 + ] + ], + id: :cachex_user + ), + worker( + Cachex, + [ + :object_cache, + [ + default_ttl: 25000, + ttl_interval: 1000, + limit: 2500 + ] + ], + id: :cachex_object + ), worker( Cachex, [ diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index fddf38450..067ecfaf4 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -37,7 +37,7 @@ defmodule Pleroma.Object do else key = "object:#{ap_id}" - Cachex.fetch!(:user_cache, key, fn _ -> + Cachex.fetch!(:object_cache, key, fn _ -> object = get_by_ap_id(ap_id) if object do @@ -56,7 +56,7 @@ defmodule Pleroma.Object do 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)), - {:ok, true} <- Cachex.del(:user_cache, "object:#{id}") do + {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do {:ok, object} end end -- cgit v1.2.3 From 755f166406afbe7def824139fb52d1bc442165b2 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 1 Nov 2018 09:55:38 +0100 Subject: =?UTF-8?q?Pleroma.Web.MastodonAPI.StatusView:=20Do=20not=20fail?= =?UTF-8?q?=20when=20URL=20isn=E2=80=99t=20a=20string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/web/mastodon_api/views/status_view.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 80e80c8f5..1efd99470 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -240,7 +240,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do summary = object["name"] content = - if !!summary and summary != "" do + if !!summary and summary != "" and is_bitstring(object["url"]) do "

#{summary}

#{object["content"]}" else object["content"] -- cgit v1.2.3 From b2da5262eacf65b1f5fcb6c4f9e31561df1884dd Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 1 Nov 2018 09:56:37 +0100 Subject: Pleroma.Web.ActivityPub.Transmogrifier: fix_url when not a string/empty Thanks prismo.news, I hate it --- lib/pleroma/web/activity_pub/transmogrifier.ex | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index cbc800ad6..56918342c 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -57,6 +57,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do object |> fix_actor |> fix_attachments + |> fix_url |> fix_context |> fix_in_reply_to |> fix_emoji @@ -171,6 +172,27 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def fix_attachments(object), do: object + def fix_url(%{"url" => url} = object) when is_map(url) do + object + |> Map.put("url", url["href"]) + end + + def fix_url(%{"url" => url} = object) when is_list(url) do + first_element = Enum.at(url, 0) + + url_string = + cond do + is_bitstring(first_element) -> first_element + is_map(first_element) -> first_element["href"] || "" + true -> "" + end + + object + |> Map.put("url", url_string) + end + + def fix_url(object), do: object + def fix_emoji(%{"tag" => tags} = object) when is_list(tags) do emoji = tags |> Enum.filter(fn data -> data["type"] == "Emoji" and data["icon"] end) -- cgit v1.2.3 From 9b77030d3ca9530fbea05aeb2191915bb1c454cb Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 8 Sep 2018 14:01:00 +0200 Subject: Add basic configuration management module. --- lib/pleroma/config.ex | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 lib/pleroma/config.ex (limited to 'lib') diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex new file mode 100644 index 000000000..510d8d498 --- /dev/null +++ b/lib/pleroma/config.ex @@ -0,0 +1,15 @@ +defmodule Pleroma.Config do + use Agent + + def start_link(initial) do + Agent.start_link(fn -> initial end, name: __MODULE__) + end + + def get(path) do + Agent.get(__MODULE__, Kernel, :get_in, [path]) + end + + def put(path, value) do + Agent.update(__MODULE__, Kernel, :put_in, [path, value]) + end +end -- cgit v1.2.3 From e6ec01afb648cb99e5fc4db3a64fe1ed74fd0105 Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 8 Sep 2018 14:01:16 +0200 Subject: Start configuration manager. --- lib/pleroma/application.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index a6b921b45..f30fcd1e4 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -10,6 +10,7 @@ defmodule Pleroma.Application do # Define workers and child supervisors to be supervised children = [ + worker(Pleroma.Config, [Application.get_all_env(:pleroma)]), # Start the Ecto repository supervisor(Pleroma.Repo, []), # Start the endpoint when the application starts -- cgit v1.2.3 From 1e9ced5af478ba38c9e9d46140891a8f4473e02d Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 8 Sep 2018 14:02:38 +0200 Subject: Test Relay, switch to runtime configuration. --- lib/pleroma/web/activity_pub/activity_pub_controller.ex | 14 ++++++++++++++ lib/pleroma/web/federator/federator.ex | 5 +++-- lib/pleroma/web/router.ex | 9 +++------ 3 files changed, 20 insertions(+), 8 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 a7b1c0079..531e98237 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -6,11 +6,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.Federator + alias Pleroma.Config require Logger action_fallback(:errors) + plug(:relay_active? when action in [:relay]) + + def relay_active?(conn, _) do + if Config.get([:instance, :allow_relay]) do + conn + else + conn + |> put_status(404) + |> json(%{error: "not found"}) + |> halt + end + end + def user(conn, %{"nickname" => nickname}) do with %User{} = user <- User.get_cached_by_nickname(nickname), {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index 078f3ec11..9ea2507a1 100644 --- a/lib/pleroma/web/federator/federator.ex +++ b/lib/pleroma/web/federator/federator.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.Federator do alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Config require Logger @websub Application.get_env(:pleroma, :websub) @@ -71,9 +72,9 @@ defmodule Pleroma.Web.Federator do Logger.info(fn -> "Sending #{activity.data["id"]} out via Salmon" end) Pleroma.Web.Salmon.publish(actor, activity) - if Mix.env() != :test do + if Config.get([:instance, :allow_relay]) do Logger.info(fn -> "Relaying #{activity.data["id"]} out" end) - Pleroma.Web.ActivityPub.Relay.publish(activity) + Relay.publish(activity) end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index b531b6188..7b7affe5e 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -5,7 +5,6 @@ defmodule Pleroma.Web.Router do @instance Application.get_env(:pleroma, :instance) @federating Keyword.get(@instance, :federating) - @allow_relay Keyword.get(@instance, :allow_relay) @public Keyword.get(@instance, :public) @registrations_open Keyword.get(@instance, :registrations_open) @@ -354,11 +353,9 @@ defmodule Pleroma.Web.Router do end if @federating do - if @allow_relay do - scope "/relay", Pleroma.Web.ActivityPub do - pipe_through(:ap_relay) - get("/", ActivityPubController, :relay) - end + scope "/relay", Pleroma.Web.ActivityPub do + pipe_through(:ap_relay) + get("/", ActivityPubController, :relay) end scope "/", Pleroma.Web.ActivityPub do -- cgit v1.2.3 From 585b29337ce66eb2c574e71588db542044574609 Mon Sep 17 00:00:00 2001 From: Lee Starnes Date: Fri, 12 Oct 2018 00:19:43 -0500 Subject: Ensure filters have a filter_id --- lib/pleroma/filter.ex | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/filter.ex b/lib/pleroma/filter.ex index fe904df3a..25ed38f34 100644 --- a/lib/pleroma/filter.ex +++ b/lib/pleroma/filter.ex @@ -36,6 +36,34 @@ defmodule Pleroma.Filter do Repo.all(query) end + def create(%Pleroma.Filter{user_id: user_id, filter_id: nil} = filter) do + # If filter_id wasn't given, use the max filter_id for this user plus 1. + # XXX This could result in a race condition if a user tries to add two + # different filters for their account from two different clients at the + # same time, but that should be unlikely. + + max_id_query = + from( + f in Pleroma.Filter, + where: f.user_id == ^user_id, + select: max(f.filter_id) + ) + + filter_id = + case Repo.one(max_id_query) do + # Start allocating from 1 + nil -> + 1 + + max_id -> + max_id + 1 + end + + filter + |> Map.put(:filter_id, filter_id) + |> Repo.insert() + end + def create(%Pleroma.Filter{} = filter) do Repo.insert(filter) end -- cgit v1.2.3 From 9f03b5c4f773d0ee969a100c30bd6c1a885bebc5 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 09:40:47 +0000 Subject: activitypub: transmogrifier: add support for Page objects --- lib/pleroma/web/activity_pub/transmogrifier.ex | 2 +- lib/pleroma/web/activity_pub/utils.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 56918342c..5bc151b97 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -263,7 +263,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do # - tags # - emoji def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = object} = data) - when objtype in ["Article", "Note", "Video"] do + when objtype in ["Article", "Note", "Video", "Page"] do actor = get_actor(data) data = diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d6ac2dd8c..3362d9325 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -175,7 +175,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do Inserts a full object if it is contained in an activity. """ def insert_full_object(%{"object" => %{"type" => type} = object_data}) - when is_map(object_data) and type in ["Article", "Note", "Video"] do + when is_map(object_data) and type in ["Article", "Note", "Video", "Page"] do with {:ok, _} <- Object.create(object_data) do :ok end -- cgit v1.2.3 From 4d8f0761258e0ea7cfca2f4f93b47e55bb657c66 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 10:00:16 +0000 Subject: mastodon api: add support for rendering Page objects --- lib/pleroma/web/mastodon_api/views/status_view.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 1efd99470..27fe23594 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -236,7 +236,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do content end - def render_content(%{"type" => "Article"} = object) do + def render_content(%{"type" => object_type} = object) when object_type in ["Article", "Page"] do summary = object["name"] content = -- cgit v1.2.3 From 24ba08de13ef8c0cb4330a613758d006453dfec3 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 1 Nov 2018 10:01:35 +0000 Subject: twitter api: add support for rendering Page objects --- lib/pleroma/web/twitter_api/views/activity_view.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index fb97f199b..8e8b3f5ed 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -283,7 +283,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do {summary, content} end - def render_content(%{"type" => "Article"} = object) do + def render_content(%{"type" => object_type} = object) when object_type in ["Article", "Page"] do summary = object["name"] || object["summary"] content = -- cgit v1.2.3 From 3c7d4ff27100420f69e68fb256a2181a1a35a4a7 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 1 Nov 2018 15:07:27 +0100 Subject: Pleroma.Web.TwitterAPI.ActivityView: Harden TwitterAPI against remnant of prismo --- lib/pleroma/web/twitter_api/views/activity_view.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index 8e8b3f5ed..83e8fb765 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -287,7 +287,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do summary = object["name"] || object["summary"] content = - if !!summary and summary != "" do + if !!summary and summary != "" and is_bitstring(object["url"]) do "

#{summary}

#{object["content"]}" else object["content"] -- cgit v1.2.3 From 45ebc8dd9a27ae862aad1c8251a71b95a2c3be17 Mon Sep 17 00:00:00 2001 From: lain Date: Fri, 2 Nov 2018 17:33:51 +0100 Subject: Check for empty string in_reply_to ids. --- lib/pleroma/web/common_api/utils.ex | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 2a5a2cc15..b22c4cc03 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -19,6 +19,8 @@ defmodule Pleroma.Web.CommonAPI.Utils do end end + def get_replied_to_activity(""), do: nil + def get_replied_to_activity(id) when not is_nil(id) do Repo.get(Activity, id) end -- cgit v1.2.3 From 0cca7edbe065b2b1aa5f81bad72025f73cae5cf8 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Fri, 2 Nov 2018 19:38:57 +0000 Subject: Fix hashtag search When we lowercase the search it will succesfully do a case insenstive match. Now #Linux will match #linux and #LINUX whereas previously it would only match the exact case. --- lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index e03027be7..f6cf081fd 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -508,6 +508,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> Map.put("type", "Create") |> Map.put("local_only", local_only) |> Map.put("blocking_user", user) + |> Map.put("tag", String.downcase(params["tag"])) activities = ActivityPub.fetch_public_activities(params) -- cgit v1.2.3 From e954cfcc2c9e9b36bf31dc0bdbc90b1f8a2d47ce Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 3 Nov 2018 13:38:01 +0100 Subject: Add CORSPlug to make web-based OAuth easier. --- lib/pleroma/web/endpoint.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 955bd61f3..6673ab576 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -56,6 +56,7 @@ defmodule Pleroma.Web.Endpoint do extra: "SameSite=Strict" ) + plug(CORSPlug) plug(Pleroma.Web.Router) @doc """ -- cgit v1.2.3 From 3e50bb667f7b09482a6635634346708e9eab5ce6 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Fri, 2 Nov 2018 15:13:57 +0100 Subject: =?UTF-8?q?Pleroma.Web.MastodonAPI.StatusView:=20Content=20isn?= =?UTF-8?q?=E2=80=99t=20nullable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/web/mastodon_api/views/status_view.ex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 27fe23594..2d9a915f0 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -61,7 +61,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do in_reply_to_id: nil, in_reply_to_account_id: nil, reblog: reblogged, - content: reblogged[:content], + content: reblogged[:content] || "", created_at: created_at, reblogs_count: 0, replies_count: 0, @@ -230,7 +230,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do if !!name and name != "" do "

#{name}

#{object["content"]}" else - object["content"] + object["content"] || "" end content @@ -243,11 +243,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do if !!summary and summary != "" and is_bitstring(object["url"]) do "

#{summary}

#{object["content"]}" else - object["content"] + object["content"] || "" end content end - def render_content(object), do: object["content"] + def render_content(object), do: object["content"] || "" end -- cgit v1.2.3 From 763fc7b44fb5931f1a2f869d4c67a5ca9a0b5206 Mon Sep 17 00:00:00 2001 From: href Date: Mon, 5 Nov 2018 13:24:00 +0100 Subject: Runtime configured emojis The changes are a bit heavy since the emojis were loaded into module attributes from filesystem. This introduces a GenServer using an ETS table to cache in memory the emojis, and allows a runtime-reload with `Pleroma.Emoji.reload()`. --- lib/pleroma/application.ex | 9 +- lib/pleroma/emoji.ex | 193 +++++++++++++++++++++ lib/pleroma/formatter.ex | 126 +------------- .../web/mastodon_api/mastodon_api_controller.ex | 2 +- .../web/twitter_api/controllers/util_controller.ex | 4 +- 5 files changed, 206 insertions(+), 128 deletions(-) create mode 100644 lib/pleroma/emoji.ex (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index f30fcd1e4..607a0144c 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -13,8 +13,7 @@ defmodule Pleroma.Application do worker(Pleroma.Config, [Application.get_all_env(:pleroma)]), # Start the Ecto repository supervisor(Pleroma.Repo, []), - # Start the endpoint when the application starts - supervisor(Pleroma.Web.Endpoint, []), + worker(Pleroma.Emoji, []), # Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3) # worker(Pleroma.Worker, [arg1, arg2, arg3]), worker( @@ -57,8 +56,10 @@ defmodule Pleroma.Application do id: :cachex_idem ), worker(Pleroma.Web.Federator, []), - worker(Pleroma.Gopher.Server, []), - worker(Pleroma.Stats, []) + worker(Pleroma.Stats, []), + # Start the endpoint when the application starts + supervisor(Pleroma.Web.Endpoint, []), + worker(Pleroma.Gopher.Server, []) ] ++ if Mix.env() == :test, do: [], diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex new file mode 100644 index 000000000..cc9713b53 --- /dev/null +++ b/lib/pleroma/emoji.ex @@ -0,0 +1,193 @@ +defmodule Pleroma.Emoji do + @moduledoc """ + The emojis are loaded from: + + * the built-in Finmojis (if enabled in configuration), + * the files: `config/emoji.txt` and `config/custom_emoji.txt` + * glob paths + + This GenServer stores in an ETS table the list of the loaded emojis, and also allows to reload the list at runtime. + """ + use GenServer + @ets __MODULE__.Ets + @ets_options [:set, :protected, :named_table, {:read_concurrency, true}] + + @doc false + def start_link() do + GenServer.start_link(__MODULE__, [], name: __MODULE__) + end + + @doc "Reloads the emojis from disk." + @spec reload() :: :ok + def reload() do + GenServer.call(__MODULE__, :reload) + end + + @doc "Returns the path of the emoji `name`." + @spec get(String.t()) :: String.t() | nil + def get(name) do + case :ets.lookup(@ets, name) do + [{_, path}] -> path + _ -> nil + end + end + + @doc "Returns all the emojos!!" + @spec get_all() :: [{String.t(), String.t()}, ...] + def get_all() do + :ets.tab2list(@ets) + end + + @doc false + def init(_) do + @ets = :ets.new(@ets, @ets_options) + {:ok, nil, {:continue, :reload}} + end + + @doc false + def handle_continue(:reload, state) do + load() + {:noreply, state} + end + + @doc false + def handle_call(:reload, _from, state) do + load() + {:reply, :ok, state} + end + + @doc false + def terminate(_, _) do + :ok + end + + @doc false + def code_change(_old_vsn, state, _extra) do + load() + {:ok, state} + end + + defp load() do + emojis = + (load_finmoji(Keyword.get(Application.get_env(:pleroma, :instance), :finmoji_enabled)) ++ + load_from_file("config/emoji.txt") ++ + load_from_file("config/custom_emoji.txt") ++ + load_from_globs( + Keyword.get(Application.get_env(:pleroma, :emoji, []), :shortcode_globs, []) + )) + |> Enum.reject(fn value -> value == nil end) + + true = :ets.insert(@ets, emojis) + :ok + end + + @finmoji [ + "a_trusted_friend", + "alandislands", + "association", + "auroraborealis", + "baby_in_a_box", + "bear", + "black_gold", + "christmasparty", + "crosscountryskiing", + "cupofcoffee", + "education", + "fashionista_finns", + "finnishlove", + "flag", + "forest", + "four_seasons_of_bbq", + "girlpower", + "handshake", + "happiness", + "headbanger", + "icebreaker", + "iceman", + "joulutorttu", + "kaamos", + "kalsarikannit_f", + "kalsarikannit_m", + "karjalanpiirakka", + "kicksled", + "kokko", + "lavatanssit", + "losthopes_f", + "losthopes_m", + "mattinykanen", + "meanwhileinfinland", + "moominmamma", + "nordicfamily", + "out_of_office", + "peacemaker", + "perkele", + "pesapallo", + "polarbear", + "pusa_hispida_saimensis", + "reindeer", + "sami", + "sauna_f", + "sauna_m", + "sauna_whisk", + "sisu", + "stuck", + "suomimainittu", + "superfood", + "swan", + "the_cap", + "the_conductor", + "the_king", + "the_voice", + "theoriginalsanta", + "tomoffinland", + "torillatavataan", + "unbreakable", + "waiting", + "white_nights", + "woollysocks" + ] + defp load_finmoji(true) do + Enum.map(@finmoji, fn finmoji -> + {finmoji, "/finmoji/128px/#{finmoji}-128.png"} + end) + end + + defp load_finmoji(_), do: :ok + + defp load_from_file(file) do + if File.exists?(file) do + load_from_file_stream(File.stream!(file)) + else + [] + end + end + + defp load_from_file_stream(stream) do + stream + |> Stream.map(&String.strip/1) + |> Stream.map(fn line -> + case String.split(line, ~r/,\s*/) do + [name, file] -> {name, file} + _ -> nil + end + end) + |> Enum.to_list() + end + + defp load_from_globs(globs) do + static_path = Path.join(:code.priv_dir(:pleroma), "static") + + paths = + Enum.map(globs, fn glob -> + Path.join(static_path, glob) + |> Path.wildcard() + end) + |> Enum.concat() + + Enum.map(paths, fn path -> + shortcode = Path.basename(path, Path.extname(path)) + external_path = Path.join("/", Path.relative_to(path, static_path)) + {shortcode, external_path} + end) + end +end diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index ecc102b62..dd971df9b 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -2,6 +2,7 @@ defmodule Pleroma.Formatter do alias Pleroma.User alias Pleroma.Web.MediaProxy alias Pleroma.HTML + alias Pleroma.Emoji @tag_regex ~r/\#\w+/u def parse_tags(text, data \\ %{}) do @@ -28,125 +29,12 @@ defmodule Pleroma.Formatter do |> Enum.filter(fn {_match, user} -> user end) end - @finmoji [ - "a_trusted_friend", - "alandislands", - "association", - "auroraborealis", - "baby_in_a_box", - "bear", - "black_gold", - "christmasparty", - "crosscountryskiing", - "cupofcoffee", - "education", - "fashionista_finns", - "finnishlove", - "flag", - "forest", - "four_seasons_of_bbq", - "girlpower", - "handshake", - "happiness", - "headbanger", - "icebreaker", - "iceman", - "joulutorttu", - "kaamos", - "kalsarikannit_f", - "kalsarikannit_m", - "karjalanpiirakka", - "kicksled", - "kokko", - "lavatanssit", - "losthopes_f", - "losthopes_m", - "mattinykanen", - "meanwhileinfinland", - "moominmamma", - "nordicfamily", - "out_of_office", - "peacemaker", - "perkele", - "pesapallo", - "polarbear", - "pusa_hispida_saimensis", - "reindeer", - "sami", - "sauna_f", - "sauna_m", - "sauna_whisk", - "sisu", - "stuck", - "suomimainittu", - "superfood", - "swan", - "the_cap", - "the_conductor", - "the_king", - "the_voice", - "theoriginalsanta", - "tomoffinland", - "torillatavataan", - "unbreakable", - "waiting", - "white_nights", - "woollysocks" - ] - @instance Application.get_env(:pleroma, :instance) - @finmoji_with_filenames (if Keyword.get(@instance, :finmoji_enabled) do - Enum.map(@finmoji, fn finmoji -> - {finmoji, "/finmoji/128px/#{finmoji}-128.png"} - end) - else - [] - end) - - @emoji_from_file (with {:ok, default} <- File.read("config/emoji.txt") do - custom = - with {:ok, custom} <- File.read("config/custom_emoji.txt") do - custom - else - _e -> "" - end - - (default <> "\n" <> custom) - |> String.trim() - |> String.split(~r/\n+/) - |> Enum.map(fn line -> - [name, file] = String.split(line, ~r/,\s*/) - {name, file} - end) - else - _ -> [] - end) - - @emoji_from_globs ( - static_path = Path.join(:code.priv_dir(:pleroma), "static") - - globs = - Application.get_env(:pleroma, :emoji, []) - |> Keyword.get(:shortcode_globs, []) - - paths = - Enum.map(globs, fn glob -> - Path.join(static_path, glob) - |> Path.wildcard() - end) - |> Enum.concat() - - Enum.map(paths, fn path -> - shortcode = Path.basename(path, Path.extname(path)) - external_path = Path.join("/", Path.relative_to(path, static_path)) - {shortcode, external_path} - end) - ) - - @emoji @finmoji_with_filenames ++ @emoji_from_globs ++ @emoji_from_file + def emojify(text) do + emojify(text, Emoji.get_all()) + end - def emojify(text, emoji \\ @emoji) def emojify(text, nil), do: text def emojify(text, emoji) do @@ -166,15 +54,11 @@ defmodule Pleroma.Formatter do end def get_emoji(text) when is_binary(text) do - Enum.filter(@emoji, fn {emoji, _} -> String.contains?(text, ":#{emoji}:") end) + Enum.filter(Emoji.get_all(), fn {emoji, _} -> String.contains?(text, ":#{emoji}:") end) end def get_emoji(_), do: [] - def get_custom_emoji() do - @emoji - end - @link_regex ~r/[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+/ui @uri_schemes Application.get_env(:pleroma, :uri_schemes, []) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index f6cf081fd..e92114f57 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -158,7 +158,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end defp mastodonized_emoji do - Pleroma.Formatter.get_custom_emoji() + Pleroma.Emoji.get_all() |> Enum.map(fn {shortcode, relative_url} -> url = to_string(URI.merge(Web.base_url(), relative_url)) diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 01cd17121..e84438e97 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -6,7 +6,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do alias Pleroma.Web.WebFinger alias Pleroma.Web.CommonAPI alias Comeonin.Pbkdf2 - alias Pleroma.Formatter + alias Pleroma.{Formatter, Emoji} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.{Repo, PasswordResetToken, User} @@ -212,7 +212,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end def emoji(conn, _params) do - json(conn, Enum.into(Formatter.get_custom_emoji(), %{})) + json(conn, Enum.into(Emoji.get_all(), %{})) end def follow_import(conn, %{"list" => %Plug.Upload{} = listfile}) do -- cgit v1.2.3 From d096bc17bf75b756f6c95250660c940419d01f41 Mon Sep 17 00:00:00 2001 From: href Date: Mon, 5 Nov 2018 14:05:04 +0100 Subject: revert endpoint position in supervision tree --- lib/pleroma/application.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 607a0144c..d4bc8f63d 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -14,6 +14,8 @@ defmodule Pleroma.Application do # Start the Ecto repository supervisor(Pleroma.Repo, []), worker(Pleroma.Emoji, []), + # Start the endpoint when the application starts + supervisor(Pleroma.Web.Endpoint, []), # Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3) # worker(Pleroma.Worker, [arg1, arg2, arg3]), worker( @@ -57,8 +59,6 @@ defmodule Pleroma.Application do ), worker(Pleroma.Web.Federator, []), worker(Pleroma.Stats, []), - # Start the endpoint when the application starts - supervisor(Pleroma.Web.Endpoint, []), worker(Pleroma.Gopher.Server, []) ] ++ if Mix.env() == :test, -- cgit v1.2.3 From 6fe23c54581437fbaa42d880b57b3464bb439ce4 Mon Sep 17 00:00:00 2001 From: href Date: Mon, 5 Nov 2018 15:19:03 +0100 Subject: Runtime configured router --- lib/pleroma/plugs/federating_plug.ex | 18 +++++++ .../web/activity_pub/activity_pub_controller.ex | 1 + lib/pleroma/web/nodeinfo/nodeinfo_controller.ex | 2 + lib/pleroma/web/ostatus/ostatus_controller.ex | 1 + lib/pleroma/web/router.ex | 57 +++++++++------------- .../web/twitter_api/twitter_api_controller.ex | 12 +++++ .../web/web_finger/web_finger_controller.ex | 2 + lib/pleroma/web/websub/websub_controller.ex | 9 ++++ 8 files changed, 67 insertions(+), 35 deletions(-) create mode 100644 lib/pleroma/plugs/federating_plug.ex (limited to 'lib') diff --git a/lib/pleroma/plugs/federating_plug.ex b/lib/pleroma/plugs/federating_plug.ex new file mode 100644 index 000000000..4108d90af --- /dev/null +++ b/lib/pleroma/plugs/federating_plug.ex @@ -0,0 +1,18 @@ +defmodule Pleroma.Web.FederatingPlug do + import Plug.Conn + + def init(options) do + options + end + + def call(conn, opts) do + if Keyword.get(Application.get_env(:pleroma, :instance), :federating) do + conn + else + conn + |> put_status(404) + |> Phoenix.Controller.render(Pleroma.Web.ErrorView, "404.json") + |> halt() + end + end +end diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 531e98237..99342aad9 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -12,6 +12,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do action_fallback(:errors) + plug(Pleroma.Web.FederatingPlug when action in [:inbox, :relay]) plug(:relay_active? when action in [:relay]) def relay_active?(conn, _) do diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 5446179cb..d58f08881 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -6,6 +6,8 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do alias Pleroma.{User, Repo} alias Pleroma.Web.ActivityPub.MRF + plug(Pleroma.Web.FederatingPlug) + def schemas(conn, _params) do response = %{ links: [ diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex index 09d1b1110..2f92935e7 100644 --- a/lib/pleroma/web/ostatus/ostatus_controller.ex +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -10,6 +10,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do alias Pleroma.Web.ActivityPub.ActivityPubController alias Pleroma.Web.ActivityPub.ActivityPub + plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming]) action_fallback(:errors) def feed_redirect(conn, %{"nickname" => nickname}) do diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 7b7affe5e..b461def82 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -3,11 +3,6 @@ defmodule Pleroma.Web.Router do alias Pleroma.{Repo, User, Web.Router} - @instance Application.get_env(:pleroma, :instance) - @federating Keyword.get(@instance, :federating) - @public Keyword.get(@instance, :public) - @registrations_open Keyword.get(@instance, :registrations_open) - pipeline :api do plug(:accepts, ["json"]) plug(:fetch_session) @@ -242,11 +237,7 @@ defmodule Pleroma.Web.Router do end scope "/api", Pleroma.Web do - if @public do - pipe_through(:api) - else - pipe_through(:authenticated_api) - end + pipe_through(:api) get("/statuses/public_timeline", TwitterAPI.Controller, :public_timeline) @@ -330,12 +321,10 @@ defmodule Pleroma.Web.Router do get("/users/:nickname/feed", OStatus.OStatusController, :feed) get("/users/:nickname", OStatus.OStatusController, :feed_redirect) - if @federating do - post("/users/:nickname/salmon", OStatus.OStatusController, :salmon_incoming) - post("/push/hub/:nickname", Websub.WebsubController, :websub_subscription_request) - get("/push/subscriptions/:id", Websub.WebsubController, :websub_subscription_confirmation) - post("/push/subscriptions/:id", Websub.WebsubController, :websub_incoming) - end + post("/users/:nickname/salmon", OStatus.OStatusController, :salmon_incoming) + post("/push/hub/:nickname", Websub.WebsubController, :websub_subscription_request) + get("/push/subscriptions/:id", Websub.WebsubController, :websub_subscription_confirmation) + post("/push/subscriptions/:id", Websub.WebsubController, :websub_incoming) end pipeline :activitypub do @@ -352,29 +341,27 @@ defmodule Pleroma.Web.Router do get("/users/:nickname/outbox", ActivityPubController, :outbox) end - if @federating do - scope "/relay", Pleroma.Web.ActivityPub do - pipe_through(:ap_relay) - get("/", ActivityPubController, :relay) - end + scope "/relay", Pleroma.Web.ActivityPub do + pipe_through(:ap_relay) + get("/", ActivityPubController, :relay) + end - scope "/", Pleroma.Web.ActivityPub do - pipe_through(:activitypub) - post("/users/:nickname/inbox", ActivityPubController, :inbox) - post("/inbox", ActivityPubController, :inbox) - end + scope "/", Pleroma.Web.ActivityPub do + pipe_through(:activitypub) + post("/users/:nickname/inbox", ActivityPubController, :inbox) + post("/inbox", ActivityPubController, :inbox) + end - scope "/.well-known", Pleroma.Web do - pipe_through(:well_known) + scope "/.well-known", Pleroma.Web do + pipe_through(:well_known) - get("/host-meta", WebFinger.WebFingerController, :host_meta) - get("/webfinger", WebFinger.WebFingerController, :webfinger) - get("/nodeinfo", Nodeinfo.NodeinfoController, :schemas) - end + get("/host-meta", WebFinger.WebFingerController, :host_meta) + get("/webfinger", WebFinger.WebFingerController, :webfinger) + get("/nodeinfo", Nodeinfo.NodeinfoController, :schemas) + end - scope "/nodeinfo", Pleroma.Web do - get("/:version", Nodeinfo.NodeinfoController, :nodeinfo) - end + scope "/nodeinfo", Pleroma.Web do + get("/:version", Nodeinfo.NodeinfoController, :nodeinfo) end scope "/", Pleroma.Web.MastodonAPI do diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 7153a2bd6..3054a8106 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do require Logger + plug(:only_if_public_instance when action in [:public_timeline, :public_and_external_timeline]) action_fallback(:errors) def verify_credentials(%{assigns: %{user: user}} = conn, _params) do @@ -518,6 +519,17 @@ 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(conn, _) do + if Keyword.get(Application.get_env(:pleroma, :instance), :public) do + conn + else + conn + |> forbidden_json_reply("Invalid credentials.") + end + end + defp error_json(conn, error_message) do %{"error" => error_message, "request" => conn.request_path} |> Jason.encode!() end diff --git a/lib/pleroma/web/web_finger/web_finger_controller.ex b/lib/pleroma/web/web_finger/web_finger_controller.ex index 50d816256..002353166 100644 --- a/lib/pleroma/web/web_finger/web_finger_controller.ex +++ b/lib/pleroma/web/web_finger/web_finger_controller.ex @@ -3,6 +3,8 @@ defmodule Pleroma.Web.WebFinger.WebFingerController do alias Pleroma.Web.WebFinger + plug(Pleroma.Web.FederatingPlug) + def host_meta(conn, _params) do xml = WebFinger.host_meta() diff --git a/lib/pleroma/web/websub/websub_controller.ex b/lib/pleroma/web/websub/websub_controller.ex index 590dd74a1..c1934ba92 100644 --- a/lib/pleroma/web/websub/websub_controller.ex +++ b/lib/pleroma/web/websub/websub_controller.ex @@ -5,6 +5,15 @@ defmodule Pleroma.Web.Websub.WebsubController do alias Pleroma.Web.Websub.WebsubClientSubscription require Logger + plug( + Pleroma.Web.FederatingPlug + when action in [ + :websub_subscription_request, + :websub_subscription_confirmation, + :websub_incoming + ] + ) + def websub_subscription_request(conn, %{"nickname" => nickname} = params) do user = User.get_cached_by_nickname(nickname) -- cgit v1.2.3 From fd0e7d18d96fb242088d8c6bb7ea5e1eb7053ce8 Mon Sep 17 00:00:00 2001 From: href Date: Mon, 5 Nov 2018 18:04:43 +0100 Subject: handle_continue is OTP21+ --- lib/pleroma/emoji.ex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex index cc9713b53..7da1a2438 100644 --- a/lib/pleroma/emoji.ex +++ b/lib/pleroma/emoji.ex @@ -41,11 +41,12 @@ defmodule Pleroma.Emoji do @doc false def init(_) do @ets = :ets.new(@ets, @ets_options) - {:ok, nil, {:continue, :reload}} + GenServer.cast(self(), :reload) + {:ok, nil} end @doc false - def handle_continue(:reload, state) do + def handle_cast(:reload, state) do load() {:noreply, state} end -- cgit v1.2.3 From 83911b1443c99d3f8c6784a57d8327a22c05e606 Mon Sep 17 00:00:00 2001 From: href Date: Mon, 5 Nov 2018 21:16:56 +0100 Subject: Fix wrong return when finmoji is disabled --- lib/pleroma/emoji.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex index 7da1a2438..0a5e1d5ce 100644 --- a/lib/pleroma/emoji.ex +++ b/lib/pleroma/emoji.ex @@ -153,7 +153,7 @@ defmodule Pleroma.Emoji do end) end - defp load_finmoji(_), do: :ok + defp load_finmoji(_), do: [] defp load_from_file(file) do if File.exists?(file) do -- cgit v1.2.3 From 013f7ba8c1c4e6519cf30d192e3a41c6c96f8a63 Mon Sep 17 00:00:00 2001 From: href Date: Tue, 6 Nov 2018 14:44:00 +0100 Subject: Add federating plug & public tests --- lib/pleroma/web/twitter_api/twitter_api_controller.ex | 1 + 1 file changed, 1 insertion(+) (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 3054a8106..83d725f13 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -527,6 +527,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do else conn |> forbidden_json_reply("Invalid credentials.") + |> halt() end end -- cgit v1.2.3 From 2bc924ba451b1a324663133632093914192cec2d Mon Sep 17 00:00:00 2001 From: href Date: Tue, 6 Nov 2018 11:34:34 +0100 Subject: Get rid of Pleroma.Config in favor of Application Discussed in https://git.pleroma.social/pleroma/pleroma/merge_requests/426#note_7232 --- lib/pleroma/application.ex | 1 - lib/pleroma/config.ex | 15 --------------- lib/pleroma/web/activity_pub/activity_pub_controller.ex | 3 +-- lib/pleroma/web/federator/federator.ex | 3 +-- 4 files changed, 2 insertions(+), 20 deletions(-) delete mode 100644 lib/pleroma/config.ex (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index d4bc8f63d..eedad7675 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -10,7 +10,6 @@ defmodule Pleroma.Application do # Define workers and child supervisors to be supervised children = [ - worker(Pleroma.Config, [Application.get_all_env(:pleroma)]), # Start the Ecto repository supervisor(Pleroma.Repo, []), worker(Pleroma.Emoji, []), diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex deleted file mode 100644 index 510d8d498..000000000 --- a/lib/pleroma/config.ex +++ /dev/null @@ -1,15 +0,0 @@ -defmodule Pleroma.Config do - use Agent - - def start_link(initial) do - Agent.start_link(fn -> initial end, name: __MODULE__) - end - - def get(path) do - Agent.get(__MODULE__, Kernel, :get_in, [path]) - end - - def put(path, value) do - Agent.update(__MODULE__, Kernel, :put_in, [path, value]) - end -end diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 531e98237..47937beef 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.Federator - alias Pleroma.Config require Logger @@ -15,7 +14,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do plug(:relay_active? when action in [:relay]) def relay_active?(conn, _) do - if Config.get([:instance, :allow_relay]) do + if Keyword.get(Application.get_env(:pleroma, :instance), :allow_relay) do conn else conn diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index 9ea2507a1..01c2c89c3 100644 --- a/lib/pleroma/web/federator/federator.ex +++ b/lib/pleroma/web/federator/federator.ex @@ -7,7 +7,6 @@ defmodule Pleroma.Web.Federator do alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Utils - alias Pleroma.Config require Logger @websub Application.get_env(:pleroma, :websub) @@ -72,7 +71,7 @@ defmodule Pleroma.Web.Federator do Logger.info(fn -> "Sending #{activity.data["id"]} out via Salmon" end) Pleroma.Web.Salmon.publish(actor, activity) - if Config.get([:instance, :allow_relay]) do + if Keyword.get(Application.get_env(:pleroma, :instance), :allow_relay) do Logger.info(fn -> "Relaying #{activity.data["id"]} out" end) Relay.publish(activity) end -- cgit v1.2.3 From 4f640c43edc237f4450cc0d42896b5e0a7b4a324 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 6 Nov 2018 15:19:11 +0100 Subject: Unify Mastodon Login with OAuth login. This removes duplication in the login code. --- .../web/mastodon_api/mastodon_api_controller.ex | 41 ++++++++++-------- lib/pleroma/web/oauth/oauth_controller.ex | 48 +++++++++++++--------- .../templates/mastodon_api/mastodon/login.html.eex | 11 ----- 3 files changed, 52 insertions(+), 48 deletions(-) delete mode 100644 lib/pleroma/web/templates/mastodon_api/mastodon/login.html.eex (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index e92114f57..51a7ec2b2 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -985,9 +985,30 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def login(conn, %{"code" => code}) do + with {:ok, app} <- get_or_make_app(), + %Authorization{} = auth <- Repo.get_by(Authorization, token: code, app_id: app.id), + {:ok, token} <- Token.exchange_token(app, auth) do + + conn + |> put_session(:oauth_token, token.token) + |> redirect(to: "/web/getting-started") + end + end + def login(conn, _) do - conn - |> render(MastodonView, "login.html", %{error: false}) + with {:ok, app} <- get_or_make_app() do + path = + o_auth_path(conn, :authorize, + response_type: "code", + client_id: app.client_id, + redirect_uri: ".", + scope: app.scopes + ) + + conn + |> redirect(to: path) + end end defp get_or_make_app() do @@ -1006,22 +1027,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - def login_post(conn, %{"authorization" => %{"name" => name, "password" => password}}) do - with %User{} = user <- User.get_by_nickname_or_email(name), - true <- Pbkdf2.checkpw(password, user.password_hash), - {:ok, app} <- get_or_make_app(), - {:ok, auth} <- Authorization.create_authorization(app, user), - {:ok, token} <- Token.exchange_token(app, auth) do - conn - |> put_session(:oauth_token, token.token) - |> redirect(to: "/web/getting-started") - else - _e -> - conn - |> render(MastodonView, "login.html", %{error: "Wrong username or password"}) - end - end - def logout(conn, _) do conn |> clear_session diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 5441ee0a8..35c158fbb 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -33,25 +33,35 @@ defmodule Pleroma.Web.OAuth.OAuthController do true <- Pbkdf2.checkpw(password, user.password_hash), %App{} = app <- Repo.get_by(App, client_id: client_id), {:ok, auth} <- Authorization.create_authorization(app, user) do - if redirect_uri == "urn:ietf:wg:oauth:2.0:oob" do - render(conn, "results.html", %{ - auth: auth - }) - else - connector = if String.contains?(redirect_uri, "?"), do: "&", else: "?" - url = "#{redirect_uri}#{connector}" - url_params = %{:code => auth.token} - - url_params = - if params["state"] do - Map.put(url_params, :state, params["state"]) - else - url_params - end - - url = "#{url}#{Plug.Conn.Query.encode(url_params)}" - - redirect(conn, external: url) + # Special case: Local MastodonFE. + redirect_uri = + if redirect_uri == "." do + mastodon_api_url(conn, :login) + else + redirect_uri + end + + cond do + redirect_uri == "urn:ietf:wg:oauth:2.0:oob" -> + render(conn, "results.html", %{ + auth: auth + }) + + true -> + connector = if String.contains?(redirect_uri, "?"), do: "&", else: "?" + url = "#{redirect_uri}#{connector}" + url_params = %{:code => auth.token} + + url_params = + if params["state"] do + Map.put(url_params, :state, params["state"]) + else + url_params + end + + url = "#{url}#{Plug.Conn.Query.encode(url_params)}" + + redirect(conn, external: url) end end end diff --git a/lib/pleroma/web/templates/mastodon_api/mastodon/login.html.eex b/lib/pleroma/web/templates/mastodon_api/mastodon/login.html.eex deleted file mode 100644 index 34cd7ed89..000000000 --- a/lib/pleroma/web/templates/mastodon_api/mastodon/login.html.eex +++ /dev/null @@ -1,11 +0,0 @@ -

Login to Mastodon Frontend

-<%= if @error do %> -

<%= @error %>

-<% end %> -<%= form_for @conn, mastodon_api_path(@conn, :login), [as: "authorization"], fn f -> %> -<%= text_input f, :name, placeholder: "Username or email" %> -
-<%= password_input f, :password, placeholder: "Password" %> -
-<%= submit "Log in" %> -<% end %> -- cgit v1.2.3 From 7d328c658da69ec236d10fa89d23f2a6886b3205 Mon Sep 17 00:00:00 2001 From: href Date: Tue, 6 Nov 2018 16:00:48 +0100 Subject: Small wrapper module around Application.get_env/put_env Same API as the old Pleroma.Config --- lib/pleroma/config.ex | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 lib/pleroma/config.ex (limited to 'lib') diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex new file mode 100644 index 000000000..fc5338591 --- /dev/null +++ b/lib/pleroma/config.ex @@ -0,0 +1,26 @@ +defmodule Pleroma.Config do + def get([key]), do: get(key) + + def get([parent_key | keys]) do + Application.get_env(:pleroma, parent_key) + |> get_in(keys) + end + + def get(key) do + Application.get_env(:pleroma, key) + end + + def put([key], value), do: put(key, value) + + def put([parent_key | keys], value) do + parent = + Application.get_env(:pleroma, parent_key) + |> put_in(keys, value) + + Application.put_env(:pleroma, parent_key, parent) + end + + def put(key, value) do + Application.put_env(:pleroma, key, value) + end +end -- cgit v1.2.3 From a8f1e30cb81fe17866e3ee33f5b3558dd5b33764 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 6 Nov 2018 16:05:58 +0100 Subject: Formatting. --- lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 51a7ec2b2..5cb007740 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -989,7 +989,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do with {:ok, app} <- get_or_make_app(), %Authorization{} = auth <- Repo.get_by(Authorization, token: code, app_id: app.id), {:ok, token} <- Token.exchange_token(app, auth) do - conn |> put_session(:oauth_token, token.token) |> redirect(to: "/web/getting-started") -- cgit v1.2.3 From 5bb88fd1749931e755157760ec833c5d50ebb8c8 Mon Sep 17 00:00:00 2001 From: href Date: Tue, 6 Nov 2018 19:34:57 +0100 Subject: Runtime configuration Related to #85 Everything should now be configured at runtime, with the exception of the `Pleroma.HTML` scrubbers (the scrubbers used can be changed at runtime, but their configuration is compile-time) because it's building a module with a macro. --- lib/pleroma/config.ex | 26 +++++-- lib/pleroma/formatter.ex | 2 - lib/pleroma/gopher/server.ex | 15 ++-- lib/pleroma/html.ex | 4 +- lib/pleroma/upload.ex | 13 ++-- lib/pleroma/uploaders/swift/keystone.ex | 11 ++- lib/pleroma/uploaders/swift/swift.ex | 6 +- lib/pleroma/web/activity_pub/activity_pub.ex | 6 +- .../web/activity_pub/mrf/normalize_markup.ex | 4 +- .../web/activity_pub/mrf/reject_non_public.ex | 10 +-- lib/pleroma/web/activity_pub/mrf/simple_policy.ex | 85 +++++++++++++--------- lib/pleroma/web/activity_pub/transmogrifier.ex | 7 +- lib/pleroma/web/common_api/common_api.ex | 16 ++-- lib/pleroma/web/federator/federator.ex | 4 +- .../web/mastodon_api/mastodon_api_controller.ex | 47 ++++++------ .../web/twitter_api/controllers/util_controller.ex | 55 +++++++------- lib/pleroma/web/twitter_api/twitter_api.ex | 23 +++--- 17 files changed, 172 insertions(+), 162 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex index fc5338591..15f771b6e 100644 --- a/lib/pleroma/config.ex +++ b/lib/pleroma/config.ex @@ -1,13 +1,29 @@ defmodule Pleroma.Config do - def get([key]), do: get(key) + defmodule Error do + defexception [:message] + end + + def get(key), do: get(key, nil) + + def get([key], default), do: get(key, default) - def get([parent_key | keys]) do + def get([parent_key | keys], default) do Application.get_env(:pleroma, parent_key) - |> get_in(keys) + |> get_in(keys) || default end - def get(key) do - Application.get_env(:pleroma, key) + def get(key, default) do + Application.get_env(:pleroma, key, default) + end + + def get!(key) do + value = get(key, nil) + + if value == nil do + raise(Error, message: "Missing configuration value: #{inspect(key)}") + else + value + end end def put([key], value), do: put(key, value) diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index dd971df9b..26bb17377 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -29,8 +29,6 @@ defmodule Pleroma.Formatter do |> Enum.filter(fn {_match, user} -> user end) end - @instance Application.get_env(:pleroma, :instance) - def emojify(text) do emojify(text, Emoji.get_all()) end diff --git a/lib/pleroma/gopher/server.ex b/lib/pleroma/gopher/server.ex index d34037f4f..e6361a82c 100644 --- a/lib/pleroma/gopher/server.ex +++ b/lib/pleroma/gopher/server.ex @@ -1,16 +1,16 @@ defmodule Pleroma.Gopher.Server do use GenServer require Logger - @gopher Application.get_env(:pleroma, :gopher) def start_link() do - ip = Keyword.get(@gopher, :ip, {0, 0, 0, 0}) - port = Keyword.get(@gopher, :port, 1234) + config = Pleroma.Config.get(:gopher, []) + ip = Keyword.get(config, :ip, {0, 0, 0, 0}) + port = Keyword.get(config, :port, 1234) GenServer.start_link(__MODULE__, [ip, port], []) end def init([ip, port]) do - if Keyword.get(@gopher, :enabled, false) do + if Pleroma.Config.get([:gopher, :enabled], false) do Logger.info("Starting gopher server on #{port}") :ranch.start_listener( @@ -37,9 +37,6 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do alias Pleroma.Repo alias Pleroma.HTML - @instance Application.get_env(:pleroma, :instance) - @gopher Application.get_env(:pleroma, :gopher) - def start_link(ref, socket, transport, opts) do pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts]) {:ok, pid} @@ -62,7 +59,7 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do def link(name, selector, type \\ 1) do address = Pleroma.Web.Endpoint.host() - port = Keyword.get(@gopher, :port, 1234) + port = Pleroma.Config.get([:gopher, :port], 1234) "#{type}#{name}\t#{selector}\t#{address}\t#{port}\r\n" end @@ -85,7 +82,7 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do end def response("") do - info("Welcome to #{Keyword.get(@instance, :name, "Pleroma")}!") <> + info("Welcome to #{Pleroma.Config.get([:instance, :name], "Pleroma")}!") <> link("Public Timeline", "/main/public") <> link("Federated Timeline", "/main/all") <> ".\r\n" end diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index 00b26963d..1b920d7fd 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -1,14 +1,12 @@ defmodule Pleroma.HTML do alias HtmlSanitizeEx.Scrubber - @markup Application.get_env(:pleroma, :markup) - defp get_scrubbers(scrubber) when is_atom(scrubber), do: [scrubber] defp get_scrubbers(scrubbers) when is_list(scrubbers), do: scrubbers defp get_scrubbers(_), do: [Pleroma.HTML.Scrubber.Default] def get_scrubbers() do - Keyword.get(@markup, :scrub_policy) + Pleroma.Config.get([:markup, :scrub_policy]) |> get_scrubbers end diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index 2293ff54e..89aa779f9 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -1,9 +1,6 @@ defmodule Pleroma.Upload do alias Ecto.UUID - @storage_backend Application.get_env(:pleroma, Pleroma.Upload) - |> Keyword.fetch!(:uploader) - def check_file_size(path, nil), do: true def check_file_size(path, size_limit) do @@ -21,8 +18,7 @@ defmodule Pleroma.Upload do true <- check_file_size(file.path, size_limit) do strip_exif_data(content_type, file.path) - {:ok, url_path} = - @storage_backend.put_file(name, uuid, file.path, content_type, should_dedupe) + {:ok, url_path} = uploader().put_file(name, uuid, file.path, content_type, should_dedupe) %{ "type" => "Document", @@ -57,8 +53,7 @@ defmodule Pleroma.Upload do content_type ) - {:ok, url_path} = - @storage_backend.put_file(name, uuid, tmp_path, content_type, should_dedupe) + {:ok, url_path} = uploader().put_file(name, uuid, tmp_path, content_type, should_dedupe) %{ "type" => "Image", @@ -182,4 +177,8 @@ defmodule Pleroma.Upload do _e -> "application/octet-stream" end end + + defp uploader() do + Pleroma.Config.get!([Pleroma.Upload, :uploader]) + end end diff --git a/lib/pleroma/uploaders/swift/keystone.ex b/lib/pleroma/uploaders/swift/keystone.ex index a79214319..e578b3c61 100644 --- a/lib/pleroma/uploaders/swift/keystone.ex +++ b/lib/pleroma/uploaders/swift/keystone.ex @@ -1,11 +1,9 @@ defmodule Pleroma.Uploaders.Swift.Keystone do use HTTPoison.Base - @settings Application.get_env(:pleroma, Pleroma.Uploaders.Swift) - def process_url(url) do Enum.join( - [Keyword.fetch!(@settings, :auth_url), url], + [Pleroma.Config.get!([Pleroma.Uploaders.Swift, :auth_url]), url], "/" ) end @@ -16,9 +14,10 @@ defmodule Pleroma.Uploaders.Swift.Keystone do end def get_token() do - username = Keyword.fetch!(@settings, :username) - password = Keyword.fetch!(@settings, :password) - tenant_id = Keyword.fetch!(@settings, :tenant_id) + settings = Pleroma.Config.get(Pleroma.Uploaders.Swift) + username = Keyword.fetch!(settings, :username) + password = Keyword.fetch!(settings, :password) + tenant_id = Keyword.fetch!(settings, :tenant_id) case post( "/tokens", diff --git a/lib/pleroma/uploaders/swift/swift.ex b/lib/pleroma/uploaders/swift/swift.ex index 819dfebda..fa08ca966 100644 --- a/lib/pleroma/uploaders/swift/swift.ex +++ b/lib/pleroma/uploaders/swift/swift.ex @@ -1,17 +1,15 @@ defmodule Pleroma.Uploaders.Swift.Client do use HTTPoison.Base - @settings Application.get_env(:pleroma, Pleroma.Uploaders.Swift) - def process_url(url) do Enum.join( - [Keyword.fetch!(@settings, :storage_url), url], + [Pleroma.Config.get!([Pleroma.Uploaders.Swift, :storage_url]), url], "/" ) end def upload_file(filename, body, content_type) do - object_url = Keyword.fetch!(@settings, :object_url) + object_url = Pleroma.Config.get!([Pleroma.Uploaders.Swift, :object_url]) token = Pleroma.Uploaders.Swift.Keystone.get_token() case put("#{filename}", body, "X-Auth-Token": token, "Content-Type": content_type) do diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 32c14995f..c6733e487 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -10,8 +10,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do @httpoison Application.get_env(:pleroma, :httpoison) - @instance Application.get_env(:pleroma, :instance) - # For Announce activities, we filter the recipients based on following status for any actors # that match actual users. See issue #164 for more information about why this is necessary. defp get_recipients(%{"type" => "Announce"} = data) do @@ -659,14 +657,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - @quarantined_instances Keyword.get(@instance, :quarantined_instances, []) - def should_federate?(inbox, public) do if public do true else inbox_info = URI.parse(inbox) - inbox_info.host not in @quarantined_instances + !Enum.member?(Pleroma.Config.get([:instance, :quarantined_instances], []), inbox_info.host) end end diff --git a/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex b/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex index b4f91f3cc..c53cb1ad2 100644 --- a/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex +++ b/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex @@ -3,10 +3,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do @behaviour Pleroma.Web.ActivityPub.MRF - @mrf_normalize_markup Application.get_env(:pleroma, :mrf_normalize_markup) - def filter(%{"type" => activity_type} = object) when activity_type == "Create" do - scrub_policy = Keyword.get(@mrf_normalize_markup, :scrub_policy) + scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy]) child = object["object"] diff --git a/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex b/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex index 129d04617..627284083 100644 --- a/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex +++ b/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex @@ -2,10 +2,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do alias Pleroma.User @behaviour Pleroma.Web.ActivityPub.MRF - @mrf_rejectnonpublic Application.get_env(:pleroma, :mrf_rejectnonpublic) - @allow_followersonly Keyword.get(@mrf_rejectnonpublic, :allow_followersonly) - @allow_direct Keyword.get(@mrf_rejectnonpublic, :allow_direct) - @impl true def filter(%{"type" => "Create"} = object) do user = User.get_cached_by_ap_id(object["actor"]) @@ -20,6 +16,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do true -> "direct" end + policy = Pleroma.Config.get(:mrf_rejectnonpublic) + case visibility do "public" -> {:ok, object} @@ -28,14 +26,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do {:ok, object} "followers" -> - with true <- @allow_followersonly do + with true <- Keyword.get(policy, :allow_followersonly) do {:ok, object} else _e -> {:reject, nil} end "direct" -> - with true <- @allow_direct do + with true <- Keyword.get(policy, :allow_direct) do {:ok, object} else _e -> {:reject, nil} diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 319721d48..341b5bce3 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -2,60 +2,75 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do alias Pleroma.User @behaviour Pleroma.Web.ActivityPub.MRF - @mrf_policy Application.get_env(:pleroma, :mrf_simple) + defp check_accept(%{host: actor_host} = _actor_info, object) do + accepts = Pleroma.Config.get([:mrf_simple, :accept]) - @accept Keyword.get(@mrf_policy, :accept) - defp check_accept(%{host: actor_host} = actor_info, object) - when length(@accept) > 0 and not (actor_host in @accept) do - {:reject, nil} + cond do + accepts == [] -> {:ok, object} + Enum.member?(accepts, actor_host) -> {:ok, object} + true -> {:reject, nil} + end end - defp check_accept(actor_info, object), do: {:ok, object} - - @reject Keyword.get(@mrf_policy, :reject) - defp check_reject(%{host: actor_host} = actor_info, object) when actor_host in @reject do - {:reject, nil} + defp check_reject(%{host: actor_host} = _actor_info, object) do + if Enum.member?(Pleroma.Config.get([:mrf_simple, :reject]), actor_host) do + {:reject, nil} + else + {:ok, object} + end end - defp check_reject(actor_info, object), do: {:ok, object} + defp check_media_removal( + %{host: actor_host} = _actor_info, + %{"type" => "Create", "object" => %{"attachement" => child_attachement}} = object + ) + when length(child_attachement) > 0 do + object = + if Enum.member?(Pleroma.Config.get([:mrf_simple, :media_removal]), actor_host) do + child_object = Map.delete(object["object"], "attachment") + Map.put(object, "object", child_object) + else + object + end - @media_removal Keyword.get(@mrf_policy, :media_removal) - defp check_media_removal(%{host: actor_host} = actor_info, %{"type" => "Create"} = object) - when actor_host in @media_removal do - child_object = Map.delete(object["object"], "attachment") - object = Map.put(object, "object", child_object) {:ok, object} end - defp check_media_removal(actor_info, object), do: {:ok, object} + defp check_media_removal(_actor_info, object), do: {:ok, object} - @media_nsfw Keyword.get(@mrf_policy, :media_nsfw) defp check_media_nsfw( - %{host: actor_host} = actor_info, + %{host: actor_host} = _actor_info, %{ "type" => "Create", "object" => %{"attachment" => child_attachment} = child_object } = object ) - when actor_host in @media_nsfw and length(child_attachment) > 0 do - tags = (child_object["tag"] || []) ++ ["nsfw"] - child_object = Map.put(child_object, "tags", tags) - child_object = Map.put(child_object, "sensitive", true) - object = Map.put(object, "object", child_object) + when length(child_attachment) > 0 do + object = + if Enum.member?(Pleroma.Config.get([:mrf_simple, :media_nsfw]), actor_host) do + tags = (child_object["tag"] || []) ++ ["nsfw"] + child_object = Map.put(child_object, "tags", tags) + child_object = Map.put(child_object, "sensitive", true) + Map.put(object, "object", child_object) + else + object + end + {:ok, object} end - defp check_media_nsfw(actor_info, object), do: {:ok, object} - - @ftl_removal Keyword.get(@mrf_policy, :federated_timeline_removal) - defp check_ftl_removal(%{host: actor_host} = actor_info, object) - when actor_host in @ftl_removal do - user = User.get_by_ap_id(object["actor"]) + defp check_media_nsfw(_actor_info, object), do: {:ok, object} - # flip to/cc relationship to make the post unlisted + defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do object = - if "https://www.w3.org/ns/activitystreams#Public" in object["to"] and - user.follower_address in object["cc"] do + with true <- + Enum.member?( + Pleroma.Config.get([:mrf_simple, :federated_timeline_removal]), + actor_host + ), + user <- User.get_by_ap_id(object["actor"]), + true <- "https://www.w3.org/ns/activitystreams#Public" in object["to"], + true <- user.follower_address in object["cc"] do to = List.delete(object["to"], "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address] @@ -68,14 +83,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do |> Map.put("to", to) |> Map.put("cc", cc) else - object + _ -> object end {:ok, object} end - defp check_ftl_removal(actor_info, object), do: {:ok, object} - @impl true def filter(object) do actor_info = URI.parse(object["actor"]) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 5bc151b97..d72f4a39a 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -506,9 +506,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - @ap_config Application.get_env(:pleroma, :activitypub) - @accept_blocks Keyword.get(@ap_config, :accept_blocks) - def handle_incoming( %{ "type" => "Undo", @@ -517,7 +514,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do "id" => id } = _data ) do - with true <- @accept_blocks, + with true <- Pleroma.Config.get([:activitypub, :accept_blocks]), %User{local: true} = blocked <- User.get_cached_by_ap_id(blocked), %User{} = blocker <- User.get_or_fetch_by_ap_id(blocker), {:ok, activity} <- ActivityPub.unblock(blocker, blocked, id, false) do @@ -531,7 +528,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def handle_incoming( %{"type" => "Block", "object" => blocked, "actor" => blocker, "id" => id} = data ) do - with true <- @accept_blocks, + with true <- Pleroma.Config.get([:activitypub, :accept_blocks]), %User{local: true} = blocked = User.get_cached_by_ap_id(blocked), %User{} = blocker = User.get_or_fetch_by_ap_id(blocker), {:ok, activity} <- ActivityPub.block(blocker, blocked, id, false) do diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 8f47bb127..77e4dbbd7 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -70,15 +70,17 @@ defmodule Pleroma.Web.CommonAPI do def get_visibility(_), do: "public" - @instance Application.get_env(:pleroma, :instance) - @allowed_post_formats Keyword.get(@instance, :allowed_post_formats) - - defp get_content_type(content_type) when content_type in @allowed_post_formats, do: content_type - defp get_content_type(_), do: "text/plain" + defp get_content_type(content_type) do + if Enum.member?(Pleroma.Config.get([:instance, :allowed_post_formats]), content_type) do + content_type + else + "text/plain" + end + end - @limit Keyword.get(@instance, :limit) def post(user, %{"status" => status} = data) do visibility = get_visibility(data) + limit = Pleroma.Config.get([:instance, :limit]) with status <- String.trim(status), attachments <- attachments_from_ids(data["media_ids"]), @@ -98,7 +100,7 @@ defmodule Pleroma.Web.CommonAPI do context <- make_context(inReplyTo), cw <- data["spoiler_text"], full_payload <- String.trim(status <> (data["spoiler_text"] || "")), - length when length in 1..@limit <- String.length(full_payload), + length when length in 1..limit <- String.length(full_payload), object <- make_note_data( user.ap_id, diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index 01c2c89c3..6071d08e4 100644 --- a/lib/pleroma/web/federator/federator.ex +++ b/lib/pleroma/web/federator/federator.ex @@ -12,8 +12,6 @@ defmodule Pleroma.Web.Federator do @websub Application.get_env(:pleroma, :websub) @ostatus Application.get_env(:pleroma, :ostatus) @httpoison Application.get_env(:pleroma, :httpoison) - @instance Application.get_env(:pleroma, :instance) - @federating Keyword.get(@instance, :federating) @max_jobs 20 def init(args) do @@ -147,7 +145,7 @@ defmodule Pleroma.Web.Federator do end def enqueue(type, payload, priority \\ 1) do - if @federating do + if Pleroma.Config.get([:instance, :federating]) do if Mix.env() == :test do handle(type, payload) else diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index e92114f57..0e7d12c20 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -132,22 +132,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - @instance Application.get_env(:pleroma, :instance) @mastodon_api_level "2.5.0" def masto_instance(conn, _params) do + instance = Pleroma.Config.get(:instance) + response = %{ uri: Web.base_url(), - title: Keyword.get(@instance, :name), - description: Keyword.get(@instance, :description), - version: "#{@mastodon_api_level} (compatible; #{Keyword.get(@instance, :version)})", - email: Keyword.get(@instance, :email), + title: Keyword.get(instance, :name), + description: Keyword.get(instance, :description), + version: "#{@mastodon_api_level} (compatible; #{Keyword.get(instance, :version)})", + email: Keyword.get(instance, :email), urls: %{ streaming_api: String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws") }, stats: Stats.get_stats(), thumbnail: Web.base_url() <> "/instance/thumbnail.jpeg", - max_toot_chars: Keyword.get(@instance, :limit) + max_toot_chars: Keyword.get(instance, :limit) } json(conn, response) @@ -581,15 +582,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - @activitypub Application.get_env(:pleroma, :activitypub) - @follow_handshake_timeout Keyword.get(@activitypub, :follow_handshake_timeout) - def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do with %User{} = followed <- Repo.get(User, id), {:ok, follower} <- User.maybe_direct_follow(follower, followed), {:ok, _activity} <- ActivityPub.follow(follower, followed), {:ok, follower, followed} <- - User.wait_and_refresh(@follow_handshake_timeout, follower, followed) do + User.wait_and_refresh( + Pleroma.Config.get([:activitypub, :follow_handshake_timeout]), + follower, + followed + ) do render(conn, AccountView, "relationship.json", %{user: follower, target: followed}) else {:error, message} -> @@ -880,6 +882,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do if user && token do mastodon_emoji = mastodonized_emoji() + limit = Pleroma.Config.get([:instance, :limit]) + accounts = Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user})) @@ -899,7 +903,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do auto_play_gif: false, display_sensitive_media: false, reduce_motion: false, - max_toot_chars: Keyword.get(@instance, :limit) + max_toot_chars: limit }, rights: %{ delete_others_notice: !!user.info["is_moderator"] @@ -959,7 +963,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do push_subscription: nil, accounts: accounts, custom_emojis: mastodon_emoji, - char_limit: Keyword.get(@instance, :limit) + char_limit: limit } |> Jason.encode!() @@ -1165,18 +1169,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> json("Something went wrong") end - @suggestions Application.get_env(:pleroma, :suggestions) - def suggestions(%{assigns: %{user: user}} = conn, _) do - if Keyword.get(@suggestions, :enabled, false) do - api = Keyword.get(@suggestions, :third_party_engine, "") - timeout = Keyword.get(@suggestions, :timeout, 5000) - limit = Keyword.get(@suggestions, :limit, 23) - - host = - Application.get_env(:pleroma, Pleroma.Web.Endpoint) - |> Keyword.get(:url) - |> Keyword.get(:host) + suggestions = Pleroma.Config.get(:suggestions) + + if Keyword.get(suggestions, :enabled, false) do + api = Keyword.get(suggestions, :third_party_engine, "") + timeout = Keyword.get(suggestions, :timeout, 5000) + limit = Keyword.get(suggestions, :limit, 23) + + host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) user = user.nickname url = String.replace(api, "{{host}}", host) |> String.replace("{{user}}", user) diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index e84438e97..dc4a864d6 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -134,19 +134,20 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end - @instance Application.get_env(:pleroma, :instance) - @instance_fe Application.get_env(:pleroma, :fe) - @instance_chat Application.get_env(:pleroma, :chat) def config(conn, _params) do + instance = Pleroma.Config.get(:instance) + instance_fe = Pleroma.Config.get(:fe) + instance_chat = Pleroma.Config.get(:chat) + case get_format(conn) do "xml" -> response = """ - #{Keyword.get(@instance, :name)} + #{Keyword.get(instance, :name)} #{Web.base_url()} - #{Keyword.get(@instance, :limit)} - #{!Keyword.get(@instance, :registrations_open)} + #{Keyword.get(instance, :limit)} + #{!Keyword.get(instance, :registrations_open)} """ @@ -157,32 +158,32 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do _ -> data = %{ - name: Keyword.get(@instance, :name), - description: Keyword.get(@instance, :description), + name: Keyword.get(instance, :name), + description: Keyword.get(instance, :description), server: Web.base_url(), - textlimit: to_string(Keyword.get(@instance, :limit)), - closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1"), - private: if(Keyword.get(@instance, :public, true), do: "0", else: "1") + textlimit: to_string(Keyword.get(instance, :limit)), + closed: if(Keyword.get(instance, :registrations_open), do: "0", else: "1"), + private: if(Keyword.get(instance, :public, true), do: "0", else: "1") } pleroma_fe = %{ - theme: Keyword.get(@instance_fe, :theme), - background: Keyword.get(@instance_fe, :background), - logo: Keyword.get(@instance_fe, :logo), - logoMask: Keyword.get(@instance_fe, :logo_mask), - logoMargin: Keyword.get(@instance_fe, :logo_margin), - redirectRootNoLogin: Keyword.get(@instance_fe, :redirect_root_no_login), - redirectRootLogin: Keyword.get(@instance_fe, :redirect_root_login), - chatDisabled: !Keyword.get(@instance_chat, :enabled), - showInstanceSpecificPanel: Keyword.get(@instance_fe, :show_instance_panel), - scopeOptionsEnabled: Keyword.get(@instance_fe, :scope_options_enabled), - formattingOptionsEnabled: Keyword.get(@instance_fe, :formatting_options_enabled), - collapseMessageWithSubject: Keyword.get(@instance_fe, :collapse_message_with_subject), - hidePostStats: Keyword.get(@instance_fe, :hide_post_stats), - hideUserStats: Keyword.get(@instance_fe, :hide_user_stats) + theme: Keyword.get(instance_fe, :theme), + background: Keyword.get(instance_fe, :background), + logo: Keyword.get(instance_fe, :logo), + logoMask: Keyword.get(instance_fe, :logo_mask), + logoMargin: Keyword.get(instance_fe, :logo_margin), + redirectRootNoLogin: Keyword.get(instance_fe, :redirect_root_no_login), + redirectRootLogin: Keyword.get(instance_fe, :redirect_root_login), + chatDisabled: !Keyword.get(instance_chat, :enabled), + showInstanceSpecificPanel: Keyword.get(instance_fe, :show_instance_panel), + scopeOptionsEnabled: Keyword.get(instance_fe, :scope_options_enabled), + formattingOptionsEnabled: Keyword.get(instance_fe, :formatting_options_enabled), + collapseMessageWithSubject: Keyword.get(instance_fe, :collapse_message_with_subject), + hidePostStats: Keyword.get(instance_fe, :hide_post_stats), + hideUserStats: Keyword.get(instance_fe, :hide_user_stats) } - managed_config = Keyword.get(@instance, :managed_config) + managed_config = Keyword.get(instance, :managed_config) data = if managed_config do @@ -196,7 +197,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end def version(conn, _params) do - version = Keyword.get(@instance, :version) + version = Pleroma.Config.get([:instance, :version]) case get_format(conn) do "xml" -> diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index cb483df9d..5bfb83b1e 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -6,9 +6,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do alias Pleroma.Web.MediaProxy import Ecto.Query - @instance Application.get_env(:pleroma, :instance) @httpoison Application.get_env(:pleroma, :httpoison) - @registrations_open Keyword.get(@instance, :registrations_open) def create_status(%User{} = user, %{"status" => _} = data) do CommonAPI.post(user, data) @@ -21,15 +19,16 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end end - @activitypub Application.get_env(:pleroma, :activitypub) - @follow_handshake_timeout Keyword.get(@activitypub, :follow_handshake_timeout) - def follow(%User{} = follower, params) do with {:ok, %User{} = followed} <- get_user(params), {:ok, follower} <- User.maybe_direct_follow(follower, followed), {:ok, activity} <- ActivityPub.follow(follower, followed), {:ok, follower, followed} <- - User.wait_and_refresh(@follow_handshake_timeout, follower, followed) do + User.wait_and_refresh( + Pleroma.Config.get([:activitypub, :follow_handshake_timeout]), + follower, + followed + ) do {:ok, follower, followed, activity} else err -> err @@ -139,18 +138,20 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do password_confirmation: params["confirm"] } + registrations_open = Pleroma.Config.get([:instance, :registrations_open]) + # no need to query DB if registration is open token = - unless @registrations_open || is_nil(tokenString) do + unless registrations_open || is_nil(tokenString) do Repo.get_by(UserInviteToken, %{token: tokenString}) end cond do - @registrations_open || (!is_nil(token) && !token.used) -> + registrations_open || (!is_nil(token) && !token.used) -> changeset = User.register_changeset(%User{}, params) with {:ok, user} <- Repo.insert(changeset) do - !@registrations_open && UserInviteToken.mark_as_used(token.token) + !registrations_open && UserInviteToken.mark_as_used(token.token) {:ok, user} else {:error, changeset} -> @@ -161,10 +162,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do {:error, %{error: errors}} end - !@registrations_open && is_nil(token) -> + !registrations_open && is_nil(token) -> {:error, "Invalid token"} - !@registrations_open && token.used -> + !registrations_open && token.used -> {:error, "Expired token"} end end -- cgit v1.2.3 From f16c2e0b1b524fa9fc6a3733dd47e1d82f199fc7 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 6 Nov 2018 22:50:43 +0000 Subject: notification: add Notification.set_read_up_to() --- lib/pleroma/notification.ex | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index e0dcd9823..75d7461e4 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -42,6 +42,20 @@ defmodule Pleroma.Notification do Repo.all(query) end + def set_read_up_to(%{id: user_id} = _user, id) do + query = + from( + n in Notification, + where: n.user_id == ^user_id, + where: n.id <= ^id, + update: [ + set: [seen: true] + ] + ) + + Repo.update_all(query, []) + end + def get(%{id: user_id} = _user, id) do query = from( -- cgit v1.2.3 From b2105a31316d371733a75322bbf60868700f037d Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 6 Nov 2018 23:07:13 +0000 Subject: twitterapi: add notification read endpoint --- lib/pleroma/web/router.ex | 4 ++++ lib/pleroma/web/twitter_api/twitter_api_controller.ex | 13 +++++++++++++ 2 files changed, 17 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index b461def82..06d0f0623 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -272,6 +272,10 @@ defmodule Pleroma.Web.Router do get("/statuses/mentions_timeline", TwitterAPI.Controller, :mentions_timeline) get("/qvitter/statuses/notifications", TwitterAPI.Controller, :notifications) + # XXX: this is really a pleroma API, but we want to keep the pleroma namespace clean + # for now. + post("/qvitter/statuses/notifications/read", TwitterAPI.Controller, :notifications_read) + post("/statuses/update", TwitterAPI.Controller, :status_update) post("/statuses/retweet/:id", TwitterAPI.Controller, :retweet) post("/statuses/unretweet/:id", TwitterAPI.Controller, :unretweet) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 83d725f13..727469a66 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -133,6 +133,19 @@ defmodule Pleroma.Web.TwitterAPI.Controller do |> render(NotificationView, "notification.json", %{notifications: notifications, for: user}) end + def notifications_read(%{assigns: %{user: user}} = conn, %{"latest_id" => latest_id} = params) do + Notification.set_read_up_to(user, latest_id) + + notifications = Notification.for_user(user, params) + + conn + |> render(NotificationView, "notification.json", %{notifications: notifications, for: user}) + end + + def notifications_read(%{assigns: %{user: user}} = conn, _) do + bad_request_reply(conn, "You need to specify latest_id") + end + def follow(%{assigns: %{user: user}} = conn, params) do case TwitterAPI.follow(user, params) do {:ok, user, followed, _activity} -> -- cgit v1.2.3 From 9070588493bc896e909e05374ff64fb3f893ec53 Mon Sep 17 00:00:00 2001 From: href Date: Wed, 7 Nov 2018 10:40:24 +0100 Subject: Runtime config: MRF changes --- lib/pleroma/web/activity_pub/mrf/simple_policy.ex | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 341b5bce3..86dcf5080 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do cond do accepts == [] -> {:ok, object} + actor_host == Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object} Enum.member?(accepts, actor_host) -> {:ok, object} true -> {:reject, nil} end @@ -22,9 +23,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defp check_media_removal( %{host: actor_host} = _actor_info, - %{"type" => "Create", "object" => %{"attachement" => child_attachement}} = object + %{"type" => "Create", "object" => %{"attachement" => child_attachment}} = object ) - when length(child_attachement) > 0 do + when length(child_attachment) > 0 do object = if Enum.member?(Pleroma.Config.get([:mrf_simple, :media_removal]), actor_host) do child_object = Map.delete(object["object"], "attachment") @@ -68,7 +69,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do Pleroma.Config.get([:mrf_simple, :federated_timeline_removal]), actor_host ), - user <- User.get_by_ap_id(object["actor"]), + user <- User.get_cached_by_ap_id(object["actor"]), true <- "https://www.w3.org/ns/activitystreams#Public" in object["to"], true <- user.follower_address in object["cc"] do to = -- cgit v1.2.3 From e42f2efae45923739b537cf35f3875578b181d37 Mon Sep 17 00:00:00 2001 From: href Date: Wed, 7 Nov 2018 16:27:07 +0100 Subject: /api/v1/accounts/relationships Return an empty array if no id in params This copies Mastodon API behaviour & fixes Mastalab app. --- lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 5cb007740..af4cf2b71 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -443,6 +443,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do render(conn, AccountView, "relationships.json", %{user: user, targets: targets}) end + # Instead of returning a 400 when no "id" params is present, Mastodon returns an empty array. + def relationships(%{assigns: %{user: user}} = conn, _) do + conn + |> json([]) + end + def update_media(%{assigns: %{user: _}} = conn, data) do with %Object{} = object <- Repo.get(Object, data["id"]), true <- is_binary(data["description"]), -- cgit v1.2.3 From 3b02fd9fb7a834771c0582bf5a113f04ec2d46e0 Mon Sep 17 00:00:00 2001 From: lain Date: Thu, 8 Nov 2018 16:05:28 +0100 Subject: Small refactor. --- lib/pleroma/web/activity_pub/views/object_view.ex | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex index cc0b0556b..df734a871 100644 --- a/lib/pleroma/web/activity_pub/views/object_view.ex +++ b/lib/pleroma/web/activity_pub/views/object_view.ex @@ -3,23 +3,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do alias Pleroma.Web.ActivityPub.Transmogrifier def render("object.json", %{object: object}) do - base = %{ - "@context" => [ - "https://www.w3.org/ns/activitystreams", - "https://w3id.org/security/v1", - %{ - "manuallyApprovesFollowers" => "as:manuallyApprovesFollowers", - "sensitive" => "as:sensitive", - "Hashtag" => "as:Hashtag", - "ostatus" => "http://ostatus.org#", - "atomUri" => "ostatus:atomUri", - "inReplyToAtomUri" => "ostatus:inReplyToAtomUri", - "conversation" => "ostatus:conversation", - "toot" => "http://joinmastodon.org/ns#", - "Emoji" => "toot:Emoji" - } - ] - } + base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header() additional = Transmogrifier.prepare_object(object.data) Map.merge(base, additional) -- cgit v1.2.3 From 34bd411781c598386f35397eb0affe124390c066 Mon Sep 17 00:00:00 2001 From: lain Date: Thu, 8 Nov 2018 16:39:38 +0100 Subject: Unify json ld header handling. --- lib/pleroma/web/activity_pub/transmogrifier.ex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 5bc151b97..db6823f2c 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -607,7 +607,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do data = data |> Map.put("object", object) - |> Map.put("@context", "https://www.w3.org/ns/activitystreams") + |> Map.merge(Utils.make_json_ld_header()) {:ok, data} end @@ -626,7 +626,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do data = data |> Map.put("object", object) - |> Map.put("@context", "https://www.w3.org/ns/activitystreams") + |> Map.merge(Utils.make_json_ld_header()) {:ok, data} end @@ -644,7 +644,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do data = data |> Map.put("object", object) - |> Map.put("@context", "https://www.w3.org/ns/activitystreams") + |> Map.merge(Utils.make_json_ld_header()) {:ok, data} end @@ -654,7 +654,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do data = data |> maybe_fix_object_url - |> Map.put("@context", "https://www.w3.org/ns/activitystreams") + |> Map.merge(Utils.make_json_ld_header()) {:ok, data} end -- cgit v1.2.3 From f733470037761723887386c7878b4f1d23dca304 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 16:51:48 +0000 Subject: user view: unify a @context entry that was missed --- lib/pleroma/web/activity_pub/views/user_view.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 16419e1b7..eb335813d 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -17,7 +17,6 @@ defmodule Pleroma.Web.ActivityPub.UserView do public_key = :public_key.pem_encode([public_key]) %{ - "@context" => "https://www.w3.org/ns/activitystreams", "id" => user.ap_id, "type" => "Application", "following" => "#{user.ap_id}/following", @@ -36,6 +35,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do "sharedInbox" => "#{Pleroma.Web.Endpoint.url()}/inbox" } } + |> Map.merge(Utils.make_json_ld_header()) end def render("user.json", %{user: user}) do -- cgit v1.2.3 From da16ada4240d2ba48f3972aedad26314a3ce4e49 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 16:52:14 +0000 Subject: utils: use litepub @context instead of that huge mess --- lib/pleroma/web/activity_pub/utils.ex | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 3362d9325..d81c824f0 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -70,18 +70,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do %{ "@context" => [ "https://www.w3.org/ns/activitystreams", - "https://w3id.org/security/v1", - %{ - "manuallyApprovesFollowers" => "as:manuallyApprovesFollowers", - "sensitive" => "as:sensitive", - "Hashtag" => "as:Hashtag", - "ostatus" => "http://ostatus.org#", - "atomUri" => "ostatus:atomUri", - "inReplyToAtomUri" => "ostatus:inReplyToAtomUri", - "conversation" => "ostatus:conversation", - "toot" => "http://joinmastodon.org/ns#", - "Emoji" => "toot:Emoji" - } + "https://litepub.github.io/litepub/context.jsonld" ] } end -- cgit v1.2.3 From abcacec97d1002e92696c8c7f69b05130420b18f Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 8 Nov 2018 19:38:38 +0100 Subject: Pleroma.Web.ActivityPub.Utils: Use locally-served JSON-LD Litepub context instead of Github-hosted one --- lib/pleroma/web/activity_pub/utils.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d81c824f0..174906537 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -70,7 +70,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do %{ "@context" => [ "https://www.w3.org/ns/activitystreams", - "https://litepub.github.io/litepub/context.jsonld" + "#{Web.base_url()}/litepub-1.0.jsonld" ] } end -- cgit v1.2.3 From 144dc048b8c5f71b41f9f14b6cc4315de4dca707 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 18:55:50 +0000 Subject: user: only consider `to` recipients as mention targets --- lib/pleroma/user.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b2f59ab6b..0d11101a3 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -472,7 +472,7 @@ defmodule Pleroma.User do ) end - def get_notified_from_activity(%Activity{recipients: to, data: %{"type" => "Announce"} = data}) do + def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => to} = data}) do object = Object.normalize(data["object"]) actor = User.get_cached_by_ap_id(data["actor"]) @@ -490,12 +490,14 @@ defmodule Pleroma.User do Repo.all(query) end - def get_notified_from_activity(%Activity{recipients: to}) do + def get_notified_from_activity(%Activity{data: %{"to" => to}}) do query = get_notified_from_activity_query(to) Repo.all(query) end + def get_notified_from_activity(_), do: [] + def get_recipients_from_activity(%Activity{recipients: to}) do query = from( -- cgit v1.2.3 From 3e33479c05c315e04b0947136f1429c79c85c63c Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 18:56:14 +0000 Subject: activitypub: transmogrifier: only consider `to` users as mention targets --- lib/pleroma/web/activity_pub/transmogrifier.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index a112d4ced..1471c9416 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -693,7 +693,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end def add_mention_tags(object) do - recipients = object["to"] ++ (object["cc"] || []) + recipients = object["to"] || [] mentions = recipients -- cgit v1.2.3 From 4e93d6ae14fc2e4829769e58e66b6fb95e661e7f Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 19:17:01 +0000 Subject: common api: utils: flip to/cc for mentions --- lib/pleroma/web/common_api/utils.ex | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index b22c4cc03..728f24c7e 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -34,21 +34,29 @@ defmodule Pleroma.Web.CommonAPI.Utils do end def to_for_user_and_mentions(user, mentions, inReplyTo, "public") do - to = ["https://www.w3.org/ns/activitystreams#Public"] - mentioned_users = Enum.map(mentions, fn {_, %{ap_id: ap_id}} -> ap_id end) - cc = [user.follower_address | mentioned_users] + + to = ["https://www.w3.org/ns/activitystreams#Public" | mentioned_users] + cc = [user.follower_address] if inReplyTo do - {to, Enum.uniq([inReplyTo.data["actor"] | cc])} + {Enum.uniq([inReplyTo.data["actor"] | to]), cc} else {to, cc} end end def to_for_user_and_mentions(user, mentions, inReplyTo, "unlisted") do - {to, cc} = to_for_user_and_mentions(user, mentions, inReplyTo, "public") - {cc, to} + mentioned_users = Enum.map(mentions, fn {_, %{ap_id: ap_id}} -> ap_id end) + + to = [user.follower_address | mentioned_users] + cc = ["https://www.w3.org/ns/activitystreams#Public"] + + if inReplyTo do + {Enum.uniq([inReplyTo.data["actor"] | to]), cc} + else + {to, cc} + end end def to_for_user_and_mentions(user, mentions, inReplyTo, "private") do -- cgit v1.2.3 From 934125695d640a08de136ef3924909aaa81fdcc1 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 8 Nov 2018 20:21:45 +0100 Subject: Move /litepub-1.0.jsonld to /schemas/litepub-0.1.jsonld --- lib/pleroma/web/activity_pub/utils.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 174906537..152bb5a8d 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -70,7 +70,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do %{ "@context" => [ "https://www.w3.org/ns/activitystreams", - "#{Web.base_url()}/litepub-1.0.jsonld" + "#{Web.base_url()}/schemas/litepub-0.1.jsonld" ] } end -- cgit v1.2.3 From 2fab32ab61d305bbea13c27ac23b1180b638c4cd Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 8 Nov 2018 20:22:12 +0100 Subject: Pleroma.Web.Endpoint: Whitelist schemas directory --- lib/pleroma/web/endpoint.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 6673ab576..b38f33863 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -17,7 +17,7 @@ defmodule Pleroma.Web.Endpoint do Plug.Static, at: "/", from: :pleroma, - only: ~w(index.html static finmoji emoji packs sounds images instance sw.js favicon.png) + only: ~w(index.html static finmoji emoji packs sounds images instance sw.js favicon.png schemas) ) # Code reloading can be explicitly enabled under the -- cgit v1.2.3 From 0a2c1a3419d6b5aaf078609063d355f3d6ea046a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 19:30:55 +0000 Subject: user: add optional local_only param to get_notified_from_activity() --- lib/pleroma/user.ex | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 0d11101a3..acb355a05 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -464,15 +464,25 @@ defmodule Pleroma.User do update_and_set_cache(cs) end - def get_notified_from_activity_query(to) do + def get_notified_from_activity_query(to, false) do from( u in User, - where: u.ap_id in ^to, + where: u.ap_id in ^to + ) + end + + def get_notified_from_activity_query(to, true) do + query = get_notified_from_activity_query(to, false) + + from( + u in query, where: u.local == true ) end - def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => to} = data}) do + def get_notified_from_activity(activity, local_only \\ true) + + def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => to} = data}, local_only) do object = Object.normalize(data["object"]) actor = User.get_cached_by_ap_id(data["actor"]) @@ -485,18 +495,18 @@ defmodule Pleroma.User do end |> Enum.uniq() - query = get_notified_from_activity_query(to) + query = get_notified_from_activity_query(to, local_only) Repo.all(query) end - def get_notified_from_activity(%Activity{data: %{"to" => to}}) do - query = get_notified_from_activity_query(to) + def get_notified_from_activity(%Activity{data: %{"to" => to}}, local_only) do + query = get_notified_from_activity_query(to, local_only) Repo.all(query) end - def get_notified_from_activity(_), do: [] + def get_notified_from_activity(_, _), do: [] def get_recipients_from_activity(%Activity{recipients: to}) do query = -- cgit v1.2.3 From 6b4064fa5ddd8396faf7d6afef891d70e7a2e881 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 19:31:59 +0000 Subject: activitypub: transmogrifier: unify mention extraction --- lib/pleroma/user.ex | 5 ++++- lib/pleroma/web/activity_pub/transmogrifier.ex | 7 ++----- lib/pleroma/web/activity_pub/utils.ex | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index acb355a05..260d904bc 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -482,7 +482,10 @@ defmodule Pleroma.User do def get_notified_from_activity(activity, local_only \\ true) - def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => to} = data}, local_only) do + def get_notified_from_activity( + %Activity{data: %{"type" => "Announce", "to" => to} = data}, + local_only + ) do object = Object.normalize(data["object"]) actor = User.get_cached_by_ap_id(data["actor"]) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 1471c9416..6a0fdb433 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -693,12 +693,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end def add_mention_tags(object) do - recipients = object["to"] || [] - mentions = - recipients - |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end) - |> Enum.filter(& &1) + object + |> Utils.get_notified_from_object() |> Enum.map(fn user -> %{"type" => "Mention", "href" => user.ap_id, "name" => "@#{user.nickname}"} end) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d81c824f0..fd9c5eb59 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -95,6 +95,10 @@ defmodule Pleroma.Web.ActivityPub.Utils do "#{Web.base_url()}/#{type}/#{UUID.generate()}" end + def get_notified_from_object(object) do + User.get_notified_from_activity(%Activity{data: object}, false) + end + def create_context(context) do context = context || generate_id("contexts") changeset = Object.context_mapping(context) -- cgit v1.2.3 From 81d6ca17830538aea2815a0381f3a287d68c454f Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 20:01:42 +0000 Subject: user: implement AS2 mention extraction + unify Announce handling --- lib/pleroma/user.ex | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 260d904bc..71bdbebee 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -482,28 +482,37 @@ defmodule Pleroma.User do def get_notified_from_activity(activity, local_only \\ true) - def get_notified_from_activity( - %Activity{data: %{"type" => "Announce", "to" => to} = data}, - local_only - ) do + def get_notified_from_activity(%Activity{data: %{"to" => to} = data}, local_only) do object = Object.normalize(data["object"]) - actor = User.get_cached_by_ap_id(data["actor"]) - # ensure that the actor who published the announced object appears only once - to = - if actor.nickname != nil do - to ++ [object.data["actor"]] + # somehow, get an AS2 object, preferring the normalized object if we have one + object_data = + if object do + object.data else - to + if is_map(data["object"]) do + data["object"] + else + %{} + end end - |> Enum.uniq() - query = get_notified_from_activity_query(to, local_only) + # finally extract AS2 mentions from this object + tagged_mentions = + if object_data["tag"] do + object_data["tag"] + |> Enum.filter(fn x -> is_map(x) end) + |> Enum.filter(fn x -> x["type"] == "Mention" end) + |> Enum.map(fn x -> x["href"] end) + else + [] + end - Repo.all(query) - end + # ensure all mentioned users are unique + to = + (to ++ tagged_mentions) + |> Enum.uniq() - def get_notified_from_activity(%Activity{data: %{"to" => to}}, local_only) do query = get_notified_from_activity_query(to, local_only) Repo.all(query) -- cgit v1.2.3 From d26cd6c1bfe1d493b9443f2bd181ce90f22b36a2 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:23:45 +0000 Subject: user: factor out user set fetching from User.get_notified_from_activity() --- lib/pleroma/user.ex | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 71bdbebee..0e4aa0903 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -464,15 +464,15 @@ defmodule Pleroma.User do update_and_set_cache(cs) end - def get_notified_from_activity_query(to, false) do + def get_users_from_set_query(ap_ids, false) do from( u in User, - where: u.ap_id in ^to + where: u.ap_id in ^ap_ids ) end - def get_notified_from_activity_query(to, true) do - query = get_notified_from_activity_query(to, false) + def get_users_from_set_query(ap_ids, true) do + query = get_users_from_set_query(ap_ids, false) from( u in query, @@ -480,6 +480,11 @@ defmodule Pleroma.User do ) end + def get_users_from_set(ap_ids, local_only \\ true) do + get_users_from_set_query(ap_ids, local_only) + |> Repo.all() + end + def get_notified_from_activity(activity, local_only \\ true) def get_notified_from_activity(%Activity{data: %{"to" => to} = data}, local_only) do @@ -513,9 +518,7 @@ defmodule Pleroma.User do (to ++ tagged_mentions) |> Enum.uniq() - query = get_notified_from_activity_query(to, local_only) - - Repo.all(query) + get_users_from_set(to, local_only) end def get_notified_from_activity(_, _), do: [] -- cgit v1.2.3 From cdfdd77e30eb7d83b68d932148cc24a3fbcd5967 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:41:26 +0000 Subject: notification: implement new Notification.get_notified_from_activity() --- lib/pleroma/notification.ex | 60 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 75d7461e4..ca4113d31 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -1,6 +1,6 @@ defmodule Pleroma.Notification do use Ecto.Schema - alias Pleroma.{User, Activity, Notification, Repo} + alias Pleroma.{User, Activity, Notification, Repo, Object} import Ecto.Query schema "notifications" do @@ -95,7 +95,7 @@ defmodule Pleroma.Notification do def create_notifications(%Activity{id: _, data: %{"to" => _, "type" => type}} = activity) when type in ["Create", "Like", "Announce", "Follow"] do - users = User.get_notified_from_activity(activity) + users = get_notified_from_activity(activity) notifications = Enum.map(users, fn user -> create_notification(activity, user) end) {:ok, notifications} @@ -113,4 +113,60 @@ defmodule Pleroma.Notification do notification end end + + def get_notified_from_activity( + %Activity{data: %{"to" => _, "type" => type} = data} = activity, + local_only \\ true + ) + when type in ["Create", "Like", "Announce", "Follow"] do + recipients = + [] + |> maybe_notify_to_recipients(activity) + |> maybe_notify_mentioned_recipients(activity) + |> Enum.uniq() + + User.get_users_from_set(recipients, local_only) + end + + defp maybe_notify_to_recipients( + recipients, + %Activity{data: %{"to" => to, "type" => type}} = activity + ) do + recipients ++ to + end + + defp maybe_notify_mentioned_recipients( + recipients, + %Activity{data: %{"to" => to, "type" => type} = data} = activity + ) + when type == "Create" do + object = Object.normalize(data["object"]) + + object_data = + cond do + !is_nil(object) -> + object.data + + is_map(data["object"]) -> + data["object"] + + true -> + %{} + end + + tagged_mentions = maybe_extract_mentions(object_data) + + recipients ++ tagged_mentions + end + + defp maybe_notify_mentioned_recipients(recipients, _), do: recipients + + defp maybe_extract_mentions(%{"tag" => tag}) do + tag + |> Enum.filter(fn x -> is_map(x) end) + |> Enum.filter(fn x -> x["type"] == "Mention" end) + |> Enum.map(fn x -> x["href"] end) + end + + defp maybe_extract_mentions(_), do: [] end -- cgit v1.2.3 From 6cadfcb21eb58de3d4c635fb563cd4bcebffd3e2 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:42:33 +0000 Subject: activitypub: utils: switch to using new Notification.get_notified_from_activity(). --- lib/pleroma/web/activity_pub/utils.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index fd9c5eb59..a9a4c895b 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -1,5 +1,5 @@ defmodule Pleroma.Web.ActivityPub.Utils do - alias Pleroma.{Repo, Web, Object, Activity, User} + alias Pleroma.{Repo, Web, Object, Activity, User, Notification} alias Pleroma.Web.Router.Helpers alias Pleroma.Web.Endpoint alias Ecto.{Changeset, UUID} @@ -96,7 +96,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do end def get_notified_from_object(object) do - User.get_notified_from_activity(%Activity{data: object}, false) + Notification.get_notified_from_activity(%Activity{data: object}, false) end def create_context(context) do -- cgit v1.2.3 From 8c805ada32ced1e33c5f1c9171f8032c0bf7597d Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:42:49 +0000 Subject: user: remove obsolete User.get_notified_from_activity(). --- lib/pleroma/user.ex | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 0e4aa0903..be634a8e1 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -485,44 +485,6 @@ defmodule Pleroma.User do |> Repo.all() end - def get_notified_from_activity(activity, local_only \\ true) - - def get_notified_from_activity(%Activity{data: %{"to" => to} = data}, local_only) do - object = Object.normalize(data["object"]) - - # somehow, get an AS2 object, preferring the normalized object if we have one - object_data = - if object do - object.data - else - if is_map(data["object"]) do - data["object"] - else - %{} - end - end - - # finally extract AS2 mentions from this object - tagged_mentions = - if object_data["tag"] do - object_data["tag"] - |> Enum.filter(fn x -> is_map(x) end) - |> Enum.filter(fn x -> x["type"] == "Mention" end) - |> Enum.map(fn x -> x["href"] end) - else - [] - end - - # ensure all mentioned users are unique - to = - (to ++ tagged_mentions) - |> Enum.uniq() - - get_users_from_set(to, local_only) - end - - def get_notified_from_activity(_, _), do: [] - def get_recipients_from_activity(%Activity{recipients: to}) do query = from( -- cgit v1.2.3 From b9871e7e5aaf59e92d0fe00e8dfe0de2855a3c12 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:55:52 +0000 Subject: activitypub: utils: wrap Note objects in a Create when extracting mentions --- lib/pleroma/web/activity_pub/utils.ex | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index a9a4c895b..d438236c7 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -95,6 +95,17 @@ defmodule Pleroma.Web.ActivityPub.Utils do "#{Web.base_url()}/#{type}/#{UUID.generate()}" end + def get_notified_from_object(%{"type" => type} = object) when type == "Note" do + fake_create_activity = %{ + "to" => object["to"], + "cc" => object["cc"], + "type" => "Create", + "object" => object + } + + Notification.get_notified_from_activity(%Activity{data: fake_create_activity}, false) + end + def get_notified_from_object(object) do Notification.get_notified_from_activity(%Activity{data: object}, false) end -- cgit v1.2.3 From b3c360ce2c846bfcd89af347382b8d62762c9ceb Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 09:07:40 +0000 Subject: notification: add fallback get_notified_from_activity() --- lib/pleroma/notification.ex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index ca4113d31..a3aeb1221 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -114,9 +114,11 @@ defmodule Pleroma.Notification do end end + def get_notified_from_activity(activity, local_only \\ true) + def get_notified_from_activity( %Activity{data: %{"to" => _, "type" => type} = data} = activity, - local_only \\ true + local_only ) when type in ["Create", "Like", "Announce", "Follow"] do recipients = @@ -128,6 +130,8 @@ defmodule Pleroma.Notification do User.get_users_from_set(recipients, local_only) end + def get_notified_from_activity(_, local_only), do: [] + defp maybe_notify_to_recipients( recipients, %Activity{data: %{"to" => to, "type" => type}} = activity -- cgit v1.2.3 From e4971553c74436b7060f410fe6cbd4f7a9c13b80 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 13:39:44 +0000 Subject: activitypub: utils: use same object type list for mention extraction as insertion --- lib/pleroma/web/activity_pub/utils.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d438236c7..fac91830a 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do import Ecto.Query require Logger + @supported_object_types ["Article", "Note", "Video", "Page"] + # Some implementations send the actor URI as the actor field, others send the entire actor object, # so figure out what the actor's URI is based on what we have. def get_ap_id(object) do @@ -95,7 +97,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do "#{Web.base_url()}/#{type}/#{UUID.generate()}" end - def get_notified_from_object(%{"type" => type} = object) when type == "Note" do + def get_notified_from_object(%{"type" => type} = object) when type in @supported_object_types do fake_create_activity = %{ "to" => object["to"], "cc" => object["cc"], @@ -179,7 +181,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do Inserts a full object if it is contained in an activity. """ def insert_full_object(%{"object" => %{"type" => type} = object_data}) - when is_map(object_data) and type in ["Article", "Note", "Video", "Page"] do + when is_map(object_data) and type in @supported_object_types do with {:ok, _} <- Object.create(object_data) do :ok end -- cgit v1.2.3 From e6d246882da834380ea0903fdad1fa7ef5951277 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 10 Nov 2018 10:05:41 +0000 Subject: federator: don't federate anything other than Note objects to OStatus --- lib/pleroma/web/federator/federator.ex | 11 +++++++---- lib/pleroma/web/ostatus/ostatus.ex | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index 6071d08e4..962cacfa3 100644 --- a/lib/pleroma/web/federator/federator.ex +++ b/lib/pleroma/web/federator/federator.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.Federator do alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.OStatus require Logger @websub Application.get_env(:pleroma, :websub) @@ -63,11 +64,13 @@ defmodule Pleroma.Web.Federator do {:ok, actor} = WebFinger.ensure_keys_present(actor) if ActivityPub.is_public?(activity) do - Logger.info(fn -> "Sending #{activity.data["id"]} out via WebSub" end) - Websub.publish(Pleroma.Web.OStatus.feed_path(actor), actor, activity) + if OStatus.is_representable?(activity) do + Logger.info(fn -> "Sending #{activity.data["id"]} out via WebSub" end) + Websub.publish(Pleroma.Web.OStatus.feed_path(actor), actor, activity) - Logger.info(fn -> "Sending #{activity.data["id"]} out via Salmon" end) - Pleroma.Web.Salmon.publish(actor, activity) + Logger.info(fn -> "Sending #{activity.data["id"]} out via Salmon" end) + Pleroma.Web.Salmon.publish(actor, activity) + end if Keyword.get(Application.get_env(:pleroma, :instance), :allow_relay) do Logger.info(fn -> "Relaying #{activity.data["id"]} out" end) diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index 916c894eb..1d0019d3b 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -11,6 +11,21 @@ defmodule Pleroma.Web.OStatus do alias Pleroma.Web.OStatus.{FollowHandler, UnfollowHandler, NoteHandler, DeleteHandler} alias Pleroma.Web.ActivityPub.Transmogrifier + def is_representable?(%Activity{data: data}) do + object = Object.normalize(data["object"]) + + cond do + is_nil(object) -> + false + + object.data["type"] == "Note" -> + true + + true -> + false + end + end + def feed_path(user) do "#{user.ap_id}/feed.atom" end -- cgit v1.2.3 From 03a9990baf64cfa1abc9fb914ff4b3b24a71d416 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 10 Nov 2018 11:18:25 +0000 Subject: endpoint: fix formatting --- lib/pleroma/web/endpoint.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index b38f33863..2469d7283 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -17,7 +17,8 @@ defmodule Pleroma.Web.Endpoint do Plug.Static, at: "/", from: :pleroma, - only: ~w(index.html static finmoji emoji packs sounds images instance sw.js favicon.png schemas) + only: + ~w(index.html static finmoji emoji packs sounds images instance sw.js favicon.png schemas) ) # Code reloading can be explicitly enabled under the -- cgit v1.2.3 From 4f87b8362b44cf1b628248dbf38eabf670575ca2 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 10 Nov 2018 11:23:50 +0000 Subject: endpoint: move CORSPlug in front of Plug.Static --- lib/pleroma/web/endpoint.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 2469d7283..cb5de087b 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -11,6 +11,8 @@ defmodule Pleroma.Web.Endpoint do # # You should set gzip to true if you are running phoenix.digest # when deploying your static files in production. + plug(CORSPlug) + plug(Plug.Static, at: "/media", from: Pleroma.Uploaders.Local.upload_path(), gzip: false) plug( @@ -57,7 +59,6 @@ defmodule Pleroma.Web.Endpoint do extra: "SameSite=Strict" ) - plug(CORSPlug) plug(Pleroma.Web.Router) @doc """ -- cgit v1.2.3 From f8310114a6a4154118e54ebaac6f4a96941be4a6 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 10 Nov 2018 12:04:09 +0000 Subject: activitypub: object view: sanitize both the activity and the object when an activity is given for rendering --- lib/pleroma/web/activity_pub/views/object_view.ex | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex index df734a871..1911ddfb7 100644 --- a/lib/pleroma/web/activity_pub/views/object_view.ex +++ b/lib/pleroma/web/activity_pub/views/object_view.ex @@ -1,11 +1,23 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do use Pleroma.Web, :view + alias Pleroma.{Object, Activity} alias Pleroma.Web.ActivityPub.Transmogrifier - def render("object.json", %{object: object}) do + def render("object.json", %{object: %Object{} = object}) do base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header() additional = Transmogrifier.prepare_object(object.data) Map.merge(base, additional) end + + def render("object.json", %{object: %Activity{} = activity}) do + base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header() + object = Object.normalize(activity.data["object"]) + + additional = + Transmogrifier.prepare_object(activity.data) + |> Map.put("object", Transmogrifier.prepare_object(object.data)) + + Map.merge(base, additional) + end end -- cgit v1.2.3 From e1814bb322dda732143fdb0cb60dbce82fe433da Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Fri, 13 Jul 2018 01:02:18 +0200 Subject: Document mix tasks --- lib/mix/tasks/make_moderator.ex | 9 ++++++++- lib/mix/tasks/register_user.ex | 8 ++++++++ lib/mix/tasks/set_locked.ex | 11 ++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/make_moderator.ex b/lib/mix/tasks/make_moderator.ex index a454a958e..000671c44 100644 --- a/lib/mix/tasks/make_moderator.ex +++ b/lib/mix/tasks/make_moderator.ex @@ -1,9 +1,16 @@ defmodule Mix.Tasks.SetModerator do + @moduledoc """ + Set moderator to a local user + + Usage: ``mix set_moderator `` + + Example: ``mix set_moderator lain`` + """ + use Mix.Task import Mix.Ecto alias Pleroma.{Repo, User} - @shortdoc "Set moderator status" def run([nickname | rest]) do Application.ensure_all_started(:pleroma) diff --git a/lib/mix/tasks/register_user.ex b/lib/mix/tasks/register_user.ex index e74721c49..1f5321093 100644 --- a/lib/mix/tasks/register_user.ex +++ b/lib/mix/tasks/register_user.ex @@ -1,4 +1,12 @@ defmodule Mix.Tasks.RegisterUser do + @moduledoc """ + Manually register a local user + + Usage: ``mix register_user `` + + Example: ``mix register_user 仮面の告白 lain lain@example.org "blushy-crushy fediverse idol + pleroma dev" pleaseDontHeckLain`` + """ + use Mix.Task alias Pleroma.{Repo, User} diff --git a/lib/mix/tasks/set_locked.ex b/lib/mix/tasks/set_locked.ex index 2b3b18b09..a154595ca 100644 --- a/lib/mix/tasks/set_locked.ex +++ b/lib/mix/tasks/set_locked.ex @@ -1,9 +1,18 @@ defmodule Mix.Tasks.SetLocked do + @moduledoc """ + Lock a local user + + The local user will then have to manually accept/reject followers. This can also be done by the user into their settings. + + Usage: ``mix set_locked `` + + Example: ``mix set_locked lain`` + """ + use Mix.Task import Mix.Ecto alias Pleroma.{Repo, User} - @shortdoc "Set locked status" def run([nickname | rest]) do ensure_started(Repo, []) -- cgit v1.2.3 From 8b2541e4e7fb37f38422bf6c02cc10863a927e61 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Fri, 2 Nov 2018 09:32:48 +0100 Subject: Document the mix tasks in ex_doc instead --- lib/mix/tasks/deactivate_user.ex | 8 +++++++- lib/mix/tasks/generate_config.ex | 10 +++++++++- lib/mix/tasks/generate_invite_token.ex | 9 ++++++++- lib/mix/tasks/make_moderator.ex | 2 +- lib/mix/tasks/rm_user.ex | 8 +++++++- 5 files changed, 32 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/deactivate_user.ex b/lib/mix/tasks/deactivate_user.ex index f18541787..e71ed1ec0 100644 --- a/lib/mix/tasks/deactivate_user.ex +++ b/lib/mix/tasks/deactivate_user.ex @@ -2,7 +2,13 @@ defmodule Mix.Tasks.DeactivateUser do use Mix.Task alias Pleroma.User - @shortdoc "Deactivate a user" + @moduledoc """ + Deactivates a user (local or remote) + + Usage: ``mix deactivate_user `` + + Example: ``mix deactivate_user lain`` + """ def run([nickname]) do Mix.Task.run("app.start") diff --git a/lib/mix/tasks/generate_config.ex b/lib/mix/tasks/generate_config.ex index 70a110561..e3cbbf131 100644 --- a/lib/mix/tasks/generate_config.ex +++ b/lib/mix/tasks/generate_config.ex @@ -1,7 +1,15 @@ defmodule Mix.Tasks.GenerateConfig do use Mix.Task - @shortdoc "Generates a new config" + @moduledoc """ + Generate a new config + + ## Usage + ``mix generate_config`` + + This mix task is interactive, and will overwrite the config present at ``config/generated_config.exs``. + """ + def run(_) do IO.puts("Answer a few questions to generate a new config\n") IO.puts("--- THIS WILL OVERWRITE YOUR config/generated_config.exs! ---\n") diff --git a/lib/mix/tasks/generate_invite_token.ex b/lib/mix/tasks/generate_invite_token.ex index c4daa9a6c..418ef3790 100644 --- a/lib/mix/tasks/generate_invite_token.ex +++ b/lib/mix/tasks/generate_invite_token.ex @@ -1,7 +1,14 @@ defmodule Mix.Tasks.GenerateInviteToken do use Mix.Task - @shortdoc "Generate invite token for user" + @moduledoc """ + Generates invite token + + This is in the form of a URL to be used by the Invited user to register themselves. + + ## Usage + ``mix generate_invite_token`` + """ def run([]) do Mix.Task.run("app.start") diff --git a/lib/mix/tasks/make_moderator.ex b/lib/mix/tasks/make_moderator.ex index 000671c44..15586dc30 100644 --- a/lib/mix/tasks/make_moderator.ex +++ b/lib/mix/tasks/make_moderator.ex @@ -2,7 +2,7 @@ defmodule Mix.Tasks.SetModerator do @moduledoc """ Set moderator to a local user - Usage: ``mix set_moderator `` + Usage: ``mix set_moderator `` Example: ``mix set_moderator lain`` """ diff --git a/lib/mix/tasks/rm_user.ex b/lib/mix/tasks/rm_user.ex index b7c922d6c..50463046c 100644 --- a/lib/mix/tasks/rm_user.ex +++ b/lib/mix/tasks/rm_user.ex @@ -2,7 +2,13 @@ defmodule Mix.Tasks.RmUser do use Mix.Task alias Pleroma.User - @shortdoc "Permanently delete a user" + @moduledoc """ + Permanently deletes a user + + Usage: ``mix rm_user [nickname]`` + + Example: ``mix rm_user lain`` + """ def run([nickname]) do Mix.Task.run("app.start") -- cgit v1.2.3 From 64c0289893e870cf3f5525fdffb6b25ab3cc2f25 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 8 Nov 2018 15:21:09 +0100 Subject: lib/mix/tasks: Add remaining documentation for mix tasks --- lib/mix/tasks/generate_password_reset.ex | 8 +++++++- lib/mix/tasks/reactivate_user.ex | 8 +++++++- lib/mix/tasks/relay_follow.ex | 7 +++++++ lib/mix/tasks/relay_unfollow.ex | 8 +++++++- lib/mix/tasks/unsubscribe_user.ex | 9 ++++++++- 5 files changed, 36 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/generate_password_reset.ex b/lib/mix/tasks/generate_password_reset.ex index 6bf640150..e581e2e11 100644 --- a/lib/mix/tasks/generate_password_reset.ex +++ b/lib/mix/tasks/generate_password_reset.ex @@ -2,7 +2,13 @@ defmodule Mix.Tasks.GeneratePasswordReset do use Mix.Task alias Pleroma.User - @shortdoc "Generate password reset link for user" + @doc """ + Generate password reset link for user + + Usage: ``mix generate_password_reset `` + + Example: ``mix generate_password_reset lain`` + """ def run([nickname]) do Mix.Task.run("app.start") diff --git a/lib/mix/tasks/reactivate_user.ex b/lib/mix/tasks/reactivate_user.ex index 40bd068ea..41e4cbbec 100644 --- a/lib/mix/tasks/reactivate_user.ex +++ b/lib/mix/tasks/reactivate_user.ex @@ -2,7 +2,13 @@ defmodule Mix.Tasks.ReactivateUser do use Mix.Task alias Pleroma.User - @shortdoc "Reactivate a user" + @doc """ + Reactivate a user + + Usage: ``mix reactivate_user `` + + Example: ``mix reactivate_user lain`` + """ def run([nickname]) do Mix.Task.run("app.start") diff --git a/lib/mix/tasks/relay_follow.ex b/lib/mix/tasks/relay_follow.ex index ac6f20924..7428ec6ef 100644 --- a/lib/mix/tasks/relay_follow.ex +++ b/lib/mix/tasks/relay_follow.ex @@ -4,6 +4,13 @@ defmodule Mix.Tasks.RelayFollow do alias Pleroma.Web.ActivityPub.Relay @shortdoc "Follows a remote relay" + @doc """ + Follows a remote relay + + Usage: ``mix relay_follow `` + + Example: ``mix relay_follow https://example.org/relay`` + """ def run([target]) do Mix.Task.run("app.start") diff --git a/lib/mix/tasks/relay_unfollow.ex b/lib/mix/tasks/relay_unfollow.ex index 4621ace83..cb13a0729 100644 --- a/lib/mix/tasks/relay_unfollow.ex +++ b/lib/mix/tasks/relay_unfollow.ex @@ -3,7 +3,13 @@ defmodule Mix.Tasks.RelayUnfollow do require Logger alias Pleroma.Web.ActivityPub.Relay - @shortdoc "Follows a remote relay" + @doc """ + Unfollows a remote relay + + Usage: ``mix relay_follow `` + + Example: ``mix relay_follow https://example.org/relay`` + """ def run([target]) do Mix.Task.run("app.start") diff --git a/lib/mix/tasks/unsubscribe_user.ex b/lib/mix/tasks/unsubscribe_user.ex index bb72634b6..75811374b 100644 --- a/lib/mix/tasks/unsubscribe_user.ex +++ b/lib/mix/tasks/unsubscribe_user.ex @@ -3,7 +3,14 @@ defmodule Mix.Tasks.UnsubscribeUser do alias Pleroma.{User, Repo} require Logger - @shortdoc "Unsubscribe all users from a target and then deactivate them" + @doc """ + Deactivate and Unsubscribe local users from a user + + Usage: ``mix unsubscribe_user `` + + Example: ``mix unsubscribe_user lain`` + """ + def run([nickname]) do def run([nickname]) do Mix.Task.run("app.start") -- cgit v1.2.3 From 5e3207045e5c58c4c0ebb5d37d0cbfbd5a7db4db Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 8 Nov 2018 15:26:11 +0100 Subject: lib/mix/tasks/unsubscribe_user.ex: Fix syntax from bad line copy --- lib/mix/tasks/unsubscribe_user.ex | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/mix/tasks/unsubscribe_user.ex b/lib/mix/tasks/unsubscribe_user.ex index 75811374b..fe4f7d479 100644 --- a/lib/mix/tasks/unsubscribe_user.ex +++ b/lib/mix/tasks/unsubscribe_user.ex @@ -10,7 +10,6 @@ defmodule Mix.Tasks.UnsubscribeUser do Example: ``mix unsubscribe_user lain`` """ - def run([nickname]) do def run([nickname]) do Mix.Task.run("app.start") -- cgit v1.2.3 From 5ecb5629f6714cf20df3ac28eef585822fb2ea45 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 8 Nov 2018 15:28:50 +0100 Subject: lib/mix/tasks: s/@doc/@moduledoc/ --- lib/mix/tasks/generate_password_reset.ex | 2 +- lib/mix/tasks/reactivate_user.ex | 2 +- lib/mix/tasks/relay_follow.ex | 2 +- lib/mix/tasks/relay_unfollow.ex | 2 +- lib/mix/tasks/unsubscribe_user.ex | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/generate_password_reset.ex b/lib/mix/tasks/generate_password_reset.ex index e581e2e11..f7f4c4f59 100644 --- a/lib/mix/tasks/generate_password_reset.ex +++ b/lib/mix/tasks/generate_password_reset.ex @@ -2,7 +2,7 @@ defmodule Mix.Tasks.GeneratePasswordReset do use Mix.Task alias Pleroma.User - @doc """ + @moduledoc """ Generate password reset link for user Usage: ``mix generate_password_reset `` diff --git a/lib/mix/tasks/reactivate_user.ex b/lib/mix/tasks/reactivate_user.ex index 41e4cbbec..a30d3ac8b 100644 --- a/lib/mix/tasks/reactivate_user.ex +++ b/lib/mix/tasks/reactivate_user.ex @@ -2,7 +2,7 @@ defmodule Mix.Tasks.ReactivateUser do use Mix.Task alias Pleroma.User - @doc """ + @moduledoc """ Reactivate a user Usage: ``mix reactivate_user `` diff --git a/lib/mix/tasks/relay_follow.ex b/lib/mix/tasks/relay_follow.ex index 7428ec6ef..4d57c6bca 100644 --- a/lib/mix/tasks/relay_follow.ex +++ b/lib/mix/tasks/relay_follow.ex @@ -4,7 +4,7 @@ defmodule Mix.Tasks.RelayFollow do alias Pleroma.Web.ActivityPub.Relay @shortdoc "Follows a remote relay" - @doc """ + @moduledoc """ Follows a remote relay Usage: ``mix relay_follow `` diff --git a/lib/mix/tasks/relay_unfollow.ex b/lib/mix/tasks/relay_unfollow.ex index cb13a0729..bd69fd8a0 100644 --- a/lib/mix/tasks/relay_unfollow.ex +++ b/lib/mix/tasks/relay_unfollow.ex @@ -3,7 +3,7 @@ defmodule Mix.Tasks.RelayUnfollow do require Logger alias Pleroma.Web.ActivityPub.Relay - @doc """ + @moduledoc """ Unfollows a remote relay Usage: ``mix relay_follow `` diff --git a/lib/mix/tasks/unsubscribe_user.ex b/lib/mix/tasks/unsubscribe_user.ex index fe4f7d479..62ea61a5c 100644 --- a/lib/mix/tasks/unsubscribe_user.ex +++ b/lib/mix/tasks/unsubscribe_user.ex @@ -3,7 +3,7 @@ defmodule Mix.Tasks.UnsubscribeUser do alias Pleroma.{User, Repo} require Logger - @doc """ + @moduledoc """ Deactivate and Unsubscribe local users from a user Usage: ``mix unsubscribe_user `` -- cgit v1.2.3 From 97e50f3191f6ea8479729b639921180fcadccf73 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 10 Nov 2018 12:08:53 +0000 Subject: activitypub: transmogrifier: sanitize internal representation details from outgoing objects this causes JSON-LD parsers to get upset and has also lead to developer confusion from outside projects which tried to parse our internal data. accordingly, it seems better to just remove it. --- lib/pleroma/web/activity_pub/transmogrifier.ex | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 6a0fdb433..d51d8626b 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -589,6 +589,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> prepare_attachments |> set_conversation |> set_reply_to_uri + |> strip_internal_fields + |> strip_internal_tags end # @doc @@ -755,6 +757,29 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> Map.put("attachment", attachments) end + defp strip_internal_fields(object) do + object + |> Map.drop([ + "likes", + "like_count", + "announcements", + "announcement_count", + "emoji", + "context_id" + ]) + end + + defp strip_internal_tags(%{"tag" => tags} = object) do + tags = + tags + |> Enum.filter(fn x -> is_map(x) end) + + object + |> Map.put("tag", tags) + end + + defp strip_internal_tags(object), do: object + defp user_upgrade_task(user) do old_follower_address = User.ap_followers(user) -- cgit v1.2.3 From 419ed3a0ca62dbcc4ea3985f6561e2aad4b48e5b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 11 Nov 2018 05:11:27 +0000 Subject: oauth: fix token decode regression --- lib/pleroma/web/oauth/oauth_controller.ex | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 35c158fbb..d03c8b05a 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -143,8 +143,11 @@ defmodule Pleroma.Web.OAuth.OAuthController do end end + # XXX - for whatever reason our token arrives urlencoded, but Plug.Conn should be + # decoding it. Investigate sometime. defp fix_padding(token) do token + |> URI.decode() |> Base.url_decode64!(padding: false) |> Base.url_encode64() end -- cgit v1.2.3 From f516e317ea639bf0d2cdf3d1f1e2e00b5b7c90ef Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 11 Nov 2018 06:10:21 +0000 Subject: plugs: add CSPPlug --- lib/pleroma/plugs/csp_plug.ex | 38 ++++++++++++++++++++++++++++++++++++++ lib/pleroma/web/endpoint.ex | 1 + 2 files changed, 39 insertions(+) create mode 100644 lib/pleroma/plugs/csp_plug.ex (limited to 'lib') diff --git a/lib/pleroma/plugs/csp_plug.ex b/lib/pleroma/plugs/csp_plug.ex new file mode 100644 index 000000000..15d466c36 --- /dev/null +++ b/lib/pleroma/plugs/csp_plug.ex @@ -0,0 +1,38 @@ +defmodule Pleroma.Plugs.CSPPlug do + import Plug.Conn + + def init(opts), do: opts + + def call(conn, options) do + conn = merge_resp_headers(conn, headers()) + end + + defp headers do + [ + {"x-xss-protection", "1; mode=block"}, + {"x-permitted-cross-domain-policies", "none"}, + {"x-frame-options", "DENY"}, + {"x-content-type-options", "nosniff"}, + {"referrer-policy", "same-origin"}, + {"x-download-options", "noopen"}, + {"content-security-policy", csp_string() <> ";"} + ] + end + + defp csp_string do + [ + "default-src 'none'", + "base-uri 'self'", + "form-action *", + "frame-ancestors 'none'", + "img-src 'self' data: https:", + "media-src 'self' https:", + "style-src 'self' 'unsafe-inline'", + "font-src 'self'", + "script-src 'self'", + "connect-src 'self' " <> String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws"), + "upgrade-insecure-requests" + ] + |> Enum.join("; ") + end +end diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index cb5de087b..370d2d792 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -12,6 +12,7 @@ defmodule Pleroma.Web.Endpoint do # You should set gzip to true if you are running phoenix.digest # when deploying your static files in production. plug(CORSPlug) + plug(Pleroma.Plugs.CSPPlug) plug(Plug.Static, at: "/media", from: Pleroma.Uploaders.Local.upload_path(), gzip: false) -- cgit v1.2.3 From a2bf5426cb84940dbd58aec10a7b1b0a90f26a60 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 11 Nov 2018 06:42:14 +0000 Subject: sample config: document how to make CSPPlug send STS headers (off by default to allow for SSL debugging) --- lib/mix/tasks/sample_config.eex | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/mix/tasks/sample_config.eex b/lib/mix/tasks/sample_config.eex index 3881ead26..824bc97a1 100644 --- a/lib/mix/tasks/sample_config.eex +++ b/lib/mix/tasks/sample_config.eex @@ -25,6 +25,10 @@ config :pleroma, Pleroma.Repo, hostname: "localhost", pool_size: 10 +# Enable Strict-Transport-Security once SSL is working: +# config :pleroma, :csp, +# sts: true + # Configure S3 support if desired. # The public S3 endpoint is different depending on region and provider, # consult your S3 provider's documentation for details on what to use. -- cgit v1.2.3 From 331cf6ada1e4df51b366c79126e094ee335dd684 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 11 Nov 2018 06:50:28 +0000 Subject: csp plug: add sts support --- lib/pleroma/plugs/csp_plug.ex | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/plugs/csp_plug.ex b/lib/pleroma/plugs/csp_plug.ex index 15d466c36..56f2376ee 100644 --- a/lib/pleroma/plugs/csp_plug.ex +++ b/lib/pleroma/plugs/csp_plug.ex @@ -1,10 +1,17 @@ defmodule Pleroma.Plugs.CSPPlug do + alias Pleroma.Config import Plug.Conn def init(opts), do: opts def call(conn, options) do - conn = merge_resp_headers(conn, headers()) + if Config.get([:csp, :enabled]) do + conn = + merge_resp_headers(conn, headers()) + |> maybe_send_sts_header(Config.get([:csp, :sts])) + else + conn + end end defp headers do @@ -35,4 +42,14 @@ defmodule Pleroma.Plugs.CSPPlug do ] |> Enum.join("; ") end + + defp maybe_send_sts_header(conn, true) do + max_age = Config.get([:csp, :sts_max_age]) + + merge_resp_headers(conn, [ + {"strict-transport-security", "max-age=#{max_age}; includeSubDomains"} + ]) + end + + defp maybe_send_sts_header(conn, _), do: conn end -- cgit v1.2.3 From df72978dce3805157537e8fa1a2fec35fcf9a7cd Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 11 Nov 2018 06:53:42 +0000 Subject: csp plug: add support for certificate transparency --- lib/pleroma/plugs/csp_plug.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/plugs/csp_plug.ex b/lib/pleroma/plugs/csp_plug.ex index 56f2376ee..8fc21b909 100644 --- a/lib/pleroma/plugs/csp_plug.ex +++ b/lib/pleroma/plugs/csp_plug.ex @@ -44,10 +44,12 @@ defmodule Pleroma.Plugs.CSPPlug do end defp maybe_send_sts_header(conn, true) do - max_age = Config.get([:csp, :sts_max_age]) + max_age_sts = Config.get([:csp, :sts_max_age]) + max_age_ct = Config.get([:csp, :ct_max_age]) merge_resp_headers(conn, [ - {"strict-transport-security", "max-age=#{max_age}; includeSubDomains"} + {"strict-transport-security", "max-age=#{max_age_sts}; includeSubDomains"}, + {"expect-ct", "enforce, max-age=#{max_age_ct}"} ]) end -- cgit v1.2.3 From 1592fa2bea45eeea770044d619868087ef2591cb Mon Sep 17 00:00:00 2001 From: KokaKiwi Date: Sun, 11 Nov 2018 04:33:14 +0100 Subject: Mastodon API: Fix list streaming --- lib/pleroma/web/mastodon_api/mastodon_socket.ex | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/mastodon_socket.ex b/lib/pleroma/web/mastodon_api/mastodon_socket.ex index bc628ba56..0f3d5ff7c 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_socket.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_socket.ex @@ -26,15 +26,19 @@ defmodule Pleroma.Web.MastodonAPI.MastodonSocket do "list", "hashtag" ] <- params["stream"] do - topic = if stream == "list", do: "list:#{params["list"]}", else: stream - socket_stream = if stream == "hashtag", do: "hashtag:#{params["tag"]}", else: stream + topic = + case stream do + "hashtag" -> "hashtag:#{params["tag"]}" + "list" -> "list:#{params["list"]}" + _ -> stream + end socket = socket |> assign(:topic, topic) |> assign(:user, user) - Pleroma.Web.Streamer.add_socket(socket_stream, socket) + Pleroma.Web.Streamer.add_socket(topic, socket) {:ok, socket} else _e -> :error -- cgit v1.2.3 From fe67665e19cc98faff4a8ee53a3f4ca4190ca2ef Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 12 Nov 2018 15:08:02 +0000 Subject: rename CSPPlug to HTTPSecurityPlug. --- lib/pleroma/plugs/csp_plug.ex | 57 --------------------------------- lib/pleroma/plugs/http_security_plug.ex | 57 +++++++++++++++++++++++++++++++++ lib/pleroma/web/endpoint.ex | 2 +- 3 files changed, 58 insertions(+), 58 deletions(-) delete mode 100644 lib/pleroma/plugs/csp_plug.ex create mode 100644 lib/pleroma/plugs/http_security_plug.ex (limited to 'lib') diff --git a/lib/pleroma/plugs/csp_plug.ex b/lib/pleroma/plugs/csp_plug.ex deleted file mode 100644 index 8fc21b909..000000000 --- a/lib/pleroma/plugs/csp_plug.ex +++ /dev/null @@ -1,57 +0,0 @@ -defmodule Pleroma.Plugs.CSPPlug do - alias Pleroma.Config - import Plug.Conn - - def init(opts), do: opts - - def call(conn, options) do - if Config.get([:csp, :enabled]) do - conn = - merge_resp_headers(conn, headers()) - |> maybe_send_sts_header(Config.get([:csp, :sts])) - else - conn - end - end - - defp headers do - [ - {"x-xss-protection", "1; mode=block"}, - {"x-permitted-cross-domain-policies", "none"}, - {"x-frame-options", "DENY"}, - {"x-content-type-options", "nosniff"}, - {"referrer-policy", "same-origin"}, - {"x-download-options", "noopen"}, - {"content-security-policy", csp_string() <> ";"} - ] - end - - defp csp_string do - [ - "default-src 'none'", - "base-uri 'self'", - "form-action *", - "frame-ancestors 'none'", - "img-src 'self' data: https:", - "media-src 'self' https:", - "style-src 'self' 'unsafe-inline'", - "font-src 'self'", - "script-src 'self'", - "connect-src 'self' " <> String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws"), - "upgrade-insecure-requests" - ] - |> Enum.join("; ") - end - - defp maybe_send_sts_header(conn, true) do - max_age_sts = Config.get([:csp, :sts_max_age]) - max_age_ct = Config.get([:csp, :ct_max_age]) - - merge_resp_headers(conn, [ - {"strict-transport-security", "max-age=#{max_age_sts}; includeSubDomains"}, - {"expect-ct", "enforce, max-age=#{max_age_ct}"} - ]) - end - - defp maybe_send_sts_header(conn, _), do: conn -end diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex new file mode 100644 index 000000000..8d652a2f3 --- /dev/null +++ b/lib/pleroma/plugs/http_security_plug.ex @@ -0,0 +1,57 @@ +defmodule Pleroma.Plugs.HTTPSecurityPlug do + alias Pleroma.Config + import Plug.Conn + + def init(opts), do: opts + + def call(conn, options) do + if Config.get([:http_security, :enabled]) do + conn = + merge_resp_headers(conn, headers()) + |> maybe_send_sts_header(Config.get([:http_security, :sts])) + else + conn + end + end + + defp headers do + [ + {"x-xss-protection", "1; mode=block"}, + {"x-permitted-cross-domain-policies", "none"}, + {"x-frame-options", "DENY"}, + {"x-content-type-options", "nosniff"}, + {"referrer-policy", "same-origin"}, + {"x-download-options", "noopen"}, + {"content-security-policy", csp_string() <> ";"} + ] + end + + defp csp_string do + [ + "default-src 'none'", + "base-uri 'self'", + "form-action *", + "frame-ancestors 'none'", + "img-src 'self' data: https:", + "media-src 'self' https:", + "style-src 'self' 'unsafe-inline'", + "font-src 'self'", + "script-src 'self'", + "connect-src 'self' " <> String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws"), + "upgrade-insecure-requests" + ] + |> Enum.join("; ") + end + + defp maybe_send_sts_header(conn, true) do + max_age_sts = Config.get([:http_security, :sts_max_age]) + max_age_ct = Config.get([:http_security, :ct_max_age]) + + merge_resp_headers(conn, [ + {"strict-transport-security", "max-age=#{max_age_sts}; includeSubDomains"}, + {"expect-ct", "enforce, max-age=#{max_age_ct}"} + ]) + end + + defp maybe_send_sts_header(conn, _), do: conn +end diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 370d2d792..7783b8e5c 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -12,7 +12,7 @@ defmodule Pleroma.Web.Endpoint do # You should set gzip to true if you are running phoenix.digest # when deploying your static files in production. plug(CORSPlug) - plug(Pleroma.Plugs.CSPPlug) + plug(Pleroma.Plugs.HTTPSecurityPlug) plug(Plug.Static, at: "/media", from: Pleroma.Uploaders.Local.upload_path(), gzip: false) -- cgit v1.2.3 From ee5932a504d69e591aad7bdd52bd97d1f92d4e32 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 12 Nov 2018 15:14:46 +0000 Subject: http security: allow referrer-policy to be configured --- lib/pleroma/plugs/http_security_plug.ex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex index 8d652a2f3..960c7f6bf 100644 --- a/lib/pleroma/plugs/http_security_plug.ex +++ b/lib/pleroma/plugs/http_security_plug.ex @@ -15,12 +15,14 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do end defp headers do + referrer_policy = Config.get([:http_security, :referrer_policy]) + [ {"x-xss-protection", "1; mode=block"}, {"x-permitted-cross-domain-policies", "none"}, {"x-frame-options", "DENY"}, {"x-content-type-options", "nosniff"}, - {"referrer-policy", "same-origin"}, + {"referrer-policy", referrer_policy}, {"x-download-options", "noopen"}, {"content-security-policy", csp_string() <> ";"} ] -- cgit v1.2.3 From 2829fa41830ad8565fc186c3dc110f4d275f8827 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 12 Nov 2018 15:17:04 +0000 Subject: sample config: chase http_security change --- lib/mix/tasks/sample_config.eex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mix/tasks/sample_config.eex b/lib/mix/tasks/sample_config.eex index 824bc97a1..462c34636 100644 --- a/lib/mix/tasks/sample_config.eex +++ b/lib/mix/tasks/sample_config.eex @@ -26,7 +26,7 @@ config :pleroma, Pleroma.Repo, pool_size: 10 # Enable Strict-Transport-Security once SSL is working: -# config :pleroma, :csp, +# config :pleroma, :http_security, # sts: true # Configure S3 support if desired. -- cgit v1.2.3 From cb6fd738614a016fc143221a5ae588aa82f3a251 Mon Sep 17 00:00:00 2001 From: scarlett Date: Mon, 12 Nov 2018 15:38:39 +0000 Subject: Twitter API: Fall back to user.nickname if user has no name --- lib/pleroma/web/twitter_api/views/user_view.ex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index a662f83b6..a100a1127 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -55,8 +55,12 @@ defmodule Pleroma.Web.TwitterAPI.UserView do "statusnet_blocking" => statusnet_blocking, "friends_count" => user_info[:following_count], "id" => user.id, - "name" => user.name, - "name_html" => HTML.strip_tags(user.name) |> Formatter.emojify(emoji), + "name" => user.name || user.nickname, + "name_html" => + if(user.name, + do: HTML.strip_tags(user.name) |> Formatter.emojify(emoji), + else: user.nickname + ), "profile_image_url" => image, "profile_image_url_https" => image, "profile_image_url_profile_size" => image, -- cgit v1.2.3 From 87c76a9a2fa95702df05e935c8eb232188df1318 Mon Sep 17 00:00:00 2001 From: shibayashi Date: Tue, 13 Nov 2018 00:32:38 +0100 Subject: Add __Host- prefix when secure flag is enabled --- lib/pleroma/web/endpoint.ex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 7783b8e5c..85bb4ff5f 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -46,13 +46,18 @@ defmodule Pleroma.Web.Endpoint do plug(Plug.MethodOverride) plug(Plug.Head) + cookie_name = + if Application.get_env(:pleroma, Pleroma.Web.Endpoint) |> Keyword.get(:secure_cookie_flag), + do: "__Host-pleroma_key", + else: "pleroma_key" + # The session will be stored in the cookie and signed, # this means its contents can be read but not tampered with. # Set :encryption_salt if you would also like to encrypt it. plug( Plug.Session, store: :cookie, - key: "_pleroma_key", + key: cookie_name, signing_salt: "CqaoopA2", http_only: true, secure: -- cgit v1.2.3 From 9b553a1087a3539280a4a085bcf7a79f29972f0a Mon Sep 17 00:00:00 2001 From: href Date: Tue, 13 Nov 2018 15:58:02 +0100 Subject: media_proxy: CSP, content-disposition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adds CSP headers to the media proxy endpoint * Sends `content-disposition: attachment; …` for non-image/video/audio content types The default list can be overwritten with `:media_proxy, :safe_content_types` in the configuration. * Also now appends the filename to the proxy URL (fixes some mobile apps, it was requested a while ago) --- lib/pleroma/web/media_proxy/controller.ex | 44 ++++++++++++++++++++++++++++-- lib/pleroma/web/media_proxy/media_proxy.ex | 5 +++- lib/pleroma/web/router.ex | 2 +- 3 files changed, 46 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/media_proxy/controller.ex b/lib/pleroma/web/media_proxy/controller.ex index 8195a665e..10e6b4e52 100644 --- a/lib/pleroma/web/media_proxy/controller.ex +++ b/lib/pleroma/web/media_proxy/controller.ex @@ -11,15 +11,47 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do error: "public, must-revalidate, max-age=160" } - def remote(conn, %{"sig" => sig, "url" => url}) do + # Content-types that will not be returned as content-disposition attachments + # Override with :media_proxy, :safe_content_types in the configuration + @safe_content_types [ + "image/gif", + "image/jpeg", + "image/jpg", + "image/png", + "image/svg+xml", + "audio/mpeg", + "audio/mp3", + "video/webm", + "video/mp4" + ] + + def remote(conn, params = %{"sig" => sig, "url" => url}) do config = Application.get_env(:pleroma, :media_proxy, []) with true <- Keyword.get(config, :enabled, false), {:ok, url} <- Pleroma.Web.MediaProxy.decode_url(sig, url), - {:ok, content_type, body} <- proxy_request(url) do + filename <- Path.basename(url), + true <- + if(Map.get(params, "filename"), + do: filename == Path.basename(conn.request_path), + else: true + ), + {:ok, content_type, body} <- proxy_request(url), + safe_content_type <- + Enum.member?( + Keyword.get(config, :safe_content_types, @safe_content_types), + content_type + ) do conn |> put_resp_content_type(content_type) |> set_cache_header(:default) + |> put_resp_header( + "content-security-policy", + "default-src 'none'; style-src 'unsafe-inline'; media-src data:; img-src 'self' data:" + ) + |> put_resp_header("x-xss-protection", "1; mode=block") + |> put_resp_header("x-content-type-options", "nosniff") + |> put_attachement_header(safe_content_type, filename) |> send_resp(200, body) else false -> @@ -92,6 +124,12 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do # TODO: the body is passed here as well because some hosts do not provide a content-type. # At some point we may want to use magic numbers to discover the content-type and reply a proper one. defp proxy_request_content_type(headers, _body) do - headers["Content-Type"] || headers["content-type"] || "image/jpeg" + headers["Content-Type"] || headers["content-type"] || "application/octet-stream" + end + + defp put_attachement_header(conn, true, _), do: conn + + defp put_attachement_header(conn, false, filename) do + put_resp_header(conn, "content-disposition", "attachment; filename='#{filename}'") end end diff --git a/lib/pleroma/web/media_proxy/media_proxy.ex b/lib/pleroma/web/media_proxy/media_proxy.ex index 37718f48b..6819c0917 100644 --- a/lib/pleroma/web/media_proxy/media_proxy.ex +++ b/lib/pleroma/web/media_proxy/media_proxy.ex @@ -15,7 +15,10 @@ defmodule Pleroma.Web.MediaProxy do base64 = Base.url_encode64(url, @base64_opts) sig = :crypto.hmac(:sha, secret, base64) sig64 = sig |> Base.url_encode64(@base64_opts) - Keyword.get(config, :base_url, Pleroma.Web.base_url()) <> "/proxy/#{sig64}/#{base64}" + filename = Path.basename(url) + + Keyword.get(config, :base_url, Pleroma.Web.base_url()) <> + "/proxy/#{sig64}/#{base64}/#{filename}" end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 06d0f0623..2d4302dcd 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -378,12 +378,12 @@ defmodule Pleroma.Web.Router do end pipeline :remote_media do - plug(:accepts, ["html"]) end scope "/proxy/", Pleroma.Web.MediaProxy do pipe_through(:remote_media) get("/:sig/:url", MediaProxyController, :remote) + get("/:sig/:url/:filename", MediaProxyController, :remote) end scope "/", Fallback do -- cgit v1.2.3 From 2cf40237ff44cdb04b20546ca51efb671270dbc2 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 13 Nov 2018 19:46:34 +0100 Subject: MastodonAPI: Add pagination to private messages. --- lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 83728c81e..a0b74311b 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -278,9 +278,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - def dm_timeline(%{assigns: %{user: user}} = conn, _params) do + def dm_timeline(%{assigns: %{user: user}} = conn, params) do query = - ActivityPub.fetch_activities_query([user.ap_id], %{"type" => "Create", visibility: "direct"}) + ActivityPub.fetch_activities_query( + [user.ap_id], + Map.merge(params, %{"type" => "Create", visibility: "direct"}) + ) activities = Repo.all(query) -- cgit v1.2.3 From ea9a776d7beb32b157269652759b85cdc17fec32 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 13 Nov 2018 20:08:50 +0100 Subject: TwitterApi: Add direct message endpoint --- lib/pleroma/web/router.ex | 1 + lib/pleroma/web/twitter_api/twitter_api_controller.ex | 13 +++++++++++++ 2 files changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 06d0f0623..7384f054b 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -270,6 +270,7 @@ defmodule Pleroma.Web.Router do get("/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline) get("/statuses/mentions", TwitterAPI.Controller, :mentions_timeline) get("/statuses/mentions_timeline", TwitterAPI.Controller, :mentions_timeline) + get("/statuses/dm_timeline", TwitterAPI.Controller, :dm_timeline) get("/qvitter/statuses/notifications", TwitterAPI.Controller, :notifications) # XXX: this is really a pleroma API, but we want to keep the pleroma namespace clean diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 727469a66..dfcafdcc9 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -126,6 +126,19 @@ defmodule Pleroma.Web.TwitterAPI.Controller do |> render(ActivityView, "index.json", %{activities: activities, for: user}) end + def dm_timeline(%{assigns: %{user: user}} = conn, params) do + query = + ActivityPub.fetch_activities_query( + [user.ap_id], + Map.merge(params, %{"type" => "Create", visibility: "direct"}) + ) + + activities = Repo.all(query) + + conn + |> render(ActivityView, "index.json", %{activities: activities, for: user}) + end + def notifications(%{assigns: %{user: user}} = conn, params) do notifications = Notification.for_user(user, params) -- cgit v1.2.3 From f52a1d1ec5d44eb882b7bebf4d3242737ff9701b Mon Sep 17 00:00:00 2001 From: href Date: Tue, 13 Nov 2018 23:41:33 +0100 Subject: media_proxy: use path only to retrieve filename --- lib/pleroma/web/media_proxy/controller.ex | 2 +- lib/pleroma/web/media_proxy/media_proxy.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/media_proxy/controller.ex b/lib/pleroma/web/media_proxy/controller.ex index 10e6b4e52..bb257c262 100644 --- a/lib/pleroma/web/media_proxy/controller.ex +++ b/lib/pleroma/web/media_proxy/controller.ex @@ -30,7 +30,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do with true <- Keyword.get(config, :enabled, false), {:ok, url} <- Pleroma.Web.MediaProxy.decode_url(sig, url), - filename <- Path.basename(url), + filename <- Path.basename(URI.parse(url).path), true <- if(Map.get(params, "filename"), do: filename == Path.basename(conn.request_path), diff --git a/lib/pleroma/web/media_proxy/media_proxy.ex b/lib/pleroma/web/media_proxy/media_proxy.ex index 6819c0917..93c36b4ed 100644 --- a/lib/pleroma/web/media_proxy/media_proxy.ex +++ b/lib/pleroma/web/media_proxy/media_proxy.ex @@ -15,7 +15,7 @@ defmodule Pleroma.Web.MediaProxy do base64 = Base.url_encode64(url, @base64_opts) sig = :crypto.hmac(:sha, secret, base64) sig64 = sig |> Base.url_encode64(@base64_opts) - filename = Path.basename(url) + filename = Path.basename(URI.parse(url).path) Keyword.get(config, :base_url, Pleroma.Web.base_url()) <> "/proxy/#{sig64}/#{base64}/#{filename}" -- cgit v1.2.3