lib/tutter.rb in tutter-0.0.5 vs lib/tutter.rb in tutter-0.0.6
- old
+ new
@@ -1,16 +1,18 @@
-require 'rubygems'
+require 'json'
require 'octokit'
-require 'yaml'
require 'sinatra'
+require 'thin'
require 'tutter/action'
-require 'json'
+require 'yaml'
+# Modular sinatra app Tutter
class Tutter < Sinatra::Base
+ enable :logging
configure do
- set :config_path, ENV['TUTTER_CONFIG_PATH'] || "conf/tutter.yaml"
+ set :config_path, ENV['TUTTER_CONFIG_PATH'] || 'conf/tutter.yaml'
set :config, YAML.load_file(settings.config_path)
end
configure :development do
require 'sinatra/reloader'
@@ -20,80 +22,93 @@
configure :test do
set :bind, '0.0.0.0'
end
+ def verify_signature(payload_body, secret_token)
+ signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret_token, payload_body)
+ return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE'])
+ end
+
# Return project settings from config
- def get_project_settings project
+ def project_settings(project)
settings.config['projects'].each do |p|
return p if p['name'] == project
end
- false
+ error(404, 'Project does not exist in tutter.conf')
end
- def try_action event, data
- project = data['repository']['full_name'] || error(400, 'Bad request')
+ # Return actions for event from config
+ def actions_for_event(event, config)
+ config['actions'][event] || error(404,
+ "No Actions for #{event} in tutter.conf"
+ )
+ end
- conf = get_project_settings(project) || error(404, 'Project does not exist in tutter.conf')
-
- # Setup octokit endpoints
+ def octokit_client(config)
Octokit.configure do |c|
- c.api_endpoint = conf['github_api_endpoint']
- c.web_endpoint = conf['github_site']
+ c.api_endpoint = config['github_api_endpoint']
+ c.web_endpoint = config['github_site']
+ c.auto_paginate = config['github_api_auto_paginate'] or false
end
- if conf['access_token_env_var']
- access_token = ENV[conf['access_token_env_var']] || ''
+ if config['access_token_env_var']
+ access_token = ENV[config['access_token_env_var']] || ''
else
- access_token = conf['access_token'] || ''
+ access_token = config['access_token'] || ''
end
- client = Octokit::Client.new :access_token => access_token
+ Octokit::Client.new access_token: access_token
+ end
- # Load action
- action = Action.create(conf['action'],
- conf['action_settings'],
- client,
- project,
- event,
- data)
+ def prepare_actions(project, event, data, config)
+ client = octokit_client(config)
+ actions_for_event(event, config).each do |a|
+ yield Action.create(a,
+ config['action_settings'],
+ client,
+ project,
+ event,
+ data), a
+ end
+ end
- status_code, message = action.run
-
- return status_code, message
+ def try_actions(event, data, project, config)
+ responses = { event: event, responses: {} }
+ prepare_actions(project, event, data, config) do |action, name|
+ status_code, message = action.run
+ responses[:responses][name] = { status_code: status_code,
+ message: message
+ }
+ break if status_code != 200
+ end
+ [responses[:responses].values.last[:status_code], responses.to_json]
end
post '/' do
- event = env['HTTP_X_GITHUB_EVENT']
+ event = env['HTTP_X_GITHUB_EVENT'] || error(500, 'Invalid request')
- unless event
- error(500, "Invalid request")
- end
-
# Get a 200 OK message in the Github webhook history
# Previously this showed an error.
- if event == "ping"
- return 200, "Tutter likes this hook!"
- end
+ return 200, 'Tutter likes this hook!' if event == 'ping'
# Github send data in JSON format, parse it!
+ request_body = request.body.read
begin
- data = JSON.parse request.body.read
+ data = JSON.parse request_body
rescue JSON::ParserError
error(400, 'POST data is not JSON')
end
- # Check actions with repo
+ project = data['repository']['full_name'] || error(400, 'Bad request')
+ config = project_settings(project)
+ verify_signature(request_body, config['hook_secret']) if config['hook_secret']
- if data['repository']
- return try_action(event, data)
- end
-
- error(400, "Unsupported request: #{event}")
+ return try_actions(event, data, project, config) if data['repository']
end
get '/' do
'Source code and documentation at https://github.com/jhaals/tutter'
end
- run! if app_file == $0
+ run! if app_file == $PROGRAM_NAME
end