Skip to content

Commit 46002ee

Browse files
chore: formatting cleanup and plugin integration wiring
Apply formatter fixes across the codebase, add service_plugins association, and wire plugin system into bundle compilation and KDL generation.
1 parent c9a46d8 commit 46002ee

116 files changed

Lines changed: 1988 additions & 638 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

config/config.exs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ config :sentinel_cp, :github_webhook,
9292
default_branch: "main"
9393

9494
# ACME / Let's Encrypt configuration
95-
config :sentinel_cp, :acme,
96-
directory_url: "https://acme-v02.api.letsencrypt.org/directory"
95+
config :sentinel_cp, :acme, directory_url: "https://acme-v02.api.letsencrypt.org/directory"
9796

9897
# Import environment specific config. This must remain at the bottom
9998
# of this file so it overrides the configuration defined above.

config/test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ config :phoenix_live_view,
4242
config :phoenix,
4343
sort_verified_routes_query_params: true
4444

45+
# Bundle storage (local filesystem in test)
46+
config :sentinel_cp, SentinelCp.Bundles.Storage,
47+
backend: :local,
48+
local_dir: Path.expand("../tmp/test_bundles", __DIR__)
49+
4550
# Bundle signing disabled in test (individual tests can override)
4651
config :sentinel_cp, :bundle_signing, enabled: false
4752

lib/mix/tasks/sentinel/config/apply.ex

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ defmodule Mix.Tasks.Sentinel.Config.Apply do
3535
apply_config(slug, file, opts)
3636

3737
_ ->
38-
Mix.shell().error("Usage: mix sentinel.config.apply <project_slug> <file> [--dry-run] [--yes]")
38+
Mix.shell().error(
39+
"Usage: mix sentinel.config.apply <project_slug> <file> [--dry-run] [--yes]"
40+
)
41+
3942
exit({:shutdown, 1})
4043
end
4144
end
@@ -123,15 +126,19 @@ defmodule Mix.Tasks.Sentinel.Config.Apply do
123126
cond do
124127
String.ends_with?(path, [".yml", ".yaml"]) ->
125128
case YamlElixir.read_from_string(content) do
126-
{:ok, parsed} -> parsed
129+
{:ok, parsed} ->
130+
parsed
131+
127132
{:error, reason} ->
128133
Mix.shell().error("Failed to parse YAML: #{inspect(reason)}")
129134
exit({:shutdown, 1})
130135
end
131136

132137
String.ends_with?(path, ".json") ->
133138
case Jason.decode(content) do
134-
{:ok, parsed} -> parsed
139+
{:ok, parsed} ->
140+
parsed
141+
135142
{:error, reason} ->
136143
Mix.shell().error("Failed to parse JSON: #{inspect(reason)}")
137144
exit({:shutdown, 1})
@@ -145,7 +152,9 @@ defmodule Mix.Tasks.Sentinel.Config.Apply do
145152

146153
{:error, _} ->
147154
case Jason.decode(content) do
148-
{:ok, parsed} -> parsed
155+
{:ok, parsed} ->
156+
parsed
157+
149158
{:error, _} ->
150159
Mix.shell().error("Unable to parse file as YAML or JSON: #{path}")
151160
exit({:shutdown, 1})

lib/mix/tasks/sentinel/config/diff.ex

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,19 @@ defmodule Mix.Tasks.Sentinel.Config.Diff do
8787
cond do
8888
String.ends_with?(path, [".yml", ".yaml"]) ->
8989
case YamlElixir.read_from_string(content) do
90-
{:ok, parsed} -> parsed
90+
{:ok, parsed} ->
91+
parsed
92+
9193
{:error, reason} ->
9294
Mix.shell().error("Failed to parse YAML: #{inspect(reason)}")
9395
exit({:shutdown, 1})
9496
end
9597

9698
String.ends_with?(path, ".json") ->
9799
case Jason.decode(content) do
98-
{:ok, parsed} -> parsed
100+
{:ok, parsed} ->
101+
parsed
102+
99103
{:error, reason} ->
100104
Mix.shell().error("Failed to parse JSON: #{inspect(reason)}")
101105
exit({:shutdown, 1})
@@ -108,7 +112,9 @@ defmodule Mix.Tasks.Sentinel.Config.Diff do
108112

109113
{:error, _} ->
110114
case Jason.decode(content) do
111-
{:ok, parsed} -> parsed
115+
{:ok, parsed} ->
116+
parsed
117+
112118
{:error, _} ->
113119
Mix.shell().error("Unable to parse file as YAML or JSON: #{path}")
114120
exit({:shutdown, 1})

lib/mix/tasks/sentinel/config/export.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ defmodule Mix.Tasks.Sentinel.Config.Export do
3535
export(slug, opts)
3636

3737
_ ->
38-
Mix.shell().error("Usage: mix sentinel.config.export <project_slug> [--format yaml|json] [--output file]")
38+
Mix.shell().error(
39+
"Usage: mix sentinel.config.export <project_slug> [--format yaml|json] [--output file]"
40+
)
41+
3942
exit({:shutdown, 1})
4043
end
4144
end

lib/sentinel_cp/analytics/waf_anomaly_detector.ex

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ defmodule SentinelCp.Analytics.WafAnomalyDetector do
2525
anomalies =
2626
Enum.flat_map(observations, fn {metric_type, observed} ->
2727
case Map.get(baselines, metric_type) do
28-
%{mean: mean, stddev: stddev} when is_number(mean) and is_number(stddev) and stddev > 0 ->
28+
%{mean: mean, stddev: stddev}
29+
when is_number(mean) and is_number(stddev) and stddev > 0 ->
2930
detect_spike(metric_type, observed, mean, stddev, sigma_threshold)
3031

3132
_ ->
@@ -39,7 +40,13 @@ defmodule SentinelCp.Analytics.WafAnomalyDetector do
3940
@doc """
4041
Detects spike anomalies where the observed value exceeds mean + threshold * stddev.
4142
"""
42-
def detect_spike(metric_type, observed, mean, stddev, sigma_threshold \\ @default_sigma_threshold) do
43+
def detect_spike(
44+
metric_type,
45+
observed,
46+
mean,
47+
stddev,
48+
sigma_threshold \\ @default_sigma_threshold
49+
) do
4350
deviation = (observed - mean) / stddev
4451

4552
if deviation > sigma_threshold do
@@ -49,7 +56,8 @@ defmodule SentinelCp.Analytics.WafAnomalyDetector do
4956
%{
5057
anomaly_type: "spike",
5158
severity: severity,
52-
description: "#{metric_type} spike: #{Float.round(observed * 1.0, 1)} observed vs #{Float.round(mean, 1)} expected (#{Float.round(deviation, 1)} sigma)",
59+
description:
60+
"#{metric_type} spike: #{Float.round(observed * 1.0, 1)} observed vs #{Float.round(mean, 1)} expected (#{Float.round(deviation, 1)} sigma)",
5361
observed_value: observed * 1.0,
5462
expected_mean: mean,
5563
expected_stddev: stddev,
@@ -85,7 +93,12 @@ defmodule SentinelCp.Analytics.WafAnomalyDetector do
8593
@doc """
8694
Detects IP burst anomalies (unusual number of unique attacking IPs).
8795
"""
88-
def detect_ip_burst(unique_ips, baseline_mean, baseline_stddev, sigma_threshold \\ @default_sigma_threshold) do
96+
def detect_ip_burst(
97+
unique_ips,
98+
baseline_mean,
99+
baseline_stddev,
100+
sigma_threshold \\ @default_sigma_threshold
101+
) do
89102
if baseline_stddev > 0 do
90103
detect_spike("unique_ips", unique_ips, baseline_mean, baseline_stddev, sigma_threshold)
91104
|> Enum.map(&Map.put(&1, :anomaly_type, "ip_burst"))
@@ -97,7 +110,12 @@ defmodule SentinelCp.Analytics.WafAnomalyDetector do
97110
@doc """
98111
Detects rate change anomalies (sudden increase in block rate).
99112
"""
100-
def detect_rate_change(current_rate, baseline_mean, baseline_stddev, sigma_threshold \\ @default_sigma_threshold) do
113+
def detect_rate_change(
114+
current_rate,
115+
baseline_mean,
116+
baseline_stddev,
117+
sigma_threshold \\ @default_sigma_threshold
118+
) do
101119
if baseline_stddev > 0 do
102120
detect_spike("block_rate", current_rate, baseline_mean, baseline_stddev, sigma_threshold)
103121
|> Enum.map(&Map.put(&1, :anomaly_type, "rate_change"))

lib/sentinel_cp/analytics/waf_anomaly_worker.ex

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ defmodule SentinelCp.Analytics.WafAnomalyWorker do
3838
end)
3939

4040
if total_anomalies > 0 do
41-
Logger.info("WafAnomalyWorker: detected #{total_anomalies} anomalies across #{length(project_ids)} projects")
41+
Logger.info(
42+
"WafAnomalyWorker: detected #{total_anomalies} anomalies across #{length(project_ids)} projects"
43+
)
4244
end
4345

4446
schedule_next()
@@ -80,12 +82,17 @@ defmodule SentinelCp.Analytics.WafAnomalyWorker do
8082

8183
case Analytics.create_waf_anomaly(attrs) do
8284
{:ok, anomaly} ->
83-
SentinelCp.Events.emit("security.waf_anomaly", %{
84-
anomaly_id: anomaly.id,
85-
anomaly_type: anomaly.anomaly_type,
86-
severity: anomaly.severity,
87-
description: anomaly.description
88-
}, project_id: project_id)
85+
SentinelCp.Events.emit(
86+
"security.waf_anomaly",
87+
%{
88+
anomaly_id: anomaly.id,
89+
anomaly_type: anomaly.anomaly_type,
90+
severity: anomaly.severity,
91+
description: anomaly.description
92+
},
93+
project_id: project_id
94+
)
95+
8996
true
9097

9198
{:error, _} ->

lib/sentinel_cp/audit/audit_checkpoint.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ defmodule SentinelCp.Audit.AuditCheckpoint do
3131
:entries_count,
3232
:project_id
3333
])
34-
|> validate_required([:sequence_number, :last_entry_hash, :digest, :signature, :entries_count])
34+
|> validate_required([
35+
:sequence_number,
36+
:last_entry_hash,
37+
:digest,
38+
:signature,
39+
:entries_count
40+
])
3541
|> validate_number(:sequence_number, greater_than: 0)
3642
|> validate_number(:entries_count, greater_than_or_equal_to: 0)
3743
end

lib/sentinel_cp/audit/compliance_export.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ defmodule SentinelCp.Audit.ComplianceExport do
137137
end
138138

139139
defp encode_metadata(nil), do: ""
140+
140141
defp encode_metadata(metadata) when is_map(metadata) do
141142
metadata
142143
|> Enum.map(fn {k, v} -> "#{k}=#{inspect(v)}" end)

lib/sentinel_cp/bundles/compile_worker.ex

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defmodule SentinelCp.Bundles.CompileWorker do
1111

1212
alias SentinelCp.Bundles
1313
alias SentinelCp.Bundles.{Compiler, Risk, Signing, Storage}
14-
alias SentinelCp.{Audit, Services}
14+
alias SentinelCp.{Audit, Plugins, Services}
1515

1616
@impl Oban.Worker
1717
def perform(%Oban.Job{args: %{"bundle_id" => bundle_id}}) do
@@ -110,15 +110,20 @@ defmodule SentinelCp.Bundles.CompileWorker do
110110
end
111111

112112
defp build_extra_files(project_id) do
113-
case Services.get_internal_ca(project_id) do
114-
nil ->
115-
[]
116-
117-
ca ->
118-
[
119-
{"internal-ca/ca.pem", ca.ca_cert_pem},
120-
{"internal-ca/crl.pem", ca.crl_pem || ""}
121-
]
122-
end
113+
ca_files =
114+
case Services.get_internal_ca(project_id) do
115+
nil ->
116+
[]
117+
118+
ca ->
119+
[
120+
{"internal-ca/ca.pem", ca.ca_cert_pem},
121+
{"internal-ca/crl.pem", ca.crl_pem || ""}
122+
]
123+
end
124+
125+
plugin_files = Plugins.collect_plugin_files(project_id)
126+
127+
ca_files ++ plugin_files
123128
end
124129
end

0 commit comments

Comments
 (0)