aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/application.ex24
-rw-r--r--lib/pleroma/conversation/participation.ex10
-rw-r--r--lib/pleroma/html.ex4
-rw-r--r--lib/pleroma/object.ex88
-rw-r--r--lib/pleroma/object/fetcher.ex2
-rw-r--r--lib/pleroma/plugs/oauth_scopes_plug.ex9
-rw-r--r--lib/pleroma/uploaders/local.ex13
-rw-r--r--lib/pleroma/uploaders/mdii.ex37
-rw-r--r--lib/pleroma/uploaders/s3.ex14
-rw-r--r--lib/pleroma/uploaders/uploader.ex3
-rw-r--r--lib/pleroma/user.ex59
-rw-r--r--lib/pleroma/utils.ex12
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex40
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub_controller.ex6
-rw-r--r--lib/pleroma/web/activity_pub/mrf/drop_policy.ex2
-rw-r--r--lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex2
-rw-r--r--lib/pleroma/web/activity_pub/publisher.ex8
-rw-r--r--lib/pleroma/web/activity_pub/relay.ex4
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex2
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex11
-rw-r--r--lib/pleroma/web/activity_pub/views/user_view.ex8
-rw-r--r--lib/pleroma/web/endpoint.ex2
-rw-r--r--lib/pleroma/web/federator/federator.ex8
-rw-r--r--lib/pleroma/web/federator/publisher.ex2
-rw-r--r--lib/pleroma/web/masto_fe_controller.ex25
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex3
-rw-r--r--lib/pleroma/web/metadata/twitter_card.ex2
-rw-r--r--lib/pleroma/web/metadata/utils.ex2
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex2
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex9
-rw-r--r--lib/pleroma/web/router.ex4
-rw-r--r--lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex11
-rw-r--r--lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex14
-rw-r--r--lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex (renamed from lib/pleroma/web/templates/twitter_api/util/followed.html.eex)0
-rw-r--r--lib/pleroma/web/templates/twitter_api/util/follow.html.eex11
-rw-r--r--lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex14
-rw-r--r--lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex112
-rw-r--r--lib/pleroma/web/twitter_api/controllers/util_controller.ex103
-rw-r--r--lib/pleroma/web/twitter_api/views/remote_follow_view.ex10
39 files changed, 449 insertions, 243 deletions
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index 5b844aa41..2ae052069 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -5,6 +5,7 @@
defmodule Pleroma.Application do
import Cachex.Spec
use Application
+ require Logger
@name Mix.Project.config()[:name]
@version Mix.Project.config()[:version]
@@ -33,6 +34,7 @@ defmodule Pleroma.Application do
Pleroma.HTML.compile_scrubbers()
Pleroma.Config.DeprecationWarnings.warn()
setup_instrumenters()
+ load_custom_modules()
# Define workers and child supervisors to be supervised
children =
@@ -68,6 +70,28 @@ defmodule Pleroma.Application do
Supervisor.start_link(children, opts)
end
+ def load_custom_modules do
+ dir = Pleroma.Config.get([:modules, :runtime_dir])
+
+ if dir && File.exists?(dir) do
+ dir
+ |> Pleroma.Utils.compile_dir()
+ |> case do
+ {:error, _errors, _warnings} ->
+ raise "Invalid custom modules"
+
+ {:ok, modules, _warnings} ->
+ if @env != :test do
+ Enum.each(modules, fn mod ->
+ Logger.info("Custom module loaded: #{inspect(mod)}")
+ end)
+ end
+
+ :ok
+ end
+ end
+ end
+
defp setup_instrumenters do
require Prometheus.Registry
diff --git a/lib/pleroma/conversation/participation.ex b/lib/pleroma/conversation/participation.ex
index aafe57280..e5d28ebff 100644
--- a/lib/pleroma/conversation/participation.ex
+++ b/lib/pleroma/conversation/participation.ex
@@ -64,11 +64,13 @@ defmodule Pleroma.Conversation.Participation do
end
def mark_as_read(participation) do
- participation
- |> read_cng(%{read: true})
- |> Repo.update()
+ __MODULE__
+ |> where(id: ^participation.id)
+ |> update(set: [read: true])
+ |> select([p], p)
+ |> Repo.update_all([])
|> case do
- {:ok, participation} ->
+ {1, [participation]} ->
participation = Repo.preload(participation, :user)
User.set_unread_conversation_count(participation.user)
{:ok, participation}
diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex
index 2cae29f35..11513106e 100644
--- a/lib/pleroma/html.ex
+++ b/lib/pleroma/html.ex
@@ -10,9 +10,7 @@ defmodule Pleroma.HTML do
dir = Path.join(:code.priv_dir(:pleroma), "scrubbers")
dir
- |> File.ls!()
- |> Enum.map(&Path.join(dir, &1))
- |> Kernel.ParallelCompiler.compile()
+ |> Pleroma.Utils.compile_dir()
|> case do
{:error, _errors, _warnings} ->
raise "Compiling scrubbers failed"
diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex
index eb37b95a6..2452a7389 100644
--- a/lib/pleroma/object.ex
+++ b/lib/pleroma/object.ex
@@ -17,6 +17,8 @@ defmodule Pleroma.Object do
require Logger
+ @type t() :: %__MODULE__{}
+
schema "objects" do
field(:data, :map)
@@ -79,6 +81,20 @@ defmodule Pleroma.Object do
Repo.one(from(object in Object, where: fragment("(?)->>'id' = ?", object.data, ^ap_id)))
end
+ @doc """
+ Get a single attachment by it's name and href
+ """
+ @spec get_attachment_by_name_and_href(String.t(), String.t()) :: Object.t() | nil
+ def get_attachment_by_name_and_href(name, href) do
+ query =
+ from(o in Object,
+ where: fragment("(?)->>'name' = ?", o.data, ^name),
+ where: fragment("(?)->>'href' = ?", o.data, ^href)
+ )
+
+ Repo.one(query)
+ end
+
defp warn_on_no_object_preloaded(ap_id) do
"Object.normalize() called without preloaded object (#{inspect(ap_id)}). Consider preloading the object"
|> Logger.debug()
@@ -164,6 +180,7 @@ defmodule Pleroma.Object do
def delete(%Object{data: %{"id" => id}} = object) do
with {:ok, _obj} = swap_object_with_tombstone(object),
+ :ok <- delete_attachments(object),
deleted_activity = Activity.delete_all_by_object_ap_id(id),
{:ok, true} <- Cachex.del(:object_cache, "object:#{id}"),
{:ok, _} <- Cachex.del(:web_resp_cache, URI.parse(id).path) do
@@ -171,6 +188,77 @@ defmodule Pleroma.Object do
end
end
+ defp delete_attachments(%{data: %{"attachment" => [_ | _] = attachments, "actor" => actor}}) do
+ hrefs =
+ Enum.flat_map(attachments, fn attachment ->
+ Enum.map(attachment["url"], & &1["href"])
+ end)
+
+ names = Enum.map(attachments, & &1["name"])
+
+ uploader = Pleroma.Config.get([Pleroma.Upload, :uploader])
+
+ # find all objects for copies of the attachments, name and actor doesn't matter here
+ delete_ids =
+ from(o in Object,
+ where:
+ fragment(
+ "to_jsonb(array(select jsonb_array_elements((?)#>'{url}') ->> 'href'))::jsonb \\?| (?)",
+ o.data,
+ ^hrefs
+ )
+ )
+ |> Repo.all()
+ # we should delete 1 object for any given attachment, but don't delete files if
+ # there are more than 1 object for it
+ |> Enum.reduce(%{}, fn %{
+ id: id,
+ data: %{
+ "url" => [%{"href" => href}],
+ "actor" => obj_actor,
+ "name" => name
+ }
+ },
+ acc ->
+ Map.update(acc, href, %{id: id, count: 1}, fn val ->
+ case obj_actor == actor and name in names do
+ true ->
+ # set id of the actor's object that will be deleted
+ %{val | id: id, count: val.count + 1}
+
+ false ->
+ # another actor's object, just increase count to not delete file
+ %{val | count: val.count + 1}
+ end
+ end)
+ end)
+ |> Enum.map(fn {href, %{id: id, count: count}} ->
+ # only delete files that have single instance
+ with 1 <- count do
+ prefix =
+ case Pleroma.Config.get([Pleroma.Upload, :base_url]) do
+ nil -> "media"
+ _ -> ""
+ end
+
+ base_url = Pleroma.Config.get([__MODULE__, :base_url], Pleroma.Web.base_url())
+
+ file_path = String.trim_leading(href, "#{base_url}/#{prefix}")
+
+ uploader.delete_file(file_path)
+ end
+
+ id
+ end)
+
+ from(o in Object, where: o.id in ^delete_ids)
+ |> Repo.delete_all()
+
+ :ok
+ end
+
+ defp delete_attachments(%{data: _data}), do: :ok
+
def prune(%Object{data: %{"id" => id}} = object) do
with {:ok, object} <- Repo.delete(object),
{:ok, true} <- Cachex.del(:object_cache, "object:#{id}"),
diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex
index 4d71c91a8..a1bde90f1 100644
--- a/lib/pleroma/object/fetcher.ex
+++ b/lib/pleroma/object/fetcher.ex
@@ -154,7 +154,7 @@ defmodule Pleroma.Object.Fetcher do
end
def fetch_and_contain_remote_object_from_id(id) when is_binary(id) do
- Logger.info("Fetching object #{id} via AP")
+ Logger.debug("Fetching object #{id} via AP")
date = Pleroma.Signature.signed_date()
diff --git a/lib/pleroma/plugs/oauth_scopes_plug.ex b/lib/pleroma/plugs/oauth_scopes_plug.ex
index 174a8389c..07c0f7fdb 100644
--- a/lib/pleroma/plugs/oauth_scopes_plug.ex
+++ b/lib/pleroma/plugs/oauth_scopes_plug.ex
@@ -18,16 +18,13 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do
token = assigns[:token]
scopes = transform_scopes(scopes, options)
- matched_scopes = token && filter_descendants(scopes, token.scopes)
+ matched_scopes = (token && filter_descendants(scopes, token.scopes)) || []
cond do
- is_nil(token) ->
- maybe_perform_instance_privacy_check(conn, options)
-
- op == :| && Enum.any?(matched_scopes) ->
+ token && op == :| && Enum.any?(matched_scopes) ->
conn
- op == :& && matched_scopes == scopes ->
+ token && op == :& && matched_scopes == scopes ->
conn
options[:fallback] == :proceed_unauthenticated ->
diff --git a/lib/pleroma/uploaders/local.ex b/lib/pleroma/uploaders/local.ex
index 36b3c35ec..2e6fe3292 100644
--- a/lib/pleroma/uploaders/local.ex
+++ b/lib/pleroma/uploaders/local.ex
@@ -5,10 +5,12 @@
defmodule Pleroma.Uploaders.Local do
@behaviour Pleroma.Uploaders.Uploader
+ @impl true
def get_file(_) do
{:ok, {:static_dir, upload_path()}}
end
+ @impl true
def put_file(upload) do
{local_path, file} =
case Enum.reverse(Path.split(upload.path)) do
@@ -33,4 +35,15 @@ defmodule Pleroma.Uploaders.Local do
def upload_path do
Pleroma.Config.get!([__MODULE__, :uploads])
end
+
+ @impl true
+ def delete_file(path) do
+ upload_path()
+ |> Path.join(path)
+ |> File.rm()
+ |> case do
+ :ok -> :ok
+ {:error, posix_error} -> {:error, to_string(posix_error)}
+ end
+ end
end
diff --git a/lib/pleroma/uploaders/mdii.ex b/lib/pleroma/uploaders/mdii.ex
deleted file mode 100644
index c36f3d61d..000000000
--- a/lib/pleroma/uploaders/mdii.ex
+++ /dev/null
@@ -1,37 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Uploaders.MDII do
- @moduledoc "Represents uploader for https://github.com/hakaba-hitoyo/minimal-digital-image-infrastructure"
-
- alias Pleroma.Config
- alias Pleroma.HTTP
-
- @behaviour Pleroma.Uploaders.Uploader
-
- # MDII-hosted images are never passed through the MediaPlug; only local media.
- # Delegate to Pleroma.Uploaders.Local
- def get_file(file) do
- Pleroma.Uploaders.Local.get_file(file)
- end
-
- def put_file(upload) do
- cgi = Config.get([Pleroma.Uploaders.MDII, :cgi])
- files = Config.get([Pleroma.Uploaders.MDII, :files])
-
- {:ok, file_data} = File.read(upload.tempfile)
-
- extension = String.split(upload.name, ".") |> List.last()
- query = "#{cgi}?#{extension}"
-
- with {:ok, %{status: 200, body: body}} <-
- HTTP.post(query, file_data, [], adapter: [pool: :default]) do
- remote_file_name = String.split(body) |> List.first()
- public_url = "#{files}/#{remote_file_name}.#{extension}"
- {:ok, {:url, public_url}}
- else
- _ -> Pleroma.Uploaders.Local.put_file(upload)
- end
- end
-end
diff --git a/lib/pleroma/uploaders/s3.ex b/lib/pleroma/uploaders/s3.ex
index 9876b6398..feb89cea6 100644
--- a/lib/pleroma/uploaders/s3.ex
+++ b/lib/pleroma/uploaders/s3.ex
@@ -10,6 +10,7 @@ defmodule Pleroma.Uploaders.S3 do
# The file name is re-encoded with S3's constraints here to comply with previous
# links with less strict filenames
+ @impl true
def get_file(file) do
config = Config.get([__MODULE__])
bucket = Keyword.fetch!(config, :bucket)
@@ -35,6 +36,7 @@ defmodule Pleroma.Uploaders.S3 do
])}}
end
+ @impl true
def put_file(%Pleroma.Upload{} = upload) do
config = Config.get([__MODULE__])
bucket = Keyword.get(config, :bucket)
@@ -69,6 +71,18 @@ defmodule Pleroma.Uploaders.S3 do
end
end
+ @impl true
+ def delete_file(file) do
+ [__MODULE__, :bucket]
+ |> Config.get()
+ |> ExAws.S3.delete_object(file)
+ |> ExAws.request()
+ |> case do
+ {:ok, %{status_code: 204}} -> :ok
+ error -> {:error, inspect(error)}
+ end
+ end
+
@regex Regex.compile!("[^0-9a-zA-Z!.*/'()_-]")
def strict_encode(name) do
String.replace(name, @regex, "-")
diff --git a/lib/pleroma/uploaders/uploader.ex b/lib/pleroma/uploaders/uploader.ex
index c0b22c28a..d71e213d2 100644
--- a/lib/pleroma/uploaders/uploader.ex
+++ b/lib/pleroma/uploaders/uploader.ex
@@ -36,6 +36,8 @@ defmodule Pleroma.Uploaders.Uploader do
@callback put_file(Pleroma.Upload.t()) ::
:ok | {:ok, file_spec()} | {:error, String.t()} | :wait_callback
+ @callback delete_file(file :: String.t()) :: :ok | {:error, String.t()}
+
@callback http_callback(Plug.Conn.t(), Map.t()) ::
{:ok, Plug.Conn.t()}
| {:ok, Plug.Conn.t(), file_spec()}
@@ -43,7 +45,6 @@ defmodule Pleroma.Uploaders.Uploader do
@optional_callbacks http_callback: 2
@spec put_file(module(), Pleroma.Upload.t()) :: {:ok, file_spec()} | {:error, String.t()}
-
def put_file(uploader, upload) do
case uploader.put_file(upload) do
:ok -> {:ok, {:file, upload.path}}
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 706aee2ff..2e225415c 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -1430,20 +1430,47 @@ defmodule Pleroma.User do
Creates an internal service actor by URI if missing.
Optionally takes nickname for addressing.
"""
- def get_or_create_service_actor_by_ap_id(uri, nickname \\ nil) do
- with user when is_nil(user) <- get_cached_by_ap_id(uri) do
- {:ok, user} =
- %User{
- invisible: true,
- local: true,
- ap_id: uri,
- nickname: nickname,
- follower_address: uri <> "/followers"
- }
- |> Repo.insert()
+ @spec get_or_create_service_actor_by_ap_id(String.t(), String.t()) :: User.t() | nil
+ def get_or_create_service_actor_by_ap_id(uri, nickname) do
+ {_, user} =
+ case get_cached_by_ap_id(uri) do
+ nil ->
+ with {:error, %{errors: errors}} <- create_service_actor(uri, nickname) do
+ Logger.error("Cannot create service actor: #{uri}/.\n#{inspect(errors)}")
+ {:error, nil}
+ end
- user
- end
+ %User{invisible: false} = user ->
+ set_invisible(user)
+
+ user ->
+ {:ok, user}
+ end
+
+ user
+ end
+
+ @spec set_invisible(User.t()) :: {:ok, User.t()}
+ defp set_invisible(user) do
+ user
+ |> change(%{invisible: true})
+ |> update_and_set_cache()
+ end
+
+ @spec create_service_actor(String.t(), String.t()) ::
+ {:ok, User.t()} | {:error, Ecto.Changeset.t()}
+ defp create_service_actor(uri, nickname) do
+ %User{
+ invisible: true,
+ local: true,
+ ap_id: uri,
+ nickname: nickname,
+ follower_address: uri <> "/followers"
+ }
+ |> change
+ |> unique_constraint(:nickname)
+ |> Repo.insert()
+ |> set_cache()
end
# AP style
@@ -1855,9 +1882,9 @@ defmodule Pleroma.User do
])
with {:ok, updated_user} <- update_and_set_cache(changeset) do
- if user.is_admin && !updated_user.is_admin do
- # Tokens & authorizations containing any admin scopes must be revoked (revoking all).
- # This is an extra safety measure (tokens' admin scopes won't be accepted for non-admins).
+ if user.is_admin != updated_user.is_admin do
+ # Admin status change results in change of accessible OAuth scopes, and instead of changing
+ # already issued tokens we revoke them, requiring user to sign in again
global_sign_out(user)
end
diff --git a/lib/pleroma/utils.ex b/lib/pleroma/utils.ex
new file mode 100644
index 000000000..8d36a0001
--- /dev/null
+++ b/lib/pleroma/utils.ex
@@ -0,0 +1,12 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Utils do
+ def compile_dir(dir) when is_binary(dir) do
+ dir
+ |> File.ls!()
+ |> Enum.map(&Path.join(dir, &1))
+ |> Kernel.ParallelCompiler.compile()
+ end
+end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 16e6b0057..60c9e7e64 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -1298,28 +1298,26 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def fetch_follow_information_for_user(user) do
with {:ok, following_data} <-
Fetcher.fetch_and_contain_remote_object_from_id(user.following_address),
- following_count when is_integer(following_count) <- following_data["totalItems"],
{:ok, hide_follows} <- collection_private(following_data),
{:ok, followers_data} <-
Fetcher.fetch_and_contain_remote_object_from_id(user.follower_address),
- followers_count when is_integer(followers_count) <- followers_data["totalItems"],
{:ok, hide_followers} <- collection_private(followers_data) do
{:ok,
%{
hide_follows: hide_follows,
- follower_count: followers_count,
- following_count: following_count,
+ follower_count: normalize_counter(followers_data["totalItems"]),
+ following_count: normalize_counter(following_data["totalItems"]),
hide_followers: hide_followers
}}
else
- {:error, _} = e ->
- e
-
- e ->
- {:error, e}
+ {:error, _} = e -> e
+ e -> {:error, e}
end
end
+ defp normalize_counter(counter) when is_integer(counter), do: counter
+ defp normalize_counter(_), do: 0
+
defp maybe_update_follow_information(data) do
with {:enabled, true} <-
{:enabled, Pleroma.Config.get([:instance, :external_user_synchronization])},
@@ -1339,24 +1337,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
end
+ defp collection_private(%{"first" => %{"type" => type}})
+ when type in ["CollectionPage", "OrderedCollectionPage"],
+ do: {:ok, false}
+
defp collection_private(%{"first" => first}) do
- if is_map(first) and
- first["type"] in ["CollectionPage", "OrderedCollectionPage"] do
+ with {:ok, %{"type" => type}} when type in ["CollectionPage", "OrderedCollectionPage"] <-
+ Fetcher.fetch_and_contain_remote_object_from_id(first) do
{:ok, false}
else
- with {:ok, %{"type" => type}} when type in ["CollectionPage", "OrderedCollectionPage"] <-
- Fetcher.fetch_and_contain_remote_object_from_id(first) do
- {:ok, false}
- else
- {:error, {:ok, %{status: code}}} when code in [401, 403] ->
- {:ok, true}
-
- {:error, _} = e ->
- e
-
- e ->
- {:error, e}
- end
+ {:error, {:ok, %{status: code}}} when code in [401, 403] -> {:ok, true}
+ {:error, _} = e -> e
+ e -> {:error, e}
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 dec5da0d3..5059e3984 100644
--- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
@@ -257,7 +257,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
# only accept relayed Creates
def inbox(conn, %{"type" => "Create"} = params) do
- Logger.info(
+ Logger.debug(
"Signature missing or not from author, relayed Create message, fetching object from source"
)
@@ -270,11 +270,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
headers = Enum.into(conn.req_headers, %{})
if String.contains?(headers["signature"], params["actor"]) do
- Logger.info(
+ Logger.debug(
"Signature validation error for: #{params["actor"]}, make sure you are forwarding the HTTP Host header!"
)
- Logger.info(inspect(conn.req_headers))
+ Logger.debug(inspect(conn.req_headers))
end
json(conn, dgettext("errors", "error"))
diff --git a/lib/pleroma/web/activity_pub/mrf/drop_policy.ex b/lib/pleroma/web/activity_pub/mrf/drop_policy.ex
index f7831bc3e..4a5709974 100644
--- a/lib/pleroma/web/activity_pub/mrf/drop_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/drop_policy.ex
@@ -9,7 +9,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.DropPolicy do
@impl true
def filter(object) do
- Logger.info("REJECTING #{inspect(object)}")
+ Logger.debug("REJECTING #{inspect(object)}")
{:reject, object}
end
diff --git a/lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex b/lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex
index 26b8539fe..df774b0f7 100644
--- a/lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
]
def perform(:prefetch, url) do
- Logger.info("Prefetching #{inspect(url)}")
+ Logger.debug("Prefetching #{inspect(url)}")
url
|> MediaProxy.url()
diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex
index 4073d3d63..e4e3ab44a 100644
--- a/lib/pleroma/web/activity_pub/publisher.ex
+++ b/lib/pleroma/web/activity_pub/publisher.ex
@@ -48,7 +48,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
* `id`: the ActivityStreams URI of the message
"""
def publish_one(%{inbox: inbox, json: json, actor: %User{} = actor, id: id} = params) do
- Logger.info("Federating #{id} to #{inbox}")
+ Logger.debug("Federating #{id} to #{inbox}")
%{host: host, path: path} = URI.parse(inbox)
digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64())
@@ -228,7 +228,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
public = is_public?(activity)
if public && Config.get([:instance, :allow_relay]) do
- Logger.info(fn -> "Relaying #{activity.data["id"]} out" end)
+ Logger.debug(fn -> "Relaying #{activity.data["id"]} out" end)
Relay.publish(activity)
end
@@ -264,6 +264,10 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
"rel" => "self",
"type" => "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href" => user.ap_id
+ },
+ %{
+ "rel" => "http://ostatus.org/schema/1.0/subscribe",
+ "template" => "#{Pleroma.Web.base_url()}/ostatus_subscribe?acct={uri}"
}
]
end
diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex
index 99a804568..48a1b71e0 100644
--- a/lib/pleroma/web/activity_pub/relay.ex
+++ b/lib/pleroma/web/activity_pub/relay.ex
@@ -9,10 +9,12 @@ defmodule Pleroma.Web.ActivityPub.Relay do
alias Pleroma.Web.ActivityPub.ActivityPub
require Logger
+ @relay_nickname "relay"
+
def get_actor do
actor =
relay_ap_id()
- |> User.get_or_create_service_actor_by_ap_id()
+ |> User.get_or_create_service_actor_by_ap_id(@relay_nickname)
actor
end
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index ecba27bef..3fa789d53 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -397,7 +397,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
%{"type" => "Create", "object" => %{"type" => objtype} = object} = data,
options
)
- when objtype in ["Article", "Note", "Video", "Page", "Question", "Answer"] do
+ when objtype in ["Article", "Event", "Note", "Video", "Page", "Question", "Answer"] do
actor = Containment.get_actor(data)
data =
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index e87d09134..db7084246 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -22,7 +22,16 @@ defmodule Pleroma.Web.ActivityPub.Utils do
require Logger
require Pleroma.Constants
- @supported_object_types ["Article", "Note", "Video", "Page", "Question", "Answer", "Audio"]
+ @supported_object_types [
+ "Article",
+ "Note",
+ "Event",
+ "Video",
+ "Page",
+ "Question",
+ "Answer",
+ "Audio"
+ ]
@strip_status_report_states ~w(closed resolved)
@supported_report_states ~w(open closed resolved)
@valid_visibilities ~w(public unlisted private direct)
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index 9059aa634..350c4391d 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -201,7 +201,6 @@ defmodule Pleroma.Web.ActivityPub.UserView do
%{
"id" => "#{user.ap_id}/followers",
"type" => "OrderedCollection",
- "totalItems" => total,
"first" =>
if showing_items do
collection(followers, "#{user.ap_id}/followers", 1, showing_items, total)
@@ -209,6 +208,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"#{user.ap_id}/followers?page=1"
end
}
+ |> maybe_put_total_items(showing_count, total)
|> Map.merge(Utils.make_json_ld_header())
end
@@ -251,6 +251,12 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|> Map.merge(Utils.make_json_ld_header())
end
+ defp maybe_put_total_items(map, false, _total), do: map
+
+ defp maybe_put_total_items(map, true, total) do
+ Map.put(map, "totalItems", total)
+ end
+
def collection(collection, iri, page, show_items \\ true, total \\ nil) do
offset = (page - 1) * 10
items = Enum.slice(collection, offset, 10)
diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex
index bbea31682..d32c38a05 100644
--- a/lib/pleroma/web/endpoint.ex
+++ b/lib/pleroma/web/endpoint.ex
@@ -59,7 +59,7 @@ defmodule Pleroma.Web.Endpoint do
plug(Pleroma.Plugs.TrailingFormatPlug)
plug(Plug.RequestId)
- plug(Plug.Logger)
+ plug(Plug.Logger, log: :debug)
plug(Pleroma.Plugs.Parsers)
diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex
index e8a56ebd7..f506a7d24 100644
--- a/lib/pleroma/web/federator/federator.ex
+++ b/lib/pleroma/web/federator/federator.ex
@@ -58,7 +58,7 @@ defmodule Pleroma.Web.Federator do
end
def perform(:incoming_ap_doc, params) do
- Logger.info("Handling incoming AP activity")
+ Logger.debug("Handling incoming AP activity")
params = Utils.normalize_params(params)
@@ -71,13 +71,13 @@ defmodule Pleroma.Web.Federator do
{:ok, activity}
else
%Activity{} ->
- Logger.info("Already had #{params["id"]}")
+ Logger.debug("Already had #{params["id"]}")
:error
_e ->
# Just drop those for now
- Logger.info("Unhandled activity")
- Logger.info(Jason.encode!(params, pretty: true))
+ Logger.debug("Unhandled activity")
+ Logger.debug(Jason.encode!(params, pretty: true))
:error
end
end
diff --git a/lib/pleroma/web/federator/publisher.ex b/lib/pleroma/web/federator/publisher.ex
index fb9b26649..1d045c644 100644
--- a/lib/pleroma/web/federator/publisher.ex
+++ b/lib/pleroma/web/federator/publisher.ex
@@ -47,7 +47,7 @@ defmodule Pleroma.Web.Federator.Publisher do
Config.get([:instance, :federation_publisher_modules])
|> Enum.each(fn module ->
if module.is_representable?(activity) do
- Logger.info("Publishing #{activity.data["id"]} using #{inspect(module)}")
+ Logger.debug("Publishing #{activity.data["id"]} using #{inspect(module)}")
module.publish(user, activity)
end
end)
diff --git a/lib/pleroma/web/masto_fe_controller.ex b/lib/pleroma/web/masto_fe_controller.ex
index ca261ad6e..9f7e4943c 100644
--- a/lib/pleroma/web/masto_fe_controller.ex
+++ b/lib/pleroma/web/masto_fe_controller.ex
@@ -20,18 +20,21 @@ defmodule Pleroma.Web.MastoFEController do
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action != :index)
@doc "GET /web/*path"
- def index(%{assigns: %{user: user}} = conn, _params) do
- token = get_session(conn, :oauth_token)
+ def index(%{assigns: %{user: user, token: token}} = conn, _params)
+ when not is_nil(user) and not is_nil(token) do
+ conn
+ |> put_layout(false)
+ |> render("index.html",
+ token: token.token,
+ user: user,
+ custom_emojis: Pleroma.Emoji.get_all()
+ )
+ end
- if user && token do
- conn
- |> put_layout(false)
- |> render("index.html", token: token, user: user, custom_emojis: Pleroma.Emoji.get_all())
- else
- conn
- |> put_session(:return_to, conn.request_path)
- |> redirect(to: "/web/login")
- end
+ def index(conn, _params) do
+ conn
+ |> put_session(:return_to, conn.request_path)
+ |> redirect(to: "/web/login")
end
@doc "GET /web/manifest.json"
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index a0257dfa6..e9590224b 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -421,7 +421,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
end
- def render_content(%{data: %{"type" => "Video"}} = object) do
+ def render_content(%{data: %{"type" => object_type}} = object)
+ when object_type in ["Video", "Event"] do
with name when not is_nil(name) and name != "" <- object.data["name"] do
"<p><a href=\"#{object.data["id"]}\">#{name}</a></p>#{object.data["content"]}"
else
diff --git a/lib/pleroma/web/metadata/twitter_card.ex b/lib/pleroma/web/metadata/twitter_card.ex
index d6a6049b3..67419a666 100644
--- a/lib/pleroma/web/metadata/twitter_card.ex
+++ b/lib/pleroma/web/metadata/twitter_card.ex
@@ -31,7 +31,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
if attachments == [] or Metadata.activity_nsfw?(object) do
[
image_tag(user),
- {:meta, [property: "twitter:card", content: "summary_large_image"], []}
+ {:meta, [property: "twitter:card", content: "summary"], []}
]
else
attachments
diff --git a/lib/pleroma/web/metadata/utils.ex b/lib/pleroma/web/metadata/utils.ex
index c0dae1b7e..000bd9f66 100644
--- a/lib/pleroma/web/metadata/utils.ex
+++ b/lib/pleroma/web/metadata/utils.ex
@@ -15,6 +15,7 @@ defmodule Pleroma.Web.Metadata.Utils do
|> String.replace(~r/<br\s?\/?>/, " ")
|> HTML.get_cached_stripped_html_for_activity(object, "metadata")
|> Emoji.Formatter.demojify()
+ |> HtmlEntities.decode()
|> Formatter.truncate()
end
@@ -22,6 +23,7 @@ defmodule Pleroma.Web.Metadata.Utils do
content
|> scrub_html
|> Emoji.Formatter.demojify()
+ |> HtmlEntities.decode()
|> Formatter.truncate(max_length)
end
diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex
index 69dfa92e3..0bbf84fd3 100644
--- a/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex
@@ -52,7 +52,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
@doc """
Lists the packs available on the instance as JSON.
- The information is public and does not require authentification. The format is
+ The information is public and does not require authentication. The format is
a map of "pack directory name" to pack.json contents.
"""
def list_packs(conn, _params) do
diff --git a/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex b/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
index 8fed3f5bb..772c535a4 100644
--- a/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
@@ -22,7 +22,14 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
plug(
OAuthScopesPlug,
- %{scopes: ["read:statuses"]} when action in [:conversation, :conversation_statuses]
+ %{scopes: ["read:statuses"]}
+ when action in [:conversation, :conversation_statuses, :emoji_reactions_by]
+ )
+
+ plug(
+ OAuthScopesPlug,
+ %{scopes: ["write:statuses"]}
+ when action in [:react_with_emoji, :unreact_with_emoji]
)
plug(
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index b32cd7c90..787d300fb 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -229,9 +229,9 @@ defmodule Pleroma.Web.Router do
pipe_through(:pleroma_html)
post("/main/ostatus", UtilController, :remote_subscribe)
- get("/ostatus_subscribe", UtilController, :remote_follow)
+ get("/ostatus_subscribe", RemoteFollowController, :follow)
- post("/ostatus_subscribe", UtilController, :do_remote_follow)
+ post("/ostatus_subscribe", RemoteFollowController, :do_follow)
end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
diff --git a/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex
new file mode 100644
index 000000000..5ba192cd7
--- /dev/null
+++ b/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex
@@ -0,0 +1,11 @@
+<%= if @error == :error do %>
+ <h2>Error fetching user</h2>
+<% else %>
+ <h2>Remote follow</h2>
+ <img height="128" width="128" src="<%= avatar_url(@followee) %>">
+ <p><%= @followee.nickname %></p>
+ <%= form_for @conn, remote_follow_path(@conn, :do_follow), [as: "user"], fn f -> %>
+ <%= hidden_input f, :id, value: @followee.id %>
+ <%= submit "Authorize" %>
+ <% end %>
+<% end %>
diff --git a/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex
new file mode 100644
index 000000000..df44988ee
--- /dev/null
+++ b/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex
@@ -0,0 +1,14 @@
+<%= if @error do %>
+<h2><%= @error %></h2>
+<% end %>
+<h2>Log in to follow</h2>
+<p><%= @followee.nickname %></p>
+<img height="128" width="128" src="<%= avatar_url(@followee) %>">
+<%= form_for @conn, remote_follow_path(@conn, :do_follow), [as: "authorization"], fn f -> %>
+<%= text_input f, :name, placeholder: "Username", required: true %>
+<br>
+<%= password_input f, :password, placeholder: "Password", required: true %>
+<br>
+<%= hidden_input f, :id, value: @followee.id %>
+<%= submit "Authorize" %>
+<% end %>
diff --git a/lib/pleroma/web/templates/twitter_api/util/followed.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex
index da473d502..da473d502 100644
--- a/lib/pleroma/web/templates/twitter_api/util/followed.html.eex
+++ b/lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex
diff --git a/lib/pleroma/web/templates/twitter_api/util/follow.html.eex b/lib/pleroma/web/templates/twitter_api/util/follow.html.eex
deleted file mode 100644
index 06359fa6c..000000000
--- a/lib/pleroma/web/templates/twitter_api/util/follow.html.eex
+++ /dev/null
@@ -1,11 +0,0 @@
-<%= if @error == :error do %>
- <h2>Error fetching user</h2>
-<% else %>
- <h2>Remote follow</h2>
- <img width="128" height="128" src="<%= @avatar %>">
- <p><%= @name %></p>
- <%= form_for @conn, util_path(@conn, :do_remote_follow), [as: "user"], fn f -> %>
- <%= hidden_input f, :id, value: @id %>
- <%= submit "Authorize" %>
- <% end %>
-<% end %>
diff --git a/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex b/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex
deleted file mode 100644
index 4e3a2be67..000000000
--- a/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex
+++ /dev/null
@@ -1,14 +0,0 @@
-<%= if @error do %>
- <h2><%= @error %></h2>
-<% end %>
-<h2>Log in to follow</h2>
-<p><%= @name %></p>
-<img height="128" width="128" src="<%= @avatar %>">
-<%= form_for @conn, util_path(@conn, :do_remote_follow), [as: "authorization"], fn f -> %>
-<%= text_input f, :name, placeholder: "Username" %>
-<br>
-<%= password_input f, :password, placeholder: "Password" %>
-<br>
-<%= hidden_input f, :id, value: @id %>
-<%= submit "Authorize" %>
-<% end %>
diff --git a/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex b/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex
new file mode 100644
index 000000000..e0d4d5632
--- /dev/null
+++ b/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex
@@ -0,0 +1,112 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
+ use Pleroma.Web, :controller
+
+ require Logger
+
+ alias Pleroma.Activity
+ alias Pleroma.Object.Fetcher
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.User
+ alias Pleroma.Web.Auth.Authenticator
+ alias Pleroma.Web.CommonAPI
+
+ @status_types ["Article", "Event", "Note", "Video", "Page", "Question"]
+
+ # Note: follower can submit the form (with password auth) not being signed in (having no token)
+ plug(
+ OAuthScopesPlug,
+ %{fallback: :proceed_unauthenticated, scopes: ["follow", "write:follows"]}
+ when action in [:do_follow]
+ )
+
+ # GET /ostatus_subscribe
+ #
+ def follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do
+ case is_status?(acct) do
+ true -> follow_status(conn, user, acct)
+ _ -> follow_account(conn, user, acct)
+ end
+ end
+
+ defp follow_status(conn, _user, acct) do
+ with {:ok, object} <- Fetcher.fetch_object_from_id(acct),
+ %Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(object.data["id"]) do
+ redirect(conn, to: o_status_path(conn, :notice, activity_id))
+ else
+ error ->
+ handle_follow_error(conn, error)
+ end
+ end
+
+ defp follow_account(conn, user, acct) do
+ with {:ok, followee} <- User.get_or_fetch(acct) do
+ render(conn, follow_template(user), %{error: false, followee: followee, acct: acct})
+ else
+ {:error, _reason} ->
+ render(conn, follow_template(user), %{error: :error})
+ end
+ end
+
+ defp follow_template(%User{} = _user), do: "follow.html"
+ defp follow_template(_), do: "follow_login.html"
+
+ defp is_status?(acct) do
+ case Fetcher.fetch_and_contain_remote_object_from_id(acct) do
+ {:ok, %{"type" => type}} when type in @status_types ->
+ true
+
+ _ ->
+ false
+ end
+ end
+
+ # POST /ostatus_subscribe
+ #
+ def do_follow(%{assigns: %{user: %User{} = user}} = conn, %{"user" => %{"id" => id}}) do
+ with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
+ {:ok, _, _, _} <- CommonAPI.follow(user, followee) do
+ render(conn, "followed.html", %{error: false})
+ else
+ error ->
+ handle_follow_error(conn, error)
+ end
+ end
+
+ def do_follow(conn, %{"authorization" => %{"name" => _, "password" => _, "id" => id}}) do
+ with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
+ {_, {:ok, user}, _} <- {:auth, Authenticator.get_user(conn), followee},
+ {:ok, _, _, _} <- CommonAPI.follow(user, followee) do
+ render(conn, "followed.html", %{error: false})
+ else
+ error ->
+ handle_follow_error(conn, error)
+ end
+ end
+
+ def do_follow(%{assigns: %{user: nil}} = conn, _) do
+ Logger.debug("Insufficient permissions: follow | write:follows.")
+ render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."})
+ end
+
+ defp handle_follow_error(conn, {:auth, _, followee} = _) do
+ render(conn, "follow_login.html", %{error: "Wrong username or password", followee: followee})
+ end
+
+ defp handle_follow_error(conn, {:fetch_user, error} = _) do
+ Logger.debug("Remote follow failed with error #{inspect(error)}")
+ render(conn, "followed.html", %{error: "Could not find user"})
+ end
+
+ defp handle_follow_error(conn, {:error, "Could not follow user:" <> _} = _) do
+ render(conn, "followed.html", %{error: "Error following account"})
+ end
+
+ defp handle_follow_error(conn, error) do
+ Logger.debug("Remote follow failed with error #{inspect(error)}")
+ render(conn, "followed.html", %{error: "Something went wrong."})
+ end
+end
diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
index 2305bb413..f08b9d28c 100644
--- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
@@ -7,12 +7,10 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
require Logger
- alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.Emoji
alias Pleroma.Healthcheck
alias Pleroma.Notification
- alias Pleroma.Plugs.AuthenticationPlug
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User
alias Pleroma.Web
@@ -22,7 +20,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
plug(
OAuthScopesPlug,
%{scopes: ["follow", "write:follows"]}
- when action in [:do_remote_follow, :follow_import]
+ when action == :follow_import
+ )
+
+ # Note: follower can submit the form (with password auth) not being signed in (having no token)
+ plug(
+ OAuthScopesPlug,
+ %{fallback: :proceed_unauthenticated, scopes: ["follow", "write:follows"]}
+ when action == :do_remote_follow
)
plug(OAuthScopesPlug, %{scopes: ["follow", "write:blocks"]} when action == :blocks_import)
@@ -77,94 +82,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
end
- def remote_follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do
- if is_status?(acct) do
- {:ok, object} = Pleroma.Object.Fetcher.fetch_object_from_id(acct)
- %Activity{id: activity_id} = Activity.get_create_by_object_ap_id(object.data["id"])
- redirect(conn, to: "/notice/#{activity_id}")
- else
- with {:ok, followee} <- User.get_or_fetch(acct) do
- conn
- |> render(follow_template(user), %{
- error: false,
- acct: acct,
- avatar: User.avatar_url(followee),
- name: followee.nickname,
- id: followee.id
- })
- else
- {:error, _reason} ->
- render(conn, follow_template(user), %{error: :error})
- end
- end
- end
-
- defp follow_template(%User{} = _user), do: "follow.html"
- defp follow_template(_), do: "follow_login.html"
-
- defp is_status?(acct) do
- case Pleroma.Object.Fetcher.fetch_and_contain_remote_object_from_id(acct) do
- {:ok, %{"type" => type}} when type in ["Article", "Note", "Video", "Page", "Question"] ->
- true
-
- _ ->
- false
- end
- end
-
- def do_remote_follow(conn, %{
- "authorization" => %{"name" => username, "password" => password, "id" => id}
- }) do
- with %User{} = followee <- User.get_cached_by_id(id),
- {_, %User{} = user, _} <- {:auth, User.get_cached_by_nickname(username), followee},
- {_, true, _} <- {
- :auth,
- AuthenticationPlug.checkpw(password, user.password_hash),
- followee
- },
- {:ok, _follower, _followee, _activity} <- CommonAPI.follow(user, followee) do
- conn
- |> render("followed.html", %{error: false})
- else
- # Was already following user
- {:error, "Could not follow user:" <> _rest} ->
- render(conn, "followed.html", %{error: "Error following account"})
-
- {:auth, _, followee} ->
- conn
- |> render("follow_login.html", %{
- error: "Wrong username or password",
- id: id,
- name: followee.nickname,
- avatar: User.avatar_url(followee)
- })
-
- e ->
- Logger.debug("Remote follow failed with error #{inspect(e)}")
- render(conn, "followed.html", %{error: "Something went wrong."})
- end
- end
-
- def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) do
- with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
- {:ok, _follower, _followee, _activity} <- CommonAPI.follow(user, followee) do
- conn
- |> render("followed.html", %{error: false})
- else
- # Was already following user
- {:error, "Could not follow user:" <> _rest} ->
- render(conn, "followed.html", %{error: "Error following account"})
-
- {:fetch_user, error} ->
- Logger.debug("Remote follow failed with error #{inspect(error)}")
- render(conn, "followed.html", %{error: "Could not find user"})
-
- e ->
- Logger.debug("Remote follow failed with error #{inspect(e)}")
- render(conn, "followed.html", %{error: "Something went wrong."})
- end
- end
-
def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do
with {:ok, _} <- Notification.read_one(user, notification_id) do
json(conn, %{status: "success"})
@@ -345,7 +262,9 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
def delete_account(%{assigns: %{user: user}} = conn, params) do
- case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
+ password = params["password"] || ""
+
+ case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} ->
User.delete(user)
json(conn, %{status: "success"})
diff --git a/lib/pleroma/web/twitter_api/views/remote_follow_view.ex b/lib/pleroma/web/twitter_api/views/remote_follow_view.ex
new file mode 100644
index 000000000..d469c4726
--- /dev/null
+++ b/lib/pleroma/web/twitter_api/views/remote_follow_view.ex
@@ -0,0 +1,10 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.TwitterAPI.RemoteFollowView do
+ use Pleroma.Web, :view
+ import Phoenix.HTML.Form
+
+ defdelegate avatar_url(user), to: Pleroma.User
+end