Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.6KB

  1. defmodule Pleroma.Repo.Migrations.AddThreadVisibilityFunction do
  2. use Ecto.Migration
  3. @disable_ddl_transaction true
  4. def up do
  5. statement = """
  6. CREATE OR REPLACE FUNCTION thread_visibility(actor varchar, activity_id varchar) RETURNS boolean AS $$
  7. DECLARE
  8. public varchar := 'https://www.w3.org/ns/activitystreams#Public';
  9. child objects%ROWTYPE;
  10. activity activities%ROWTYPE;
  11. actor_user users%ROWTYPE;
  12. author_fa varchar;
  13. valid_recipients varchar[];
  14. BEGIN
  15. --- Fetch our actor.
  16. SELECT * INTO actor_user FROM users WHERE users.ap_id = actor;
  17. --- Fetch our initial activity.
  18. SELECT * INTO activity FROM activities WHERE activities.data->>'id' = activity_id;
  19. LOOP
  20. --- Ensure that we have an activity before continuing.
  21. --- If we don't, the thread is not satisfiable.
  22. IF activity IS NULL THEN
  23. RETURN false;
  24. END IF;
  25. --- We only care about Create activities.
  26. IF activity.data->>'type' != 'Create' THEN
  27. RETURN true;
  28. END IF;
  29. --- Normalize the child object into child.
  30. SELECT * INTO child FROM objects
  31. INNER JOIN activities ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = objects.data->>'id'
  32. WHERE COALESCE(activity.data->'object'->>'id', activity.data->>'object') = objects.data->>'id';
  33. --- Fetch the author's AS2 following collection.
  34. SELECT COALESCE(users.follower_address, '') INTO author_fa FROM users WHERE users.ap_id = activity.actor;
  35. --- Prepare valid recipients array.
  36. valid_recipients := ARRAY[actor, public];
  37. IF ARRAY[author_fa] && actor_user.following THEN
  38. valid_recipients := valid_recipients || author_fa;
  39. END IF;
  40. --- Check visibility.
  41. IF NOT valid_recipients && activity.recipients THEN
  42. --- activity not visible, break out of the loop
  43. RETURN false;
  44. END IF;
  45. --- If there's a parent, load it and do this all over again.
  46. IF (child.data->'inReplyTo' IS NOT NULL) AND (child.data->'inReplyTo' != 'null'::jsonb) THEN
  47. SELECT * INTO activity FROM activities
  48. INNER JOIN objects ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = objects.data->>'id'
  49. WHERE child.data->>'inReplyTo' = objects.data->>'id';
  50. ELSE
  51. RETURN true;
  52. END IF;
  53. END LOOP;
  54. END;
  55. $$ LANGUAGE plpgsql IMMUTABLE;
  56. """
  57. execute(statement)
  58. end
  59. def down do
  60. execute("drop function if exists thread_visibility(actor varchar, activity_id varchar)")
  61. end
  62. end