Class: BugReportsClient::WebhooksController

Inherits:
ActionController::Base
  • Object
show all
Defined in:
app/controllers/bug_reports_client/webhooks_controller.rb

Overview

Receives closure notifications from the bug-reports API when a report's GitHub issue is closed. Deliberately inherits from ActionController::Base (not the host's ApplicationController) so no host auth chain or callbacks interfere with machine-to-machine requests. Payloads are verified with a per-app HMAC-SHA256 signature before anything is touched; when the sender includes a signed timestamp, stale (replayed) callbacks are rejected too.

Defined Under Namespace

Classes: SignatureError

Constant Summary collapse

MAX_BODY_BYTES =

Callback payloads are small JSON documents - anything bigger is bogus.

1_048_576
TIMESTAMP_TOLERANCE =

How old a timestamped callback may be before it is treated as a replay.

5 * 60

Instance Method Summary collapse

Instance Method Details

#receiveObject

POST /webhook



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'app/controllers/bug_reports_client/webhooks_controller.rb', line 20

def receive
  return head :content_too_large if request.content_length.to_i > MAX_BODY_BYTES

  raw_body = request.raw_post
  verify_signature!(raw_body)

  payload = JSON.parse(raw_body)
  Rails.logger.info "BugReportsClient: report closed: ##{payload['bug_report_id']} - #{payload['title']}"

  # Mark the local record closed so the reporter sees the resolved alert.
  # A bare column write, not update!: legacy reports (or ones predating a
  # form-schema change that added required fields) must still be closable.
  local_report = BugReport.find_by(remote_bug_report_id: payload["bug_report_id"])
  if local_report
    local_report.update_columns(status: "closed", updated_at: Time.current)
  else
    Rails.logger.warn "BugReportsClient: no local report for remote ID #{payload['bug_report_id']}"
  end

  head :ok
rescue SignatureError
  head :unauthorized
rescue JSON::ParserError => e
  Rails.logger.error "BugReportsClient: webhook parse error: #{e.message}"
  head :unprocessable_entity
end