aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2019-03-20 21:09:36 +0100
committerlain <lain@soykaf.club>2019-03-20 21:09:36 +0100
commit8468f3f6d48693d2a27a257e5555aa71decff3df (patch)
tree9f61dcf50e315bba1842bda2e43d866adb7dbad7
parent0d14def0ca781b79ffb3c1022472ac64f990cdf8 (diff)
downloadpleroma-8468f3f6d48693d2a27a257e5555aa71decff3df.tar.gz
Add safe dm mode option.
-rw-r--r--config/config.exs3
-rw-r--r--docs/config.md3
-rw-r--r--lib/pleroma/formatter.ex20
-rw-r--r--lib/pleroma/web/common_api/common_api.ex3
-rw-r--r--lib/pleroma/web/common_api/utils.ex12
-rw-r--r--test/formatter_test.exs25
-rw-r--r--test/web/common_api/common_api_test.exs18
7 files changed, 76 insertions, 8 deletions
diff --git a/config/config.exs b/config/config.exs
index ccdd35777..b01c097c5 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -174,7 +174,8 @@ config :pleroma, :instance,
no_attachment_links: false,
welcome_user_nickname: nil,
welcome_message: nil,
- max_report_comment_size: 1000
+ max_report_comment_size: 1000,
+ safe_dm_mentions: false
config :pleroma, :markup,
# XXX - unfortunately, inline images must be enabled by default right now, because
diff --git a/docs/config.md b/docs/config.md
index 201180373..78967204b 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -101,7 +101,8 @@ config :pleroma, Pleroma.Mailer,
* `no_attachment_links`: Set to true to disable automatically adding attachment link text to statuses
* `welcome_message`: A message that will be send to a newly registered users as a direct message.
* `welcome_user_nickname`: The nickname of the local user that sends the welcome message.
-* `max_report_size`: The maximum size of the report comment (Default: `1000`)
+* `max_report_comment_size`: The maximum size of the report comment (Default: `1000`)
+* `safe_dm_mentions`: If set to true, only mentions at the beginning of a post will be used to address people in direct messages. This is to prevent accidental mentioning of people when talking about them (e.g. "@friend hey i really don't like @enemy"). (Default: `false`)
## :logger
* `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog
diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex
index 1e4ede3f2..e3625383b 100644
--- a/lib/pleroma/formatter.ex
+++ b/lib/pleroma/formatter.ex
@@ -8,6 +8,7 @@ defmodule Pleroma.Formatter do
alias Pleroma.User
alias Pleroma.Web.MediaProxy
+ @safe_mention_regex ~r/^(\s*(?<mentions>@.+?\s+)+)(?<rest>.*)/
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
@link_regex ~r{((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+}ui
# credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
@@ -45,15 +46,28 @@ defmodule Pleroma.Formatter do
@doc """
Parses a text and replace plain text links with HTML. Returns a tuple with a result text, mentions, and hashtags.
+
+ If the 'safe_mention' option is given, only consecutive mentions at the start the post are actually mentioned.
"""
@spec linkify(String.t(), keyword()) ::
{String.t(), [{String.t(), User.t()}], [{String.t(), String.t()}]}
def linkify(text, options \\ []) do
options = options ++ @auto_linker_config
- acc = %{mentions: MapSet.new(), tags: MapSet.new()}
- {text, %{mentions: mentions, tags: tags}} = AutoLinker.link_map(text, acc, options)
- {text, MapSet.to_list(mentions), MapSet.to_list(tags)}
+ if options[:safe_mention] && Regex.named_captures(@safe_mention_regex, text) do
+ %{"mentions" => mentions, "rest" => rest} = Regex.named_captures(@safe_mention_regex, text)
+ acc = %{mentions: MapSet.new(), tags: MapSet.new()}
+
+ {text_mentions, %{mentions: mentions}} = AutoLinker.link_map(mentions, acc, options)
+ {text_rest, %{tags: tags}} = AutoLinker.link_map(rest, acc, options)
+
+ {text_mentions <> text_rest, MapSet.to_list(mentions), MapSet.to_list(tags)}
+ else
+ acc = %{mentions: MapSet.new(), tags: MapSet.new()}
+ {text, %{mentions: mentions, tags: tags}} = AutoLinker.link_map(text, acc, options)
+
+ {text, MapSet.to_list(mentions), MapSet.to_list(tags)}
+ end
end
def emojify(text) do
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index b5f79c3bf..50d60aade 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -142,7 +142,8 @@ defmodule Pleroma.Web.CommonAPI do
make_content_html(
status,
attachments,
- data
+ data,
+ visibility
),
{to, cc} <- to_for_user_and_mentions(user, mentions, in_reply_to, visibility),
context <- make_context(in_reply_to),
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index b7513ef28..368945418 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -101,7 +101,8 @@ defmodule Pleroma.Web.CommonAPI.Utils do
def make_content_html(
status,
attachments,
- data
+ data,
+ visibility
) do
no_attachment_links =
data
@@ -110,8 +111,15 @@ defmodule Pleroma.Web.CommonAPI.Utils do
content_type = get_content_type(data["content_type"])
+ options =
+ if visibility == "direct" && Config.get([:instance, :safe_dm_mentions]) do
+ [safe_mention: true]
+ else
+ []
+ end
+
status
- |> format_input(content_type)
+ |> format_input(content_type, options)
|> maybe_add_attachments(attachments, no_attachment_links)
|> maybe_add_nsfw_tag(data)
end
diff --git a/test/formatter_test.exs b/test/formatter_test.exs
index 7d8864bf4..fcdf931b7 100644
--- a/test/formatter_test.exs
+++ b/test/formatter_test.exs
@@ -181,6 +181,31 @@ defmodule Pleroma.FormatterTest do
expected_text = "@a hi"
assert {^expected_text, [] = _mentions, [] = _tags} = Formatter.linkify(text)
end
+
+ test "given the 'safe_mention' option, it will only mention people in the beginning" do
+ user = insert(:user)
+ _other_user = insert(:user)
+ third_user = insert(:user)
+ text = " @#{user.nickname} hey dude i hate @#{third_user.nickname}"
+ {expected_text, mentions, [] = _tags} = Formatter.linkify(text, safe_mention: true)
+
+ assert mentions == [{"@#{user.nickname}", user}]
+
+ assert expected_text ==
+ "<span class='h-card'><a data-user='#{user.id}' class='u-url mention' href='#{
+ user.ap_id
+ }'>@<span>#{user.nickname}</span></a></span> hey dude i hate <span class='h-card'><a data-user='#{
+ third_user.id
+ }' class='u-url mention' href='#{third_user.ap_id}'>@<span>#{third_user.nickname}</span></a></span>"
+ end
+
+ test "given the 'safe_mention' option, it will still work without any mention" do
+ text = "A post without any mention"
+ {expected_text, mentions, [] = _tags} = Formatter.linkify(text, safe_mention: true)
+
+ assert mentions == []
+ assert expected_text == text
+ end
end
describe ".parse_tags" do
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
index f83f80b40..34aa5bf18 100644
--- a/test/web/common_api/common_api_test.exs
+++ b/test/web/common_api/common_api_test.exs
@@ -10,6 +10,24 @@ defmodule Pleroma.Web.CommonAPITest do
import Pleroma.Factory
+ test "with the safe_dm_mention option set, it does not mention people beyond the initial tags" do
+ har = insert(:user)
+ jafnhar = insert(:user)
+ tridi = insert(:user)
+ option = Pleroma.Config.get([:instance, :safe_dm_mentions])
+ Pleroma.Config.put([:instance, :safe_dm_mentions], true)
+
+ {:ok, activity} =
+ CommonAPI.post(har, %{
+ "status" => "@#{jafnhar.nickname} hey, i never want to see @#{tridi.nickname} again",
+ "visibility" => "direct"
+ })
+
+ refute tridi.ap_id in activity.recipients
+ assert jafnhar.ap_id in activity.recipients
+ Pleroma.Config.put([:instance, :safe_dm_mentions], option)
+ end
+
test "it de-duplicates tags" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "#2hu #2HU"})