Replace `MastodonAPIController.account_register/2` rate limiter
authorEgor Kislitsyn <egor@kislitsyn.com>
Tue, 11 Jun 2019 09:06:03 +0000 (16:06 +0700)
committerEgor Kislitsyn <egor@kislitsyn.com>
Tue, 11 Jun 2019 09:06:03 +0000 (16:06 +0700)
config/config.exs
config/test.exs
docs/config.md
lib/pleroma/plugs/rate_limit_plug.ex [deleted file]
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
test/plugs/rate_limit_plug_test.exs [deleted file]
test/web/mastodon_api/mastodon_api_controller_test.exs

index d20d4fda91d13365fb72f7aacf30028aeb151497..3d2c6d48e6f21ae453d1327e7ee179da4d190307 100644 (file)
@@ -247,8 +247,6 @@ config :pleroma, :instance,
   skip_thread_containment: false,
   limit_unauthenticated_to_local_content: true
 
-config :pleroma, :app_account_creation, enabled: true, max_requests: 25, interval: 1800
-
 config :pleroma, :markup,
   # XXX - unfortunately, inline images must be enabled by default right now, because
   # of custom emoji.  Issue #275 discusses defanging that somehow.
@@ -503,7 +501,9 @@ config :pleroma, :database, rum_enabled: false
 config :http_signatures,
   adapter: Pleroma.Signature
 
-config :pleroma, :rate_limit, search: [{1000, 10}, {1000, 30}]
+config :pleroma, :rate_limit,
+  search: [{1000, 10}, {1000, 30}],
+  app_account_creation: {1_800_000, 25}
 
 # Import environment specific config. This must remain at the bottom
 # of this file so it overrides the configuration defined above.
index 7861b959811db29e3bd5c0743db10bb0b0e897f3..95129f409ff846dd8e0ccaec08f2548ffdd926f8 100644 (file)
@@ -59,7 +59,7 @@ config :pleroma, Pleroma.ScheduledActivity,
   total_user_limit: 3,
   enabled: false
 
-config :pleroma, :app_account_creation, max_requests: 5
+config :pleroma, :rate_limit, app_account_creation: {1000, 5}
 
 config :pleroma, :http_security, report_uri: "https://endpoint.com"
 
index e31e2b90f58629a4cbc71594572fc601eae6cfcc..b62b8049052faf0f98e8a49dbccbea255bc44be4 100644 (file)
@@ -114,12 +114,6 @@ config :pleroma, Pleroma.Emails.Mailer,
 * `skip_thread_containment`: Skip filter out broken threads. The default is `false`.
 * `limit_unauthenticated_to_local_content`: Limit unauthenticated users to search for local statutes and users only. The default is `true`.
 
-## :app_account_creation
-REST API for creating an account settings
-* `enabled`: Enable/disable registration
-* `max_requests`: Number of requests allowed for creating accounts
-* `interval`: Interval for restricting requests for one ip (seconds)
-
 ## :logger
 * `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog, and `Quack.Logger` to log to Slack
 
@@ -568,7 +562,7 @@ config :ueberauth, Ueberauth,
   providers: [
     microsoft: {Ueberauth.Strategy.Microsoft, [callback_params: []]}
   ]
-  
+
 # Keycloak
 # Note: make sure to add `keycloak:ueberauth_keycloak_strategy` entry to `OAUTH_CONSUMER_STRATEGIES` environment variable
 keycloak_url = "https://publicly-reachable-keycloak-instance.org:8080"
diff --git a/lib/pleroma/plugs/rate_limit_plug.ex b/lib/pleroma/plugs/rate_limit_plug.ex
deleted file mode 100644 (file)
index 466f64a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.RateLimitPlug do
-  import Phoenix.Controller, only: [json: 2]
-  import Plug.Conn
-
-  def init(opts), do: opts
-
-  def call(conn, opts) do
-    enabled? = Pleroma.Config.get([:app_account_creation, :enabled])
-
-    case check_rate(conn, Map.put(opts, :enabled, enabled?)) do
-      {:ok, _count} -> conn
-      {:error, _count} -> render_error(conn)
-      %Plug.Conn{} = conn -> conn
-    end
-  end
-
-  defp check_rate(conn, %{enabled: true} = opts) do
-    max_requests = opts[:max_requests]
-    bucket_name = conn.remote_ip |> Tuple.to_list() |> Enum.join(".")
-
-    ExRated.check_rate(bucket_name, opts[:interval] * 1000, max_requests)
-  end
-
-  defp check_rate(conn, _), do: conn
-
-  defp render_error(conn) do
-    conn
-    |> put_status(:forbidden)
-    |> json(%{error: "Rate limit exceeded."})
-    |> halt()
-  end
-end
index 20b08fda40ad1afc5c748239e3771a59013d194b..46049dd24a9bd7a1e6e1e2af772c41e0ee1d8bc9 100644 (file)
@@ -46,15 +46,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 
   require Logger
 
-  plug(
-    Pleroma.Plugs.RateLimitPlug,
-    %{
-      max_requests: Config.get([:app_account_creation, :max_requests]),
-      interval: Config.get([:app_account_creation, :interval])
-    }
-    when action in [:account_register]
-  )
-
+  plug(Pleroma.Plugs.RateLimiter, :app_account_creation when action == :account_register)
   plug(Pleroma.Plugs.RateLimiter, :search when action in [:search, :search2, :account_search])
 
   @local_mastodon_name "Mastodon-Local"
diff --git a/test/plugs/rate_limit_plug_test.exs b/test/plugs/rate_limit_plug_test.exs
deleted file mode 100644 (file)
index 2ec9a8f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-defmodule Pleroma.Plugs.RateLimitPlugTest do
-  use ExUnit.Case, async: true
-  use Plug.Test
-
-  alias Pleroma.Plugs.RateLimitPlug
-
-  @opts RateLimitPlug.init(%{max_requests: 5, interval: 1})
-
-  setup do
-    enabled = Pleroma.Config.get([:app_account_creation, :enabled])
-
-    Pleroma.Config.put([:app_account_creation, :enabled], true)
-
-    on_exit(fn ->
-      Pleroma.Config.put([:app_account_creation, :enabled], enabled)
-    end)
-
-    :ok
-  end
-
-  test "it restricts by opts" do
-    conn = conn(:get, "/")
-    bucket_name = conn.remote_ip |> Tuple.to_list() |> Enum.join(".")
-    ms = 1000
-
-    conn = RateLimitPlug.call(conn, @opts)
-    {1, 4, _, _, _} = ExRated.inspect_bucket(bucket_name, ms, 5)
-    conn = RateLimitPlug.call(conn, @opts)
-    {2, 3, _, _, _} = ExRated.inspect_bucket(bucket_name, ms, 5)
-    conn = RateLimitPlug.call(conn, @opts)
-    {3, 2, _, _, _} = ExRated.inspect_bucket(bucket_name, ms, 5)
-    conn = RateLimitPlug.call(conn, @opts)
-    {4, 1, _, _, _} = ExRated.inspect_bucket(bucket_name, ms, 5)
-    conn = RateLimitPlug.call(conn, @opts)
-    {5, 0, to_reset, _, _} = ExRated.inspect_bucket(bucket_name, ms, 5)
-    conn = RateLimitPlug.call(conn, @opts)
-    assert conn.status == 403
-    assert conn.halted
-    assert conn.resp_body == "{\"error\":\"Rate limit exceeded.\"}"
-
-    Process.sleep(to_reset)
-
-    conn = conn(:get, "/")
-    conn = RateLimitPlug.call(conn, @opts)
-    {1, 4, _, _, _} = ExRated.inspect_bucket(bucket_name, ms, 5)
-    refute conn.status == 403
-    refute conn.halted
-    refute conn.resp_body
-  end
-end
index 33c8e209a91dfa29158c4c23bb4fe9f6056b7e3f..c569ae9ddcacdaf7fb7eb16f8f401003679fcc90 100644 (file)
@@ -3501,24 +3501,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
   end
 
   describe "create account by app" do
-    setup do
-      enabled = Pleroma.Config.get([:app_account_creation, :enabled])
-      max_requests = Pleroma.Config.get([:app_account_creation, :max_requests])
-      interval = Pleroma.Config.get([:app_account_creation, :interval])
-
-      Pleroma.Config.put([:app_account_creation, :enabled], true)
-      Pleroma.Config.put([:app_account_creation, :max_requests], 5)
-      Pleroma.Config.put([:app_account_creation, :interval], 1)
-
-      on_exit(fn ->
-        Pleroma.Config.put([:app_account_creation, :enabled], enabled)
-        Pleroma.Config.put([:app_account_creation, :max_requests], max_requests)
-        Pleroma.Config.put([:app_account_creation, :interval], interval)
-      end)
-
-      :ok
-    end
-
     test "Account registration via Application", %{conn: conn} do
       conn =
         conn
@@ -3621,7 +3603,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
           agreement: true
         })
 
-      assert json_response(conn, 403) == %{"error" => "Rate limit exceeded."}
+      assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"}
     end
   end