From 1b8fd7e65af980c42b72f584c2a957b12ca5c78b Mon Sep 17 00:00:00 2001
From: Mark Felder <feld@feld.me>
Date: Fri, 16 Oct 2020 17:32:05 +0000
Subject: [PATCH 1/6] Adds feature to permit e.g., local admins and community
 moderators to automatically follow all newly registered accounts

---
 config/config.exs                |  1 +
 config/description.exs           | 11 +++++++++++
 docs/configuration/cheatsheet.md |  1 +
 lib/pleroma/user.ex              | 11 +++++++++++
 test/pleroma/user_test.exs       | 18 ++++++++++++++++++
 5 files changed, 42 insertions(+)

diff --git a/config/config.exs b/config/config.exs
index 2c6142360..0f3785d12 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -235,6 +235,7 @@ config :pleroma, :instance,
     "text/bbcode"
   ],
   autofollowed_nicknames: [],
+  autofollowing_nicknames: [],
   max_pinned_statuses: 1,
   attachment_links: false,
   max_report_comment_size: 1000,
diff --git a/config/description.exs b/config/description.exs
index 2a1898922..2bbb12540 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -837,6 +837,17 @@ config :pleroma, :config_description, [
           "rinpatch"
         ]
       },
+      %{
+        key: :autofollowing_nicknames,
+        type: {:list, :string},
+        description:
+          "Set to nicknames of (local) users that automatically follows every newly registered user",
+        suggestions: [
+          "admin",
+          "info",
+          "moderator",
+        ]
+      },
       %{
         key: :attachment_links,
         type: :boolean,
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index 0b13d7e88..f4b4b6c3c 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -45,6 +45,7 @@ To add configuration to your config file, you can copy it from the base config.
     older software for theses nicknames.
 * `max_pinned_statuses`: The maximum number of pinned statuses. `0` will disable the feature.
 * `autofollowed_nicknames`: Set to nicknames of (local) users that every new user should automatically follow.
+* `autofollowing_nicknames`: Set to nicknames of (local) users that automatically follows every newly registered user.
 * `attachment_links`: Set to true to enable automatically adding attachment link text to statuses.
 * `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`.
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index dc41d0001..2a3495103 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -765,6 +765,16 @@ defmodule Pleroma.User do
     follow_all(user, autofollowed_users)
   end
 
+  defp autofollowing_users(user) do
+    candidates = Config.get([:instance, :autofollowing_nicknames])
+
+    User.Query.build(%{nickname: candidates, local: true, deactivated: false})
+    |> Repo.all()
+    |> Enum.each(&follow(&1, user, :follow_accept))
+
+    {:ok, :success}
+  end
+
   @doc "Inserts provided changeset, performs post-registration actions (confirmation email sending etc.)"
   def register(%Ecto.Changeset{} = changeset) do
     with {:ok, user} <- Repo.insert(changeset) do
@@ -774,6 +784,7 @@ defmodule Pleroma.User do
 
   def post_register_action(%User{} = user) do
     with {:ok, user} <- autofollow_users(user),
+         {:ok, _} <- autofollowing_users(user),
          {:ok, user} <- set_cache(user),
          {:ok, _} <- send_welcome_email(user),
          {:ok, _} <- send_welcome_message(user),
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index 7220ce846..9ae52d594 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -388,6 +388,7 @@ defmodule Pleroma.UserTest do
     }
 
     setup do: clear_config([:instance, :autofollowed_nicknames])
+    setup do: clear_config([:instance, :autofollowing_nicknames])
     setup do: clear_config([:welcome])
     setup do: clear_config([:instance, :account_activation_required])
 
@@ -408,6 +409,23 @@ defmodule Pleroma.UserTest do
       refute User.following?(registered_user, remote_user)
     end
 
+    test "it adds automatic followers for new registered accounts" do
+      user1 = insert(:user)
+      user2 = insert(:user)
+
+      Pleroma.Config.put([:instance, :autofollowing_nicknames], [
+        user1.nickname,
+        user2.nickname
+      ])
+
+      cng = User.register_changeset(%User{}, @full_user_data)
+
+      {:ok, registered_user} = User.register(cng)
+
+      assert User.following?(user1, registered_user)
+      assert User.following?(user2, registered_user)
+    end
+
     test "it sends a welcome message if it is set" do
       welcome_user = insert(:user)
       Pleroma.Config.put([:welcome, :direct_message, :enabled], true)

From efd6572ffbf4cce86e28d351d3cbddd0a5334980 Mon Sep 17 00:00:00 2001
From: Mark Felder <feld@feld.me>
Date: Fri, 16 Oct 2020 17:43:44 +0000
Subject: [PATCH 2/6] Remove suggestions

---
 config/description.exs | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/config/description.exs b/config/description.exs
index 2bbb12540..79e1368d0 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -841,12 +841,7 @@ config :pleroma, :config_description, [
         key: :autofollowing_nicknames,
         type: {:list, :string},
         description:
-          "Set to nicknames of (local) users that automatically follows every newly registered user",
-        suggestions: [
-          "admin",
-          "info",
-          "moderator",
-        ]
+          "Set to nicknames of (local) users that automatically follows every newly registered user"
       },
       %{
         key: :attachment_links,

From d16336e7fbf7851ee5f50a17747067f2be741581 Mon Sep 17 00:00:00 2001
From: Mark Felder <feld@feld.me>
Date: Sat, 17 Oct 2020 16:54:05 +0000
Subject: [PATCH 3/6] Document autofollowing_nicknames

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 36a84b1a8..fd5b9034d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Mix tasks for controlling user account confirmation status in bulk (`mix pleroma.user confirm_all` and `mix pleroma.user unconfirm_all`)
 - Mix task for sending confirmation emails to all unconfirmed users (`mix pleroma.email send_confirmation_mails`)
 - Mix task option for force-unfollowing relays
+- Setting `:instance, autofollowing_nicknames` to provide a way to make accounts automatically follow new users that register on the local Pleroma instance.
 
 ### Changed
 

From 60e379ce0b74bbe1b0f40a954aec040beab20e4e Mon Sep 17 00:00:00 2001
From: lain <lain@soykaf.club>
Date: Fri, 23 Oct 2020 13:53:01 +0200
Subject: [PATCH 4/6] User: Correctly handle whitespace names.

---
 lib/pleroma/user.ex                           |  5 +-
 lib/pleroma/web/activity_pub/activity_pub.ex  |  4 --
 test/fixtures/mewmew_no_name.json             | 46 +++++++++++++++++++
 .../web/activity_pub/activity_pub_test.exs    | 11 +++++
 4 files changed, 60 insertions(+), 6 deletions(-)
 create mode 100644 test/fixtures/mewmew_no_name.json

diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index dc41d0001..72f507f1e 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -426,7 +426,6 @@ defmodule Pleroma.User do
       params,
       [
         :bio,
-        :name,
         :emoji,
         :ap_id,
         :inbox,
@@ -455,7 +454,9 @@ defmodule Pleroma.User do
         :accepts_chat_messages
       ]
     )
-    |> validate_required([:name, :ap_id])
+    |> cast(params, [:name], empty_values: [])
+    |> validate_required([:ap_id])
+    |> validate_required([:name], trim: false)
     |> unique_constraint(:nickname)
     |> validate_format(:nickname, @email_regex)
     |> validate_length(:bio, max: bio_limit)
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index d17c892a7..df18db603 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -1378,10 +1378,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
          {:ok, data} <- user_data_from_user_object(data) do
       {:ok, maybe_update_follow_information(data)}
     else
-      {:error, "Object has been deleted" = e} ->
-        Logger.debug("Could not decode user at fetch #{ap_id}, #{inspect(e)}")
-        {:error, e}
-
       {:error, {:reject, reason} = e} ->
         Logger.info("Rejected user #{ap_id}: #{inspect(reason)}")
         {:error, e}
diff --git a/test/fixtures/mewmew_no_name.json b/test/fixtures/mewmew_no_name.json
new file mode 100644
index 000000000..532d4cf70
--- /dev/null
+++ b/test/fixtures/mewmew_no_name.json
@@ -0,0 +1,46 @@
+{
+   "@context" : [
+      "https://www.w3.org/ns/activitystreams",
+      "https://princess.cat/schemas/litepub-0.1.jsonld",
+      {
+         "@language" : "und"
+      }
+   ],
+   "attachment" : [],
+   "capabilities" : {
+      "acceptsChatMessages" : true
+   },
+   "discoverable" : false,
+   "endpoints" : {
+      "oauthAuthorizationEndpoint" : "https://princess.cat/oauth/authorize",
+      "oauthRegistrationEndpoint" : "https://princess.cat/api/v1/apps",
+      "oauthTokenEndpoint" : "https://princess.cat/oauth/token",
+      "sharedInbox" : "https://princess.cat/inbox",
+      "uploadMedia" : "https://princess.cat/api/ap/upload_media"
+   },
+   "followers" : "https://princess.cat/users/mewmew/followers",
+   "following" : "https://princess.cat/users/mewmew/following",
+   "icon" : {
+      "type" : "Image",
+      "url" : "https://princess.cat/media/12794fb50e86911e65be97f69196814049dcb398a2f8b58b99bb6591576e648c.png?name=blobcatpresentpink.png"
+   },
+   "id" : "https://princess.cat/users/mewmew",
+   "image" : {
+      "type" : "Image",
+      "url" : "https://princess.cat/media/05d8bf3953ab6028fc920494ffc643fbee9dcef40d7bdd06f107e19acbfbd7f9.png"
+   },
+   "inbox" : "https://princess.cat/users/mewmew/inbox",
+   "manuallyApprovesFollowers" : true,
+   "name" : " ",
+   "outbox" : "https://princess.cat/users/mewmew/outbox",
+   "preferredUsername" : "mewmew",
+   "publicKey" : {
+      "id" : "https://princess.cat/users/mewmew#main-key",
+      "owner" : "https://princess.cat/users/mewmew",
+      "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAru7VpygVef4zrFwnj0Mh\nrbO/2z2EdKN3rERtNrT8zWsLXNLQ50lfpRPnGDrd+xq7Rva4EIu0d5KJJ9n4vtY0\nuxK3On9vA2oyjLlR9O0lI3XTrHJborG3P7IPXrmNUMFpHiFHNqHp5tugUrs1gUFq\n7tmOmM92IP4Wjk8qNHFcsfnUbaPTX7sNIhteQKdi5HrTb/6lrEIe4G/FlMKRqxo3\nRNHuv6SNFQuiUKvFzjzazvjkjvBSm+aFROgdHa2tKl88StpLr7xmuY8qNFCRT6W0\nLacRp6c8ah5f03Kd+xCBVhCKvKaF1K0ERnQTBiitUh85md+Mtx/CoDoLnmpnngR3\nvQIDAQAB\n-----END PUBLIC KEY-----\n\n"
+   },
+   "summary" : "please reply to my posts as direct messages if you have many followers",
+   "tag" : [],
+   "type" : "Person",
+   "url" : "https://princess.cat/users/mewmew"
+}
diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs
index 6ac883b23..43bd14ee6 100644
--- a/test/pleroma/web/activity_pub/activity_pub_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_test.exs
@@ -2273,4 +2273,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert length(activities) == 2
     end
   end
+
+  test "allow fetching of accounts with an empty string name field" do
+    Tesla.Mock.mock(fn
+      %{method: :get, url: "https://princess.cat/users/mewmew"} ->
+        file = File.read!("test/fixtures/mewmew_no_name.json")
+        %Tesla.Env{status: 200, body: file}
+    end)
+
+    {:ok, user} = ActivityPub.make_user_from_ap_id("https://princess.cat/users/mewmew")
+    assert user.name == " "
+  end
 end

From a999e8b0b73372ed129c5a26acfe73e5f7478c5b Mon Sep 17 00:00:00 2001
From: lain <lain@soykaf.club>
Date: Fri, 23 Oct 2020 13:55:08 +0200
Subject: [PATCH 5/6] Changelog: Add info about whitespace name remote users.

---
 CHANGELOG.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index afeaa930b..1f15a8b95 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -47,7 +47,8 @@ switched to a new configuration mechanism, however it was not officially removed
 
 - Add documented-but-missing chat pagination.
 - Allow sending out emails again.
-- Allow sending chat messages to yourself
+- Allow sending chat messages to yourself.
+- Fix remote users with a whitespace name.
 
 ## Unreleased (Patch)
 

From de6d49c8cec84a530f2835313c95064ae8df3604 Mon Sep 17 00:00:00 2001
From: lain <lain@soykaf.club>
Date: Mon, 26 Oct 2020 16:33:26 +0100
Subject: [PATCH 6/6] ActivityPub: Add back debug call + explanation.

---
 lib/pleroma/web/activity_pub/activity_pub.ex | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index df18db603..13869f897 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -1378,6 +1378,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
          {:ok, data} <- user_data_from_user_object(data) do
       {:ok, maybe_update_follow_information(data)}
     else
+      # If this has been deleted, only log a debug and not an error
+      {:error, "Object has been deleted" = e} ->
+        Logger.debug("Could not decode user at fetch #{ap_id}, #{inspect(e)}")
+        {:error, e}
+
       {:error, {:reject, reason} = e} ->
         Logger.info("Rejected user #{ap_id}: #{inspect(reason)}")
         {:error, e}