Skip to content

Instantly share code, notes, and snippets.

@johnagan
Last active February 14, 2016 04:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnagan/4911d6ce079ea882199f to your computer and use it in GitHub Desktop.
Save johnagan/4911d6ce079ea882199f to your computer and use it in GitHub Desktop.
require 'net/http'
require 'sinatra'
require 'json'
require 'uri'
CONTEXT = "spoof check"
GITHUB_ROOT = "https://api.github.com"
HEADERS = {
'Content-Type' => 'text/json',
'Authorization' => "token #{ENV['GITHUB_TOKEN']}"
}
# Update the Status API
def update_status(payload, status)
sha = payload.after
repo = payload.repository.full_name
state, description = status.first
# setup http post
uri = URI.parse("#{GITHUB_ROOT}/repos/#{repo}/statuses/#{sha}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
# post to GitHub
params = {:state => state, :description => description, :context => CONTEXT}
http.post(uri.path, params.to_json, HEADERS)
end
# validate all commits are from the pusher
def validate(payload)
# read all committer emails
committers = payload.commits.map{ |c| c.author.email }.uniq
# validate all commits are from the pusher
if committers.count > 1
{:failure => "Includes commits from #{committers.count} committers"}
elsif !committers.include?(payload.pusher.email)
{:failure => "Committer doesn't match pusher"}
else
{:success => "All commits match pusher"}
end
end
# Respond to WebHook Event
post '/payload' do
payload = JSON.parse(request.body.read, object_class: OpenStruct)
# update status to pending until completed
update_status(payload, :pending => "validating commits")
# update GitHub
update_status(payload, validate(payload))
end

Validate A GitHub Pusher

Create a Webhook and watch for the Push Event. This event is triggered when you push from the command-line or commit a change through the Web UI.

The JSON Payload will contain the Git Author and the Git Commiter for each files modified. These values come from the .gitconfig on the user's computer.

The payload also contains the Pusher's Info who is the authenticated GitHub user that has pushed up the code.

To prevent merges until identity checks are passed, enable Protected Branches and Required Status Checks, then have your CI server run checks against the JSON payload delivered from the Webhook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment