Purge Rejected Follow requests in daily task (#334)
authorfloatingghost <hannah@coffee-and-dreams.uk>
Sat, 3 Dec 2022 23:17:43 +0000 (23:17 +0000)
committerfloatingghost <hannah@coffee-and-dreams.uk>
Sat, 3 Dec 2022 23:17:43 +0000 (23:17 +0000)
Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk>
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/334

config/description.exs
docs/docs/configuration/cheatsheet.md
lib/mix/tasks/pleroma/instance.ex
lib/pleroma/activity/pruner.ex
lib/pleroma/web/activity_pub/object_validators/accept_reject_validator.ex
lib/pleroma/web/views/manifest_view.ex
lib/pleroma/workers/cron/database_prune_worker.ex
test/pleroma/activity/pruner_test.exs
test/pleroma/web/pleroma_api/controllers/emoji_file_controller_test.exs
test/pleroma/web/twitter_api/remote_follow_controller_test.exs
test/support/factory.ex

index fc10cbf8107a8d41617bf6c67c0c062805c8084d..001a21cbad6e5468469ad40af67f39418613b846 100644 (file)
@@ -691,8 +691,8 @@ config :pleroma, :config_description, [
         key: :public,
         type: :boolean,
         description:
-          "Makes the client API in authenticated mode-only except for user-profiles." <>
-            " Useful for disabling the Local Timeline and The Whole Known Network. " <>
+          "Switching this on will allow unauthenticated users access to all public resources on your instance" <>
+            " Switching it off is useful for disabling the Local Timeline and The Whole Known Network. " <>
             " Note: when setting to `false`, please also check `:restrict_unauthenticated` setting."
       },
       %{
@@ -2998,8 +2998,7 @@ config :pleroma, :config_description, [
     key: :restrict_unauthenticated,
     label: "Restrict Unauthenticated",
     type: :group,
-    description:
-      "Disallow viewing timelines, user profiles and statuses for unauthenticated users.",
+    description: "Disallow unauthenticated viewing of timelines, user profiles and statuses.",
     children: [
       %{
         key: :timelines,
@@ -3009,12 +3008,12 @@ config :pleroma, :config_description, [
           %{
             key: :local,
             type: :boolean,
-            description: "Disallow view public timeline."
+            description: "Disallow viewing the public timeline."
           },
           %{
             key: :federated,
             type: :boolean,
-            description: "Disallow view federated timeline."
+            description: "Disallow viewing the whole known network timeline."
           }
         ]
       },
@@ -3026,29 +3025,29 @@ config :pleroma, :config_description, [
           %{
             key: :local,
             type: :boolean,
-            description: "Disallow view local user profiles."
+            description: "Disallow viewing local user profiles."
           },
           %{
             key: :remote,
             type: :boolean,
-            description: "Disallow view remote user profiles."
+            description: "Disallow viewing remote user profiles."
           }
         ]
       },
       %{
         key: :activities,
         type: :map,
-        description: "Settings for statuses.",
+        description: "Settings for posts.",
         children: [
           %{
             key: :local,
             type: :boolean,
-            description: "Disallow view local statuses."
+            description: "Disallow viewing local posts."
           },
           %{
             key: :remote,
             type: :boolean,
-            description: "Disallow view remote statuses."
+            description: "Disallow viewing remote posts."
           }
         ]
       }
index 517fd1993282d81fb169644d3a5cc7753684fbe0..12c044d67500a38c1fe76a576accf9ca3b1b4673 100644 (file)
@@ -33,7 +33,8 @@ To add configuration to your config file, you can copy it from the base config.
 * `federation_incoming_replies_max_depth`: Max. depth of reply-to activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes.
 * `federation_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it.
 * `allow_relay`: Permits remote instances to subscribe to all public posts of your instance. This may increase the visibility of your instance.
-* `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. Note that there is a dependent setting restricting or allowing unauthenticated access to specific resources, see `restrict_unauthenticated` for more details.
+* `public`: Allows unauthenticated access to public resources on your instance. This is essentially used as the default value for `:restrict_unauthenticated`. 
+   See `restrict_unauthenticated` for more details.
 * `quarantined_instances`: *DEPRECATED* ActivityPub instances where activities will not be sent. They can still reach there via other means, we just won't send them.
 * `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML).
 * `extended_nickname_format`: Set to `true` to use extended local nicknames format (allows underscores/dashes). This will break federation with
@@ -1094,7 +1095,7 @@ config :pleroma, :database_config_whitelist, [
 
 ### :restrict_unauthenticated
 
-Restrict access for unauthenticated users to timelines (public and federated), user profiles and statuses.
+Restrict access for unauthenticated users to timelines (public and federated), user profiles and posts.
 
 * `timelines`: public and federated timelines
   * `local`: public timeline
@@ -1102,13 +1103,24 @@ Restrict access for unauthenticated users to timelines (public and federated), u
 * `profiles`: user profiles
   * `local`
   * `remote`
-* `activities`: statuses
+* `activities`: posts
   * `local`
   * `remote`
 
-Note: when `:instance, :public` is set to `false`, all `:restrict_unauthenticated` items be effectively set to `true` by default. If you'd like to allow unauthenticated access to specific API endpoints on a private instance, please explicitly set `:restrict_unauthenticated` to non-default value in `config/prod.secret.exs`.
+#### When :instance, :public is `true`
 
-Note: setting `restrict_unauthenticated/timelines/local` to `true` has no practical sense if `restrict_unauthenticated/timelines/federated` is set to `false` (since local public activities will still be delivered to unauthenticated users as part of federated timeline).
+When your instance is in "public" mode, all public resources (users, posts, timelines) are accessible to unauthenticated users.
+
+Turning any of the `:restrict_unauthenticated` options to `true` will restrict access to the corresponding resources.
+
+#### When :instance, :public is `false`
+
+When `:instance, :public` is set to `false`, all of the `:restrict_unauthenticated` options will effectively be set to `true` by default,
+meaning that only authenticated users will be able to access the corresponding resources.
+
+If you'd like to allow unauthenticated access to specific resources, you can turn these settings to `false`.
+
+**Note**: setting `restrict_unauthenticated/timelines/local` to `true` has no practical sense if `restrict_unauthenticated/timelines/federated` is set to `false` (since local public activities will still be delivered to unauthenticated users as part of federated timeline).
 
 ## Pleroma.Web.ApiSpec.CastAndValidate
 
index 8954b3b7cf767ac2506a74114ec13b5cbeab6b5c..0647c330fbd37b29b28a2c80480cc4a754338883 100644 (file)
@@ -59,7 +59,7 @@ defmodule Mix.Tasks.Pleroma.Instance do
           get_option(
             options,
             :domain,
-            "What domain will your instance use? (e.g pleroma.soykaf.com)"
+            "What domain will your instance use? (e.g akkoma.example.com)"
           ),
           ":"
         ) ++ [443]
index 054ee514ae5313cbb3ba7949f07d6e05052227b3..7f561ebae5e41bd6676d7004dceb26918400f12a 100644 (file)
@@ -35,6 +35,17 @@ defmodule Pleroma.Activity.Pruner do
     |> Repo.delete_all(timeout: :infinity)
   end
 
+  def prune_stale_follow_requests do
+    before_time = cutoff()
+
+    from(a in Activity,
+      where:
+        fragment("?->>'type' = ?", a.data, "Follow") and a.inserted_at < ^before_time and
+          fragment("?->>'state' = ?", a.data, "reject")
+    )
+    |> Repo.delete_all(timeout: :infinity)
+  end
+
   defp cutoff do
     DateTime.utc_now() |> Timex.shift(days: -@cutoff)
   end
index 847d0be6222ea9050fe0f596ad01087b9f03312f..0561a9ddf1f719cdbf7a0b314df3836e3bd3129a 100644 (file)
@@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator do
   use Ecto.Schema
 
   alias Pleroma.Activity
-  alias Pleroma.Object
   alias Pleroma.User
 
   import Ecto.Changeset
index d8c736cef647429ca76f92306ad7423acdcb0abe..5177b0eba949877cc79727b0baeaa73378124fbf 100644 (file)
@@ -13,14 +13,14 @@ defmodule Pleroma.Web.ManifestView do
       description: Config.get([:instance, :description]),
       icons: [
         %{
-            src: "/static/logo.svg",
-            type: "image/svg+xml"
+          src: "/static/logo.svg",
+          type: "image/svg+xml"
         },
         %{
-            src: "/static/logo-512.png",
-            sizes: "512x512",
-            type: "image/png",
-            purpose: "maskable"
+          src: "/static/logo-512.png",
+          sizes: "512x512",
+          type: "image/png",
+          purpose: "maskable"
         }
       ],
       theme_color: Config.get([:manifest, :theme_color]),
index 99ea2e836c9cc4753bb786024c745ff267285413..58995c69a656c0efe761b95f647f27867632a9d7 100644 (file)
@@ -15,6 +15,9 @@ defmodule Pleroma.Workers.Cron.PruneDatabaseWorker do
     Logger.info("Pruning old deletes")
     ActivityPruner.prune_deletes()
 
+    Logger.info("Pruning old follow requests")
+    ActivityPruner.prune_stale_follow_requests()
+
     Logger.info("Pruning old undos")
     ActivityPruner.prune_undos()
 
index 312d4f5e493e7f6b1bc37f6a889c3ff80b74e773..e8d4b30aad0725159752f5c2e5feabaf4f274fa5 100644 (file)
@@ -24,4 +24,40 @@ defmodule Pleroma.Activity.PrunerTest do
       refute Activity.get_by_id(old_delete.id)
     end
   end
+
+  describe "prune_stale_follow_requests" do
+    test "it prunes old follow requests" do
+      follower = insert(:user)
+      followee = insert(:user)
+
+      new_follow_request =
+        insert(
+          :follow_activity,
+          follower: follower,
+          followed: followee,
+          state: "reject"
+        )
+
+      old_not_rejected_request =
+        insert(:follow_activity,
+          follower: follower,
+          followed: followee,
+          state: "pending",
+          inserted_at: DateTime.utc_now() |> DateTime.add(-31 * 24, :hour)
+        )
+
+      old_follow_request =
+        insert(:follow_activity,
+          follower: follower,
+          followed: followee,
+          inserted_at: DateTime.utc_now() |> DateTime.add(-31 * 24, :hour),
+          state: "reject"
+        )
+
+      Pruner.prune_stale_follow_requests()
+      assert Activity.get_by_id(new_follow_request.id)
+      assert Activity.get_by_id(old_not_rejected_request.id)
+      refute Activity.get_by_id(old_follow_request.id)
+    end
+  end
 end
index 54739124953e7d5332643b4163a66a748187c15e..61a44b8bafb3e0759844ef65a98b1592b59035a1 100644 (file)
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: false
 
   import Mock
   import Tesla.Mock
index 15e9b5884ec0947dd6a2a7199f97666d82679ce5..e7c496eb04adccf3f25c217231376bf6aa1c09b5 100644 (file)
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
-  use Pleroma.Web.ConnCase, async: true
+  use Pleroma.Web.ConnCase, async: false
 
   alias Pleroma.MFA
   alias Pleroma.MFA.TOTP
index 3e426c565594ac8299d8acfa447e7058202f1e1a..6ce4decbcc144212797e8569c90b2b0c152f67d7 100644 (file)
@@ -469,6 +469,7 @@ defmodule Pleroma.Factory do
       data: data,
       actor: follower.ap_id
     }
+    |> Map.merge(attrs)
   end
 
   def report_activity_factory(attrs \\ %{}) do