diff options
| author | Roman Chvanikov <chvanikoff@pm.me> | 2019-07-24 16:37:52 +0300 | 
|---|---|---|
| committer | Roman Chvanikov <chvanikoff@pm.me> | 2019-07-24 16:37:52 +0300 | 
| commit | d2da3d30f3349946500423bab53e0c1221ab7b9b (patch) | |
| tree | 338d2e3b0412a9be89a462173e367495c5e9ad40 /lib | |
| parent | afc7708dbe00a70be616f00f01b22b0d01b9b61b (diff) | |
| parent | 53fad36b57b61b28db595e445cd01fd6044dab6b (diff) | |
| download | pleroma-d2da3d30f3349946500423bab53e0c1221ab7b9b.tar.gz pleroma-d2da3d30f3349946500423bab53e0c1221ab7b9b.zip | |
Merge branch 'develop' into feature/digest-email
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/pleroma/signature.ex | 15 | ||||
| -rw-r--r-- | lib/pleroma/user.ex | 20 | ||||
| -rw-r--r-- | lib/pleroma/user_invite_token.ex | 2 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 23 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/mrf.ex | 10 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/mrf/simple_policy.ex | 55 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/publisher.ex | 60 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/visibility.ex | 13 | ||||
| -rw-r--r-- | lib/pleroma/web/admin_api/admin_api_controller.ex | 31 | ||||
| -rw-r--r-- | lib/pleroma/web/admin_api/config.ex | 14 | ||||
| -rw-r--r-- | lib/pleroma/web/common_api/utils.ex | 7 | ||||
| -rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 10 | ||||
| -rw-r--r-- | lib/pleroma/web/rich_media/parser.ex | 5 | ||||
| -rw-r--r-- | lib/pleroma/web/router.ex | 26 | ||||
| -rw-r--r-- | lib/pleroma/web/streamer.ex | 45 | 
15 files changed, 254 insertions, 82 deletions
| diff --git a/lib/pleroma/signature.ex b/lib/pleroma/signature.ex index 2a0823ecf..0bf49fd7c 100644 --- a/lib/pleroma/signature.ex +++ b/lib/pleroma/signature.ex @@ -10,9 +10,18 @@ defmodule Pleroma.Signature do    alias Pleroma.Web.ActivityPub.ActivityPub    def key_id_to_actor_id(key_id) do -    URI.parse(key_id) -    |> Map.put(:fragment, nil) -    |> URI.to_string() +    uri = +      URI.parse(key_id) +      |> Map.put(:fragment, nil) + +    uri = +      if String.ends_with?(uri.path, "/publickey") do +        Map.put(uri, :path, String.replace(uri.path, "/publickey", "")) +      else +        uri +      end + +    URI.to_string(uri)    end    def fetch_public_key(conn) do diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index c0e418e2f..e8a3f9663 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -587,12 +587,23 @@ defmodule Pleroma.User do    @spec get_followers_query(User.t()) :: Ecto.Query.t()    def get_followers_query(user), do: get_followers_query(user, nil) +  @spec get_followers(User.t(), pos_integer()) :: {:ok, list(User.t())}    def get_followers(user, page \\ nil) do      q = get_followers_query(user, page)      {:ok, Repo.all(q)}    end +  @spec get_external_followers(User.t(), pos_integer()) :: {:ok, list(User.t())} +  def get_external_followers(user, page \\ nil) do +    q = +      user +      |> get_followers_query(page) +      |> User.Query.build(%{external: true}) + +    {:ok, Repo.all(q)} +  end +    def get_followers_ids(user, page \\ nil) do      q = get_followers_query(user, page) @@ -874,12 +885,17 @@ defmodule Pleroma.User do    def blocks?(%User{info: info} = _user, %{ap_id: ap_id}) do      blocks = info.blocks -    domain_blocks = info.domain_blocks + +    domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(info.domain_blocks) +      %{host: host} = URI.parse(ap_id) -    Enum.member?(blocks, ap_id) || Enum.any?(domain_blocks, &(&1 == host)) +    Enum.member?(blocks, ap_id) || +      Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, host)    end +  def blocks?(nil, _), do: false +    def subscribed_to?(user, %{ap_id: ap_id}) do      with %User{} = target <- get_cached_by_ap_id(ap_id) do        Enum.member?(target.info.subscribers, user.ap_id) diff --git a/lib/pleroma/user_invite_token.ex b/lib/pleroma/user_invite_token.ex index fadc89891..b9e80acdd 100644 --- a/lib/pleroma/user_invite_token.ex +++ b/lib/pleroma/user_invite_token.ex @@ -74,7 +74,7 @@ defmodule Pleroma.UserInviteToken do    @spec find_by_token(token()) :: {:ok, UserInviteToken.t()} | nil    def find_by_token(token) do -    with invite <- Repo.get_by(UserInviteToken, token: token) do +    with %UserInviteToken{} = invite <- Repo.get_by(UserInviteToken, token: token) do        {:ok, invite}      end    end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 31397b09f..a42c50875 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -631,17 +631,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do        |> Map.put("pinned_activity_ids", user.info.pinned_activities)      recipients = -      if reading_user do -        ["https://www.w3.org/ns/activitystreams#Public"] ++ -          [reading_user.ap_id | reading_user.following] -      else -        ["https://www.w3.org/ns/activitystreams#Public"] -      end +      user_activities_recipients(%{ +        "godmode" => params["godmode"], +        "reading_user" => reading_user +      })      fetch_activities(recipients, params)      |> Enum.reverse()    end +  defp user_activities_recipients(%{"godmode" => true}) do +    [] +  end + +  defp user_activities_recipients(%{"reading_user" => reading_user}) do +    if reading_user do +      ["https://www.w3.org/ns/activitystreams#Public"] ++ +        [reading_user.ap_id | reading_user.following] +    else +      ["https://www.w3.org/ns/activitystreams#Public"] +    end +  end +    defp restrict_since(query, %{"since_id" => ""}), do: query    defp restrict_since(query, %{"since_id" => since_id}) do diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex index 10ceef715..dd204b21c 100644 --- a/lib/pleroma/web/activity_pub/mrf.ex +++ b/lib/pleroma/web/activity_pub/mrf.ex @@ -25,4 +25,14 @@ defmodule Pleroma.Web.ActivityPub.MRF do    defp get_policies(policy) when is_atom(policy), do: [policy]    defp get_policies(policies) when is_list(policies), do: policies    defp get_policies(_), do: [] + +  @spec subdomains_regex([String.t()]) :: [Regex.t()] +  def subdomains_regex(domains) when is_list(domains) do +    for domain <- domains, do: ~r(^#{String.replace(domain, "*.", "(.*\\.)*")}$) +  end + +  @spec subdomain_match?([Regex.t()], String.t()) :: boolean() +  def subdomain_match?(domains, host) do +    Enum.any?(domains, fn domain -> Regex.match?(domain, host) end) +  end  end diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 433d23c5f..2cf63d3db 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -4,22 +4,29 @@  defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do    alias Pleroma.User +  alias Pleroma.Web.ActivityPub.MRF    @moduledoc "Filter activities depending on their origin instance" -  @behaviour Pleroma.Web.ActivityPub.MRF +  @behaviour MRF    defp check_accept(%{host: actor_host} = _actor_info, object) do -    accepts = Pleroma.Config.get([:mrf_simple, :accept]) +    accepts = +      Pleroma.Config.get([:mrf_simple, :accept]) +      |> MRF.subdomains_regex()      cond do        accepts == [] -> {:ok, object}        actor_host == Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object} -      Enum.member?(accepts, actor_host) -> {:ok, object} +      MRF.subdomain_match?(accepts, actor_host) -> {:ok, object}        true -> {:reject, nil}      end    end    defp check_reject(%{host: actor_host} = _actor_info, object) do -    if Enum.member?(Pleroma.Config.get([:mrf_simple, :reject]), actor_host) do +    rejects = +      Pleroma.Config.get([:mrf_simple, :reject]) +      |> MRF.subdomains_regex() + +    if MRF.subdomain_match?(rejects, actor_host) do        {:reject, nil}      else        {:ok, object} @@ -31,8 +38,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do           %{"type" => "Create", "object" => %{"attachment" => child_attachment}} = object         )         when length(child_attachment) > 0 do +    media_removal = +      Pleroma.Config.get([:mrf_simple, :media_removal]) +      |> MRF.subdomains_regex() +      object = -      if Enum.member?(Pleroma.Config.get([:mrf_simple, :media_removal]), actor_host) do +      if MRF.subdomain_match?(media_removal, actor_host) do          child_object = Map.delete(object["object"], "attachment")          Map.put(object, "object", child_object)        else @@ -51,8 +62,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do             "object" => child_object           } = object         ) do +    media_nsfw = +      Pleroma.Config.get([:mrf_simple, :media_nsfw]) +      |> MRF.subdomains_regex() +      object = -      if Enum.member?(Pleroma.Config.get([:mrf_simple, :media_nsfw]), actor_host) do +      if MRF.subdomain_match?(media_nsfw, actor_host) do          tags = (child_object["tag"] || []) ++ ["nsfw"]          child_object = Map.put(child_object, "tag", tags)          child_object = Map.put(child_object, "sensitive", true) @@ -67,12 +82,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do    defp check_media_nsfw(_actor_info, object), do: {:ok, object}    defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do +    timeline_removal = +      Pleroma.Config.get([:mrf_simple, :federated_timeline_removal]) +      |> MRF.subdomains_regex() +      object = -      with true <- -             Enum.member?( -               Pleroma.Config.get([:mrf_simple, :federated_timeline_removal]), -               actor_host -             ), +      with true <- MRF.subdomain_match?(timeline_removal, actor_host),             user <- User.get_cached_by_ap_id(object["actor"]),             true <- "https://www.w3.org/ns/activitystreams#Public" in object["to"] do          to = @@ -94,7 +109,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do    end    defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do -    if actor_host in Pleroma.Config.get([:mrf_simple, :report_removal]) do +    report_removal = +      Pleroma.Config.get([:mrf_simple, :report_removal]) +      |> MRF.subdomains_regex() + +    if MRF.subdomain_match?(report_removal, actor_host) do        {:reject, nil}      else        {:ok, object} @@ -104,7 +123,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do    defp check_report_removal(_actor_info, object), do: {:ok, object}    defp check_avatar_removal(%{host: actor_host} = _actor_info, %{"icon" => _icon} = object) do -    if actor_host in Pleroma.Config.get([:mrf_simple, :avatar_removal]) do +    avatar_removal = +      Pleroma.Config.get([:mrf_simple, :avatar_removal]) +      |> MRF.subdomains_regex() + +    if MRF.subdomain_match?(avatar_removal, actor_host) do        {:ok, Map.delete(object, "icon")}      else        {:ok, object} @@ -114,7 +137,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do    defp check_avatar_removal(_actor_info, object), do: {:ok, object}    defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image} = object) do -    if actor_host in Pleroma.Config.get([:mrf_simple, :banner_removal]) do +    banner_removal = +      Pleroma.Config.get([:mrf_simple, :banner_removal]) +      |> MRF.subdomains_regex() + +    if MRF.subdomain_match?(banner_removal, actor_host) do        {:ok, Map.delete(object, "image")}      else        {:ok, object} diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index c505223f7..016d78216 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -87,18 +87,23 @@ defmodule Pleroma.Web.ActivityPub.Publisher do      if public do        true      else -      inbox_info = URI.parse(inbox) -      !Enum.member?(Config.get([:instance, :quarantined_instances], []), inbox_info.host) +      %{host: host} = URI.parse(inbox) + +      quarantined_instances = +        Config.get([:instance, :quarantined_instances], []) +        |> Pleroma.Web.ActivityPub.MRF.subdomains_regex() + +      !Pleroma.Web.ActivityPub.MRF.subdomain_match?(quarantined_instances, host)      end    end +  @spec recipients(User.t(), Activity.t()) :: list(User.t()) | []    defp recipients(actor, activity) do -    followers = +    {:ok, followers} =        if actor.follower_address in activity.recipients do -        {:ok, followers} = User.get_followers(actor) -        Enum.filter(followers, &(!&1.local)) +        User.get_external_followers(actor)        else -        [] +        {:ok, []}        end      Pleroma.Web.Salmon.remote_users(actor, activity) ++ followers @@ -112,6 +117,45 @@ defmodule Pleroma.Web.ActivityPub.Publisher do      |> Enum.map(& &1.ap_id)    end +  @as_public "https://www.w3.org/ns/activitystreams#Public" + +  defp maybe_use_sharedinbox(%User{info: %{source_data: data}}), +    do: (is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"] + +  @doc """ +  Determine a user inbox to use based on heuristics.  These heuristics +  are based on an approximation of the ``sharedInbox`` rules in the +  [ActivityPub specification][ap-sharedinbox]. + +  Please do not edit this function (or its children) without reading +  the spec, as editing the code is likely to introduce some breakage +  without some familiarity. + +     [ap-sharedinbox]: https://www.w3.org/TR/activitypub/#shared-inbox-delivery +  """ +  def determine_inbox( +        %Activity{data: activity_data}, +        %User{info: %{source_data: data}} = user +      ) do +    to = activity_data["to"] || [] +    cc = activity_data["cc"] || [] +    type = activity_data["type"] + +    cond do +      type == "Delete" -> +        maybe_use_sharedinbox(user) + +      @as_public in to || @as_public in cc -> +        maybe_use_sharedinbox(user) + +      length(to) + length(cc) > 1 -> +        maybe_use_sharedinbox(user) + +      true -> +        data["inbox"] +    end +  end +    @doc """    Publishes an activity with BCC to all relevant peers.    """ @@ -166,8 +210,8 @@ defmodule Pleroma.Web.ActivityPub.Publisher do      recipients(actor, activity)      |> Enum.filter(fn user -> User.ap_enabled?(user) end) -    |> Enum.map(fn %{info: %{source_data: data}} -> -      (is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"] +    |> Enum.map(fn %User{} = user -> +      determine_inbox(activity, user)      end)      |> Enum.uniq()      |> Enum.filter(fn inbox -> should_federate?(inbox, public) end) diff --git a/lib/pleroma/web/activity_pub/visibility.ex b/lib/pleroma/web/activity_pub/visibility.ex index 2666edc7c..097fceb08 100644 --- a/lib/pleroma/web/activity_pub/visibility.ex +++ b/lib/pleroma/web/activity_pub/visibility.ex @@ -8,14 +8,14 @@ defmodule Pleroma.Web.ActivityPub.Visibility do    alias Pleroma.Repo    alias Pleroma.User +  @public "https://www.w3.org/ns/activitystreams#Public" + +  @spec is_public?(Object.t() | Activity.t() | map()) :: boolean()    def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false    def is_public?(%Object{data: data}), do: is_public?(data)    def is_public?(%Activity{data: data}), do: is_public?(data)    def is_public?(%{"directMessage" => true}), do: false - -  def is_public?(data) do -    "https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || [])) -  end +  def is_public?(data), do: @public in (data["to"] ++ (data["cc"] || []))    def is_private?(activity) do      with false <- is_public?(activity), @@ -69,15 +69,14 @@ defmodule Pleroma.Web.ActivityPub.Visibility do    end    def get_visibility(object) do -    public = "https://www.w3.org/ns/activitystreams#Public"      to = object.data["to"] || []      cc = object.data["cc"] || []      cond do -      public in to -> +      @public in to ->          "public" -      public in cc -> +      @public in cc ->          "unlisted"        # this should use the sql for the object's activity diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index 4a0bf4823..1ae5acd91 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -82,6 +82,25 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do      end    end +  def list_user_statuses(conn, %{"nickname" => nickname} = params) do +    godmode = params["godmode"] == "true" || params["godmode"] == true + +    with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do +      {_, page_size} = page_params(params) + +      activities = +        ActivityPub.fetch_user_activities(user, nil, %{ +          "limit" => page_size, +          "godmode" => godmode +        }) + +      conn +      |> json(StatusView.render("index.json", %{activities: activities, as: :activity})) +    else +      _ -> {:error, :not_found} +    end +  end +    def user_toggle_activation(conn, %{"nickname" => nickname}) do      user = User.get_cached_by_nickname(nickname) @@ -272,11 +291,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    @doc "Revokes invite by token"    def revoke_invite(conn, %{"token" => token}) do -    invite = UserInviteToken.find_by_token!(token) -    {:ok, updated_invite} = UserInviteToken.update_invite(invite, %{used: true}) - -    conn -    |> json(AccountView.render("invite.json", %{invite: updated_invite})) +    with {:ok, invite} <- UserInviteToken.find_by_token(token), +         {:ok, updated_invite} = UserInviteToken.update_invite(invite, %{used: true}) do +      conn +      |> json(AccountView.render("invite.json", %{invite: updated_invite})) +    else +      nil -> {:error, :not_found} +    end    end    @doc "Get a password reset token (base64 string) for given nickname" diff --git a/lib/pleroma/web/admin_api/config.ex b/lib/pleroma/web/admin_api/config.ex index b4eb8e002..dde05ea7b 100644 --- a/lib/pleroma/web/admin_api/config.ex +++ b/lib/pleroma/web/admin_api/config.ex @@ -84,6 +84,7 @@ defmodule Pleroma.Web.AdminAPI.Config do    end    defp do_convert({:dispatch, [entity]}), do: %{"tuple" => [":dispatch", [inspect(entity)]]} +  defp do_convert({:partial_chain, entity}), do: %{"tuple" => [":partial_chain", inspect(entity)]}    defp do_convert(entity) when is_tuple(entity),      do: %{"tuple" => do_convert(Tuple.to_list(entity))} @@ -113,11 +114,15 @@ defmodule Pleroma.Web.AdminAPI.Config do    defp do_transform(%Regex{} = entity) when is_map(entity), do: entity    defp do_transform(%{"tuple" => [":dispatch", [entity]]}) do -    cleaned_string = String.replace(entity, ~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "") -    {dispatch_settings, []} = Code.eval_string(cleaned_string, [], requires: [], macros: []) +    {dispatch_settings, []} = do_eval(entity)      {:dispatch, [dispatch_settings]}    end +  defp do_transform(%{"tuple" => [":partial_chain", entity]}) do +    {partial_chain, []} = do_eval(entity) +    {:partial_chain, partial_chain} +  end +    defp do_transform(%{"tuple" => entity}) do      Enum.reduce(entity, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end)    end @@ -149,4 +154,9 @@ defmodule Pleroma.Web.AdminAPI.Config do        do: String.to_existing_atom("Elixir." <> value),        else: value    end + +  defp do_eval(entity) do +    cleaned_string = String.replace(entity, ~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "") +    Code.eval_string(cleaned_string, [], requires: [], macros: []) +  end  end diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index fcc000969..94462c3dd 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -439,6 +439,13 @@ defmodule Pleroma.Web.CommonAPI.Utils do    def maybe_notify_mentioned_recipients(recipients, _), do: recipients +  # Do not notify subscribers if author is making a reply +  def maybe_notify_subscribers(recipients, %Activity{ +        object: %Object{data: %{"inReplyTo" => _ap_id}} +      }) do +    recipients +  end +    def maybe_notify_subscribers(          recipients,          %Activity{data: %{"actor" => actor, "type" => type}} = activity diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index e8b43e475..d660f3f05 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -883,7 +883,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      with %Activity{data: %{"object" => object}} <- Activity.get_by_id(id),           %Object{data: %{"likes" => likes}} <- Object.normalize(object) do        q = from(u in User, where: u.ap_id in ^likes) -      users = Repo.all(q) + +      users = +        Repo.all(q) +        |> Enum.filter(&(not User.blocks?(user, &1)))        conn        |> put_view(AccountView) @@ -897,7 +900,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      with %Activity{data: %{"object" => object}} <- Activity.get_by_id(id),           %Object{data: %{"announcements" => announces}} <- Object.normalize(object) do        q = from(u in User, where: u.ap_id in ^announces) -      users = Repo.all(q) + +      users = +        Repo.all(q) +        |> Enum.filter(&(not User.blocks?(user, &1)))        conn        |> put_view(AccountView) diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex index b69b2be61..f5f9e358c 100644 --- a/lib/pleroma/web/rich_media/parser.ex +++ b/lib/pleroma/web/rich_media/parser.ex @@ -55,8 +55,8 @@ defmodule Pleroma.Web.RichMedia.Parser do          ttl_setters: [MyModule]    """    def set_ttl_based_on_image({:ok, data}, url) do -    with {:ok, nil} <- Cachex.ttl(:rich_media_cache, url) do -      ttl = get_ttl_from_image(data, url) +    with {:ok, nil} <- Cachex.ttl(:rich_media_cache, url), +         ttl when is_number(ttl) <- get_ttl_from_image(data, url) do        Cachex.expire_at(:rich_media_cache, url, ttl * 1000)        {:ok, data}      else @@ -82,6 +82,7 @@ defmodule Pleroma.Web.RichMedia.Parser do        html        |> maybe_parse() +      |> Map.put(:url, url)        |> clean_parsed_data()        |> check_parsed_data()      rescue diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 73d601ac5..0717e9aa0 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -154,22 +154,12 @@ defmodule Pleroma.Web.Router do      post("/users/follow", AdminAPIController, :user_follow)      post("/users/unfollow", AdminAPIController, :user_unfollow) -    # TODO: to be removed at version 1.0 -    delete("/user", AdminAPIController, :user_delete) -    post("/user", AdminAPIController, :user_create) -      delete("/users", AdminAPIController, :user_delete)      post("/users", AdminAPIController, :user_create)      patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation)      put("/users/tag", AdminAPIController, :tag_users)      delete("/users/tag", AdminAPIController, :untag_users) -    # TODO: to be removed at version 1.0 -    get("/permission_group/:nickname", AdminAPIController, :right_get) -    get("/permission_group/:nickname/:permission_group", AdminAPIController, :right_get) -    post("/permission_group/:nickname/:permission_group", AdminAPIController, :right_add) -    delete("/permission_group/:nickname/:permission_group", AdminAPIController, :right_delete) -      get("/users/:nickname/permission_group", AdminAPIController, :right_get)      get("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_get)      post("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_add) @@ -190,13 +180,11 @@ defmodule Pleroma.Web.Router do      post("/users/revoke_invite", AdminAPIController, :revoke_invite)      post("/users/email_invite", AdminAPIController, :email_invite) -    # TODO: to be removed at version 1.0 -    get("/password_reset", AdminAPIController, :get_password_reset) -      get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset)      get("/users", AdminAPIController, :list_users)      get("/users/:nickname", AdminAPIController, :user_show) +    get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses)      get("/reports", AdminAPIController, :list_reports)      get("/reports/:id", AdminAPIController, :report_show) @@ -665,6 +653,12 @@ defmodule Pleroma.Web.Router do      end    end +  scope "/", Pleroma.Web.ActivityPub do +    pipe_through(:activitypub) +    post("/inbox", ActivityPubController, :inbox) +    post("/users/:nickname/inbox", ActivityPubController, :inbox) +  end +    scope "/relay", Pleroma.Web.ActivityPub do      pipe_through(:ap_service_actor) @@ -679,12 +673,6 @@ defmodule Pleroma.Web.Router do      post("/inbox", ActivityPubController, :inbox)    end -  scope "/", Pleroma.Web.ActivityPub do -    pipe_through(:activitypub) -    post("/inbox", ActivityPubController, :inbox) -    post("/users/:nickname/inbox", ActivityPubController, :inbox) -  end -    scope "/.well-known", Pleroma.Web do      pipe_through(:well_known) diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 4f325113a..9ee331030 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -13,6 +13,7 @@ defmodule Pleroma.Web.Streamer do    alias Pleroma.User    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Visibility +  alias Pleroma.Web.CommonAPI    alias Pleroma.Web.MastodonAPI.NotificationView    @keepalive_interval :timer.seconds(30) @@ -118,10 +119,14 @@ defmodule Pleroma.Web.Streamer do      topics      |> Map.get("#{topic}:#{item.user_id}", [])      |> Enum.each(fn socket -> -      send( -        socket.transport_pid, -        {:text, represent_notification(socket.assigns[:user], item)} -      ) +      with %User{} = user <- User.get_cached_by_ap_id(socket.assigns[:user].ap_id), +           true <- should_send?(user, item), +           false <- CommonAPI.thread_muted?(user, item.activity) do +        send( +          socket.transport_pid, +          {:text, represent_notification(socket.assigns[:user], item)} +        ) +      end      end)      {:noreply, topics} @@ -225,19 +230,37 @@ defmodule Pleroma.Web.Streamer do      |> Jason.encode!()    end +  defp should_send?(%User{} = user, %Activity{} = item) do +    blocks = user.info.blocks || [] +    mutes = user.info.mutes || [] +    reblog_mutes = user.info.muted_reblogs || [] +    domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.info.domain_blocks) + +    with parent when not is_nil(parent) <- Object.normalize(item), +         true <- Enum.all?([blocks, mutes, reblog_mutes], &(item.actor not in &1)), +         true <- Enum.all?([blocks, mutes], &(parent.data["actor"] not in &1)), +         %{host: item_host} <- URI.parse(item.actor), +         %{host: parent_host} <- URI.parse(parent.data["actor"]), +         false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, item_host), +         false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, parent_host), +         true <- thread_containment(item, user) do +      true +    else +      _ -> false +    end +  end + +  defp should_send?(%User{} = user, %Notification{activity: activity}) do +    should_send?(user, activity) +  end +    def push_to_socket(topics, topic, %Activity{data: %{"type" => "Announce"}} = item) do      Enum.each(topics[topic] || [], fn socket ->        # Get the current user so we have up-to-date blocks etc.        if socket.assigns[:user] do          user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) -        blocks = user.info.blocks || [] -        mutes = user.info.mutes || [] -        reblog_mutes = user.info.muted_reblogs || [] -        with parent when not is_nil(parent) <- Object.normalize(item), -             true <- Enum.all?([blocks, mutes, reblog_mutes], &(item.actor not in &1)), -             true <- Enum.all?([blocks, mutes], &(parent.data["actor"] not in &1)), -             true <- thread_containment(item, user) do +        if should_send?(user, item) do            send(socket.transport_pid, {:text, represent_update(item, user)})          end        else | 
