Add a configurable auto-cleanup for captchas
This commit is contained in:
parent
2e72d49e37
commit
6062885df6
5 changed files with 31 additions and 2 deletions
|
@ -12,6 +12,7 @@ config :pleroma, Pleroma.Repo, types: Pleroma.PostgresTypes
|
||||||
|
|
||||||
config :pleroma, Pleroma.Captcha,
|
config :pleroma, Pleroma.Captcha,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
minutes_retained: 5,
|
||||||
method: Pleroma.Captcha.Kocaptcha
|
method: Pleroma.Captcha.Kocaptcha
|
||||||
|
|
||||||
config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "http://localhost:9093"
|
config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "http://localhost:9093"
|
||||||
|
|
|
@ -167,6 +167,7 @@ Web Push Notifications configuration. You can use the mix task `mix web_push.gen
|
||||||
## Pleroma.Captcha
|
## Pleroma.Captcha
|
||||||
* `enabled`: Whether the captcha should be shown on registration
|
* `enabled`: Whether the captcha should be shown on registration
|
||||||
* `method`: The method/service to use for captcha
|
* `method`: The method/service to use for captcha
|
||||||
|
* `minutes_retained`: The time in minutes for which the captcha is valid (stored in the cache)
|
||||||
|
|
||||||
### Pleroma.Captcha.Kocaptcha
|
### Pleroma.Captcha.Kocaptcha
|
||||||
Kocaptcha is a very simple captcha service with a single API endpoint,
|
Kocaptcha is a very simple captcha service with a single API endpoint,
|
||||||
|
|
|
@ -38,7 +38,13 @@ defmodule Pleroma.Captcha do
|
||||||
if !enabled do
|
if !enabled do
|
||||||
{:reply, %{type: :none}, state}
|
{:reply, %{type: :none}, state}
|
||||||
else
|
else
|
||||||
{:reply, method().new(), state}
|
new_captcha = method().new()
|
||||||
|
|
||||||
|
minutes_retained = Pleroma.Config.get!([__MODULE__, :minutes_retained])
|
||||||
|
# Wait several minutes and if the captcha is still there, delete it
|
||||||
|
Process.send_after(self(), {:cleanup, new_captcha.token}, 1000 * 60 * minutes_retained)
|
||||||
|
|
||||||
|
{:reply, new_captcha, state}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,5 +53,12 @@ defmodule Pleroma.Captcha do
|
||||||
{:reply, method().validate(token, captcha), state}
|
{:reply, method().validate(token, captcha), state}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def handle_info({:cleanup, token}, state) do
|
||||||
|
method().cleanup(token)
|
||||||
|
|
||||||
|
{:noreply, state}
|
||||||
|
end
|
||||||
|
|
||||||
defp method, do: Pleroma.Config.get!([__MODULE__, :method])
|
defp method, do: Pleroma.Config.get!([__MODULE__, :method])
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,4 +20,9 @@ defmodule Pleroma.Captcha.Service do
|
||||||
`true` if captcha is valid, `false` if not
|
`true` if captcha is valid, `false` if not
|
||||||
"""
|
"""
|
||||||
@callback validate(token :: String.t(), captcha :: String.t()) :: boolean
|
@callback validate(token :: String.t(), captcha :: String.t()) :: boolean
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
This function is called periodically to clean up old captchas
|
||||||
|
"""
|
||||||
|
@callback cleanup(token :: String.t()) :: :ok
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,11 +29,20 @@ defmodule Pleroma.Captcha.Kocaptcha do
|
||||||
[{^token, saved_md5}] <- :ets.lookup(@ets, token),
|
[{^token, saved_md5}] <- :ets.lookup(@ets, token),
|
||||||
true <- :crypto.hash(:md5, captcha) |> Base.encode16() == String.upcase(saved_md5) do
|
true <- :crypto.hash(:md5, captcha) |> Base.encode16() == String.upcase(saved_md5) do
|
||||||
# Clear the saved value
|
# Clear the saved value
|
||||||
:ets.delete(@ets, token)
|
cleanup(token)
|
||||||
|
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
_ -> false
|
_ -> false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl Service
|
||||||
|
def cleanup(token) do
|
||||||
|
# Only delete the entry if it exists in the table, because ets:delete raises an exception if it does not
|
||||||
|
case :ets.lookup(@ets, token) do
|
||||||
|
[{^token, _}] -> :ets.delete(@ets, token)
|
||||||
|
_ -> true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue