Module: Codebot::WebListener

Defined in:
lib/codebot/web_listener.rb

Overview

This module provides methods for processing incoming webhooks and dispatching them to the IRC client.

Instance Method Summary collapse

Instance Method Details

#create_github_event(request) ⇒ Object



58
59
60
61
62
63
# File 'lib/codebot/web_listener.rb', line 58

def create_github_event(request)
  event = request.env['HTTP_X_GITHUB_EVENT']
  return [400, 'Missing event header'] if event.nil? || event.empty?

  Event.symbolize(event)
end

#create_gitlab_event(request) ⇒ Object



51
52
53
54
55
56
# File 'lib/codebot/web_listener.rb', line 51

def create_gitlab_event(request)
  event = request.env['HTTP_X_GITLAB_EVENT']
  return [400, 'Missing event header'] if event.nil? || event.empty?

  Event.symbolize("Gitlab #{event}".tr(' ', '_'))
end

#create_request(integration, request, payload) ⇒ Request, Array<Integer, String>

Creates a new request for the webhook.



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/codebot/web_listener.rb', line 75

def create_request(integration, request, payload)
  event = if integration.gitlab
            create_gitlab_event(request)
          else
            create_github_event(request)
          end
  return event if event.is_a? Array

  return [501, 'Event not yet supported'] if event.nil?

  Request.new(integration, event, payload)
end

#dispatch(core, request, endpoint, payload) ⇒ Array<Integer, String>

Dispatches a received payload to the IRC client.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/codebot/web_listener.rb', line 39

def dispatch(core, request, endpoint, payload)
  intg = integration_for(core.config, endpoint)
  return [404, 'Endpoint not registered'] if intg.nil?
  return [403, 'Invalid signature'] unless valid?(request, intg, payload)

  req = create_request(intg, request, payload)
  return req if req.is_a? Array

  core.irc_client.dispatch(req)
  [202, 'Accepted']
end

#handle_post(core, request, params) ⇒ Object

Handles a POST request.



17
18
19
20
21
22
# File 'lib/codebot/web_listener.rb', line 17

def handle_post(core, request, params)
  payload = params['payload'] || request.body.read
  dispatch(core, request, *params['splat'], payload)
rescue JSON::ParserError
  [400, 'Invalid JSON payload']
end

#integration_for(config, endpoint) ⇒ Object

Finds the integration associated with an endpoint.



28
29
30
# File 'lib/codebot/web_listener.rb', line 28

def integration_for(config, endpoint)
  IntegrationManager.new(config).find_integration_by_endpoint(endpoint)
end

#valid?(request, integration, payload) ⇒ Boolean

Verifies a webhook signature.



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/codebot/web_listener.rb', line 95

def valid?(request, integration, payload)
  return true unless integration.verify_payloads?

  secret = integration.secret
  if integration.gitlab
    secret == request.env['HTTP_X_GITLAB_TOKEN']
  else
    request_signature = request.env['HTTP_X_HUB_SIGNATURE']
    Cryptography.valid_signature?(payload, secret, request_signature)
  end
end