X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fcaptcha%2Fkocaptcha.ex;h=eac6dfa365a4c0d8b536ea4f3c08f508611b0ab4;hb=a079ec3a3cdfd42d2cbd51c7698c2c87828e5778;hp=f881c7b652a00303608763dd692e0d7d788de10f;hpb=336e37d98f1b86c0332c9f260e27455a14714fa6;p=akkoma diff --git a/lib/pleroma/captcha/kocaptcha.ex b/lib/pleroma/captcha/kocaptcha.ex index f881c7b65..eac6dfa36 100644 --- a/lib/pleroma/captcha/kocaptcha.ex +++ b/lib/pleroma/captcha/kocaptcha.ex @@ -1,73 +1,38 @@ -defmodule Pleroma.Captcha.Kocaptcha do - alias Plug.Crypto.KeyGenerator - alias Plug.Crypto.MessageEncryptor - alias Calendar.DateTime +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only +defmodule Pleroma.Captcha.Kocaptcha do alias Pleroma.Captcha.Service @behaviour Service @impl Service - def new() do + def new do endpoint = Pleroma.Config.get!([__MODULE__, :endpoint]) - case Tesla.get(endpoint <> "/new") do + case Pleroma.HTTP.get(endpoint <> "/new") do {:error, _} -> - %{error: "Kocaptcha service unavailable"} + %{error: :kocaptcha_service_unavailable} {:ok, res} -> - json_resp = Poison.decode!(res.body) - - token = json_resp["token"] - answer_md5 = json_resp["md5"] - - secret_key_base = Pleroma.Config.get!([Pleroma.Web.Endpoint, :secret_key_base]) - - # This make salt a little different for two keys - 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 - # the actual data and make it a binary to then encrypt it - encrypted_captcha_answer = - %{ - at: DateTime.now_utc(), - answer_md5: answer_md5 - } - |> :erlang.term_to_binary() - |> MessageEncryptor.encrypt(secret, sign_secret) + json_resp = Jason.decode!(res.body) %{ type: :kocaptcha, - token: token, + token: json_resp["token"], url: endpoint <> json_resp["url"], - answer_data: encrypted_captcha_answer + answer_data: json_resp["md5"], + seconds_valid: Pleroma.Config.get([Pleroma.Captcha, :seconds_valid]) } end end @impl Service - def validate(token, captcha, answer_data) do - secret_key_base = Pleroma.Config.get!([Pleroma.Web.Endpoint, :secret_key_base]) - secret = KeyGenerator.generate(secret_key_base, token <> "_encrypt") - sign_secret = KeyGenerator.generate(secret_key_base, token <> "_sign") - - # If the time found is less than (current_time - seconds_valid), then the time has already passed. - # Later we check that the time found is more than the presumed invalidatation time, that means - # that the data is still valid and the captcha can be checked - seconds_valid = Pleroma.Config.get!([Pleroma.Captcha, :seconds_valid]) - valid_if_after = DateTime.subtract!(DateTime.now_utc(), seconds_valid) - - with {:ok, data} <- MessageEncryptor.decrypt(answer_data, secret, sign_secret), - %{at: at, answer_md5: answer_md5} <- :erlang.binary_to_term(data) do - if DateTime.after?(at, valid_if_after) do - if not is_nil(captcha) and - :crypto.hash(:md5, captcha) |> Base.encode16() == String.upcase(answer_md5), - do: :ok, - else: {:error, "Invalid CAPTCHA"} - else - {:error, "CAPTCHA expired"} - end - else - _ -> {:error, "Invalid answer data"} - end + def validate(_token, captcha, answer_data) do + # Here the token is unsed, because the unencrypted captcha answer is just passed to method + if not is_nil(captcha) and + :crypto.hash(:md5, captcha) |> Base.encode16() == String.upcase(answer_data), + do: :ok, + else: {:error, :invalid} end end