import Ecto.Query
import Pleroma.Web.ActivityPub.Utils
+ import Pleroma.Web.ActivityPub.Visibility
require Logger
# only accept false as false value
local = !(params[:local] == false)
- with data <- %{"to" => to, "type" => "Accept", "actor" => actor, "object" => object},
+ with data <- %{"to" => to, "type" => "Accept", "actor" => actor.ap_id, "object" => object},
{:ok, activity} <- insert(data, local),
- :ok <- maybe_federate(activity) do
+ :ok <- maybe_federate(activity),
+ _ <- User.update_follow_request_count(actor) do
{:ok, activity}
end
end
# only accept false as false value
local = !(params[:local] == false)
- with data <- %{"to" => to, "type" => "Reject", "actor" => actor, "object" => object},
+ with data <- %{"to" => to, "type" => "Reject", "actor" => actor.ap_id, "object" => object},
{:ok, activity} <- insert(data, local),
- :ok <- maybe_federate(activity) do
+ :ok <- maybe_federate(activity),
+ _ <- User.update_follow_request_count(actor) do
{:ok, activity}
end
end
def follow(follower, followed, activity_id \\ nil, local \\ true) do
with data <- make_follow_data(follower, followed, activity_id),
{:ok, activity} <- insert(data, local),
- :ok <- maybe_federate(activity) do
+ :ok <- maybe_federate(activity),
+ _ <- User.update_follow_request_count(followed) do
{:ok, activity}
end
end
{:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"),
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
{:ok, activity} <- insert(unfollow_data, local),
- :ok <- maybe_federate(activity) do
+ :ok <- maybe_federate(activity),
+ _ <- User.update_follow_request_count(followed) do
{:ok, activity}
end
end
end
end
+ def flag(
+ %{
+ actor: actor,
+ context: context,
+ account: account,
+ statuses: statuses,
+ content: content
+ } = params
+ ) do
+ additional = params[:additional] || %{}
+
+ # only accept false as false value
+ local = !(params[:local] == false)
+
+ %{
+ actor: actor,
+ context: context,
+ account: account,
+ statuses: statuses,
+ content: content
+ }
+ |> make_flag_data(additional)
+ |> insert(local)
+ end
+
def fetch_activities_for_context(context, opts \\ %{}) do
public = ["https://www.w3.org/ns/activitystreams#Public"]
defp restrict_reblogs(query, _), do: query
+ defp restrict_muted(query, %{"with_muted" => val}) when val in [true, "true", "1"], do: query
+
+ defp restrict_muted(query, %{"muting_user" => %User{info: info}}) do
+ mutes = info.mutes
+
+ from(
+ activity in query,
+ where: fragment("not (? = ANY(?))", activity.actor, ^mutes),
+ where: fragment("not (?->'to' \\?| ?)", activity.data, ^mutes)
+ )
+ end
+
+ defp restrict_muted(query, _), do: query
+
defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do
blocks = info.blocks || []
domain_blocks = info.domain_blocks || []
|> restrict_type(opts)
|> restrict_favorited_by(opts)
|> restrict_blocked(opts)
+ |> restrict_muted(opts)
|> restrict_media(opts)
|> restrict_visibility(opts)
|> restrict_replies(opts)
public = is_public?(activity)
- reachable_inboxes_metadata =
- (Pleroma.Web.Salmon.remote_users(activity) ++ remote_followers)
- |> 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"]
- end)
- |> Enum.uniq()
- |> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
- |> Instances.filter_reachable()
-
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
json = Jason.encode!(data)
- Enum.each(reachable_inboxes_metadata, fn {inbox, unreachable_since} ->
- Federator.enqueue(:publish_single_ap, %{
+ (Pleroma.Web.Salmon.remote_users(activity) ++ remote_followers)
+ |> 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"]
+ end)
+ |> Enum.uniq()
+ |> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
+ |> Instances.filter_reachable()
+ |> Enum.each(fn {inbox, unreachable_since} ->
+ Federator.publish_single_ap(%{
inbox: inbox,
json: json,
actor: actor,
digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64())
+ date =
+ NaiveDateTime.utc_now()
+ |> Timex.format!("{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT")
+
signature =
Pleroma.Web.HTTPSignatures.sign(actor, %{
host: host,
"content-length": byte_size(json),
- digest: digest
+ digest: digest,
+ date: date
})
with {:ok, %{status: code}} when code in 200..299 <-
json,
[
{"Content-Type", "application/activity+json"},
+ {"Date", date},
{"signature", signature},
{"digest", digest}
]
end
end
- 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_private?(activity) do
- !is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers"))
- end
-
- def is_direct?(%Activity{data: %{"directMessage" => true}}), do: true
- def is_direct?(%Object{data: %{"directMessage" => true}}), do: true
-
- def is_direct?(activity) do
- !is_public?(activity) && !is_private?(activity)
- end
-
- def visible_for_user?(activity, nil) do
- is_public?(activity)
- end
-
- def visible_for_user?(activity, user) do
- x = [user.ap_id | user.following]
- y = activity.data["to"] ++ (activity.data["cc"] || [])
- visible_for_user?(activity, nil) || Enum.any?(x, &(&1 in y))
- end
-
- # guard
- def entire_thread_visible_for_user?(nil, _user), do: false
-
- # child
- def entire_thread_visible_for_user?(
- %Activity{data: %{"object" => %{"inReplyTo" => parent_id}}} = tail,
- user
- )
- when is_binary(parent_id) do
- parent = Activity.get_in_reply_to_activity(tail)
- visible_for_user?(tail, user) && entire_thread_visible_for_user?(parent, user)
- end
-
- # root
- def entire_thread_visible_for_user?(tail, user), do: visible_for_user?(tail, user)
-
# filter out broken threads
def contain_broken_threads(%Activity{} = activity, %User{} = user) do
entire_thread_visible_for_user?(activity, user)