diff options
| author | Ivan Tashkinov <ivantashkinov@gmail.com> | 2019-02-17 14:07:04 +0300 | 
|---|---|---|
| committer | Ivan Tashkinov <ivantashkinov@gmail.com> | 2019-02-17 14:07:04 +0300 | 
| commit | bc4f77b10bb4360ac00d1999b1d08fa55e1fa547 (patch) | |
| tree | 8c87c2cefd1e325a64a19c04d7d7d70ffd8cc485 /lib | |
| parent | dcf24a3233bb50689d26f9d7833f98158730ce35 (diff) | |
| parent | 3b141194715e362d65482672d00b10991d102fa2 (diff) | |
| download | pleroma-bc4f77b10bb4360ac00d1999b1d08fa55e1fa547.tar.gz pleroma-bc4f77b10bb4360ac00d1999b1d08fa55e1fa547.zip | |
[#468] Merged `upstream/develop`, resolved conflicts.
Diffstat (limited to 'lib')
82 files changed, 774 insertions, 319 deletions
| diff --git a/lib/mix/tasks/pleroma/uploads.ex b/lib/mix/tasks/pleroma/uploads.ex index f0eb13e1a..a01e61627 100644 --- a/lib/mix/tasks/pleroma/uploads.ex +++ b/lib/mix/tasks/pleroma/uploads.ex @@ -4,7 +4,8 @@  defmodule Mix.Tasks.Pleroma.Uploads do    use Mix.Task -  alias Pleroma.{Upload, Uploaders.Local} +  alias Pleroma.Upload +  alias Pleroma.Uploaders.Local    alias Mix.Tasks.Pleroma.Common    require Logger @@ -20,7 +21,7 @@ defmodule Mix.Tasks.Pleroma.Uploads do     - `--delete` - delete local uploads after migrating them to the target uploader -   A list of avalible uploaders can be seen in config.exs +   A list of available uploaders can be seen in config.exs    """    def run(["migrate_local", target_uploader | args]) do      delete? = Enum.member?(args, "--delete") @@ -96,6 +97,7 @@ defmodule Mix.Tasks.Pleroma.Uploads do        timeout: 150_000      )      |> Stream.chunk_every(@log_every) +    # credo:disable-for-next-line Credo.Check.Warning.UnusedEnumOperation      |> Enum.reduce(0, fn done, count ->        count = count + length(done)        Mix.shell().info("Uploaded #{count}/#{total_count} files") diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index ffc45fd03..037e44716 100644 --- a/lib/mix/tasks/pleroma/user.ex +++ b/lib/mix/tasks/pleroma/user.ex @@ -5,7 +5,8 @@  defmodule Mix.Tasks.Pleroma.User do    use Mix.Task    import Ecto.Changeset -  alias Pleroma.{Repo, User} +  alias Pleroma.Repo +  alias Pleroma.User    alias Mix.Tasks.Pleroma.Common    @shortdoc "Manages Pleroma users" @@ -211,7 +212,7 @@ defmodule Mix.Tasks.Pleroma.User do        user = Repo.get(User, user.id) -      if length(user.following) == 0 do +      if Enum.empty?(user.following) do          Mix.shell().info("Successfully unsubscribed all followers from #{user.nickname}")        end      else diff --git a/lib/pleroma/PasswordResetToken.ex b/lib/pleroma/PasswordResetToken.ex index c3c0384d2..750ddd3c0 100644 --- a/lib/pleroma/PasswordResetToken.ex +++ b/lib/pleroma/PasswordResetToken.ex @@ -7,7 +7,9 @@ defmodule Pleroma.PasswordResetToken do    import Ecto.Changeset -  alias Pleroma.{User, PasswordResetToken, Repo} +  alias Pleroma.User +  alias Pleroma.Repo +  alias Pleroma.PasswordResetToken    schema "password_reset_tokens" do      belongs_to(:user, User, type: Pleroma.FlakeId) diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index f0aa3ce97..cdfe7ea9e 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -4,7 +4,11 @@  defmodule Pleroma.Activity do    use Ecto.Schema -  alias Pleroma.{Repo, Activity, Notification} + +  alias Pleroma.Repo +  alias Pleroma.Activity +  alias Pleroma.Notification +    import Ecto.Query    @type t :: %__MODULE__{} diff --git a/lib/pleroma/captcha/captcha.ex b/lib/pleroma/captcha/captcha.ex index 0207bcbea..aa41acd1a 100644 --- a/lib/pleroma/captcha/captcha.ex +++ b/lib/pleroma/captcha/captcha.ex @@ -3,9 +3,9 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Captcha do +  alias Calendar.DateTime    alias Plug.Crypto.KeyGenerator    alias Plug.Crypto.MessageEncryptor -  alias Calendar.DateTime    use GenServer diff --git a/lib/pleroma/emails/user_email.ex b/lib/pleroma/emails/user_email.ex index c42c53c99..a3a09e96c 100644 --- a/lib/pleroma/emails/user_email.ex +++ b/lib/pleroma/emails/user_email.ex @@ -7,7 +7,8 @@ defmodule Pleroma.UserEmail do    import Swoosh.Email -  alias Pleroma.Web.{Endpoint, Router} +  alias Pleroma.Web.Endpoint +  alias Pleroma.Web.Router    defp instance_config, do: Pleroma.Config.get(:instance) diff --git a/lib/pleroma/filter.ex b/lib/pleroma/filter.ex index 308bd70e1..bdc34698c 100644 --- a/lib/pleroma/filter.ex +++ b/lib/pleroma/filter.ex @@ -4,8 +4,12 @@  defmodule Pleroma.Filter do    use Ecto.Schema -  import Ecto.{Changeset, Query} -  alias Pleroma.{User, Repo} + +  import Ecto.Changeset +  import Ecto.Query + +  alias Pleroma.User +  alias Pleroma.Repo    schema "filters" do      belongs_to(:user, User, type: Pleroma.FlakeId) diff --git a/lib/pleroma/flake_id.ex b/lib/pleroma/flake_id.ex index 69ab8ccf9..9f098ce33 100644 --- a/lib/pleroma/flake_id.ex +++ b/lib/pleroma/flake_id.ex @@ -27,7 +27,7 @@ defmodule Pleroma.FlakeId do      Kernel.to_string(id)    end -  def to_string(flake = <<_::integer-size(64), _::integer-size(48), _::integer-size(16)>>) do +  def to_string(<<_::integer-size(64), _::integer-size(48), _::integer-size(16)>> = flake) do      encode_base62(flake)    end @@ -42,7 +42,7 @@ defmodule Pleroma.FlakeId do      def from_string(unquote(Kernel.to_string(i))), do: <<0::integer-size(128)>>    end -  def from_string(flake = <<_::integer-size(128)>>), do: flake +  def from_string(<<_::integer-size(128)>> = flake), do: flake    def from_string(string) when is_binary(string) and byte_size(string) < 18 do      case Integer.parse(string) do diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 386096a52..f31aafa0d 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -3,10 +3,10 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Formatter do +  alias Pleroma.Emoji +  alias Pleroma.HTML    alias Pleroma.User    alias Pleroma.Web.MediaProxy -  alias Pleroma.HTML -  alias Pleroma.Emoji    @tag_regex ~r/((?<=[^&])|\A)(\#)(\w+)/u    @markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/ diff --git a/lib/pleroma/gopher/server.ex b/lib/pleroma/gopher/server.ex index 336142e9b..32cb817d2 100644 --- a/lib/pleroma/gopher/server.ex +++ b/lib/pleroma/gopher/server.ex @@ -37,17 +37,17 @@ end  defmodule Pleroma.Gopher.Server.ProtocolHandler do    alias Pleroma.Web.ActivityPub.ActivityPub -  alias Pleroma.User    alias Pleroma.Activity -  alias Pleroma.Repo    alias Pleroma.HTML +  alias Pleroma.User +  alias Pleroma.Repo    def start_link(ref, socket, transport, opts) do      pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts])      {:ok, pid}    end -  def init(ref, socket, transport, _Opts = []) do +  def init(ref, socket, transport, [] = _Opts) do      :ok = :ranch.accept_ack(ref)      loop(socket, transport)    end diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index b4a4742ee..4dc6998b1 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -83,8 +83,7 @@ defmodule Pleroma.HTML.Scrubber.TwitterText do    """    @markup Application.get_env(:pleroma, :markup) -  @uri_schemes Application.get_env(:pleroma, :uri_schemes, []) -  @valid_schemes Keyword.get(@uri_schemes, :valid_schemes, []) +  @valid_schemes Pleroma.Config.get([:uri_schemes, :valid_schemes], [])    require HtmlSanitizeEx.Scrubber.Meta    alias HtmlSanitizeEx.Scrubber.Meta @@ -126,10 +125,11 @@ defmodule Pleroma.HTML.Scrubber.Default do    require HtmlSanitizeEx.Scrubber.Meta    alias HtmlSanitizeEx.Scrubber.Meta +  # credo:disable-for-previous-line +  # No idea how to fix this one…    @markup Application.get_env(:pleroma, :markup) -  @uri_schemes Application.get_env(:pleroma, :uri_schemes, []) -  @valid_schemes Keyword.get(@uri_schemes, :valid_schemes, []) +  @valid_schemes Pleroma.Config.get([:uri_schemes, :valid_schemes], [])    Meta.remove_cdata_sections_before_scrub()    Meta.strip_comments() diff --git a/lib/pleroma/instances/instance.ex b/lib/pleroma/instances/instance.ex index 4a4ca26dd..48bc939dd 100644 --- a/lib/pleroma/instances/instance.ex +++ b/lib/pleroma/instances/instance.ex @@ -2,13 +2,13 @@ defmodule Pleroma.Instances.Instance do    @moduledoc "Instance."    alias Pleroma.Instances +  alias Pleroma.Repo    alias Pleroma.Instances.Instance    use Ecto.Schema -  import Ecto.{Query, Changeset} - -  alias Pleroma.Repo +  import Ecto.Query +  import Ecto.Changeset    schema "instances" do      field(:host, :string) diff --git a/lib/pleroma/list.ex b/lib/pleroma/list.ex index ca66c6916..55c4cf6df 100644 --- a/lib/pleroma/list.ex +++ b/lib/pleroma/list.ex @@ -4,8 +4,13 @@  defmodule Pleroma.List do    use Ecto.Schema -  import Ecto.{Changeset, Query} -  alias Pleroma.{User, Repo, Activity} + +  import Ecto.Query +  import Ecto.Changeset + +  alias Pleroma.Activity +  alias Pleroma.Repo +  alias Pleroma.User    schema "lists" do      belongs_to(:user, User, type: Pleroma.FlakeId) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 2364d36da..c88512567 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -4,8 +4,14 @@  defmodule Pleroma.Notification do    use Ecto.Schema -  alias Pleroma.{User, Activity, Notification, Repo} + +  alias Pleroma.User +  alias Pleroma.Activity +  alias Pleroma.Notification +  alias Pleroma.Repo    alias Pleroma.Web.CommonAPI.Utils +  alias Pleroma.Web.CommonAPI +    import Ecto.Query    schema "notifications" do @@ -112,7 +118,7 @@ defmodule Pleroma.Notification do    # TODO move to sql, too.    def create_notification(%Activity{} = activity, %User{} = user) do      unless User.blocks?(user, %{ap_id: activity.data["actor"]}) or -             user.ap_id == activity.data["actor"] or +             CommonAPI.thread_muted?(user, activity) or user.ap_id == activity.data["actor"] or               (activity.data["type"] == "Follow" and                  Enum.any?(Notification.for_user(user), fn notif ->                    notif.activity.data["type"] == "Follow" and diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 7b46a3b05..5f1fc801b 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -4,8 +4,15 @@  defmodule Pleroma.Object do    use Ecto.Schema -  alias Pleroma.{Repo, Object, User, Activity, ObjectTombstone} -  import Ecto.{Query, Changeset} + +  alias Pleroma.Repo +  alias Pleroma.Object +  alias Pleroma.User +  alias Pleroma.Activity +  alias Pleroma.ObjectTombstone + +  import Ecto.Query +  import Ecto.Changeset    schema "objects" do      field(:data, :map) diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex index 2a266c407..057553e24 100644 --- a/lib/pleroma/plugs/http_security_plug.ex +++ b/lib/pleroma/plugs/http_security_plug.ex @@ -33,7 +33,22 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do    end    defp csp_string do -    protocol = Config.get([Pleroma.Web.Endpoint, :protocol]) +    scheme = Config.get([Pleroma.Web.Endpoint, :url])[:scheme] +    websocket_url = String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws") + +    connect_src = +      if Mix.env() == :dev do +        "connect-src 'self' http://localhost:3035/ " <> websocket_url +      else +        "connect-src 'self' " <> websocket_url +      end + +    script_src = +      if Mix.env() == :dev do +        "script-src 'self' 'unsafe-eval'" +      else +        "script-src 'self'" +      end      [        "default-src 'none'", @@ -43,10 +58,10 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do        "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"),        "manifest-src 'self'", -      if protocol == "https" do +      connect_src, +      script_src, +      if scheme == "https" do          "upgrade-insecure-requests"        end      ] diff --git a/lib/pleroma/plugs/instance_static.ex b/lib/pleroma/plugs/instance_static.ex index 11f108de7..41125921a 100644 --- a/lib/pleroma/plugs/instance_static.ex +++ b/lib/pleroma/plugs/instance_static.ex @@ -33,7 +33,7 @@ defmodule Pleroma.Plugs.InstanceStatic do    for only <- @only do      at = Plug.Router.Utils.split("/") -    def call(conn = %{request_path: "/" <> unquote(only) <> _}, opts) do +    def call(%{request_path: "/" <> unquote(only) <> _} = conn, opts) do        call_static(          conn,          opts, diff --git a/lib/pleroma/plugs/oauth_plug.ex b/lib/pleroma/plugs/oauth_plug.ex index 945a1d49f..22f0406f4 100644 --- a/lib/pleroma/plugs/oauth_plug.ex +++ b/lib/pleroma/plugs/oauth_plug.ex @@ -6,11 +6,9 @@ defmodule Pleroma.Plugs.OAuthPlug do    import Plug.Conn    import Ecto.Query -  alias Pleroma.{ -    User, -    Repo, -    Web.OAuth.Token -  } +  alias Pleroma.User +  alias Pleroma.Repo +  alias Pleroma.Web.OAuth.Token    @realm_reg Regex.compile!("Bearer\:?\s+(.*)$", "i") diff --git a/lib/pleroma/plugs/uploaded_media.ex b/lib/pleroma/plugs/uploaded_media.ex index be53ac00c..13aa8641a 100644 --- a/lib/pleroma/plugs/uploaded_media.ex +++ b/lib/pleroma/plugs/uploaded_media.ex @@ -23,7 +23,7 @@ defmodule Pleroma.Plugs.UploadedMedia do      %{static_plug_opts: static_plug_opts}    end -  def call(conn = %{request_path: <<"/", @path, "/", file::binary>>}, opts) do +  def call(%{request_path: <<"/", @path, "/", file::binary>>} = conn, opts) do      config = Pleroma.Config.get([Pleroma.Upload])      with uploader <- Keyword.fetch!(config, :uploader), diff --git a/lib/pleroma/plugs/user_fetcher_plug.ex b/lib/pleroma/plugs/user_fetcher_plug.ex index f874e2f95..7ed4602bb 100644 --- a/lib/pleroma/plugs/user_fetcher_plug.ex +++ b/lib/pleroma/plugs/user_fetcher_plug.ex @@ -3,9 +3,10 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Plugs.UserFetcherPlug do -  import Plug.Conn -  alias Pleroma.Repo    alias Pleroma.User +  alias Pleroma.Repo + +  import Plug.Conn    def init(options) do      options diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index b3566ceb6..fe0ce9051 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -4,7 +4,8 @@  defmodule Pleroma.Stats do    import Ecto.Query -  alias Pleroma.{User, Repo} +  alias Pleroma.User +  alias Pleroma.Repo    def start_link do      agent = Agent.start_link(fn -> {[], %{}} end, name: __MODULE__) @@ -23,7 +24,7 @@ defmodule Pleroma.Stats do    def schedule_update do      spawn(fn ->        # 1 hour -      Process.sleep(1000 * 60 * 60 * 1) +      Process.sleep(1000 * 60 * 60)        schedule_update()      end) diff --git a/lib/pleroma/thread_mute.ex b/lib/pleroma/thread_mute.ex new file mode 100644 index 000000000..0b577113d --- /dev/null +++ b/lib/pleroma/thread_mute.ex @@ -0,0 +1,45 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.ThreadMute do +  use Ecto.Schema +  alias Pleroma.{Repo, User, ThreadMute} +  require Ecto.Query + +  schema "thread_mutes" do +    belongs_to(:user, User, type: Pleroma.FlakeId) +    field(:context, :string) +  end + +  def changeset(mute, params \\ %{}) do +    mute +    |> Ecto.Changeset.cast(params, [:user_id, :context]) +    |> Ecto.Changeset.foreign_key_constraint(:user_id) +    |> Ecto.Changeset.unique_constraint(:user_id, name: :unique_index) +  end + +  def query(user_id, context) do +    user_id = Pleroma.FlakeId.from_string(user_id) + +    ThreadMute +    |> Ecto.Query.where(user_id: ^user_id) +    |> Ecto.Query.where(context: ^context) +  end + +  def add_mute(user_id, context) do +    %ThreadMute{} +    |> changeset(%{user_id: user_id, context: context}) +    |> Repo.insert() +  end + +  def remove_mute(user_id, context) do +    query(user_id, context) +    |> Repo.delete_all() +  end + +  def check_muted(user_id, context) do +    query(user_id, context) +    |> Repo.all() +  end +end diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index ce2a1b696..91a5db8c5 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -180,7 +180,7 @@ defmodule Pleroma.Upload do    end    # For Mix.Tasks.MigrateLocalUploads -  defp prepare_upload(upload = %__MODULE__{tempfile: path}, _opts) do +  defp prepare_upload(%__MODULE__{tempfile: path} = upload, _opts) do      with {:ok, content_type} <- Pleroma.MIME.file_mime_type(path) do        {:ok, %__MODULE__{upload | content_type: content_type}}      end diff --git a/lib/pleroma/upload/filter/dedupe.ex b/lib/pleroma/upload/filter/dedupe.ex index 8fcce320f..e4c225833 100644 --- a/lib/pleroma/upload/filter/dedupe.ex +++ b/lib/pleroma/upload/filter/dedupe.ex @@ -6,7 +6,7 @@ defmodule Pleroma.Upload.Filter.Dedupe do    @behaviour Pleroma.Upload.Filter    alias Pleroma.Upload -  def filter(upload = %Upload{name: name}) do +  def filter(%Upload{name: name} = upload) do      extension = String.split(name, ".") |> List.last()      shasum = :crypto.hash(:sha256, File.read!(upload.tempfile)) |> Base.encode16(case: :lower)      filename = shasum <> "." <> extension diff --git a/lib/pleroma/uploaders/mdii.ex b/lib/pleroma/uploaders/mdii.ex index 320b07abd..190ed9f3a 100644 --- a/lib/pleroma/uploaders/mdii.ex +++ b/lib/pleroma/uploaders/mdii.ex @@ -25,7 +25,7 @@ defmodule Pleroma.Uploaders.MDII do      query = "#{cgi}?#{extension}"      with {:ok, %{status: 200, body: body}} <- -           @httpoison.post(query, file_data, adapter: [pool: :default]) do +           @httpoison.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}} diff --git a/lib/pleroma/uploaders/s3.ex b/lib/pleroma/uploaders/s3.ex index fbd89616c..0038ba01f 100644 --- a/lib/pleroma/uploaders/s3.ex +++ b/lib/pleroma/uploaders/s3.ex @@ -27,7 +27,7 @@ defmodule Pleroma.Uploaders.S3 do        ])}}    end -  def put_file(upload = %Pleroma.Upload{}) do +  def put_file(%Pleroma.Upload{} = upload) do      config = Pleroma.Config.get([__MODULE__])      bucket = Keyword.get(config, :bucket) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 33630ac7c..3c6a9953d 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -5,13 +5,23 @@  defmodule Pleroma.User do    use Ecto.Schema -  import Ecto.{Changeset, Query} -  alias Pleroma.{Repo, User, Object, Web, Activity, Notification} +  import Ecto.Changeset +  import Ecto.Query + +  alias Pleroma.Repo +  alias Pleroma.User +  alias Pleroma.Object +  alias Pleroma.Web +  alias Pleroma.Activity +  alias Pleroma.Notification    alias Comeonin.Pbkdf2    alias Pleroma.Formatter    alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils -  alias Pleroma.Web.{OStatus, Websub, OAuth} -  alias Pleroma.Web.ActivityPub.{Utils, ActivityPub} +  alias Pleroma.Web.OStatus +  alias Pleroma.Web.Websub +  alias Pleroma.Web.OAuth +  alias Pleroma.Web.ActivityPub.Utils +  alias Pleroma.Web.ActivityPub.ActivityPub    require Logger @@ -96,12 +106,6 @@ defmodule Pleroma.User do      "#{ap_id(user)}/followers"    end -  def follow_changeset(struct, params \\ %{}) do -    struct -    |> cast(params, [:following]) -    |> validate_required([:following]) -  end -    def user_info(%User{} = user) do      oneself = if user.local, do: 1, else: 0 @@ -256,8 +260,9 @@ defmodule Pleroma.User do    @doc "Inserts provided changeset, performs post-registration actions (confirmation email sending etc.)"    def register(%Ecto.Changeset{} = changeset) do      with {:ok, user} <- Repo.insert(changeset), -         {:ok, _} <- try_send_confirmation_email(user), -         {:ok, user} <- autofollow_users(user) do +         {:ok, user} <- autofollow_users(user), +         {:ok, _} <- Pleroma.User.WelcomeMessage.post_welcome_message_to_user(user), +         {:ok, _} <- try_send_confirmation_email(user) do        {:ok, user}      end    end @@ -307,10 +312,13 @@ defmodule Pleroma.User do      end    end -  @doc "A mass follow for local users. Ignores blocks and has no side effects" +  @doc "A mass follow for local users. Respects blocks in both directions but does not create activities."    @spec follow_all(User.t(), list(User.t())) :: {atom(), User.t()}    def follow_all(follower, followeds) do -    followed_addresses = Enum.map(followeds, fn %{follower_address: fa} -> fa end) +    followed_addresses = +      followeds +      |> Enum.reject(fn followed -> blocks?(follower, followed) || blocks?(followed, follower) end) +      |> Enum.map(fn %{follower_address: fa} -> fa end)      q =        from(u in User, @@ -724,7 +732,7 @@ defmodule Pleroma.User do      # Strip the beginning @ off if there is a query      query = String.trim_leading(query, "@") -    if resolve, do: User.get_or_fetch_by_nickname(query) +    if resolve, do: get_or_fetch(query)      fts_results = do_search(fts_search_subquery(query), for_user) diff --git a/lib/pleroma/user/welcome_message.ex b/lib/pleroma/user/welcome_message.ex new file mode 100644 index 000000000..8018ac22f --- /dev/null +++ b/lib/pleroma/user/welcome_message.ex @@ -0,0 +1,30 @@ +defmodule Pleroma.User.WelcomeMessage do +  alias Pleroma.User +  alias Pleroma.Web.CommonAPI + +  def post_welcome_message_to_user(user) do +    with %User{} = sender_user <- welcome_user(), +         message when is_binary(message) <- welcome_message() do +      CommonAPI.post(sender_user, %{ +        "visibility" => "direct", +        "status" => "@#{user.nickname}\n#{message}" +      }) +    else +      _ -> {:ok, nil} +    end +  end + +  defp welcome_user() do +    with nickname when is_binary(nickname) <- +           Pleroma.Config.get([:instance, :welcome_user_nickname]), +         %User{local: true} = user <- User.get_cached_by_nickname(nickname) do +      user +    else +      _ -> nil +    end +  end + +  defp welcome_message() do +    Pleroma.Config.get([:instance, :welcome_message]) +  end +end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index b33912721..ab2872f56 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -3,13 +3,22 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.ActivityPub do -  alias Pleroma.{Activity, Repo, Object, Upload, User, Notification, Instances} -  alias Pleroma.Web.ActivityPub.{Transmogrifier, MRF} +  alias Pleroma.Activity +  alias Pleroma.Repo +  alias Pleroma.Object +  alias Pleroma.Upload +  alias Pleroma.User +  alias Pleroma.Notification +  alias Pleroma.Instances +  alias Pleroma.Web.ActivityPub.Transmogrifier +  alias Pleroma.Web.ActivityPub.MRF    alias Pleroma.Web.WebFinger    alias Pleroma.Web.Federator    alias Pleroma.Web.OStatus +    import Ecto.Query    import Pleroma.Web.ActivityPub.Utils +    require Logger    @httpoison Application.get_env(:pleroma, :httpoison) @@ -19,19 +28,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do    defp get_recipients(%{"type" => "Announce"} = data) do      to = data["to"] || []      cc = data["cc"] || [] -    recipients = to ++ cc      actor = User.get_cached_by_ap_id(data["actor"]) -    recipients -    |> Enum.filter(fn recipient -> -      case User.get_cached_by_ap_id(recipient) do -        nil -> -          true - -        user -> -          User.following?(user, actor) -      end -    end) +    recipients = +      (to ++ cc) +      |> Enum.filter(fn recipient -> +        case User.get_cached_by_ap_id(recipient) do +          nil -> +            true + +          user -> +            User.following?(user, actor) +        end +      end)      {recipients, to, cc}    end @@ -119,7 +128,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do            activity.data["object"]            |> Map.get("tag", [])            |> Enum.filter(fn tag -> is_bitstring(tag) end) -          |> Enum.map(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end) +          |> Enum.each(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end)            if activity.data["object"]["attachment"] != [] do              Pleroma.Web.Streamer.stream("public:media", activity) @@ -809,8 +818,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do      if object = Object.get_cached_by_ap_id(id) do        {:ok, object}      else -      Logger.info("Fetching #{id} via AP") -        with {:ok, data} <- fetch_and_contain_remote_object_from_id(id),             nil <- Object.normalize(data),             params <- %{ @@ -842,7 +849,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do    end    def fetch_and_contain_remote_object_from_id(id) do -    Logger.info("Fetching #{id} via AP") +    Logger.info("Fetching object #{id} via AP")      with true <- String.starts_with?(id, "http"),           {:ok, %{body: body, status: code}} when code in 200..299 <- diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 2cdf132e2..69879476e 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -5,12 +5,15 @@  defmodule Pleroma.Web.ActivityPub.ActivityPubController do    use Pleroma.Web, :controller -  alias Pleroma.{Activity, User, Object} -  alias Pleroma.Web.ActivityPub.{ObjectView, UserView} +  alias Pleroma.Activity +  alias Pleroma.User +  alias Pleroma.Object +  alias Pleroma.Web.ActivityPub.ObjectView +  alias Pleroma.Web.ActivityPub.UserView    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Relay -  alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Web.ActivityPub.Transmogrifier +  alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Web.Federator    require Logger diff --git a/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex b/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex index 4c6e612b2..8ab1dd4e5 100644 --- a/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex @@ -6,40 +6,80 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do    alias Pleroma.User    @behaviour Pleroma.Web.ActivityPub.MRF -  defp delist_message(message) do +  defp delist_message(message, threshold) when threshold > 0 do      follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address -    message -    |> Map.put("to", [follower_collection]) -    |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"]) +    follower_collection? = Enum.member?(message["to"] ++ message["cc"], follower_collection) + +    message = +      case recipients = get_recipient_count(message) do +        {:public, _} +        when follower_collection? and recipients > threshold -> +          message +          |> Map.put("to", [follower_collection]) +          |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"]) + +        {:public, _} when recipients > threshold -> +          message +          |> Map.put("to", []) +          |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"]) + +        _ -> +          message +      end + +    {:ok, message} +  end + +  defp delist_message(message, _threshold), do: {:ok, message} + +  defp reject_message(message, threshold) when threshold > 0 do +    with {_, recipients} <- get_recipient_count(message) do +      if recipients > threshold do +        {:reject, nil} +      else +        {:ok, message} +      end +    end +  end + +  defp reject_message(message, _threshold), do: {:ok, message} + +  defp get_recipient_count(message) do +    recipients = (message["to"] || []) ++ (message["cc"] || []) +    follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address + +    if Enum.member?(recipients, "https://www.w3.org/ns/activitystreams#Public") do +      recipients = +        recipients +        |> List.delete("https://www.w3.org/ns/activitystreams#Public") +        |> List.delete(follower_collection) + +      {:public, length(recipients)} +    else +      recipients = +        recipients +        |> List.delete(follower_collection) + +      {:not_public, length(recipients)} +    end    end    @impl true    def filter(%{"type" => "Create"} = message) do -    delist_threshold = Pleroma.Config.get([:mrf_hellthread, :delist_threshold]) -      reject_threshold =        Pleroma.Config.get(          [:mrf_hellthread, :reject_threshold],          Pleroma.Config.get([:mrf_hellthread, :threshold])        ) -    recipients = (message["to"] || []) ++ (message["cc"] || []) - -    cond do -      length(recipients) > reject_threshold and reject_threshold > 0 -> -        {:reject, nil} - -      length(recipients) > delist_threshold and delist_threshold > 0 -> -        if Enum.member?(message["to"], "https://www.w3.org/ns/activitystreams#Public") or -             Enum.member?(message["cc"], "https://www.w3.org/ns/activitystreams#Public") do -          {:ok, delist_message(message)} -        else -          {:ok, message} -        end +    delist_threshold = Pleroma.Config.get([:mrf_hellthread, :delist_threshold]) -      true -> -        {:ok, message} +    with {:ok, message} <- reject_message(message, reject_threshold), +         {:ok, message} <- delist_message(message, delist_threshold) do +      {:ok, message} +    else +      _e -> {:reject, nil}      end    end diff --git a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex index ce6d2e529..5fdc03414 100644 --- a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex @@ -12,9 +12,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do      String.match?(string, pattern)    end -  defp check_reject(%{"object" => %{"content" => content}} = message) do +  defp check_reject(%{"object" => %{"content" => content, "summary" => summary}} = message) do      if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern -> -         string_matches?(content, pattern) +         string_matches?(content, pattern) or string_matches?(summary, pattern)         end) do        {:reject, nil}      else @@ -22,10 +22,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do      end    end -  defp check_ftl_removal(%{"to" => to, "object" => %{"content" => content}} = message) do +  defp check_ftl_removal( +         %{"to" => to, "object" => %{"content" => content, "summary" => summary}} = message +       ) do      if "https://www.w3.org/ns/activitystreams#Public" in to and           Enum.any?(Pleroma.Config.get([:mrf_keyword, :federated_timeline_removal]), fn pattern -> -           string_matches?(content, pattern) +           string_matches?(content, pattern) or string_matches?(summary, pattern)           end) do        to = List.delete(to, "https://www.w3.org/ns/activitystreams#Public")        cc = ["https://www.w3.org/ns/activitystreams#Public" | message["cc"] || []] @@ -41,14 +43,20 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do      end    end -  defp check_replace(%{"object" => %{"content" => content}} = message) do -    content = -      Enum.reduce(Pleroma.Config.get([:mrf_keyword, :replace]), content, fn {pattern, replacement}, -                                                                            acc -> -        String.replace(acc, pattern, replacement) +  defp check_replace(%{"object" => %{"content" => content, "summary" => summary}} = message) do +    {content, summary} = +      Enum.reduce(Pleroma.Config.get([:mrf_keyword, :replace]), {content, summary}, fn {pattern, +                                                                                        replacement}, +                                                                                       {content_acc, +                                                                                        summary_acc} -> +        {String.replace(content_acc, pattern, replacement), +         String.replace(summary_acc, pattern, replacement)}        end) -    {:ok, put_in(message["object"]["content"], content)} +    {:ok, +     message +     |> put_in(["object", "content"], content) +     |> put_in(["object", "summary"], summary)}    end    @impl true diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex index c0a52e349..c496063ea 100644 --- a/lib/pleroma/web/activity_pub/relay.ex +++ b/lib/pleroma/web/activity_pub/relay.ex @@ -3,7 +3,9 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.Relay do -  alias Pleroma.{User, Object, Activity} +  alias Pleroma.User +  alias Pleroma.Object +  alias Pleroma.Activity    alias Pleroma.Web.ActivityPub.ActivityPub    require Logger diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 7151efdeb..26b2dd575 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -6,9 +6,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do    @moduledoc """    A module to handle coding from internal to wire ActivityPub and back.    """ +  alias Pleroma.Activity    alias Pleroma.User    alias Pleroma.Object -  alias Pleroma.Activity    alias Pleroma.Repo    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Utils @@ -649,7 +649,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do      if object = Object.normalize(id), do: {:ok, object}, else: nil    end -  def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) do +  def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) when is_binary(inReplyTo) do      with false <- String.starts_with?(inReplyTo, "http"),           {:ok, %{data: replied_to_object}} <- get_obj_helper(inReplyTo) do        Map.put(object, "inReplyTo", replied_to_object["external_url"] || inReplyTo) @@ -765,12 +765,18 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do    def add_hashtags(object) do      tags =        (object["tag"] || []) -      |> Enum.map(fn tag -> -        %{ -          "href" => Pleroma.Web.Endpoint.url() <> "/tags/#{tag}", -          "name" => "##{tag}", -          "type" => "Hashtag" -        } +      |> Enum.map(fn +        # Expand internal representation tags into AS2 tags. +        tag when is_binary(tag) -> +          %{ +            "href" => Pleroma.Web.Endpoint.url() <> "/tags/#{tag}", +            "name" => "##{tag}", +            "type" => "Hashtag" +          } + +        # Do not process tags which are already AS2 tag objects. +        tag when is_map(tag) -> +          tag        end)      object diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 4a2cc6738..964e11c9d 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -3,11 +3,19 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.Utils do -  alias Pleroma.{Repo, Web, Object, Activity, User, Notification} +  alias Pleroma.Repo +  alias Pleroma.Web +  alias Pleroma.Object +  alias Pleroma.Activity +  alias Pleroma.User +  alias Pleroma.Notification    alias Pleroma.Web.Router.Helpers    alias Pleroma.Web.Endpoint -  alias Ecto.{Changeset, UUID} +  alias Ecto.Changeset +  alias Ecto.UUID +    import Ecto.Query +    require Logger    @supported_object_types ["Article", "Note", "Video", "Page"] diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex index 394d82fbc..84fa94e32 100644 --- a/lib/pleroma/web/activity_pub/views/object_view.ex +++ b/lib/pleroma/web/activity_pub/views/object_view.ex @@ -4,7 +4,8 @@  defmodule Pleroma.Web.ActivityPub.ObjectView do    use Pleroma.Web, :view -  alias Pleroma.{Object, Activity} +  alias Pleroma.Activity +  alias Pleroma.Object    alias Pleroma.Web.ActivityPub.Transmogrifier    def render("object.json", %{object: %Object{} = object}) do diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 43ec2010d..c8e154989 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -4,15 +4,34 @@  defmodule Pleroma.Web.ActivityPub.UserView do    use Pleroma.Web, :view -  alias Pleroma.Web.Salmon +    alias Pleroma.Web.WebFinger +  alias Pleroma.Web.Salmon    alias Pleroma.User    alias Pleroma.Repo    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Transmogrifier    alias Pleroma.Web.ActivityPub.Utils +  alias Pleroma.Web.Router.Helpers +  alias Pleroma.Web.Endpoint +    import Ecto.Query +  def render("endpoints.json", %{user: %User{nickname: nil, local: true} = _user}) do +    %{"sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox)} +  end + +  def render("endpoints.json", %{user: %User{local: true} = _user}) do +    %{ +      "oauthAuthorizationEndpoint" => Helpers.o_auth_url(Endpoint, :authorize), +      "oauthRegistrationEndpoint" => Helpers.mastodon_api_url(Endpoint, :create_app), +      "oauthTokenEndpoint" => Helpers.o_auth_url(Endpoint, :token_exchange), +      "sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox) +    } +  end + +  def render("endpoints.json", _), do: %{} +    # the instance itself is not a Person, but instead an Application    def render("user.json", %{user: %{nickname: nil} = user}) do      {:ok, user} = WebFinger.ensure_keys_present(user) @@ -20,6 +39,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do      public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)      public_key = :public_key.pem_encode([public_key]) +    endpoints = render("endpoints.json", %{user: user}) +      %{        "id" => user.ap_id,        "type" => "Application", @@ -35,9 +56,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do          "owner" => user.ap_id,          "publicKeyPem" => public_key        }, -      "endpoints" => %{ -        "sharedInbox" => "#{Pleroma.Web.Endpoint.url()}/inbox" -      } +      "endpoints" => endpoints      }      |> Map.merge(Utils.make_json_ld_header())    end @@ -48,6 +67,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do      public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)      public_key = :public_key.pem_encode([public_key]) +    endpoints = render("endpoints.json", %{user: user}) +      %{        "id" => user.ap_id,        "type" => "Person", @@ -65,9 +86,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do          "owner" => user.ap_id,          "publicKeyPem" => public_key        }, -      "endpoints" => %{ -        "sharedInbox" => "#{Pleroma.Web.Endpoint.url()}/inbox" -      }, +      "endpoints" => endpoints,        "icon" => %{          "type" => "Image",          "url" => User.avatar_url(user) @@ -86,7 +105,14 @@ defmodule Pleroma.Web.ActivityPub.UserView do      query = from(user in query, select: [:ap_id])      following = Repo.all(query) -    collection(following, "#{user.ap_id}/following", page, !user.info.hide_follows) +    total = +      if !user.info.hide_follows do +        length(following) +      else +        0 +      end + +    collection(following, "#{user.ap_id}/following", page, !user.info.hide_follows, total)      |> Map.merge(Utils.make_json_ld_header())    end @@ -95,10 +121,17 @@ defmodule Pleroma.Web.ActivityPub.UserView do      query = from(user in query, select: [:ap_id])      following = Repo.all(query) +    total = +      if !user.info.hide_follows do +        length(following) +      else +        0 +      end +      %{        "id" => "#{user.ap_id}/following",        "type" => "OrderedCollection", -      "totalItems" => length(following), +      "totalItems" => total,        "first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows)      }      |> Map.merge(Utils.make_json_ld_header()) @@ -109,7 +142,14 @@ defmodule Pleroma.Web.ActivityPub.UserView do      query = from(user in query, select: [:ap_id])      followers = Repo.all(query) -    collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_followers) +    total = +      if !user.info.hide_followers do +        length(followers) +      else +        0 +      end + +    collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_followers, total)      |> Map.merge(Utils.make_json_ld_header())    end @@ -118,19 +158,24 @@ defmodule Pleroma.Web.ActivityPub.UserView do      query = from(user in query, select: [:ap_id])      followers = Repo.all(query) +    total = +      if !user.info.hide_followers do +        length(followers) +      else +        0 +      end +      %{        "id" => "#{user.ap_id}/followers",        "type" => "OrderedCollection", -      "totalItems" => length(followers), -      "first" => collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_followers) +      "totalItems" => total, +      "first" => +        collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_followers, total)      }      |> Map.merge(Utils.make_json_ld_header())    end    def render("outbox.json", %{user: user, max_id: max_qid}) do -    # XXX: technically note_count is wrong for this, but it's better than nothing -    info = User.user_info(user) -      params = %{        "limit" => "10"      } @@ -158,7 +203,6 @@ defmodule Pleroma.Web.ActivityPub.UserView do        "id" => "#{iri}?max_id=#{max_id}",        "type" => "OrderedCollectionPage",        "partOf" => iri, -      "totalItems" => info.note_count,        "orderedItems" => collection,        "next" => "#{iri}?max_id=#{min_id}"      } @@ -167,7 +211,6 @@ defmodule Pleroma.Web.ActivityPub.UserView do        %{          "id" => iri,          "type" => "OrderedCollection", -        "totalItems" => info.note_count,          "first" => page        }        |> Map.merge(Utils.make_json_ld_header()) @@ -205,7 +248,6 @@ defmodule Pleroma.Web.ActivityPub.UserView do        "id" => "#{iri}?max_id=#{max_id}",        "type" => "OrderedCollectionPage",        "partOf" => iri, -      "totalItems" => -1,        "orderedItems" => collection,        "next" => "#{iri}?max_id=#{min_id}"      } @@ -214,7 +256,6 @@ defmodule Pleroma.Web.ActivityPub.UserView do        %{          "id" => iri,          "type" => "OrderedCollection", -        "totalItems" => -1,          "first" => page        }        |> Map.merge(Utils.make_json_ld_header()) diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 7084da6de..86f249c54 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -3,7 +3,11 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.CommonAPI do -  alias Pleroma.{User, Repo, Activity, Object} +  alias Pleroma.User +  alias Pleroma.Repo +  alias Pleroma.Activity +  alias Pleroma.Object +  alias Pleroma.ThreadMute    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Formatter @@ -216,4 +220,27 @@ defmodule Pleroma.Web.CommonAPI do          {:error, "Could not unpin"}      end    end + +  def add_mute(user, activity) do +    with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]) do +      {:ok, activity} +    else +      {:error, _} -> {:error, "conversation is already muted"} +    end +  end + +  def remove_mute(user, activity) do +    ThreadMute.remove_mute(user.id, activity.data["context"]) +    {:ok, activity} +  end + +  def thread_muted?(%{id: nil} = _user, _activity), do: false + +  def thread_muted?(user, activity) do +    with [] <- ThreadMute.check_muted(user.id, activity.data["context"]) do +      false +    else +      _ -> true +    end +  end  end diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 208677bd7..123107b56 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -5,12 +5,15 @@  defmodule Pleroma.Web.CommonAPI.Utils do    alias Calendar.Strftime    alias Comeonin.Pbkdf2 -  alias Pleroma.{Activity, Formatter, Object, Repo} +  alias Pleroma.Activity +  alias Pleroma.Formatter +  alias Pleroma.Object +  alias Pleroma.Repo    alias Pleroma.User    alias Pleroma.Web -  alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Web.Endpoint    alias Pleroma.Web.MediaProxy +  alias Pleroma.Web.ActivityPub.Utils    # This is a hack for twidere.    def get_by_id_or_ap_id(id) do @@ -95,7 +98,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do    def make_context(%Activity{data: %{"context" => context}}), do: context    def make_context(_), do: Utils.generate_context_id() -  def maybe_add_attachments(text, _attachments, _no_links = true), do: text +  def maybe_add_attachments(text, _attachments, true = _no_links), do: text    def maybe_add_attachments(text, attachments, _no_links) do      add_attachments(text, attachments) diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index bb7676cf0..468959a65 100644 --- a/lib/pleroma/web/federator/federator.ex +++ b/lib/pleroma/web/federator/federator.ex @@ -4,15 +4,19 @@  defmodule Pleroma.Web.Federator do    use GenServer -  alias Pleroma.User +    alias Pleroma.Activity -  alias Pleroma.Web.{WebFinger, Websub, Salmon} -  alias Pleroma.Web.Federator.RetryQueue +  alias Pleroma.User +  alias Pleroma.Web.WebFinger +  alias Pleroma.Web.Websub +  alias Pleroma.Web.Salmon    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Relay    alias Pleroma.Web.ActivityPub.Transmogrifier    alias Pleroma.Web.ActivityPub.Utils +  alias Pleroma.Web.Federator.RetryQueue    alias Pleroma.Web.OStatus +    require Logger    @websub Application.get_env(:pleroma, :websub) @@ -25,7 +29,7 @@ defmodule Pleroma.Web.Federator do    def start_link do      spawn(fn ->        # 1 minute -      Process.sleep(1000 * 60 * 1) +      Process.sleep(1000 * 60)        enqueue(:refresh_subscriptions, nil)      end) @@ -196,8 +200,7 @@ defmodule Pleroma.Web.Federator do      {:noreply, %{in: {i_running_jobs, i_queue}, out: {o_running_jobs, o_queue}}}    end -  def handle_cast(m, state) do -    IO.inspect("Unknown: #{inspect(m)}, #{inspect(state)}") +  def handle_cast(_, state) do      {:noreply, state}    end diff --git a/lib/pleroma/web/http_signatures/http_signatures.ex b/lib/pleroma/web/http_signatures/http_signatures.ex index e81f9e27a..8e2e2a44b 100644 --- a/lib/pleroma/web/http_signatures/http_signatures.ex +++ b/lib/pleroma/web/http_signatures/http_signatures.ex @@ -5,8 +5,9 @@  # https://tools.ietf.org/html/draft-cavage-http-signatures-08  defmodule Pleroma.Web.HTTPSignatures do    alias Pleroma.User -  alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Web.ActivityPub.ActivityPub +  alias Pleroma.Web.ActivityPub.Utils +    require Logger    def split_signature(sig) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 5d51e913d..942bb4338 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -4,23 +4,31 @@  defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    use Pleroma.Web, :controller -  alias Pleroma.{Repo, Object, Activity, User, Notification, Stats} +  alias Pleroma.Activity +  alias Pleroma.Config +  alias Pleroma.Filter +  alias Pleroma.Notification +  alias Pleroma.Object +  alias Pleroma.Repo +  alias Pleroma.Stats +  alias Pleroma.User    alias Pleroma.Web - -  alias Pleroma.Web.MastodonAPI.{ -    StatusView, -    AccountView, -    MastodonView, -    ListView, -    FilterView, -    PushSubscriptionView -  } - -  alias Pleroma.Web.ActivityPub.ActivityPub -  alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Web.CommonAPI -  alias Pleroma.Web.OAuth.{Authorization, Token, App}    alias Pleroma.Web.MediaProxy +  alias Pleroma.Web.Push +  alias Push.Subscription + +  alias Pleroma.Web.MastodonAPI.AccountView +  alias Pleroma.Web.MastodonAPI.FilterView +  alias Pleroma.Web.MastodonAPI.ListView +  alias Pleroma.Web.MastodonAPI.MastodonView +  alias Pleroma.Web.MastodonAPI.PushSubscriptionView +  alias Pleroma.Web.MastodonAPI.StatusView +  alias Pleroma.Web.ActivityPub.ActivityPub +  alias Pleroma.Web.ActivityPub.Utils +  alias Pleroma.Web.OAuth.App +  alias Pleroma.Web.OAuth.Authorization +  alias Pleroma.Web.OAuth.Token    import Pleroma.Web.ControllerHelper, only: [oauth_scopes: 2]    import Ecto.Query @@ -140,7 +148,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    @mastodon_api_level "2.5.0"    def masto_instance(conn, _params) do -    instance = Pleroma.Config.get(:instance) +    instance = Config.get(:instance)      response = %{        uri: Web.base_url(), @@ -236,7 +244,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do        |> Map.put("user", user)      activities = -      ActivityPub.fetch_activities([user.ap_id | user.following], params) +      [user.ap_id | user.following] +      |> ActivityPub.fetch_activities(params)        |> ActivityPub.contain_timeline(user)        |> Enum.reverse() @@ -249,14 +258,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    def public_timeline(%{assigns: %{user: user}} = conn, params) do      local_only = params["local"] in [true, "True", "true", "1"] -    params = +    activities =        params        |> Map.put("type", ["Create", "Announce"])        |> Map.put("local_only", local_only)        |> Map.put("blocking_user", user) - -    activities = -      ActivityPub.fetch_public_activities(params) +      |> ActivityPub.fetch_public_activities()        |> Enum.reverse()      conn @@ -325,6 +332,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do              as: :activity            )            |> Enum.reverse(), +        # credo:disable-for-previous-line Credo.Check.Refactor.PipeChainStart          descendants:            StatusView.render(              "index.json", @@ -333,6 +341,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do              as: :activity            )            |> Enum.reverse() +        # credo:disable-for-previous-line Credo.Check.Refactor.PipeChainStart        }        json(conn, result) @@ -456,13 +465,37 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      end    end +  def mute_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do +    activity = Activity.get_by_id(id) + +    with {:ok, activity} <- CommonAPI.add_mute(user, activity) do +      conn +      |> put_view(StatusView) +      |> try_render("status.json", %{activity: activity, for: user, as: :activity}) +    else +      {:error, reason} -> +        conn +        |> put_resp_content_type("application/json") +        |> send_resp(:bad_request, Jason.encode!(%{"error" => reason})) +    end +  end + +  def unmute_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do +    activity = Activity.get_by_id(id) + +    with {:ok, activity} <- CommonAPI.remove_mute(user, activity) do +      conn +      |> put_view(StatusView) +      |> try_render("status.json", %{activity: activity, for: user, as: :activity}) +    end +  end +    def notifications(%{assigns: %{user: user}} = conn, params) do      notifications = Notification.for_user(user, params)      result = -      Enum.map(notifications, fn x -> -        render_notification(user, x) -      end) +      notifications +      |> Enum.map(fn x -> render_notification(user, x) end)        |> Enum.filter(& &1)      conn @@ -591,7 +624,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do          []          |> Enum.map(&String.downcase(&1)) -    query_params = +    activities =        params        |> Map.put("type", "Create")        |> Map.put("local_only", local_only) @@ -599,9 +632,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do        |> Map.put("tag", tags)        |> Map.put("tag_all", tag_all)        |> Map.put("tag_reject", tag_reject) - -    activities = -      ActivityPub.fetch_public_activities(query_params) +      |> ActivityPub.fetch_public_activities()        |> Enum.reverse()      conn @@ -701,7 +732,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do           {:ok, _activity} <- ActivityPub.follow(follower, followed),           {:ok, follower, followed} <-             User.wait_and_refresh( -             Pleroma.Config.get([:activitypub, :follow_handshake_timeout]), +             Config.get([:activitypub, :follow_handshake_timeout]),               follower,               followed             ) do @@ -830,7 +861,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      tags_path = Web.base_url() <> "/tag/"      tags = -      String.split(query) +      query +      |> String.split()        |> Enum.uniq()        |> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)        |> Enum.map(fn tag -> String.slice(tag, 1..-1) end) @@ -852,7 +884,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      statuses = status_search(user, query)      tags = -      String.split(query) +      query +      |> String.split()        |> Enum.uniq()        |> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)        |> Enum.map(fn tag -> String.slice(tag, 1..-1) end) @@ -876,14 +909,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def favourites(%{assigns: %{user: user}} = conn, params) do -    params = +    activities =        params        |> Map.put("type", "Create")        |> Map.put("favorited_by", user.ap_id)        |> Map.put("blocking_user", user) - -    activities = -      ActivityPub.fetch_public_activities(params) +      |> ActivityPub.fetch_public_activities()        |> Enum.reverse()      conn @@ -999,12 +1030,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do        # we must filter the following list for the user to avoid leaking statuses the user        # does not actually have permission to see (for more info, peruse security issue #270). -      following_to = +      activities =          following          |> Enum.filter(fn x -> x in user.following end) - -      activities = -        ActivityPub.fetch_activities_bounded(following_to, following, params) +        |> ActivityPub.fetch_activities_bounded(following, params)          |> Enum.reverse()        conn @@ -1026,7 +1055,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      if user && token do        mastodon_emoji = mastodonized_emoji() -      limit = Pleroma.Config.get([:instance, :limit]) +      limit = Config.get([:instance, :limit])        accounts =          Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user})) @@ -1050,8 +1079,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do              max_toot_chars: limit            },            rights: %{ -            delete_others_notice: !!user.info.is_moderator, -            admin: !!user.info.is_admin +            delete_others_notice: present?(user.info.is_moderator), +            admin: present?(user.info.is_admin)            },            compose: %{              me: "#{user.id}", @@ -1247,7 +1276,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def get_filters(%{assigns: %{user: user}} = conn, _) do -    filters = Pleroma.Filter.get_filters(user) +    filters = Filter.get_filters(user)      res = FilterView.render("filters.json", filters: filters)      json(conn, res)    end @@ -1256,7 +1285,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do          %{assigns: %{user: user}} = conn,          %{"phrase" => phrase, "context" => context} = params        ) do -    query = %Pleroma.Filter{ +    query = %Filter{        user_id: user.id,        phrase: phrase,        context: context, @@ -1265,13 +1294,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do        # expires_at      } -    {:ok, response} = Pleroma.Filter.create(query) +    {:ok, response} = Filter.create(query)      res = FilterView.render("filter.json", filter: response)      json(conn, res)    end    def get_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id}) do -    filter = Pleroma.Filter.get(filter_id, user) +    filter = Filter.get(filter_id, user)      res = FilterView.render("filter.json", filter: filter)      json(conn, res)    end @@ -1280,7 +1309,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do          %{assigns: %{user: user}} = conn,          %{"phrase" => phrase, "context" => context, "id" => filter_id} = params        ) do -    query = %Pleroma.Filter{ +    query = %Filter{        user_id: user.id,        filter_id: filter_id,        phrase: phrase, @@ -1290,32 +1319,32 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do        # expires_at      } -    {:ok, response} = Pleroma.Filter.update(query) +    {:ok, response} = Filter.update(query)      res = FilterView.render("filter.json", filter: response)      json(conn, res)    end    def delete_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id}) do -    query = %Pleroma.Filter{ +    query = %Filter{        user_id: user.id,        filter_id: filter_id      } -    {:ok, _} = Pleroma.Filter.delete(query) +    {:ok, _} = Filter.delete(query)      json(conn, %{})    end    def create_push_subscription(%{assigns: %{user: user, token: token}} = conn, params) do -    true = Pleroma.Web.Push.enabled() -    Pleroma.Web.Push.Subscription.delete_if_exists(user, token) -    {:ok, subscription} = Pleroma.Web.Push.Subscription.create(user, token, params) +    true = Push.enabled() +    Subscription.delete_if_exists(user, token) +    {:ok, subscription} = Subscription.create(user, token, params)      view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)      json(conn, view)    end    def get_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do -    true = Pleroma.Web.Push.enabled() -    subscription = Pleroma.Web.Push.Subscription.get(user, token) +    true = Push.enabled() +    subscription = Subscription.get(user, token)      view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)      json(conn, view)    end @@ -1324,15 +1353,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do          %{assigns: %{user: user, token: token}} = conn,          params        ) do -    true = Pleroma.Web.Push.enabled() -    {:ok, subscription} = Pleroma.Web.Push.Subscription.update(user, token, params) +    true = Push.enabled() +    {:ok, subscription} = Subscription.update(user, token, params)      view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)      json(conn, view)    end    def delete_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do -    true = Pleroma.Web.Push.enabled() -    {:ok, _response} = Pleroma.Web.Push.Subscription.delete(user, token) +    true = Push.enabled() +    {:ok, _response} = Subscription.delete(user, token)      json(conn, %{})    end @@ -1343,17 +1372,21 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def suggestions(%{assigns: %{user: user}} = conn, _) do -    suggestions = Pleroma.Config.get(:suggestions) +    suggestions = 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]) +      host = Config.get([Pleroma.Web.Endpoint, :url, :host])        user = user.nickname -      url = String.replace(api, "{{host}}", host) |> String.replace("{{user}}", user) + +      url = +        api +        |> String.replace("{{host}}", host) +        |> String.replace("{{user}}", user)        with {:ok, %{status: 200, body: body}} <-               @httpoison.get( @@ -1366,8 +1399,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do                 ]               ),             {:ok, data} <- Jason.decode(body) do -        data2 = -          Enum.slice(data, 0, limit) +        data = +          data +          |> Enum.slice(0, limit)            |> Enum.map(fn x ->              Map.put(                x, @@ -1386,7 +1420,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do            end)          conn -        |> json(data2) +        |> json(data)        else          e -> Logger.error("Could not retrieve suggestions at fetch #{url}, #{inspect(e)}")        end @@ -1429,4 +1463,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      |> put_status(501)      |> json(%{error: "Can't display this activity"})    end + +  defp present?(nil), do: false +  defp present?(false), do: false +  defp present?(_), do: true  end diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 0ba4289da..9df9f14b2 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -4,11 +4,12 @@  defmodule Pleroma.Web.MastodonAPI.AccountView do    use Pleroma.Web, :view + +  alias Pleroma.HTML    alias Pleroma.User -  alias Pleroma.Web.MastodonAPI.AccountView    alias Pleroma.Web.CommonAPI.Utils +  alias Pleroma.Web.MastodonAPI.AccountView    alias Pleroma.Web.MediaProxy -  alias Pleroma.HTML    def render("accounts.json", %{users: users} = opts) do      users diff --git a/lib/pleroma/web/mastodon_api/views/filter_view.ex b/lib/pleroma/web/mastodon_api/views/filter_view.ex index 1052a449d..a685bc7b6 100644 --- a/lib/pleroma/web/mastodon_api/views/filter_view.ex +++ b/lib/pleroma/web/mastodon_api/views/filter_view.ex @@ -4,8 +4,8 @@  defmodule Pleroma.Web.MastodonAPI.FilterView do    use Pleroma.Web, :view -  alias Pleroma.Web.MastodonAPI.FilterView    alias Pleroma.Web.CommonAPI.Utils +  alias Pleroma.Web.MastodonAPI.FilterView    def render("filters.json", %{filters: filters} = opts) do      render_many(filters, FilterView, "filter.json", opts) diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index a227d742d..69f5f992c 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -9,10 +9,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do    alias Pleroma.HTML    alias Pleroma.Repo    alias Pleroma.User +  alias Pleroma.Web.CommonAPI    alias Pleroma.Web.CommonAPI.Utils -  alias Pleroma.Web.MediaProxy    alias Pleroma.Web.MastodonAPI.AccountView    alias Pleroma.Web.MastodonAPI.StatusView +  alias Pleroma.Web.MediaProxy    # TODO: Add cached version.    defp get_replied_to_activities(activities) do @@ -160,7 +161,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do        reblogged: present?(repeated),        favourited: present?(favorited),        bookmarked: present?(bookmarked), -      muted: false, +      muted: CommonAPI.thread_muted?(user, activity),        pinned: pinned?(activity, user),        sensitive: sensitive,        spoiler_text: object["summary"] || "", diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index c0254c8e6..ea75070c4 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -6,7 +6,8 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do    require Logger    alias Pleroma.Web.OAuth.Token -  alias Pleroma.{User, Repo} +  alias Pleroma.Repo +  alias Pleroma.User    @behaviour :cowboy_websocket_handler diff --git a/lib/pleroma/web/media_proxy/controller.ex b/lib/pleroma/web/media_proxy/controller.ex index de79cad73..c0552d89f 100644 --- a/lib/pleroma/web/media_proxy/controller.ex +++ b/lib/pleroma/web/media_proxy/controller.ex @@ -4,11 +4,12 @@  defmodule Pleroma.Web.MediaProxy.MediaProxyController do    use Pleroma.Web, :controller -  alias Pleroma.{Web.MediaProxy, ReverseProxy} +  alias Pleroma.ReverseProxy +  alias Pleroma.Web.MediaProxy    @default_proxy_opts [max_body_length: 25 * 1_048_576, http: [follow_redirect: true]] -  def remote(conn, params = %{"sig" => sig64, "url" => url64}) do +  def remote(conn, %{"sig" => sig64, "url" => url64} = params) do      with config <- Pleroma.Config.get([:media_proxy], []),           true <- Keyword.get(config, :enabled, false),           {:ok, url} <- MediaProxy.decode_url(sig64, url64), diff --git a/lib/pleroma/web/media_proxy/media_proxy.ex b/lib/pleroma/web/media_proxy/media_proxy.ex index e1eb1472d..39a725a69 100644 --- a/lib/pleroma/web/media_proxy/media_proxy.ex +++ b/lib/pleroma/web/media_proxy/media_proxy.ex @@ -9,7 +9,7 @@ defmodule Pleroma.Web.MediaProxy do    def url(""), do: nil -  def url(url = "/" <> _), do: url +  def url("/" <> _ = url), do: url    def url(url) do      config = Application.get_env(:pleroma, :media_proxy, []) @@ -19,11 +19,16 @@ defmodule Pleroma.Web.MediaProxy do      else        secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base] +      # Must preserve `%2F` for compatibility with S3 (https://git.pleroma.social/pleroma/pleroma/issues/580) +      replacement = get_replacement(url, ":2F:") +        # The URL is url-decoded and encoded again to ensure it is correctly encoded and not twice.        base64 =          url +        |> String.replace("%2F", replacement)          |> URI.decode()          |> URI.encode() +        |> String.replace(replacement, "%2F")          |> Base.url_encode64(@base64_opts)        sig = :crypto.hmac(:sha, secret, base64) @@ -60,4 +65,12 @@ defmodule Pleroma.Web.MediaProxy do      |> Enum.filter(fn value -> value end)      |> Path.join()    end + +  defp get_replacement(url, replacement) do +    if String.contains?(url, replacement) do +      get_replacement(url, replacement <> replacement) +    else +      replacement +    end +  end  end diff --git a/lib/pleroma/web/metadata/opengraph.ex b/lib/pleroma/web/metadata/opengraph.ex index 30333785e..190377767 100644 --- a/lib/pleroma/web/metadata/opengraph.ex +++ b/lib/pleroma/web/metadata/opengraph.ex @@ -3,10 +3,12 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.Metadata.Providers.OpenGraph do -  alias Pleroma.Web.Metadata.Providers.Provider +  alias Pleroma.HTML +  alias Pleroma.Formatter +  alias Pleroma.User    alias Pleroma.Web.Metadata -  alias Pleroma.{HTML, Formatter, User}    alias Pleroma.Web.MediaProxy +  alias Pleroma.Web.Metadata.Providers.Provider    @behaviour Provider diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 8c7df5b90..f4867d05b 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -5,10 +5,11 @@  defmodule Pleroma.Web.Nodeinfo.NodeinfoController do    use Pleroma.Web, :controller +  alias Pleroma.Config +  alias Pleroma.Repo    alias Pleroma.Stats +  alias Pleroma.User    alias Pleroma.Web -  alias Pleroma.{User, Repo} -  alias Pleroma.Config    alias Pleroma.Web.ActivityPub.MRF    plug(Pleroma.Web.FederatingPlug) @@ -32,7 +33,7 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do    # returns a nodeinfo 2.0 map, since 2.1 just adds a repository field    # under software. -  def raw_nodeinfo() do +  def raw_nodeinfo do      instance = Application.get_env(:pleroma, :instance)      media_proxy = Application.get_env(:pleroma, :media_proxy)      suggestions = Application.get_env(:pleroma, :suggestions) @@ -93,10 +94,8 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do        Config.get([:mrf_user_allowlist], [])        |> Enum.into(%{}, fn {k, v} -> {k, length(v)} end) -    mrf_transparency = Keyword.get(instance, :mrf_transparency) -      federation_response = -      if mrf_transparency do +      if Keyword.get(instance, :mrf_transparency) do          %{            mrf_policies: mrf_policies,            mrf_simple: mrf_simple, diff --git a/lib/pleroma/web/oauth/app.ex b/lib/pleroma/web/oauth/app.ex index c04626a73..3476da484 100644 --- a/lib/pleroma/web/oauth/app.ex +++ b/lib/pleroma/web/oauth/app.ex @@ -4,7 +4,7 @@  defmodule Pleroma.Web.OAuth.App do    use Ecto.Schema -  import Ecto.{Changeset} +  import Ecto.Changeset    schema "apps" do      field(:client_name, :string) @@ -25,8 +25,14 @@ defmodule Pleroma.Web.OAuth.App do      if changeset.valid? do        changeset -      |> put_change(:client_id, :crypto.strong_rand_bytes(32) |> Base.url_encode64()) -      |> put_change(:client_secret, :crypto.strong_rand_bytes(32) |> Base.url_encode64()) +      |> put_change( +        :client_id, +        :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false) +      ) +      |> put_change( +        :client_secret, +        :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false) +      )      else        changeset      end diff --git a/lib/pleroma/web/oauth/authorization.ex b/lib/pleroma/web/oauth/authorization.ex index c5b7ec9a5..d37c2cb83 100644 --- a/lib/pleroma/web/oauth/authorization.ex +++ b/lib/pleroma/web/oauth/authorization.ex @@ -5,10 +5,13 @@  defmodule Pleroma.Web.OAuth.Authorization do    use Ecto.Schema -  alias Pleroma.{User, Repo} -  alias Pleroma.Web.OAuth.{Authorization, App} +  alias Pleroma.User +  alias Pleroma.Repo +  alias Pleroma.Web.OAuth.Authorization +  alias Pleroma.Web.OAuth.App -  import Ecto.{Changeset, Query} +  import Ecto.Changeset +  import Ecto.Query    schema "oauth_authorizations" do      field(:token, :string) @@ -23,7 +26,7 @@ defmodule Pleroma.Web.OAuth.Authorization do    def create_authorization(%App{} = app, %User{} = user, scopes \\ nil) do      scopes = scopes || app.scopes -    token = :crypto.strong_rand_bytes(32) |> Base.url_encode64() +    token = :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)      authorization = %Authorization{        token: token, diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index fe2c958c9..7c1a3adbd 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -5,8 +5,11 @@  defmodule Pleroma.Web.OAuth.OAuthController do    use Pleroma.Web, :controller -  alias Pleroma.Web.OAuth.{Authorization, Token, App} -  alias Pleroma.{Repo, User} +  alias Pleroma.Web.OAuth.Authorization +  alias Pleroma.Web.OAuth.Token +  alias Pleroma.Web.OAuth.App +  alias Pleroma.Repo +  alias Pleroma.User    alias Comeonin.Pbkdf2    import Pleroma.Web.ControllerHelper, only: [oauth_scopes: 2] @@ -186,7 +189,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do      token      |> URI.decode()      |> Base.url_decode64!(padding: false) -    |> Base.url_encode64() +    |> Base.url_encode64(padding: false)    end    defp get_app_from_request(conn, params) do diff --git a/lib/pleroma/web/oauth/token.ex b/lib/pleroma/web/oauth/token.ex index 1fae5ed3a..ea4d56a29 100644 --- a/lib/pleroma/web/oauth/token.ex +++ b/lib/pleroma/web/oauth/token.ex @@ -7,8 +7,11 @@ defmodule Pleroma.Web.OAuth.Token do    import Ecto.Query -  alias Pleroma.{User, Repo} -  alias Pleroma.Web.OAuth.{Token, App, Authorization} +  alias Pleroma.User +  alias Pleroma.Repo +  alias Pleroma.Web.OAuth.Token +  alias Pleroma.Web.OAuth.App +  alias Pleroma.Web.OAuth.Authorization    schema "oauth_tokens" do      field(:token, :string) @@ -30,8 +33,8 @@ defmodule Pleroma.Web.OAuth.Token do    def create_token(%App{} = app, %User{} = user, scopes \\ nil) do      scopes = scopes || app.scopes -    token = :crypto.strong_rand_bytes(32) |> Base.url_encode64() -    refresh_token = :crypto.strong_rand_bytes(32) |> Base.url_encode64() +    token = :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false) +    refresh_token = :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)      token = %Token{        token: token, diff --git a/lib/pleroma/web/ostatus/activity_representer.ex b/lib/pleroma/web/ostatus/activity_representer.ex index 3d41fc708..9e1f24bc4 100644 --- a/lib/pleroma/web/ostatus/activity_representer.ex +++ b/lib/pleroma/web/ostatus/activity_representer.ex @@ -3,8 +3,11 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.OStatus.ActivityRepresenter do -  alias Pleroma.{Activity, User, Object} +  alias Pleroma.Activity +  alias Pleroma.User +  alias Pleroma.Object    alias Pleroma.Web.OStatus.UserRepresenter +    require Logger    defp get_href(id) do diff --git a/lib/pleroma/web/ostatus/feed_representer.ex b/lib/pleroma/web/ostatus/feed_representer.ex index 934d4042f..025d4731c 100644 --- a/lib/pleroma/web/ostatus/feed_representer.ex +++ b/lib/pleroma/web/ostatus/feed_representer.ex @@ -3,10 +3,11 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.OStatus.FeedRepresenter do -  alias Pleroma.Web.OStatus -  alias Pleroma.Web.OStatus.{UserRepresenter, ActivityRepresenter}    alias Pleroma.User +  alias Pleroma.Web.OStatus    alias Pleroma.Web.MediaProxy +  alias Pleroma.Web.OStatus.ActivityRepresenter +  alias Pleroma.Web.OStatus.UserRepresenter    def to_simple_form(user, activities, _users) do      most_recent_update = diff --git a/lib/pleroma/web/ostatus/handlers/follow_handler.ex b/lib/pleroma/web/ostatus/handlers/follow_handler.ex index becdf2fbf..91ad4bc40 100644 --- a/lib/pleroma/web/ostatus/handlers/follow_handler.ex +++ b/lib/pleroma/web/ostatus/handlers/follow_handler.ex @@ -3,7 +3,8 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.OStatus.FollowHandler do -  alias Pleroma.Web.{XML, OStatus} +  alias Pleroma.Web.XML +  alias Pleroma.Web.OStatus    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.User diff --git a/lib/pleroma/web/ostatus/handlers/note_handler.ex b/lib/pleroma/web/ostatus/handlers/note_handler.ex index c5b3e8d97..c2e585cac 100644 --- a/lib/pleroma/web/ostatus/handlers/note_handler.ex +++ b/lib/pleroma/web/ostatus/handlers/note_handler.ex @@ -4,8 +4,10 @@  defmodule Pleroma.Web.OStatus.NoteHandler do    require Logger -  alias Pleroma.Web.{XML, OStatus} -  alias Pleroma.{Object, Activity} +  alias Pleroma.Web.OStatus +  alias Pleroma.Web.XML +  alias Pleroma.Activity +  alias Pleroma.Object    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Web.CommonAPI diff --git a/lib/pleroma/web/ostatus/handlers/unfollow_handler.ex b/lib/pleroma/web/ostatus/handlers/unfollow_handler.ex index 1c64f3c3d..c9085894d 100644 --- a/lib/pleroma/web/ostatus/handlers/unfollow_handler.ex +++ b/lib/pleroma/web/ostatus/handlers/unfollow_handler.ex @@ -3,7 +3,8 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.OStatus.UnfollowHandler do -  alias Pleroma.Web.{XML, OStatus} +  alias Pleroma.Web.XML +  alias Pleroma.Web.OStatus    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.User diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index a20ca17bb..b4f5761ac 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -9,11 +9,19 @@ defmodule Pleroma.Web.OStatus do    import Pleroma.Web.XML    require Logger -  alias Pleroma.{Repo, User, Web, Object, Activity} +  alias Pleroma.Repo +  alias Pleroma.User +  alias Pleroma.Web +  alias Pleroma.Object +  alias Pleroma.Activity    alias Pleroma.Web.ActivityPub.ActivityPub -  alias Pleroma.Web.{WebFinger, Websub} -  alias Pleroma.Web.OStatus.{FollowHandler, UnfollowHandler, NoteHandler, DeleteHandler}    alias Pleroma.Web.ActivityPub.Transmogrifier +  alias Pleroma.Web.WebFinger +  alias Pleroma.Web.Websub +  alias Pleroma.Web.OStatus.FollowHandler +  alias Pleroma.Web.OStatus.UnfollowHandler +  alias Pleroma.Web.OStatus.NoteHandler +  alias Pleroma.Web.OStatus.DeleteHandler    def is_representable?(%Activity{data: data}) do      object = Object.normalize(data["object"]) diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex index 302ff38a4..db4c8f4da 100644 --- a/lib/pleroma/web/ostatus/ostatus_controller.ex +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -5,13 +5,17 @@  defmodule Pleroma.Web.OStatus.OStatusController do    use Pleroma.Web, :controller -  alias Pleroma.{User, Activity, Object} -  alias Pleroma.Web.OStatus.{FeedRepresenter, ActivityRepresenter} -  alias Pleroma.Web.{OStatus, Federator} -  alias Pleroma.Web.XML -  alias Pleroma.Web.ActivityPub.ObjectView -  alias Pleroma.Web.ActivityPub.ActivityPubController +  alias Pleroma.Activity +  alias Pleroma.Object +  alias Pleroma.User    alias Pleroma.Web.ActivityPub.ActivityPub +  alias Pleroma.Web.ActivityPub.ActivityPubController +  alias Pleroma.Web.ActivityPub.ObjectView +  alias Pleroma.Web.OStatus.ActivityRepresenter +  alias Pleroma.Web.OStatus.FeedRepresenter +  alias Pleroma.Web.Federator +  alias Pleroma.Web.OStatus +  alias Pleroma.Web.XML    plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming]) diff --git a/lib/pleroma/web/push/push.ex b/lib/pleroma/web/push/push.ex index ffd2aac91..ddd4fe037 100644 --- a/lib/pleroma/web/push/push.ex +++ b/lib/pleroma/web/push/push.ex @@ -5,7 +5,8 @@  defmodule Pleroma.Web.Push do    use GenServer -  alias Pleroma.{Repo, User} +  alias Pleroma.Repo +  alias Pleroma.User    alias Pleroma.Web.Push.Subscription    require Logger diff --git a/lib/pleroma/web/push/subscription.ex b/lib/pleroma/web/push/subscription.ex index bd9d9f3a7..242e30910 100644 --- a/lib/pleroma/web/push/subscription.ex +++ b/lib/pleroma/web/push/subscription.ex @@ -4,8 +4,11 @@  defmodule Pleroma.Web.Push.Subscription do    use Ecto.Schema +    import Ecto.Changeset -  alias Pleroma.{Repo, User} + +  alias Pleroma.Repo +  alias Pleroma.User    alias Pleroma.Web.OAuth.Token    alias Pleroma.Web.Push.Subscription diff --git a/lib/pleroma/web/rich_media/helpers.ex b/lib/pleroma/web/rich_media/helpers.ex index 521fa7ee0..abb1cf7f2 100644 --- a/lib/pleroma/web/rich_media/helpers.ex +++ b/lib/pleroma/web/rich_media/helpers.ex @@ -3,7 +3,9 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.RichMedia.Helpers do -  alias Pleroma.{Activity, Object, HTML} +  alias Pleroma.Activity +  alias Pleroma.Object +  alias Pleroma.HTML    alias Pleroma.Web.RichMedia.Parser    def fetch_data_for_activity(%Activity{} = activity) do diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex index 38f1cdeec..4341141df 100644 --- a/lib/pleroma/web/rich_media/parser.ex +++ b/lib/pleroma/web/rich_media/parser.ex @@ -9,6 +9,13 @@ defmodule Pleroma.Web.RichMedia.Parser do      Pleroma.Web.RichMedia.Parsers.OEmbed    ] +  @hackney_options [ +    pool: :media, +    timeout: 2_000, +    recv_timeout: 2_000, +    max_body: 2_000_000 +  ] +    def parse(nil), do: {:error, "No URL provided"}    if Mix.env() == :test do @@ -28,7 +35,7 @@ defmodule Pleroma.Web.RichMedia.Parser do    defp parse_url(url) do      try do -      {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: [pool: :media]) +      {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: @hackney_options)        html |> maybe_parse() |> clean_parsed_data() |> check_parsed_data()      rescue diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 6f17de1ca..e09164a77 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -240,14 +240,16 @@ defmodule Pleroma.Web.Router do        post("/statuses", MastodonAPIController, :post_status)        delete("/statuses/:id", MastodonAPIController, :delete_status) -      post("/statuses/:id/reblog", MastodonAPIController, :reblog_status) -      post("/statuses/:id/unreblog", MastodonAPIController, :unreblog_status) -      post("/statuses/:id/favourite", MastodonAPIController, :fav_status) -      post("/statuses/:id/unfavourite", MastodonAPIController, :unfav_status) -      post("/statuses/:id/pin", MastodonAPIController, :pin_status) -      post("/statuses/:id/unpin", MastodonAPIController, :unpin_status) -      post("/statuses/:id/bookmark", MastodonAPIController, :bookmark_status) -      post("/statuses/:id/unbookmark", MastodonAPIController, :unbookmark_status) +    post("/statuses/:id/reblog", MastodonAPIController, :reblog_status) +    post("/statuses/:id/unreblog", MastodonAPIController, :unreblog_status) +    post("/statuses/:id/favourite", MastodonAPIController, :fav_status) +    post("/statuses/:id/unfavourite", MastodonAPIController, :unfav_status) +    post("/statuses/:id/pin", MastodonAPIController, :pin_status) +    post("/statuses/:id/unpin", MastodonAPIController, :unpin_status) +    post("/statuses/:id/bookmark", MastodonAPIController, :bookmark_status) +    post("/statuses/:id/unbookmark", MastodonAPIController, :unbookmark_status) +    post("/statuses/:id/mute", MastodonAPIController, :mute_conversation) +    post("/statuses/:id/unmute", MastodonAPIController, :unmute_conversation)        post("/media", MastodonAPIController, :upload)        put("/media/:id", MastodonAPIController, :update_media) @@ -550,9 +552,8 @@ defmodule Pleroma.Web.Router do    scope "/", Pleroma.Web.ActivityPub do      pipe_through(:activitypub) - -    post("/users/:nickname/inbox", ActivityPubController, :inbox)      post("/inbox", ActivityPubController, :inbox) +    post("/users/:nickname/inbox", ActivityPubController, :inbox)    end    scope "/.well-known", Pleroma.Web do diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex index b1c2dc7fa..a5a9e16c6 100644 --- a/lib/pleroma/web/salmon/salmon.ex +++ b/lib/pleroma/web/salmon/salmon.ex @@ -6,10 +6,12 @@ defmodule Pleroma.Web.Salmon do    @httpoison Application.get_env(:pleroma, :httpoison)    use Bitwise +    alias Pleroma.Instances +  alias Pleroma.User    alias Pleroma.Web.XML    alias Pleroma.Web.OStatus.ActivityRepresenter -  alias Pleroma.User +    require Logger    def decode(salmon) do diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 978c77e57..4de7608e4 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -5,7 +5,11 @@  defmodule Pleroma.Web.Streamer do    use GenServer    require Logger -  alias Pleroma.{User, Notification, Activity, Object, Repo} +  alias Pleroma.User +  alias Pleroma.Notification +  alias Pleroma.Activity +  alias Pleroma.Object +  alias Pleroma.Repo    alias Pleroma.Web.ActivityPub.ActivityPub    @keepalive_interval :timer.seconds(30) diff --git a/lib/pleroma/web/templates/layout/app.html.eex b/lib/pleroma/web/templates/layout/app.html.eex index f944cbc26..db97ccac2 100644 --- a/lib/pleroma/web/templates/layout/app.html.eex +++ b/lib/pleroma/web/templates/layout/app.html.eex @@ -71,6 +71,32 @@          font-weight: 500;          font-size: 16px;        } + +      .alert-danger { +        box-sizing: border-box; +        width: 100%; +        color: #D8000C; +        background-color: #FFD2D2; +        border-radius: 4px; +        border: none; +        padding: 10px; +        margin-top: 20px; +        font-weight: 500; +        font-size: 16px; +      } + +      .alert-info { +        box-sizing: border-box; +        width: 100%; +        color: #00529B; +        background-color: #BDE5F8; +        border-radius: 4px; +        border: none; +        padding: 10px; +        margin-top: 20px; +        font-weight: 500; +        font-size: 16px; +      }      </style>    </head>    <body> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index 6e88efe11..f50599bdb 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -1,5 +1,9 @@ +<%= if get_flash(@conn, :info) do %>  <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p> +<% end %> +<%= if get_flash(@conn, :error) do %>  <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p> +<% end %>  <h2>OAuth Authorization</h2>  <%= form_for @conn, o_auth_path(@conn, :authorize), [as: "authorization"], fn f -> %>  <%= label f, :name, "Name or email" %> diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index b347faa71..e2fdedb25 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -4,14 +4,19 @@  defmodule Pleroma.Web.TwitterAPI.UtilController do    use Pleroma.Web, :controller +    require Logger + +  alias Comeonin.Pbkdf2 +  alias Pleroma.Emoji +  alias Pleroma.PasswordResetToken +  alias Pleroma.User +  alias Pleroma.Repo    alias Pleroma.Web +  alias Pleroma.Web.CommonAPI    alias Pleroma.Web.OStatus    alias Pleroma.Web.WebFinger -  alias Pleroma.Web.CommonAPI -  alias Comeonin.Pbkdf2    alias Pleroma.Web.ActivityPub.ActivityPub -  alias Pleroma.{Repo, PasswordResetToken, User, Emoji}    def show_password_reset(conn, %{"token" => token}) do      with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}), diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex index c4025cbd7..192ab7334 100644 --- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/activity_representer.ex @@ -2,16 +2,20 @@  # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only +# FIXME: Remove this module?  # THIS MODULE IS DEPRECATED! DON'T USE IT!  # USE THE Pleroma.Web.TwitterAPI.Views.ActivityView MODULE!  defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do    use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter    alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter -  alias Pleroma.{Activity, User} -  alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, ActivityView} -  alias Pleroma.Web.CommonAPI.Utils +  alias Pleroma.Activity    alias Pleroma.Formatter    alias Pleroma.HTML +  alias Pleroma.User +  alias Pleroma.Web.TwitterAPI.ActivityView +  alias Pleroma.Web.TwitterAPI.TwitterAPI +  alias Pleroma.Web.TwitterAPI.UserView +  alias Pleroma.Web.CommonAPI.Utils    alias Pleroma.Web.MastodonAPI.StatusView    defp user_by_ap_id(user_list, ap_id) do diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 7d00c01a1..db521a3ad 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -3,8 +3,13 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.TwitterAPI.TwitterAPI do -  alias Pleroma.{UserInviteToken, User, Activity, Repo, Object} -  alias Pleroma.{UserEmail, Mailer} +  alias Pleroma.UserInviteToken +  alias Pleroma.User +  alias Pleroma.Activity +  alias Pleroma.Repo +  alias Pleroma.Object +  alias Pleroma.UserEmail +  alias Pleroma.Mailer    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.TwitterAPI.UserView    alias Pleroma.Web.CommonAPI diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index b781d981f..c2f0dc2a9 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -7,12 +7,19 @@ defmodule Pleroma.Web.TwitterAPI.Controller do    import Pleroma.Web.ControllerHelper, only: [json_response: 3] -  alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, ActivityView, NotificationView} -  alias Pleroma.Web.CommonAPI -  alias Pleroma.{Repo, Activity, Object, User, Notification} +  alias Ecto.Changeset    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Utils -  alias Ecto.Changeset +  alias Pleroma.Web.CommonAPI +  alias Pleroma.Web.TwitterAPI.ActivityView +  alias Pleroma.Web.TwitterAPI.NotificationView +  alias Pleroma.Web.TwitterAPI.TwitterAPI +  alias Pleroma.Web.TwitterAPI.UserView +  alias Pleroma.Activity +  alias Pleroma.Object +  alias Pleroma.Notification +  alias Pleroma.Repo +  alias Pleroma.User    require Logger diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index d0d1221c3..661022afa 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -4,19 +4,18 @@  defmodule Pleroma.Web.TwitterAPI.ActivityView do    use Pleroma.Web, :view -  alias Pleroma.Web.CommonAPI.Utils -  alias Pleroma.User -  alias Pleroma.Web.TwitterAPI.UserView -  alias Pleroma.Web.TwitterAPI.ActivityView -  alias Pleroma.Web.TwitterAPI.TwitterAPI -  alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter -  alias Pleroma.Web.MastodonAPI.StatusView    alias Pleroma.Activity +  alias Pleroma.Formatter    alias Pleroma.HTML    alias Pleroma.Object -  alias Pleroma.User    alias Pleroma.Repo -  alias Pleroma.Formatter +  alias Pleroma.User +  alias Pleroma.Web.CommonAPI.Utils +  alias Pleroma.Web.MastodonAPI.StatusView +  alias Pleroma.Web.TwitterAPI.ActivityView +  alias Pleroma.Web.TwitterAPI.TwitterAPI +  alias Pleroma.Web.TwitterAPI.UserView +  alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter    import Ecto.Query    require Logger diff --git a/lib/pleroma/web/twitter_api/views/notification_view.ex b/lib/pleroma/web/twitter_api/views/notification_view.ex index d6a1c0a4d..e7c7a7496 100644 --- a/lib/pleroma/web/twitter_api/views/notification_view.ex +++ b/lib/pleroma/web/twitter_api/views/notification_view.ex @@ -4,10 +4,11 @@  defmodule Pleroma.Web.TwitterAPI.NotificationView do    use Pleroma.Web, :view -  alias Pleroma.{Notification, User} +  alias Pleroma.Notification +  alias Pleroma.User    alias Pleroma.Web.CommonAPI.Utils -  alias Pleroma.Web.TwitterAPI.UserView    alias Pleroma.Web.TwitterAPI.ActivityView +  alias Pleroma.Web.TwitterAPI.UserView    defp get_user(ap_id, opts) do      cond do diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index cc53dfbc2..a09450df7 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -4,11 +4,11 @@  defmodule Pleroma.Web.TwitterAPI.UserView do    use Pleroma.Web, :view -  alias Pleroma.User    alias Pleroma.Formatter +  alias Pleroma.HTML +  alias Pleroma.User    alias Pleroma.Web.CommonAPI.Utils    alias Pleroma.Web.MediaProxy -  alias Pleroma.HTML    def render("show.json", %{user: user = %User{}} = assigns) do      render_one(user, Pleroma.Web.TwitterAPI.UserView, "user.json", assigns) diff --git a/lib/pleroma/web/uploader_controller.ex b/lib/pleroma/web/uploader_controller.ex index 6c28d1197..5d8a77346 100644 --- a/lib/pleroma/web/uploader_controller.ex +++ b/lib/pleroma/web/uploader_controller.ex @@ -3,7 +3,7 @@ defmodule Pleroma.Web.UploaderController do    alias Pleroma.Uploaders.Uploader -  def callback(conn, params = %{"upload_path" => upload_path}) do +  def callback(conn, %{"upload_path" => upload_path} = params) do      process_callback(conn, :global.whereis_name({Uploader, upload_path}), params)    end diff --git a/lib/pleroma/web/web.ex b/lib/pleroma/web/web.ex index 30558e692..853aa2a87 100644 --- a/lib/pleroma/web/web.ex +++ b/lib/pleroma/web/web.ex @@ -24,7 +24,8 @@ defmodule Pleroma.Web do      quote do        use Phoenix.Controller, namespace: Pleroma.Web        import Plug.Conn -      import Pleroma.Web.{Gettext, Router.Helpers} +      import Pleroma.Web.Gettext +      import Pleroma.Web.Router.Helpers      end    end @@ -37,7 +38,9 @@ defmodule Pleroma.Web do        # Import convenience functions from controllers        import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1] -      import Pleroma.Web.{ErrorHelpers, Gettext, Router.Helpers} +      import Pleroma.Web.ErrorHelpers +      import Pleroma.Web.Gettext +      import Pleroma.Web.Router.Helpers        require Logger @@ -71,6 +74,7 @@ defmodule Pleroma.Web do    def router do      quote do        use Phoenix.Router +      # credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse        import Plug.Conn        import Phoenix.Controller      end @@ -78,6 +82,7 @@ defmodule Pleroma.Web do    def channel do      quote do +      # credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse        use Phoenix.Channel        import Pleroma.Web.Gettext      end diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 0a6338312..5ea5ae48e 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -5,9 +5,12 @@  defmodule Pleroma.Web.WebFinger do    @httpoison Application.get_env(:pleroma, :httpoison) -  alias Pleroma.{User, XmlBuilder} +  alias Pleroma.User +  alias Pleroma.XmlBuilder    alias Pleroma.Web -  alias Pleroma.Web.{XML, Salmon, OStatus} +  alias Pleroma.Web.XML +  alias Pleroma.Web.Salmon +  alias Pleroma.Web.OStatus    require Jason    require Logger diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex index 90ba79962..a08d7993d 100644 --- a/lib/pleroma/web/websub/websub.ex +++ b/lib/pleroma/web/websub/websub.ex @@ -4,11 +4,14 @@  defmodule Pleroma.Web.Websub do    alias Ecto.Changeset -  alias Pleroma.Repo    alias Pleroma.Instances -  alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription} +  alias Pleroma.Repo +  alias Pleroma.Web.Websub.WebsubServerSubscription +  alias Pleroma.Web.Websub.WebsubClientSubscription    alias Pleroma.Web.OStatus.FeedRepresenter -  alias Pleroma.Web.{XML, Endpoint, OStatus} +  alias Pleroma.Web.XML +  alias Pleroma.Web.Endpoint +  alias Pleroma.Web.OStatus    alias Pleroma.Web.Router.Helpers    require Logger diff --git a/lib/pleroma/web/websub/websub_controller.ex b/lib/pleroma/web/websub/websub_controller.ex index a92dfe87b..1ad18a8a4 100644 --- a/lib/pleroma/web/websub/websub_controller.ex +++ b/lib/pleroma/web/websub/websub_controller.ex @@ -5,8 +5,10 @@  defmodule Pleroma.Web.Websub.WebsubController do    use Pleroma.Web, :controller -  alias Pleroma.{Repo, User} -  alias Pleroma.Web.{Websub, Federator} +  alias Pleroma.Repo +  alias Pleroma.User +  alias Pleroma.Web.Websub +  alias Pleroma.Web.Federator    alias Pleroma.Web.Websub.WebsubClientSubscription    require Logger | 
