end
end
+ def block(blocker, blocked, local \\ true) do
+ follow_activity = fetch_latest_follow(blocker, blocked)
+
+ if follow_activity do
+ unfollow(blocker, blocked, local)
+ end
+
+ with block_data <- make_block_data(blocker, blocked),
+ {:ok, activity} <- insert(block_data, local),
+ :ok <- maybe_federate(activity) do
+ {:ok, activity}
+ end
+ end
+
+ def unblock(blocker, blocked, local \\ true) do
+ with %Activity{} = block_activity <- fetch_latest_block(blocker, blocked),
+ unblock_data <- make_unblock_data(blocker, blocked, block_activity),
+ {:ok, activity} <- insert(unblock_data, local),
+ :ok <- maybe_federate(activity) do
+ {:ok, activity}
+ end
+ end
+
def fetch_activities_for_context(context, opts \\ %{}) do
public = ["https://www.w3.org/ns/activitystreams#Public"]
end
end
+ def handle_incoming(%{"type" => "Undo", "object" => object_id} = data) do
+ object = Object.get_by_ap_id(object_id).data
+ data = Map.put(data, "object", object)
+
+ handle_incoming(data)
+ end
+
+ def handle_incoming(%{"type" => "Block", "object" => blocked, "actor" => blocker, "id" => id} = data) do
+ with %User{local: true} = blocked = User.get_cached_by_ap_id(blocked),
+ %User{} = blocker = User.get_or_fetch_by_ap_id(blocker),
+ {:ok, activity} <- ActivityPub.block(blocker, blocked, false) do
+ User.unfollow(follower, followed)
+ User.block(blocker, blocked.ap_id)
+ {:ok, activity}
+ else
+ e -> :error
+ end
+ end
# TODO
# Accept
# Undo for non-Announce
}
end
+ #### Block-related helpers
+ def fetch_latest_block(%User{ap_id: blocker_id}, %User{ap_id: blocked_id}) do
+ query =
+ from(
+ activity in Activity,
+ where:
+ fragment(
+ "? @> ?",
+ activity.data,
+ ^%{type: "Block", actor: blocker_id, object: blocked_id}
+ ),
+ order_by: [desc: :id],
+ limit: 1
+ )
+
+ Repo.one(query)
+ end
+
+ def make_block_data(blocker, blocked) do
+ %{
+ "type" => "Block",
+ "actor" => blocker.ap_id,
+ "to" => [blocked.ap_id],
+ "object" => blocked.ap_id
+ }
+ end
+
+ def make_unblock_data(blocker, blocked, block_activity) do
+ %{
+ "type" => "Undo",
+ "actor" => blocker.ap_id,
+ "to" => [blocked.ap_id],
+ "object" => block_activity.data
+ }
+ end
#### Create-related helpers
def make_create_data(params, additional) do