mirror of
https://github.com/discourse/discourse.git
synced 2024-12-05 08:03:40 +08:00
68b4fe4cf8
See https://github.com/discourse/discourse/security/advisories/GHSA-rcc5-28r3-23rr Co-authored-by: OsamaSayegh <asooomaasoooma90@gmail.com> Co-authored-by: Daniel Waterworth <me@danielwaterworth.com>
58 lines
1.6 KiB
Ruby
58 lines
1.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class WebHookEmitter
|
|
REQUEST_TIMEOUT = 20
|
|
|
|
def initialize(webhook, webhook_event)
|
|
@webhook = webhook
|
|
@webhook_event = webhook_event
|
|
end
|
|
|
|
def emit!(headers:, body:)
|
|
uri = URI(@webhook.payload_url.strip)
|
|
|
|
connection_opts = {
|
|
request: {
|
|
write_timeout: REQUEST_TIMEOUT,
|
|
read_timeout: REQUEST_TIMEOUT,
|
|
open_timeout: REQUEST_TIMEOUT
|
|
},
|
|
}
|
|
|
|
if !@webhook.verify_certificate
|
|
connection_opts[:ssl] = { verify: false }
|
|
end
|
|
|
|
conn = Faraday.new(nil, connection_opts) do |f|
|
|
f.adapter FinalDestination::FaradayAdapter
|
|
end
|
|
|
|
start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
|
|
error = nil
|
|
response = nil
|
|
begin
|
|
response = conn.post(uri.to_s, body, headers)
|
|
rescue => e
|
|
error = e
|
|
end
|
|
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) - start
|
|
event_update_args = {
|
|
headers: MultiJson.dump(headers),
|
|
duration: duration,
|
|
}
|
|
if response
|
|
event_update_args[:response_headers] = MultiJson.dump(response.headers)
|
|
event_update_args[:response_body] = response.body
|
|
event_update_args[:status] = response.status
|
|
else
|
|
event_update_args[:status] = -1
|
|
if error.is_a?(Faraday::Error) && error.wrapped_exception.is_a?(FinalDestination::SSRFDetector::DisallowedIpError)
|
|
error = I18n.t("webhooks.payload_url.blocked_or_internal")
|
|
end
|
|
event_update_args[:response_headers] = MultiJson.dump(error: error)
|
|
end
|
|
@webhook_event.update!(**event_update_args)
|
|
response
|
|
end
|
|
end
|