Fix credo: extract PagerDuty HMAC verification to reduce nesting
This commit is contained in:
parent
2709ab4674
commit
8f04a3f684
1 changed files with 28 additions and 25 deletions
|
|
@ -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" ->
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue