logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

20190515222404_add_thread_visibility_function.exs (2825B)


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