mirror of
https://github.com/plausible/analytics.git
synced 2024-12-23 09:33:19 +03:00
add LOG_FAILED_LOGIN_ATTEMPTS (#2936)
* add failed login logs * put failed login attempt logs behind a config option * add changelog entry * add config test * add auth_controller tests * move tests to separate non-async test module --------- Co-authored-by: Uku Taht <Uku.taht@gmail.com>
This commit is contained in:
parent
ce7401dd83
commit
40e95ffd3d
@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
|
||||
- 'Last updated X seconds ago' info to 'current visitors' tooltips
|
||||
- Add support for more Bamboo adapters, i.e. `Bamboo.MailgunAdapter`, `Bamboo.MandrillAdapter`, `Bamboo.SendGridAdapter` plausible/analytics#2649
|
||||
- Ability to change domain for existing site (requires numeric IDs data migration, instructions will be provided separately) UI + API (`PUT /api/v1/sites`)
|
||||
- Add `LOG_FAILED_LOGIN_ATTEMPTS` environment variable to enable failed login attempts logs plausible/analytics#2936
|
||||
- Add `MAILER_NAME` environment variable support plausible/analytics#2937
|
||||
- Add `MAILGUN_BASE_URI` support for `Bamboo.MailgunAdapter` plausible/analytics#2935
|
||||
|
||||
|
@ -217,6 +217,11 @@ disable_cron =
|
||||
|> get_var_from_path_or_env("DISABLE_CRON", "false")
|
||||
|> String.to_existing_atom()
|
||||
|
||||
log_failed_login_attempts =
|
||||
config_dir
|
||||
|> get_var_from_path_or_env("LOG_FAILED_LOGIN_ATTEMPTS", "false")
|
||||
|> String.to_existing_atom()
|
||||
|
||||
config :plausible,
|
||||
environment: env,
|
||||
mailer_email: mailer_email,
|
||||
@ -224,7 +229,8 @@ config :plausible,
|
||||
site_limit: site_limit,
|
||||
site_limit_exempt: site_limit_exempt,
|
||||
is_selfhost: is_selfhost,
|
||||
custom_script_name: custom_script_name
|
||||
custom_script_name: custom_script_name,
|
||||
log_failed_login_attempts: log_failed_login_attempts
|
||||
|
||||
config :plausible, :selfhost,
|
||||
enable_email_verification: enable_email_verification,
|
||||
|
@ -371,12 +371,15 @@ defmodule PlausibleWeb.AuthController do
|
||||
|> redirect(to: login_dest)
|
||||
else
|
||||
:wrong_password ->
|
||||
maybe_log_failed_login_attempts("wrong password for #{email}")
|
||||
|
||||
render(conn, "login_form.html",
|
||||
error: "Wrong email or password. Please try again.",
|
||||
layout: {PlausibleWeb.LayoutView, "focus.html"}
|
||||
)
|
||||
|
||||
:user_not_found ->
|
||||
maybe_log_failed_login_attempts("user not found for #{email}")
|
||||
Plausible.Auth.Password.dummy_calculation()
|
||||
|
||||
render(conn, "login_form.html",
|
||||
@ -385,6 +388,8 @@ defmodule PlausibleWeb.AuthController do
|
||||
)
|
||||
|
||||
{:rate_limit, _} ->
|
||||
maybe_log_failed_login_attempts("too many logging attempts for #{email}")
|
||||
|
||||
render_error(
|
||||
conn,
|
||||
429,
|
||||
@ -393,6 +398,12 @@ defmodule PlausibleWeb.AuthController do
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_log_failed_login_attempts(message) do
|
||||
if Application.get_env(:plausible, :log_failed_login_attempts) do
|
||||
Logger.warning("[login] #{message}")
|
||||
end
|
||||
end
|
||||
|
||||
@login_interval 60_000
|
||||
@login_limit 5
|
||||
defp check_ip_rate_limit(conn) do
|
||||
|
@ -149,6 +149,23 @@ defmodule Plausible.ConfigTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "log_failed_login_attempts" do
|
||||
test "can be true" do
|
||||
env = {"LOG_FAILED_LOGIN_ATTEMPTS", "true"}
|
||||
assert get_in(runtime_config(env), [:plausible, :log_failed_login_attempts]) == true
|
||||
end
|
||||
|
||||
test "can be false" do
|
||||
env = {"LOG_FAILED_LOGIN_ATTEMPTS", "false"}
|
||||
assert get_in(runtime_config(env), [:plausible, :log_failed_login_attempts]) == false
|
||||
end
|
||||
|
||||
test "is false by default" do
|
||||
env = {"LOG_FAILED_LOGIN_ATTEMPTS", nil}
|
||||
assert get_in(runtime_config(env), [:plausible, :log_failed_login_attempts]) == false
|
||||
end
|
||||
end
|
||||
|
||||
defp runtime_config(env) do
|
||||
put_system_env_undo(env)
|
||||
Config.Reader.read!("config/runtime.exs", env: :prod)
|
||||
|
51
test/plausible_web/controllers/auth_controller/logs_test.exs
Normal file
51
test/plausible_web/controllers/auth_controller/logs_test.exs
Normal file
@ -0,0 +1,51 @@
|
||||
defmodule PlausibleWeb.AuthController.LogsTest do
|
||||
use PlausibleWeb.ConnCase
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
describe "POST /login" do
|
||||
setup do
|
||||
patch_env(:log_failed_login_attempts, true)
|
||||
end
|
||||
|
||||
test "logs on missing user", %{conn: conn} do
|
||||
logs =
|
||||
capture_log(fn ->
|
||||
post(conn, "/login", email: "user@example.com", password: "password")
|
||||
end)
|
||||
|
||||
assert logs =~ "[warning] [login] user not found for user@example.com"
|
||||
end
|
||||
|
||||
test "logs on wrong password", %{conn: conn} do
|
||||
user = insert(:user, password: "password")
|
||||
|
||||
logs =
|
||||
capture_log(fn ->
|
||||
post(conn, "/login", email: user.email, password: "wrong")
|
||||
end)
|
||||
|
||||
assert logs =~ "[warning] [login] wrong password for #{user.email}"
|
||||
end
|
||||
|
||||
test "logs on too many login attempts", %{conn: conn} do
|
||||
user = insert(:user, password: "password")
|
||||
|
||||
capture_log(fn ->
|
||||
for _ <- 1..5 do
|
||||
build_conn()
|
||||
|> put_req_header("x-forwarded-for", "1.1.1.1")
|
||||
|> post("/login", email: user.email, password: "wrong")
|
||||
end
|
||||
end)
|
||||
|
||||
logs =
|
||||
capture_log(fn ->
|
||||
conn
|
||||
|> put_req_header("x-forwarded-for", "1.1.1.1")
|
||||
|> post("/login", email: user.email, password: "wrong")
|
||||
end)
|
||||
|
||||
assert logs =~ "[warning] [login] too many logging attempts for #{user.email}"
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user