Fix credo: extract PagerDuty HMAC verification to reduce nesting

This commit is contained in:
Graham McIntire 2026-02-14 16:31:54 -06:00
parent 2709ab4674
commit 8f04a3f684

View file

@ -52,36 +52,39 @@ defmodule ToweropsWeb.Api.V1.PagerdutyWebhookController do
webhook_secret = get_in(integration.credentials, ["webhook_secret"])
if is_nil(webhook_secret) or webhook_secret == "" do
# No webhook secret configured — accept without verification
# (user hasn't set up the V3 webhook extension yet)
:ok
else
signatures =
conn
|> Plug.Conn.get_req_header("x-pagerduty-signature")
|> Enum.flat_map(&String.split(&1, ","))
|> Enum.map(&String.trim/1)
expected =
:hmac
|> :crypto.mac(:sha256, webhook_secret, raw_body)
|> Base.encode16(case: :lower)
if Enum.any?(signatures, fn sig ->
case sig do
"v1=" <> hex -> Plug.Crypto.secure_compare(hex, expected)
_ -> false
end
end) do
:ok
else
Logger.warning("PagerDuty webhook signature mismatch for org #{integration.organization_id}")
{:error, :invalid_signature}
end
check_pagerduty_hmac(conn, raw_body, webhook_secret, integration.organization_id)
end
end
defp check_pagerduty_hmac(conn, raw_body, secret, org_id) do
signatures =
conn
|> Plug.Conn.get_req_header("x-pagerduty-signature")
|> Enum.flat_map(&String.split(&1, ","))
|> Enum.map(&String.trim/1)
expected =
:hmac
|> :crypto.mac(:sha256, secret, raw_body)
|> Base.encode16(case: :lower)
if signature_matches?(signatures, expected) do
:ok
else
Logger.warning("PagerDuty webhook signature mismatch for org #{org_id}")
{:error, :invalid_signature}
end
end
defp signature_matches?(signatures, expected) do
Enum.any?(signatures, fn
"v1=" <> hex -> Plug.Crypto.secure_compare(hex, expected)
_ -> false
end)
end
defp process_webhook(%{"event" => %{"event_type" => event_type, "data" => data}}, organization_id) do
case event_type do
"incident.resolved" ->