Merge branch 'move-cooldown-period' into 'develop'
Add migration cooldown period Closes #107 See merge request soapbox-pub/rebased!183
This commit is contained in:
commit
31f5bafe64
9 changed files with 100 additions and 3 deletions
|
@ -262,7 +262,8 @@
|
|||
max_endorsed_users: 20,
|
||||
birthday_required: false,
|
||||
birthday_min_age: 0,
|
||||
max_media_attachments: 1_000
|
||||
max_media_attachments: 1_000,
|
||||
migration_cooldown_period: 30
|
||||
|
||||
config :pleroma, :welcome,
|
||||
direct_message: [
|
||||
|
|
|
@ -1015,6 +1015,13 @@
|
|||
description:
|
||||
"Minimum required age (in days) for users to create account. Only used if birthday is required.",
|
||||
suggestions: [6570]
|
||||
},
|
||||
%{
|
||||
key: :migration_cooldown_period,
|
||||
type: :integer,
|
||||
description:
|
||||
"Number of days for which users won't be able to migrate account again after successful migration.",
|
||||
suggestions: [30]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -160,6 +160,7 @@ defmodule Pleroma.User do
|
|||
field(:show_birthday, :boolean, default: false)
|
||||
field(:location, :string)
|
||||
field(:language, :string)
|
||||
field(:last_move_at, :naive_datetime)
|
||||
|
||||
embeds_one(
|
||||
:notification_settings,
|
||||
|
@ -2707,4 +2708,10 @@ def get_friends_birthdays_query(%User{} = user, day, month) do
|
|||
birthday_month: month
|
||||
})
|
||||
end
|
||||
|
||||
def update_last_move_at(%__MODULE__{local: true} = user) do
|
||||
user
|
||||
|> cast(%{last_move_at: NaiveDateTime.utc_now()}, [:last_move_at])
|
||||
|> update_and_set_cache()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -450,6 +450,8 @@ def move(%User{} = origin, %User{} = target, local \\ true) do
|
|||
"target_id" => target.id
|
||||
})
|
||||
|
||||
User.update_last_move_at(origin)
|
||||
|
||||
{:ok, activity}
|
||||
else
|
||||
false -> {:error, "Target account must have the origin in `alsoKnownAs`"}
|
||||
|
|
|
@ -229,7 +229,8 @@ def move_account_operation do
|
|||
}),
|
||||
400 => Operation.response("Error", "application/json", ApiError),
|
||||
403 => Operation.response("Error", "application/json", ApiError),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
404 => Operation.response("Error", "application/json", ApiError),
|
||||
429 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
@ -51,7 +51,8 @@ def render("show.json", _) do
|
|||
post_formats: Config.get([:instance, :allowed_post_formats]),
|
||||
privileged_staff: Config.get([:instance, :privileged_staff]),
|
||||
birthday_required: Config.get([:instance, :birthday_required]),
|
||||
birthday_min_age: Config.get([:instance, :birthday_min_age])
|
||||
birthday_min_age: Config.get([:instance, :birthday_min_age]),
|
||||
migration_cooldown_period: Config.get([:instance, :migration_cooldown_period])
|
||||
},
|
||||
stats: %{mau: Pleroma.User.active_user_count()},
|
||||
vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key),
|
||||
|
|
|
@ -259,6 +259,7 @@ def move_account(%{assigns: %{user: user}, body_params: body_params} = conn, %{}
|
|||
case CommonAPI.Utils.confirm_current_password(user, body_params.password) do
|
||||
{:ok, user} ->
|
||||
with {:ok, target_user} <- find_or_fetch_user_by_nickname(body_params.target_account),
|
||||
{:period, false} <- {:period, within_cooldown?(user)},
|
||||
{:ok, _user} <- ActivityPub.move(user, target_user) do
|
||||
json(conn, %{status: "success"})
|
||||
else
|
||||
|
@ -267,6 +268,11 @@ def move_account(%{assigns: %{user: user}, body_params: body_params} = conn, %{}
|
|||
|> put_status(404)
|
||||
|> json(%{error: "Target account not found."})
|
||||
|
||||
{:period, true} ->
|
||||
conn
|
||||
|> put_status(429)
|
||||
|> json(%{error: "You are within cooldown period."})
|
||||
|
||||
{:error, error} ->
|
||||
json(conn, %{error: error})
|
||||
end
|
||||
|
@ -276,6 +282,19 @@ def move_account(%{assigns: %{user: user}, body_params: body_params} = conn, %{}
|
|||
end
|
||||
end
|
||||
|
||||
defp within_cooldown?(%{last_move_at: nil}), do: false
|
||||
|
||||
defp within_cooldown?(user) do
|
||||
cooldown_period =
|
||||
Pleroma.Config.get([:instance, :migration_cooldown_period], 0) * 60 * 60 * 24
|
||||
|
||||
now = NaiveDateTime.utc_now()
|
||||
|
||||
difference = NaiveDateTime.diff(now, user.last_move_at)
|
||||
|
||||
difference < cooldown_period
|
||||
end
|
||||
|
||||
def add_alias(%{assigns: %{user: user}, body_params: body_params} = conn, _) do
|
||||
with {:ok, alias_user} <- find_user_by_nickname(body_params.alias),
|
||||
{:ok, _user} <- user |> User.add_alias(alias_user) do
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Repo.Migrations.AddLastMoveAtToUsers do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table(:users) do
|
||||
add(:last_move_at, :naive_datetime)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,9 +6,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
use Pleroma.Web.ConnCase
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
|
||||
import Ecto.Changeset
|
||||
import Pleroma.Factory
|
||||
import Mock
|
||||
|
||||
|
@ -838,6 +840,50 @@ test "prefix nickname by @ should work", %{
|
|||
refute User.following?(follower, user)
|
||||
assert User.following?(follower, target_user)
|
||||
end
|
||||
|
||||
test "do not allow to migrate account within cooldown period", %{conn: conn, user: user} do
|
||||
user
|
||||
|> cast(
|
||||
%{last_move_at: NaiveDateTime.utc_now() |> NaiveDateTime.add(-1 * 24 * 60 * 60, :second)},
|
||||
[:last_move_at]
|
||||
)
|
||||
|> Repo.update()
|
||||
|
||||
target_user = insert(:user, also_known_as: [user.ap_id])
|
||||
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{password: "test", target_account: target_nick})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 429) == %{
|
||||
"error" => "You are within cooldown period."
|
||||
}
|
||||
end
|
||||
|
||||
test "allow to migrate account after cooldown period", %{conn: conn, user: user} do
|
||||
user
|
||||
|> cast(
|
||||
%{
|
||||
last_move_at: NaiveDateTime.utc_now() |> NaiveDateTime.add(-31 * 24 * 60 * 60, :second)
|
||||
},
|
||||
[:last_move_at]
|
||||
)
|
||||
|> Repo.update()
|
||||
|
||||
target_user = insert(:user, also_known_as: [user.ap_id])
|
||||
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{password: "test", target_account: target_nick})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/aliases" do
|
||||
|
|
Loading…
Reference in a new issue