summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2019-01-09 16:45:09 +0100
committerlain <lain@soykaf.club>2019-01-09 16:45:09 +0100
commit5027f82cdef52391e408428ecc8013b1c4847b6b (patch)
tree3ea6b7bedab44d41a1c05a74f536b746ea388afd
parent5c5c8508c203886f32b150e7d8c1f7362a4fde0e (diff)
downloadpleroma-5027f82cdef52391e408428ecc8013b1c4847b6b.tar.gz
pleroma-5027f82cdef52391e408428ecc8013b1c4847b6b.zip
Add activity visibility index.
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex25
-rw-r--r--priv/repo/migrations/20190109152453_add_visibility_function.exs46
-rw-r--r--test/web/activity_pub/activity_pub_test.exs36
3 files changed, 93 insertions, 14 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 4685f6d95..b8141146f 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -364,21 +364,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
@valid_visibilities ~w[direct unlisted public private]
- defp restrict_visibility(query, %{visibility: "direct"}) do
- public = "https://www.w3.org/ns/activitystreams#Public"
+ defp restrict_visibility(query, %{visibility: visibility})
+ when visibility in @valid_visibilities do
+ query =
+ from(
+ a in query,
+ where:
+ fragment("activity_visibility(?, ?, ?) = ?", a.actor, a.recipients, a.data, ^visibility)
+ )
- from(
- activity in query,
- join: sender in User,
- on: sender.ap_id == activity.actor,
- # Are non-direct statuses with no to/cc possible?
- where:
- fragment(
- "not (? && ?)",
- [^public, sender.follower_address],
- activity.recipients
- )
- )
+ Ecto.Adapters.SQL.to_sql(:all, Repo, query)
+
+ query
end
defp restrict_visibility(_query, %{visibility: visibility})
diff --git a/priv/repo/migrations/20190109152453_add_visibility_function.exs b/priv/repo/migrations/20190109152453_add_visibility_function.exs
new file mode 100644
index 000000000..6c94f1bb3
--- /dev/null
+++ b/priv/repo/migrations/20190109152453_add_visibility_function.exs
@@ -0,0 +1,46 @@
+defmodule Pleroma.Repo.Migrations.AddVisibilityFunction do
+ use Ecto.Migration
+
+ def up do
+ definition = """
+ create or replace function activity_visibility(actor varchar, recipients varchar[], data jsonb) returns varchar as $$
+ DECLARE
+ fa varchar;
+ public varchar := 'https://www.w3.org/ns/activitystreams#Public';
+ BEGIN
+ SELECT COALESCE(users.follower_address, '') into fa from users where users.ap_id = actor;
+
+ IF data->'to' ? public THEN
+ RETURN 'public';
+ ELSIF data->'cc' ? public THEN
+ RETURN 'unlisted';
+ ELSIF ARRAY[fa] && recipients THEN
+ RETURN 'private';
+ ELSIF not(ARRAY[fa, public] && recipients) THEN
+ RETURN 'direct';
+ ELSE
+ RETURN 'unknown';
+ END IF;
+ END;
+ $$ LANGUAGE plpgsql IMMUTABLE;
+ """
+
+ execute(definition)
+
+ create(
+ index(:activities, ["activity_visibility(actor, recipients, data)"],
+ name: :activities_visibility_index
+ )
+ )
+ end
+
+ def down do
+ drop(
+ index(:activities, ["activity_visibility(actor, recipients, data)"],
+ name: :activities_visibility_index
+ )
+ )
+
+ execute("drop function activity_visibility(actor varchar, recipients varchar[], data jsonb)")
+ end
+end
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 2453998ad..47aa5a56f 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -18,6 +18,42 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
:ok
end
+ describe "fetching restricted by visibility" do
+ test "it restricts by the appropriate visibility" do
+ user = insert(:user)
+
+ {:ok, public_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "public"})
+
+ {:ok, direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"})
+
+ {:ok, unlisted_activity} =
+ CommonAPI.post(user, %{"status" => ".", "visibility" => "unlisted"})
+
+ {:ok, private_activity} =
+ CommonAPI.post(user, %{"status" => ".", "visibility" => "private"})
+
+ activities =
+ ActivityPub.fetch_activities([], %{:visibility => "direct", "actor_id" => user.ap_id})
+
+ assert activities == [direct_activity]
+
+ activities =
+ ActivityPub.fetch_activities([], %{:visibility => "unlisted", "actor_id" => user.ap_id})
+
+ assert activities == [unlisted_activity]
+
+ activities =
+ ActivityPub.fetch_activities([], %{:visibility => "private", "actor_id" => user.ap_id})
+
+ assert activities == [private_activity]
+
+ activities =
+ ActivityPub.fetch_activities([], %{:visibility => "public", "actor_id" => user.ap_id})
+
+ assert activities == [public_activity]
+ end
+ end
+
describe "building a user from his ap id" do
test "it returns a user" do
user_id = "http://mastodon.example.org/users/admin"