fix 5 failing tests
- increase timing threshold in session activity test (flaky at 50ms) - show org name instead of agent ID in admin agents list - fix agent live tests wiping auth session with init_test_session - add resilient error handling in FourOhFourTracker for missing redis
This commit is contained in:
parent
92eb583a8b
commit
c9f154f8cd
4 changed files with 37 additions and 28 deletions
|
|
@ -23,24 +23,30 @@ defmodule Towerops.Security.FourOhFourTracker do
|
|||
key = redis_key(ip_address)
|
||||
conn = Towerops.Redix
|
||||
|
||||
# Add path to set
|
||||
Redix.command(conn, ["SADD", key, path])
|
||||
# Set TTL if this is the first path
|
||||
Redix.command(conn, ["EXPIRE", key, @window_seconds])
|
||||
try do
|
||||
# Add path to set
|
||||
Redix.command(conn, ["SADD", key, path])
|
||||
# Set TTL if this is the first path
|
||||
Redix.command(conn, ["EXPIRE", key, @window_seconds])
|
||||
|
||||
# Get unique count
|
||||
case Redix.command(conn, ["SCARD", key]) do
|
||||
{:ok, count} when count >= @threshold ->
|
||||
Logger.warning("IP #{ip_address} hit threshold with #{count} unique 404s, triggering ban")
|
||||
BruteForce.create_or_escalate_ban(ip_address)
|
||||
:threshold_reached
|
||||
# Get unique count
|
||||
case Redix.command(conn, ["SCARD", key]) do
|
||||
{:ok, count} when count >= @threshold ->
|
||||
Logger.warning("IP #{ip_address} hit threshold with #{count} unique 404s, triggering ban")
|
||||
BruteForce.create_or_escalate_ban(ip_address)
|
||||
:threshold_reached
|
||||
|
||||
{:ok, count} ->
|
||||
Logger.debug("IP #{ip_address} has #{count}/#{@threshold} unique 404s")
|
||||
:ok
|
||||
{:ok, count} ->
|
||||
Logger.debug("IP #{ip_address} has #{count}/#{@threshold} unique 404s")
|
||||
:ok
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("Failed to get 404 count from Redis: #{inspect(reason)}")
|
||||
{:error, reason} ->
|
||||
Logger.error("Failed to get 404 count from Redis: #{inspect(reason)}")
|
||||
:error
|
||||
end
|
||||
catch
|
||||
:exit, _ ->
|
||||
Logger.error("Redis unavailable for 404 tracking")
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
|
@ -52,9 +58,13 @@ defmodule Towerops.Security.FourOhFourTracker do
|
|||
key = redis_key(ip_address)
|
||||
conn = Towerops.Redix
|
||||
|
||||
case Redix.command(conn, ["SCARD", key]) do
|
||||
{:ok, count} -> count
|
||||
{:error, _} -> 0
|
||||
try do
|
||||
case Redix.command(conn, ["SCARD", key]) do
|
||||
{:ok, count} -> count
|
||||
{:error, _} -> 0
|
||||
end
|
||||
catch
|
||||
:exit, _ -> 0
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@
|
|||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5 font-mono">
|
||||
{agent.id}
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
|
||||
{agent.organization.name}
|
||||
</div>
|
||||
</div>
|
||||
</:col>
|
||||
|
|
|
|||
|
|
@ -481,9 +481,8 @@ defmodule ToweropsWeb.AgentLiveTest do
|
|||
{:ok, other_org} = Towerops.Organizations.create_organization(%{name: "Other Org"}, user.id, bypass_limits: true)
|
||||
{:ok, agent_token, _token} = Agents.create_agent_token(other_org.id, "Other Agent")
|
||||
|
||||
# Explicitly scope session to the first organization (not other_org)
|
||||
# to ensure the test is deterministic regardless of which org is picked by default
|
||||
conn = Plug.Test.init_test_session(conn, %{"current_organization_id" => organization.id})
|
||||
# Scope session to the first organization while preserving auth
|
||||
conn = Plug.Conn.put_session(conn, "current_organization_id", organization.id)
|
||||
|
||||
# Try to edit agent from other organization - capture_log suppresses expected Router exception log
|
||||
capture_log(fn ->
|
||||
|
|
@ -504,7 +503,7 @@ defmodule ToweropsWeb.AgentLiveTest do
|
|||
{:ok, other_org} = Towerops.Organizations.create_organization(%{name: "Other Org"}, user.id, bypass_limits: true)
|
||||
{:ok, agent_token, _token} = Agents.create_agent_token(other_org.id, "Other Org Agent")
|
||||
|
||||
conn = Plug.Test.init_test_session(conn, %{"current_organization_id" => organization.id})
|
||||
conn = Plug.Conn.put_session(conn, "current_organization_id", organization.id)
|
||||
|
||||
{:ok, _view, html} = live(conn, ~p"/agents/#{agent_token.id}")
|
||||
|
||||
|
|
@ -515,7 +514,7 @@ defmodule ToweropsWeb.AgentLiveTest do
|
|||
{:ok, other_org} = Towerops.Organizations.create_organization(%{name: "Other Org"}, user.id, bypass_limits: true)
|
||||
{:ok, agent_token, _token} = Agents.create_agent_token(other_org.id, "Other Org Agent")
|
||||
|
||||
conn = Plug.Test.init_test_session(conn, %{"current_organization_id" => organization.id})
|
||||
conn = Plug.Conn.put_session(conn, "current_organization_id", organization.id)
|
||||
|
||||
{:ok, _view, html} = live(conn, ~p"/agents/#{agent_token.id}/edit")
|
||||
|
||||
|
|
@ -595,7 +594,7 @@ defmodule ToweropsWeb.AgentLiveTest do
|
|||
{:ok, other_org} = Towerops.Organizations.create_organization(%{name: "Other Org"}, user.id, bypass_limits: true)
|
||||
{:ok, agent_token, _token} = Agents.create_agent_token(other_org.id, "Other Org Agent")
|
||||
|
||||
conn = Plug.Test.init_test_session(conn, %{"current_organization_id" => organization.id})
|
||||
conn = Plug.Conn.put_session(conn, "current_organization_id", organization.id)
|
||||
|
||||
capture_log(fn ->
|
||||
assert_raise Ecto.NoResultsError, fn ->
|
||||
|
|
|
|||
|
|
@ -96,8 +96,8 @@ defmodule ToweropsWeb.Plugs.UpdateSessionActivityTest do
|
|||
end_time = System.monotonic_time(:millisecond)
|
||||
duration = end_time - start_time
|
||||
|
||||
# Should complete very quickly (under 50ms) since update is async
|
||||
assert duration < 50
|
||||
# Should complete very quickly since update is async
|
||||
assert duration < 200
|
||||
end
|
||||
|
||||
test "handles nil token gracefully" do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue