Skip to content

Instantly share code, notes, and snippets.

@boopathi
Last active August 29, 2015 14:05
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 boopathi/69bca106b543d4097778 to your computer and use it in GitHub Desktop.
Save boopathi/69bca106b543d4097778 to your computer and use it in GitHub Desktop.
Github webhook deploy php
<?php
class Deploy {
//
// EDIT ME
// This will be sent as the User Agent to the Meta API. Set this as
// your GITHUB_USERNAME or APPLICATION_NAME
// Documentation: https://developer.github.com/v3/#user-agent-required
//
private $user_agent_string = "Deploy-PHP-Application";
// -----------------------------------------------------------------------
// ---------------------- DO NOT EDIT BELOW THIS -------------------------
// -----------------------------------------------------------------------
// flags - should be set on construct
private $clientIP;
private $is_github;
public $output;
// Meta API url
private $github_meta_api = "https://api.github.com/meta";
// commands
private $fuck_off_commands = array(
'echo "Fuck You"'
);
private $do_deploy_commands = array(
'echo $PWD',
'whoami',
"git pull origin master",
'git status'
);
public function __construct() {
$this->set_client_ip();
$this->is_github = $this->github_check();
// If the request is from Github
if($this->is_github) {
// then Continue Deployment Procedure
$this->output = $this->do_exec($this->do_deploy_commands);
} else {
// else just ask the user to fuck off
$this->output = $this->do_exec($this->fuck_off_commands);
}
}
private function do_exec($commands) {
$output = '';
if(!$this->is_github) {
$output .= <<<HTML
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>GITHUB WEBHOOK DEPLOYMENT SCRIPT</title>
</head>
<body style="background-color: #000000; color: #FFFFFF; font-weight: bold; padding: 0 10px;">
<pre>
HTML;
}
foreach($commands as $c) {
$tmp = shell_exec($c);
if(!$this->is_github) {
$output .= "<span style=\"color: #6BE234;\">\$</span> <span style=\"color: #729FCF;\">{$c}\n</span>";
} else {
$output .= "\$ {$c}\n";
}
$output .= htmlentities(trim($tmp)) . "\n";
}
if(!$this->is_github) {
$output .= <<<HTML
</pre>
</body>
</html>
HTML;
}
return $output;
}
// A wrapper that works on all cases to get the Actual client IP
private function set_client_ip() {
$client = '';
if(array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
$client = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else if(array_key_exists('REMOTE_ADDR', $_SERVER)) {
$client = $_SERVER['REMOTE_ADDR'];
} else if(array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
$client = $_SERVER['HTTP_CLIENT_IP'];
}
$this->clientIP = $client;
}
// Check if the requesting client is Github
private function github_check() {
$ch = curl_init($this->github_meta_api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"User-Agent: {$this->user_agent_string}"
));
$data = curl_exec($ch);
$json = json_decode($data, true);
curl_close($ch);
foreach($json["hooks"] as $cidr) {
if($this->cidr_match($this->clientIP, $cidr)) {
return true;
}
}
return false;
}
private function cidr_match($ip, $range) {
list ($subnet, $bits) = explode('/', $range);
$ip = ip2long($ip);
$subnet = ip2long($subnet);
$mask = -1 << (32 - $bits);
$subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned
return ($ip & $mask) == $subnet;
}
};
$d = new Deploy();
echo $d->output;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment