Captcha: return invalid when answer_data is nil
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Mon, 24 Feb 2020 01:41:48 +0000 (02:41 +0100)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Mon, 24 Feb 2020 01:49:53 +0000 (02:49 +0100)
lib/pleroma/captcha/captcha.ex
test/captcha_test.exs
test/support/captcha_mock.ex

index c2765a5b8941ab2bc89f0d1ec6618ae31cbddff1..cf75c3adc3bb0b41b5c74e82c461d6f312fb2875 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Captcha do
@@ -50,7 +50,7 @@ defmodule Pleroma.Captcha do
       token = new_captcha[:token]
       secret = KeyGenerator.generate(secret_key_base, token <> "_encrypt")
       sign_secret = KeyGenerator.generate(secret_key_base, token <> "_sign")
-      # Basicallty copy what Phoenix.Token does here, add the time to
+      # Basically copy what Phoenix.Token does here, add the time to
       # the actual data and make it a binary to then encrypt it
       encrypted_captcha_answer =
         %{
@@ -62,7 +62,7 @@ defmodule Pleroma.Captcha do
 
       {
         :reply,
-        # Repalce the answer with the encrypted answer
+        # Replace the answer with the encrypted answer
         %{new_captcha | answer_data: encrypted_captcha_answer},
         state
       }
@@ -82,7 +82,8 @@ defmodule Pleroma.Captcha do
     valid_if_after = DateTime.subtract!(DateTime.now_utc(), seconds_valid)
 
     result =
-      with {:ok, data} <- MessageEncryptor.decrypt(answer_data, secret, sign_secret),
+      with false <- is_nil(answer_data),
+           {:ok, data} <- MessageEncryptor.decrypt(answer_data, secret, sign_secret),
            %{at: at, answer_data: answer_md5} <- :erlang.binary_to_term(data) do
         try do
           if DateTime.before?(at, valid_if_after),
index b6f231bdb44fc077e0f79ce7713d42f222b43834..5e29b48b07d90d1645dd9d03dc8997010da6ca20 100644 (file)
@@ -3,15 +3,18 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.CaptchaTest do
-  use ExUnit.Case
+  use Pleroma.DataCase
 
   import Tesla.Mock
 
+  alias Pleroma.Captcha
   alias Pleroma.Captcha.Kocaptcha
   alias Pleroma.Captcha.Native
 
   @ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}]
 
+  clear_config([Pleroma.Captcha, :enabled])
+
   describe "Kocaptcha" do
     setup do
       ets_name = Kocaptcha.Ets
@@ -62,4 +65,52 @@ defmodule Pleroma.CaptchaTest do
       assert {:error, "Invalid CAPTCHA"} == Native.validate(token, answer, answer <> "foobar")
     end
   end
+
+  describe "Captcha Wrapper" do
+    test "validate" do
+      Pleroma.Config.put([Pleroma.Captcha, :enabled], true)
+
+      new = Captcha.new()
+
+      assert %{
+               answer_data: answer,
+               token: token
+             } = new
+
+      assert is_binary(answer)
+      assert :ok = Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", answer)
+    end
+
+    test "doesn't validate invalid answer" do
+      Pleroma.Config.put([Pleroma.Captcha, :enabled], true)
+
+      new = Captcha.new()
+
+      assert %{
+               answer_data: answer,
+               token: token
+             } = new
+
+      assert is_binary(answer)
+
+      assert {:error, "Invalid answer data"} =
+               Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", answer <> "foobar")
+    end
+
+    test "nil answer_data" do
+      Pleroma.Config.put([Pleroma.Captcha, :enabled], true)
+
+      new = Captcha.new()
+
+      assert %{
+               answer_data: answer,
+               token: token
+             } = new
+
+      assert is_binary(answer)
+
+      assert {:error, "Invalid answer data"} =
+               Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", nil)
+    end
+  end
 end
index 65ca6b3bde0381721ecb960c632d3adcf33f739b..6dae94edf480e34aba6c3e73fd83ad715ce83da3 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Captcha.Mock do
@@ -7,8 +7,17 @@ defmodule Pleroma.Captcha.Mock do
   @behaviour Service
 
   @impl Service
-  def new, do: %{type: :mock}
+  def new,
+    do: %{
+      type: :mock,
+      token: "afa1815e14e29355e6c8f6b143a39fa2",
+      answer_data: "63615261b77f5354fb8c4e4986477555",
+      url: "https://example.org/captcha.png"
+    }
 
   @impl Service
-  def validate(_token, _captcha, _data), do: :ok
+  def validate(_token, captcha, captcha) when not is_nil(captcha), do: :ok
+
+  def validate(_token, captcha, answer),
+    do: {:error, "Invalid CAPTCHA captcha: #{inspect(captcha)} ; answer: #{inspect(answer)}"}
 end