From c10394808aea41537f181291052b6eb83914a3cf Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Wed, 4 Mar 2026 16:57:48 -0600 Subject: [PATCH] chore: remove unused functions from disabled brute force protection Removed all unused private functions and imports from BruteForceProtection plug since the feature is currently disabled (Cloudflare handles security). Functions can be restored from git history if feature is re-enabled. Fixed compilation warnings: - unused function track_404_if_needed/2 - unused function maybe_track_404/2 - unused function get_remote_ip/1 - unused function get_fallback_ip/1 - unused function format_remote_ip/1 - unused function check_and_block/2 - unused function block_request/2 - unused function agent_websocket?/1 - unused alias BruteForce - unused import Plug.Conn --- .../plugs/brute_force_protection.ex | 91 ------------------- 1 file changed, 91 deletions(-) diff --git a/lib/towerops_web/plugs/brute_force_protection.ex b/lib/towerops_web/plugs/brute_force_protection.ex index ba4def99..70912f42 100644 --- a/lib/towerops_web/plugs/brute_force_protection.ex +++ b/lib/towerops_web/plugs/brute_force_protection.ex @@ -29,12 +29,6 @@ defmodule ToweropsWeb.Plugs.BruteForceProtection do - Router (needs to intercept requests before routing) """ - import Plug.Conn - - alias Towerops.Security.BruteForce - - require Logger - def init(opts), do: opts def call(conn, _opts) do @@ -42,89 +36,4 @@ defmodule ToweropsWeb.Plugs.BruteForceProtection do # Cloudflare handles security at the edge conn end - - defp agent_websocket?(conn) do - conn.request_path == "/socket/agent/websocket" - end - - defp check_and_block(conn, ip_address) do - # Whitelist bypass - if BruteForce.check_whitelist(ip_address) do - conn - else - # Check if IP is currently banned - case BruteForce.check_ban_status(ip_address) do - :allowed -> - conn - - {:blocked, banned_until} -> - Logger.warning("Blocked request from banned IP: #{ip_address}") - block_request(conn, banned_until) - end - end - end - - defp maybe_track_404(conn, ip_address) do - # Register before_send callback to track 404s after routing - register_before_send(conn, fn conn -> - track_404_if_needed(conn, ip_address) - conn - end) - end - - defp track_404_if_needed(conn, ip_address) do - # Only track 404s from unauthenticated users - if conn.status == 404 && is_nil(Map.get(conn.assigns, :current_user)) do - path = conn.request_path - Logger.debug("Tracking 404 for IP #{ip_address}: #{path}") - BruteForce.record_404_path(ip_address, path) - end - end - - defp block_request(conn, banned_until) do - retry_after = - if banned_until do - DateTime.diff(banned_until, DateTime.utc_now(), :second) - else - # Permanent ban - use a large value - 86_400 - end - - conn - |> put_resp_header("retry-after", to_string(max(0, retry_after))) - |> send_resp(403, "Forbidden - Too many invalid requests") - |> halt() - end - - defp get_remote_ip(conn) do - # Try X-Forwarded-For first (set by Traefik and other proxies) - case get_req_header(conn, "x-forwarded-for") do - [forwarded | _] -> - # X-Forwarded-For can be a comma-separated list; take the first (original client) - forwarded - |> String.split(",") - |> List.first() - |> String.trim() - - [] -> - get_fallback_ip(conn) - end - end - - defp get_fallback_ip(conn) do - # Try X-Real-IP header - case get_req_header(conn, "x-real-ip") do - [real_ip | _] -> - real_ip - - [] -> - format_remote_ip(conn.remote_ip) - end - end - - defp format_remote_ip({a, b, c, d}), do: "#{a}.#{b}.#{c}.#{d}" - - defp format_remote_ip({a, b, c, d, e, f, g, h}) do - Enum.map_join([a, b, c, d, e, f, g, h], ":", &Integer.to_string(&1, 16)) - end end