diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | config/config.exs | 3 | ||||
| -rw-r--r-- | config/description.exs | 7 | ||||
| -rw-r--r-- | docs/configuration/cheatsheet.md | 5 | ||||
| -rw-r--r-- | lib/pleroma/user.ex | 11 | ||||
| -rw-r--r-- | test/user_test.exs | 23 | ||||
| -rw-r--r-- | test/web/mastodon_api/controllers/account_controller_test.exs | 29 | 
7 files changed, 70 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b682d70b..de017e30a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).  ### Added +- Configuration: Added a blacklist for email servers.  - Chats: Added `accepts_chat_messages` field to user, exposed in APIs and federation.  - Chats: Added support for federated chats. For details, see the docs.  - ActivityPub: Added support for existing AP ids for instances migrated from Mastodon. diff --git a/config/config.exs b/config/config.exs index fa8051e40..933a899ab 100644 --- a/config/config.exs +++ b/config/config.exs @@ -516,7 +516,8 @@ config :pleroma, Pleroma.User,      "user_exists",      "users",      "web" -  ] +  ], +  email_blacklist: []  config :pleroma, Oban,    repo: Pleroma.Repo, diff --git a/config/description.exs b/config/description.exs index ae2f6d23f..d823812fb 100644 --- a/config/description.exs +++ b/config/description.exs @@ -3056,6 +3056,7 @@ config :pleroma, :config_description, [        %{          key: :restricted_nicknames,          type: {:list, :string}, +        description: "List of nicknames users may not register with.",          suggestions: [            ".well-known",            "~", @@ -3088,6 +3089,12 @@ config :pleroma, :config_description, [            "users",            "web"          ] +      }, +      %{ +        key: :email_blacklist, +        type: {:list, :string}, +        description: "List of email domains users may not register with.", +        suggestions: ["mailinator.com", "maildrop.cc"]        }      ]    }, diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index 5891fc9b0..f23cf4fe4 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -207,6 +207,11 @@ config :pleroma, :mrf_user_allowlist, %{  * `sign_object_fetches`: Sign object fetches with HTTP signatures  * `authorized_fetch_mode`: Require HTTP signatures for AP fetches +## Pleroma.User + +* `restricted_nicknames`: List of nicknames users may not register with. +* `email_blacklist`: List of email domains users may not register with. +  ## Pleroma.ScheduledActivity  * `daily_user_limit`: the number of scheduled activities a user is allowed to create in a single day (Default: `25`) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 0c1fab223..09e606b37 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -676,10 +676,19 @@ defmodule Pleroma.User do      |> validate_required([:name, :nickname, :password, :password_confirmation])      |> validate_confirmation(:password)      |> unique_constraint(:email) +    |> validate_format(:email, @email_regex) +    |> validate_change(:email, fn :email, email -> +      valid? = +        Config.get([User, :email_blacklist]) +        |> Enum.all?(fn blacklisted_domain -> +          !String.ends_with?(email, ["@" <> blacklisted_domain, "." <> blacklisted_domain]) +        end) + +      if valid?, do: [], else: [email: "Invalid email"] +    end)      |> unique_constraint(:nickname)      |> validate_exclusion(:nickname, Config.get([User, :restricted_nicknames]))      |> validate_format(:nickname, local_nickname_regex()) -    |> validate_format(:email, @email_regex)      |> validate_length(:bio, max: bio_limit)      |> validate_length(:name, min: 1, max: name_limit)      |> validate_length(:registration_reason, max: reason_limit) diff --git a/test/user_test.exs b/test/user_test.exs index 2c1f2b7c5..b47405895 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -513,6 +513,29 @@ defmodule Pleroma.UserTest do        refute changeset.valid?      end +    test "it blocks blacklisted email domains" do +      clear_config([User, :email_blacklist], ["trolling.world"]) + +      # Block with match +      params = Map.put(@full_user_data, :email, "troll@trolling.world") +      changeset = User.register_changeset(%User{}, params) +      refute changeset.valid? + +      # Block with subdomain match +      params = Map.put(@full_user_data, :email, "troll@gnomes.trolling.world") +      changeset = User.register_changeset(%User{}, params) +      refute changeset.valid? + +      # Pass with different domains that are similar +      params = Map.put(@full_user_data, :email, "troll@gnomestrolling.world") +      changeset = User.register_changeset(%User{}, params) +      assert changeset.valid? + +      params = Map.put(@full_user_data, :email, "troll@trolling.world.us") +      changeset = User.register_changeset(%User{}, params) +      assert changeset.valid? +    end +      test "it sets the password_hash and ap_id" do        changeset = User.register_changeset(%User{}, @full_user_data) diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index d390c3ce1..17a1e7d66 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -940,17 +940,32 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do        assert refresh        assert scope == "read write follow" +      clear_config([User, :email_blacklist], ["example.org"]) + +      params = %{ +        username: "lain", +        email: "lain@example.org", +        password: "PlzDontHackLain", +        bio: "Test Bio", +        agreement: true +      } +        conn =          build_conn()          |> put_req_header("content-type", "multipart/form-data")          |> put_req_header("authorization", "Bearer " <> token) -        |> post("/api/v1/accounts", %{ -          username: "lain", -          email: "lain@example.org", -          password: "PlzDontHackLain", -          bio: "Test Bio", -          agreement: true -        }) +        |> post("/api/v1/accounts", params) + +      assert %{"error" => "{\"email\":[\"Invalid email\"]}"} = +               json_response_and_validate_schema(conn, 400) + +      Pleroma.Config.put([User, :email_blacklist], []) + +      conn = +        build_conn() +        |> put_req_header("content-type", "multipart/form-data") +        |> put_req_header("authorization", "Bearer " <> token) +        |> post("/api/v1/accounts", params)        %{          "access_token" => token,  | 
