Class: Axn::Webhooks::Verify
- Inherits:
-
Object
- Object
- Axn::Webhooks::Verify
- Includes:
- Axn, VendorFacet
- Defined in:
- lib/axn/webhooks/verify.rb
Overview
The verify stage, as an Axn. A signature mismatch is a quiet failure (fail! →
401 later, no on_exception page); a verifier that raises is a loud exception
(reported to Axn.config.on_exception). The first two rows of the staged-outcome model.
Constant Summary collapse
- MESSAGES =
Why the request was rejected, keyed by Signature::REASONS. The HTTP response is a bare 401 in every case — this exists so the two causes are separable in logs and metrics (PRO-3141: a replay-window miss and an HMAC mismatch were byte-identical in the logs, and the replay case reported "signature mismatch" for a request whose signature was valid).
{ replay_window: ->(check) { "replay window exceeded (timestamp skew #{check.skew}s)" }, replay_timestamp_invalid: ->(_check) { "replay timestamp missing or unparseable" }, signature_missing: ->(_check) { "signature missing" }, signature_mismatch: ->(_check) { "signature mismatch" }, # A genuine anomaly, and worth alerting on: the client presented an `Authorization` header, # so it meant to authenticate, but not a Basic one. The bare handshake leg — which used to # land here, once per *successful* webhook, making this the highest-volume value of the # dimension — is answered with the challenge before Verify runs at all now (PRO-3148), so # the message names what is actually left rather than the leg it no longer reports. credentials_missing: lambda { |_check| "no Basic credentials offered — a non-Basic Authorization scheme (the bare handshake leg " \ "is challenged before Verify)" }, credentials_mismatch: ->(_check) { "Basic credentials rejected" }, }.freeze
Instance Method Summary collapse
Methods included from VendorFacet
Instance Method Details
#call ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/axn/webhooks/verify.rb', line 60 def call check = verifier.call(request) return if verified?(check) # Set before fail! so the result-phase dimension resolvers can read them. rejection = check.is_a?(Signature::Check) ? check : Signature::MISMATCH @reason = rejection.reason @skew = rejection.skew @suggested_unit = rejection.suggested_unit fail!((rejection), reason: @reason, skew: @skew, suggested_unit: @suggested_unit) end |