switch to using an enum system for DM acceptance

This commit is contained in:
FloatingGhost 2023-05-23 10:29:08 +01:00
parent d310f99d6a
commit ab34680554
8 changed files with 82 additions and 34 deletions

View file

@ -158,8 +158,10 @@ defmodule Pleroma.User do
field(:last_status_at, :naive_datetime) field(:last_status_at, :naive_datetime)
field(:language, :string) field(:language, :string)
field(:status_ttl_days, :integer, default: nil) field(:status_ttl_days, :integer, default: nil)
field(:accepts_direct_messages_from_followed, :boolean)
field(:accepts_direct_messages_from_not_followed, :boolean) field(:accepts_direct_messages_from, Ecto.Enum,
values: [:everybody, :people_i_follow, :nobody]
)
embeds_one( embeds_one(
:notification_settings, :notification_settings,
@ -538,7 +540,8 @@ def update_changeset(struct, params \\ %{}) do
:is_discoverable, :is_discoverable,
:actor_type, :actor_type,
:disclose_client, :disclose_client,
:status_ttl_days :status_ttl_days,
:accepts_direct_messages_from
] ]
) )
|> unique_constraint(:nickname) |> unique_constraint(:nickname)
@ -2725,16 +2728,15 @@ def following_hashtag?(%User{} = user, %Hashtag{} = hashtag) do
not is_nil(HashtagFollow.get(user, hashtag)) not is_nil(HashtagFollow.get(user, hashtag))
end end
def accepts_direct_messages?(%User{} = receiver, %User{} = sender) do def accepts_direct_messages?(
cond do %User{accepts_direct_messages_from: :people_i_follow} = receiver,
User.following?(receiver, sender) && receiver.accepts_direct_messages_from_followed == true -> %User{} = sender
true ) do
User.following?(receiver, sender)
end
receiver.accepts_direct_messages_from_not_followed == true -> def accepts_direct_messages?(%User{accepts_direct_messages_from: :everybody}, _), do: true
true
true -> def accepts_direct_messages?(%User{accepts_direct_messages_from: :nobody}, _),
false do: false
end
end
end end

View file

@ -12,7 +12,8 @@ def filter(
"type" => type, "type" => type,
"actor" => actor "actor" => actor
} = activity } = activity
) when type in ["Note", "Create"] do )
when type in ["Note", "Create"] do
min_age = Pleroma.Config.get([:mrf_reject_newly_created_account_notes, :age]) min_age = Pleroma.Config.get([:mrf_reject_newly_created_account_notes, :age])
with %User{} = user <- Pleroma.User.get_cached_by_ap_id(actor), with %User{} = user <- Pleroma.User.get_cached_by_ap_id(actor),

View file

@ -709,16 +709,16 @@ defp update_credentials_request do
description: description:
"Number of days after which statuses will be deleted. Set to -1 to disable." "Number of days after which statuses will be deleted. Set to -1 to disable."
}, },
accepts_direct_messages_from_followed: %Schema{ accepts_direct_messages_from: %Schema{
type: :boolean, type: :string,
enum: [
"everybody",
"nobody",
"people_i_follow"
],
nullable: true, nullable: true,
description: description:
"Whether to accept DMs from people you follow (will be overridden by accepts_direct_messages_from_not_followed if true)" "Who to accept DMs from"
},
accepts_direct_messages_from_not_followed: %Schema{
type: :boolean,
nullable: true,
description: "Whether to accept DMs from everyone"
} }
}, },
example: %{ example: %{
@ -740,7 +740,8 @@ defp update_credentials_request do
also_known_as: ["https://foo.bar/users/foo"], also_known_as: ["https://foo.bar/users/foo"],
discoverable: false, discoverable: false,
actor_type: "Person", actor_type: "Person",
status_ttl_days: 30 status_ttl_days: 30,
accepts_direct_messages_from: "everybody"
} }
} }
end end

View file

@ -191,7 +191,7 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p
:show_role, :show_role,
:skip_thread_containment, :skip_thread_containment,
:allow_following_move, :allow_following_move,
:also_known_as :also_known_as,
] ]
|> Enum.reduce(%{}, fn key, acc -> |> Enum.reduce(%{}, fn key, acc ->
Maps.put_if_present(acc, key, params[key], &{:ok, Params.truthy_param?(&1)}) Maps.put_if_present(acc, key, params[key], &{:ok, Params.truthy_param?(&1)})
@ -221,6 +221,7 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p
|> Maps.put_if_present(:is_discoverable, params[:discoverable]) |> Maps.put_if_present(:is_discoverable, params[:discoverable])
|> Maps.put_if_present(:language, Pleroma.Web.Gettext.normalize_locale(params[:language])) |> Maps.put_if_present(:language, Pleroma.Web.Gettext.normalize_locale(params[:language]))
|> Maps.put_if_present(:status_ttl_days, params[:status_ttl_days], status_ttl_days_value) |> Maps.put_if_present(:status_ttl_days, params[:status_ttl_days], status_ttl_days_value)
|> Maps.put_if_present(:accepts_direct_messages_from, params[:accepts_direct_messages_from])
# What happens here: # What happens here:
# #

View file

@ -354,6 +354,7 @@ defp maybe_put_settings(
|> Kernel.put_in([:source, :privacy], user.default_scope) |> Kernel.put_in([:source, :privacy], user.default_scope)
|> Kernel.put_in([:source, :pleroma, :show_role], user.show_role) |> Kernel.put_in([:source, :pleroma, :show_role], user.show_role)
|> Kernel.put_in([:source, :pleroma, :no_rich_text], user.no_rich_text) |> Kernel.put_in([:source, :pleroma, :no_rich_text], user.no_rich_text)
|> Kernel.put_in([:accepts_direct_messages_from], user.accepts_direct_messages_from)
end end
defp maybe_put_settings(data, _, _, _), do: data defp maybe_put_settings(data, _, _, _), do: data

View file

@ -3,8 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddUnfollowedDmRestrictions do
def change do def change do
alter table(:users) do alter table(:users) do
add(:accepts_direct_messages_from_followed, :boolean, default: true) add(:accepts_direct_messages_from, :string, default: "everybody")
add(:accepts_direct_messages_from_not_followed, :boolean, default: true)
end end
end end
end end

View file

@ -2758,11 +2758,10 @@ test "should not error when trying to unfollow a hashtag twice" do
end end
describe "accepts_direct_messages?/2" do describe "accepts_direct_messages?/2" do
test "should return true if the recipient follows the sender and has turned on 'accept from follows'" do test "should return true if the recipient follows the sender and has set accept to :people_i_follow" do
recipient = recipient =
insert(:user, %{ insert(:user, %{
accepts_direct_messages_from_followed: true, accepts_direct_messages_from: :people_i_follow
accepts_direct_messages_from_not_followed: false
}) })
sender = insert(:user) sender = insert(:user)
@ -2774,15 +2773,15 @@ test "should return true if the recipient follows the sender and has turned on '
assert User.accepts_direct_messages?(recipient, sender) assert User.accepts_direct_messages?(recipient, sender)
end end
test "should return true if the recipient has 'accept from everyone' on" do test "should return true if the recipient has set accept to :everyone" do
recipient = insert(:user, %{accepts_direct_messages_from_not_followed: true}) recipient = insert(:user, %{accepts_direct_messages_from: :everybody})
sender = insert(:user) sender = insert(:user)
assert User.accepts_direct_messages?(recipient, sender) assert User.accepts_direct_messages?(recipient, sender)
end end
test "should return false if the receipient has 'accept from everyone' off" do test "should return false if the receipient set accept to :nobody" do
recipient = insert(:user, %{accepts_direct_messages_from_not_followed: false}) recipient = insert(:user, %{accepts_direct_messages_from: :nobody})
sender = insert(:user) sender = insert(:user)
refute User.accepts_direct_messages?(recipient, sender) refute User.accepts_direct_messages?(recipient, sender)

View file

@ -727,4 +727,48 @@ test "actor_type field has a higher priority than bot", %{conn: conn} do
assert account["source"]["pleroma"]["actor_type"] == "Person" assert account["source"]["pleroma"]["actor_type"] == "Person"
end end
end end
describe "Updating direct message settings" do
setup do: oauth_access(["write:accounts"])
setup :request_content_type
test "changing to :everybody", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "everybody"})
|> json_response_and_validate_schema(200)
assert account["accepts_direct_messages_from"]
assert account["accepts_direct_messages_from"] == "everybody"
assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :everybody
end
test "changing to :nobody", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "nobody"})
|> json_response_and_validate_schema(200)
assert account["accepts_direct_messages_from"]
assert account["accepts_direct_messages_from"] == "nobody"
assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :nobody
end
test "changing to :people_i_follow", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "people_i_follow"})
|> json_response_and_validate_schema(200)
assert account["accepts_direct_messages_from"]
assert account["accepts_direct_messages_from"] == "people_i_follow"
assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :people_i_follow
end
test "changing to an unsupported value", %{conn: conn} do
conn
|> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "unsupported"})
|> json_response(400)
end
end
end end