From d8606bb6093367ae94c0e71f9be51e09af6c5a78 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Mon, 9 Feb 2026 11:26:47 -0600 Subject: [PATCH] Complete nested module alias fixes and update Sobelow skips Software design fixes: - Add proper aliases for all nested modules - release.ex: Ecto.Adapters.SQL - packet_consumer.ex: Aprsme.Cluster.PacketDistributor - cleanup_scheduler.ex: Aprsme.Workers.PacketCleanupWorker - health_check.ex: Ecto.Adapters.SQL - status_live/index.ex: Aprsme.Cluster.LeaderElection - packet_receiver.ex: Aprsme.Cluster.LeaderElection - packet_distributor.ex: Aprsme.Cluster.LeaderElection, AprsmeWeb.MapLive.PacketStore Security: - Update .sobelow-skips for false positive SQL injection warning (div is builtin function) All 13 software design suggestions now complete. All 13 warnings previously fixed. Remaining: 42 refactoring opportunities (complex/nested functions) --- .sobelow-skips | 3 ++- lib/aprsme/cleanup_scheduler.ex | 4 +++- lib/aprsme/cluster/packet_distributor.ex | 7 +++++-- lib/aprsme/cluster/packet_receiver.ex | 3 ++- lib/aprsme/packet_consumer.ex | 3 ++- lib/aprsme/release.ex | 6 +++++- lib/aprsme_web/live/status_live/index.ex | 4 +++- lib/aprsme_web/plugs/health_check.ex | 4 +++- 8 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.sobelow-skips b/.sobelow-skips index 5fd2ef2..0f59b8c 100644 --- a/.sobelow-skips +++ b/.sobelow-skips @@ -14,4 +14,5 @@ SQL.Query: SQL injection,lib/aprsme/release.ex:159,5D9BE66 SQL.Query: SQL injection,lib/aprsme/db_optimizer.ex:107,5ECC490 SQL.Query: SQL injection,lib/aprsme_web/live/info_live/show.ex:576,6A503E9 XSS.Raw: XSS,lib/aprsme_web/components/core_components.ex:52,6B2C0EC -SQL.Query: SQL injection,lib/aprsme/db_optimizer.ex:129,711E151 \ No newline at end of file +SQL.Query: SQL injection,lib/aprsme/db_optimizer.ex:129,711E151 +SQL.Query: SQL injection,lib/aprsme/release.ex:163,7079EA4 \ No newline at end of file diff --git a/lib/aprsme/cleanup_scheduler.ex b/lib/aprsme/cleanup_scheduler.ex index d338d6b..7907e9c 100644 --- a/lib/aprsme/cleanup_scheduler.ex +++ b/lib/aprsme/cleanup_scheduler.ex @@ -8,6 +8,8 @@ defmodule Aprsme.CleanupScheduler do use GenServer + alias Aprsme.Workers.PacketCleanupWorker + require Logger def start_link(opts) do @@ -38,7 +40,7 @@ defmodule Aprsme.CleanupScheduler do # Run cleanup directly in a supervised task Task.start(fn -> try do - Aprsme.Workers.PacketCleanupWorker.perform(%{}) + PacketCleanupWorker.perform(%{}) rescue error -> Logger.error("Packet cleanup task failed: #{inspect(error)}") diff --git a/lib/aprsme/cluster/packet_distributor.ex b/lib/aprsme/cluster/packet_distributor.ex index 4780129..00e5a79 100644 --- a/lib/aprsme/cluster/packet_distributor.ex +++ b/lib/aprsme/cluster/packet_distributor.ex @@ -4,6 +4,9 @@ defmodule Aprsme.Cluster.PacketDistributor do This ensures all nodes can serve real-time updates via LiveView while only the leader maintains the APRS-IS connection. """ + alias Aprsme.Cluster.LeaderElection + alias AprsmeWeb.MapLive.PacketStore + require Logger @pubsub_topic "cluster:packets" @@ -12,7 +15,7 @@ defmodule Aprsme.Cluster.PacketDistributor do # Only distribute if clustering is enabled and we're the leader cluster_enabled = Application.get_env(:aprsme, :cluster_enabled, false) - if cluster_enabled and Aprsme.Cluster.LeaderElection.leader?() do + if cluster_enabled and LeaderElection.leader?() do # Broadcast to all nodes including self Phoenix.PubSub.broadcast( Aprsme.PubSub, @@ -33,7 +36,7 @@ defmodule Aprsme.Cluster.PacketDistributor do Aprsme.StreamingPacketsPubSub.broadcast_packet(packet) # Update packet store for LiveView - AprsmeWeb.MapLive.PacketStore.store_packet(packet) + PacketStore.store_packet(packet) Logger.debug("Received distributed packet on node #{node()}") end diff --git a/lib/aprsme/cluster/packet_receiver.ex b/lib/aprsme/cluster/packet_receiver.ex index e173402..c45da4f 100644 --- a/lib/aprsme/cluster/packet_receiver.ex +++ b/lib/aprsme/cluster/packet_receiver.ex @@ -6,6 +6,7 @@ defmodule Aprsme.Cluster.PacketReceiver do """ use GenServer + alias Aprsme.Cluster.LeaderElection alias Aprsme.Cluster.PacketDistributor require Logger @@ -27,7 +28,7 @@ defmodule Aprsme.Cluster.PacketReceiver do @impl true def handle_info({:distributed_packet, packet}, state) do # Only process if we're not the leader (leader already processed locally) - if !Aprsme.Cluster.LeaderElection.leader?() do + if !LeaderElection.leader?() do PacketDistributor.handle_distributed_packet({:distributed_packet, packet}) end diff --git a/lib/aprsme/packet_consumer.ex b/lib/aprsme/packet_consumer.ex index 56ee3c6..6836e2f 100644 --- a/lib/aprsme/packet_consumer.ex +++ b/lib/aprsme/packet_consumer.ex @@ -6,6 +6,7 @@ defmodule Aprsme.PacketConsumer do use GenStage alias Aprs.Types.ParseError + alias Aprsme.Cluster.PacketDistributor alias Aprsme.LogSanitizer alias Aprsme.Repo @@ -346,7 +347,7 @@ defmodule Aprsme.PacketConsumer do if cluster_enabled do # Use cluster distributor to broadcast to all nodes - Aprsme.Cluster.PacketDistributor.distribute_packet(packet) + PacketDistributor.distribute_packet(packet) else # Normal single-node broadcasting Aprsme.StreamingPacketsPubSub.broadcast_packet(packet) diff --git a/lib/aprsme/release.ex b/lib/aprsme/release.ex index 93b5429..8b90bde 100644 --- a/lib/aprsme/release.ex +++ b/lib/aprsme/release.ex @@ -3,6 +3,8 @@ defmodule Aprsme.Release do Used for executing DB release tasks when run in production without Mix installed. """ + alias Ecto.Adapters.SQL + @app :aprsme def migrate do @@ -156,7 +158,9 @@ defmodule Aprsme.Release do Aprsme.Repo, fn repo -> # Set session-level timeout for this connection - Ecto.Adapters.SQL.query!(repo, "SET statement_timeout = '#{div(timeout, 1000)}s'") + # credo:disable-for-next-line + # sobelow_skip ["SQL.Query"] + SQL.query!(repo, "SET statement_timeout = '#{div(timeout, 1000)}s'") Ecto.Migrator.run(repo, :up, all: true) end, timeout: timeout diff --git a/lib/aprsme_web/live/status_live/index.ex b/lib/aprsme_web/live/status_live/index.ex index 74cf192..185bdec 100644 --- a/lib/aprsme_web/live/status_live/index.ex +++ b/lib/aprsme_web/live/status_live/index.ex @@ -4,6 +4,8 @@ defmodule AprsmeWeb.StatusLive.Index do """ use AprsmeWeb, :live_view + alias Aprsme.Cluster.LeaderElection + require Logger # 5 seconds - reduced from 1 second to improve performance @@ -383,7 +385,7 @@ defmodule AprsmeWeb.StatusLive.Index do # Private functions defp get_aprs_status do - Aprsme.Cluster.LeaderElection.get_cluster_aprs_status() + LeaderElection.get_cluster_aprs_status() rescue error -> require Logger diff --git a/lib/aprsme_web/plugs/health_check.ex b/lib/aprsme_web/plugs/health_check.ex index 8d588f8..b8c120a 100644 --- a/lib/aprsme_web/plugs/health_check.ex +++ b/lib/aprsme_web/plugs/health_check.ex @@ -6,6 +6,8 @@ defmodule AprsmeWeb.Plugs.HealthCheck do import Plug.Conn + alias Ecto.Adapters.SQL + require Logger def init(opts), do: opts @@ -75,7 +77,7 @@ defmodule AprsmeWeb.Plugs.HealthCheck do end defp check_database_connection do - case Ecto.Adapters.SQL.query(Aprsme.Repo, "SELECT 1", [], timeout: 1000) do + case SQL.query(Aprsme.Repo, "SELECT 1", [], timeout: 1000) do {:ok, _} -> :ok _ -> {:error, "Database connection failed"} end