Purge Rejected Follow requests in daily task (#334)

Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk>
Reviewed-on: AkkomaGang/akkoma#334
This commit is contained in:
floatingghost 2022-12-03 23:17:43 +00:00
parent 0c2c057c75
commit 6b882a2c0b
11 changed files with 87 additions and 26 deletions

View file

@ -691,8 +691,8 @@
key: :public, key: :public,
type: :boolean, type: :boolean,
description: description:
"Makes the client API in authenticated mode-only except for user-profiles." <> "Switching this on will allow unauthenticated users access to all public resources on your instance" <>
" Useful for disabling the Local Timeline and The Whole Known Network. " <> " 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." " Note: when setting to `false`, please also check `:restrict_unauthenticated` setting."
}, },
%{ %{
@ -2998,8 +2998,7 @@
key: :restrict_unauthenticated, key: :restrict_unauthenticated,
label: "Restrict Unauthenticated", label: "Restrict Unauthenticated",
type: :group, type: :group,
description: description: "Disallow unauthenticated viewing of timelines, user profiles and statuses.",
"Disallow viewing timelines, user profiles and statuses for unauthenticated users.",
children: [ children: [
%{ %{
key: :timelines, key: :timelines,
@ -3009,12 +3008,12 @@
%{ %{
key: :local, key: :local,
type: :boolean, type: :boolean,
description: "Disallow view public timeline." description: "Disallow viewing the public timeline."
}, },
%{ %{
key: :federated, key: :federated,
type: :boolean, type: :boolean,
description: "Disallow view federated timeline." description: "Disallow viewing the whole known network timeline."
} }
] ]
}, },
@ -3026,29 +3025,29 @@
%{ %{
key: :local, key: :local,
type: :boolean, type: :boolean,
description: "Disallow view local user profiles." description: "Disallow viewing local user profiles."
}, },
%{ %{
key: :remote, key: :remote,
type: :boolean, type: :boolean,
description: "Disallow view remote user profiles." description: "Disallow viewing remote user profiles."
} }
] ]
}, },
%{ %{
key: :activities, key: :activities,
type: :map, type: :map,
description: "Settings for statuses.", description: "Settings for posts.",
children: [ children: [
%{ %{
key: :local, key: :local,
type: :boolean, type: :boolean,
description: "Disallow view local statuses." description: "Disallow viewing local posts."
}, },
%{ %{
key: :remote, key: :remote,
type: :boolean, type: :boolean,
description: "Disallow view remote statuses." description: "Disallow viewing remote posts."
} }
] ]
} }

View 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_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. * `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. * `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. * `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). * `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 * `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_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 * `timelines`: public and federated timelines
* `local`: public timeline * `local`: public timeline
@ -1102,13 +1103,24 @@ Restrict access for unauthenticated users to timelines (public and federated), u
* `profiles`: user profiles * `profiles`: user profiles
* `local` * `local`
* `remote` * `remote`
* `activities`: statuses * `activities`: posts
* `local` * `local`
* `remote` * `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 ## Pleroma.Web.ApiSpec.CastAndValidate

View file

@ -59,7 +59,7 @@ def run(["gen" | rest]) do
get_option( get_option(
options, options,
:domain, :domain,
"What domain will your instance use? (e.g pleroma.soykaf.com)" "What domain will your instance use? (e.g akkoma.example.com)"
), ),
":" ":"
) ++ [443] ) ++ [443]

View file

@ -35,6 +35,17 @@ def prune_removes do
|> Repo.delete_all(timeout: :infinity) |> Repo.delete_all(timeout: :infinity)
end 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 defp cutoff do
DateTime.utc_now() |> Timex.shift(days: -@cutoff) DateTime.utc_now() |> Timex.shift(days: -@cutoff)
end end

View file

@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator do
use Ecto.Schema use Ecto.Schema
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.User alias Pleroma.User
import Ecto.Changeset import Ecto.Changeset

View file

@ -13,14 +13,14 @@ def render("manifest.json", _params) do
description: Config.get([:instance, :description]), description: Config.get([:instance, :description]),
icons: [ icons: [
%{ %{
src: "/static/logo.svg", src: "/static/logo.svg",
type: "image/svg+xml" type: "image/svg+xml"
}, },
%{ %{
src: "/static/logo-512.png", src: "/static/logo-512.png",
sizes: "512x512", sizes: "512x512",
type: "image/png", type: "image/png",
purpose: "maskable" purpose: "maskable"
} }
], ],
theme_color: Config.get([:manifest, :theme_color]), theme_color: Config.get([:manifest, :theme_color]),

View file

@ -15,6 +15,9 @@ def perform(_job) do
Logger.info("Pruning old deletes") Logger.info("Pruning old deletes")
ActivityPruner.prune_deletes() ActivityPruner.prune_deletes()
Logger.info("Pruning old follow requests")
ActivityPruner.prune_stale_follow_requests()
Logger.info("Pruning old undos") Logger.info("Pruning old undos")
ActivityPruner.prune_undos() ActivityPruner.prune_undos()

View file

@ -24,4 +24,40 @@ test "it prunes old delete objects" do
refute Activity.get_by_id(old_delete.id) refute Activity.get_by_id(old_delete.id)
end end
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 end

View file

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do
use Pleroma.Web.ConnCase use Pleroma.Web.ConnCase, async: false
import Mock import Mock
import Tesla.Mock import Tesla.Mock

View file

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
use Pleroma.Web.ConnCase, async: true use Pleroma.Web.ConnCase, async: false
alias Pleroma.MFA alias Pleroma.MFA
alias Pleroma.MFA.TOTP alias Pleroma.MFA.TOTP

View file

@ -469,6 +469,7 @@ def follow_activity_factory(attrs \\ %{}) do
data: data, data: data,
actor: follower.ap_id actor: follower.ap_id
} }
|> Map.merge(attrs)
end end
def report_activity_factory(attrs \\ %{}) do def report_activity_factory(attrs \\ %{}) do