xaizek / rocketgit (License: AGPLv3+) (since 2018-12-09)
Light and fast Git hosting solution suitable to serve both as a hub or as a personal code storage with its tickets, pull requests, API and much more.
<root> / tests / wh_http.php (7a25a0a32e0a454cb1a1b4af4a791d1637565a99) (10KiB) (mode 100644) [raw]
<?php
error_reporting(E_ALL | E_STRICT);
ini_set("track_errors", "On");

$test_normal = TRUE;

$INC = dirname(__FILE__) . "/../inc";
require_once(dirname(__FILE__) . "/config.php");
require_once($INC . "/init.inc.php");
require_once($INC . "/user.inc.php");
require_once("helpers.inc.php");
require_once("http.inc.php");

rg_log_set_file("wh_http.log");

require_once("common.php");

$_testns = 'wh_http';


$port1 = 64000 + (rand(0, 100000) + time()) % 1000;
$port2 = $port1 + 1;
$port3 = $port2 + 1;
rg_log('port1=' . $port1 . ' port2=' . $port2 . ' port3=' . $port3);

function clean()
{
	rg_log_set_file("wh_http_clean.log");
	for ($id = 1; $id <= 3; $id++)
		rg_exec('fuser -k -9 wh-stunnel-' . $id . '.log', '', FALSE, FALSE, FALSE);
}

prepare_http();

rg_log('');
rg_log('Generating certificates...');
$r = rg_exec('./ca.sh wh', '', FALSE, FALSE, FALSE);
if (!strstr($r['data'], 'CA_SH_OK')) {
	rg_log_ml('data: ' . $r['data']);
	rg_log('Cannot generate certificates!');
	exit(1);
}


rg_log('');
rg_log('Preparing stunnel conf file...');
$x = file_get_contents('wh-stunnel.conf');
if ($x === FALSE) {
	rg_log('Cannot load conf file');
	exit(1);
}

$y = str_replace('@@port@@', $port1, $x);
$y = str_replace('@@verify@@', '2', $y);
$y = str_replace('@@id@@', '1', $y);
$y = str_replace('@@cwd@@', __DIR__, $y);
file_put_contents('wh-stunnel.conf-1.tmp', $y);

$y = str_replace('@@port@@', $port2, $x);
$y = str_replace('@@verify@@', '2', $y);
$y = str_replace('@@id@@', '2', $y);
$y = str_replace('@@cwd@@', __DIR__, $y);
file_put_contents('wh-stunnel.conf-2.tmp', $y);

$y = str_replace('@@port@@', $port3, $x);
$y = str_replace('@@verify@@', '0', $y);
$y = str_replace('@@id@@', '3', $y);
$y = str_replace('@@cwd@@', __DIR__, $y);
file_put_contents('wh-stunnel.conf-3.tmp', $y);


rg_log('');
rg_log('Starting stunnel1...');
$pid = pcntl_fork();
if ($pid == -1) {
	rg_log('Cannot fork');
	exit(1);
}
if ($pid == 0) { //child
	rg_log_set_file('wh-stunnel-1-rg.log');
	rg_exec('stunnel wh-stunnel.conf-1.tmp 1>wh-stunnel-1-1.log 2>wh-stunnel-1-2.log',
		'', FALSE, FALSE, FALSE);
	exit(0);
}
rg_log('Started stunnel with pid ' . $pid);


rg_log('');
rg_log('Starting stunnel2...');
$pid = pcntl_fork();
if ($pid == -1) {
	rg_log('Cannot fork');
	exit(1);
}
if ($pid == 0) { //child
	rg_log_set_file('wh-stunnel-2-rg.log');
	rg_exec('stunnel wh-stunnel.conf-2.tmp 1>wh-stunnel-2-1.log 2>wh-stunnel-2-2.log',
		'', FALSE, FALSE, FALSE);
	exit(0);
}
rg_log('Started stunnel with pid ' . $pid);


rg_log('');
rg_log('Starting stunnel3...');
$pid = pcntl_fork();
if ($pid == -1) {
	rg_log('Cannot fork');
	exit(1);
}
if ($pid == 0) { //child
	rg_log_set_file('wh-stunnel-3-rg.log');
	rg_exec('stunnel wh-stunnel.conf-3.tmp 1>wh-stunnel-3-1.log 2>wh-stunnel-3-2.log',
		'', FALSE, FALSE, FALSE);
	exit(0);
}
rg_log('Started stunnel with pid ' . $pid);


register_shutdown_function('clean');

rg_log('');
rg_log("Creating a user...");
rg_test_create_user($db, $rg_ui);
$key1 = 'DEBUG::' . $rg_ui['uid'] . '::webhooks::' . $port1;
$key2 = 'DEBUG::' . $rg_ui['uid'] . '::webhooks::' . $port2;
$key3 = 'DEBUG::' . $rg_ui['uid'] . '::webhooks::' . $port3;


rg_log('');
rg_log('Login...');
$r = test_login($test_url, $rg_ui);
if ($r === FALSE) {
	rg_log("Cannot login!");
	exit(1);
}


rg_log('');
rg_log('Registering webhook1...');
$extra = array(
	'wh::htype' => 'http',
	'wh::hsubtype' => 'generic',
	'wh::description' => 'description1 <xss>',
	'wh::repo' => '',
	'wh::refname' => '',
	'wh::idata::url' => 'https://localhost:' . $port1 . '/wh.html',
	'wh::idata::events[C]' => 'on',
	'wh::idata::events[P]' => 'on',
	'wh::idata::events[B]' => 'on',
	'wh::idata::key' => 'key1 <xss>',
	'wh::idata::opaque' => $port1,
	'wh::idata::client_cert' => '',
	'wh::idata::itype' => 0,
	'wh::idata::client_ca_cert' => file_get_contents('ca/wh/certs/cacert.pem')
	);
rg_test_wh_add_edit($db, $rg_ui, 'http', 'generic', $extra);


rg_log('');
rg_log('Registering webhook2...');
$extra = array(
	'wh::htype' => 'http',
	'wh::hsubtype' => 'generic',
	'wh::description' => 'description1 <xss>',
	'wh::repo' => '',
	'wh::refname' => '',
	'wh::idata::url' => 'https://localhost:' . $port2 . '/wh.html',
	'wh::idata::events[C]' => 'on',
	'wh::idata::events[P]' => 'on',
	'wh::idata::events[B]' => 'on',
	'wh::idata::key' => 'key2 <xss>',
	'wh::idata::opaque' => $port2,
	'wh::idata::itype' => 1,
	'wh::idata::client_cert' => file_get_contents('ca/wh/certs/client.pem')
		. file_get_contents('ca/wh/private/client.key'),
	'wh::idata::client_ca_cert' => file_get_contents('ca/wh/certs/cacert.pem')
	);
rg_test_wh_add_edit($db, $rg_ui, 'http', 'generic', $extra);


rg_log('');
rg_log('Registering webhook3...');
$extra = array(
	'wh::htype' => 'http',
	'wh::hsubtype' => 'generic',
	'wh::description' => 'description1 <xss>',
	'wh::repo' => '',
	'wh::refname' => '',
	'wh::idata::url' => 'https://localhost:' . $port3 . '/wh.html',
	'wh::idata::events[C]' => 'on',
	'wh::idata::events[P]' => 'on',
	'wh::idata::events[B]' => 'on',
	'wh::idata::key' => 'key2 <xss>',
	'wh::idata::opaque' => $port3,
	'wh::idata::itype' => 2,
	'wh::idata::custom_body' => 'This is the custom_body commit=##commit## ip=##ip##',
	'wh::idata::client_cert' => '',
	'wh::idata::client_ca_cert' => file_get_contents('ca/wh/certs/cacert.pem')
	);
rg_test_wh_add_edit($db, $rg_ui, 'http', 'generic', $extra);


rg_log('Finding out the ids...');
$r = test_wait_cache('wh' . '::' . $rg_ui['uid']);
rg_log_ml('r=' . print_r($r, TRUE));
$t = array_keys($r['list']);
if (count($t) != 3) {
	rg_log('We do not have 3 ids!');
	exit(1);
}
$wh_id1 = $t[0];
$wh_id2 = $t[1];
$wh_id3 = $t[2];
rg_log('wh_id1=' . $wh_id1);
rg_log('wh_id2=' . $wh_id2);
rg_log('wh_id3=' . $wh_id3);


rg_log('');
rg_log('Creating a repo and waiting for trigger');
$repo = array();
rg_test_create_repo($db, $rg_ui, $repo);


rg_log('');
rg_log_enter('Testing if the curl posted with success (wh1) (should not work)');
$r = test_wait_cache($key1 . '::' . $wh_id1);
if (strcmp($r, "BAD") != 0) {
	$_k = 'wh::' . $rg_ui['uid'] . '::list::' . $wh_id1 . '::last_output';
	$_e = test_wait_cache($_k);
	rg_log_ml('_e:' . $_e);
	rg_log('Seems wh1 executed correctly without client'
		. ' cert (r=' . $r . ')!');
	exit(1);
}
rg_log_exit();


rg_log('');
rg_log_enter('Testing if the curl posted with success (wh2) (should work)');
$r = test_wait_cache($key2 . '::' . $wh_id2);
if (strcmp($r, "OK") != 0) {
	$_k = 'wh::' . $rg_ui['uid'] . '::list::' . $wh_id2 . '::last_output';
	$_e = test_wait_cache($_k);
	rg_log_ml('_e:' . $_e);
	rg_log('Seems wh2 did not returned success'
		. ' (r=' . $r . ')!');
	exit(1);
}
rg_log_exit();


rg_log('');
rg_log_enter('Testing if the curl posted with success (wh3) (should work)');
$r = test_wait_cache($key3 . '::' . $wh_id3);
if (strcmp($r, "OK") != 0) {
	$_k = 'wh::' . $rg_ui['uid'] . '::list::' . $wh_id3 . '::last_output';
	$_e = test_wait_cache($_k);
	rg_log_ml('_e:' . $_e);
	rg_log('Seems wh3 did not returned success'
		. ' (r=' . $r . ')!');
	exit(1);
}
rg_log_exit();


rg_log('');
rg_log_enter('Testing the edit of webhook1...');
$extra = array(
	'wh::id' => $wh_id1,
	'wh::htype' => 'http',
	'wh::hsubtype' => 'generic',
	'wh::description' => 'desc2 <xss>',
	'wh::repo' => '.*',
	'wh::refname' => '..*',
	'wh::flags[D]' => 'on',
	'wh::idata::url' => 'https://localhost:' . $port1 . '/wh.html',
	'wh::idata::events[C]' => 'on',
	'wh::idata::events[B]' => 'on',
	'wh::idata::key' => 'another key <xss>',
	'wh::idata::opaque' => 'xxx',
	'wh::idata::itype' => 1,
	'wh::idata::client_cert' => 'abc <xss>',
	'wh::idata::client_ca_cert' => 'zzz <xss>'
	);
rg_test_wh_add_edit($db, $rg_ui, 'http', 'generic', $extra);
$sql = "SELECT * FROM webhooks WHERE uid = " . $rg_ui['uid']
	. " AND id = " . $wh_id1;
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
	rg_log('Cannot do query!');
	exit(1);
}
$row = rg_sql_fetch_array($res);
rg_sql_free_result($res);
$row['idata'] = rg_unserialize($row['idata']);
$key = 'wh' . '::' . $rg_ui['uid'] . '::' . 'list' . '::' . $wh_id1;
$c = test_wait_cache($key);
$list = array('htype' => 'http', 'events' => 'CB', 'repo' => '.*',
	'refname' => '..*',
	'description' => 'desc2 <xss>', 'key' => 'another key <xss>',
	'opaque' => 'xxx', 'itype' => '1', 'flags' => 'D',
	'client_cert' => 'abc <xss>', 'client_ca_cert' => 'zzz <xss>');
foreach ($list as $k => $v) {
	if (isset($row[$k]))
		$a = $row[$k];
	else if (isset($row['idata'][$k]))
		$a = $row['idata'][$k];
	else {
		rg_log('Key [' . $k . '] not found! Bad!');
		exit(1);
	}
	if (strcmp($a, $v) != 0) {
		rg_log_ml('row: ' . print_r($row, TRUE));
		rg_log("db: Seems that [$k] has not been updated"
			. " [" . $a . "] != " . $v);
		exit(1);
	}

	if (isset($c[$k]))
		$a = $c[$k];
	else
		$a = $c['idata'][$k];
	if (strcmp($a, $v) != 0) {
		rg_log_ml('c: ' . print_r($c, TRUE));
		rg_log("cache: Seems that [$k] has not been updated"
			. " [" . $a . "] != " . $v);
		exit(1);
	}
}
rg_log_exit();


rg_log('');
rg_log_enter('Testing the delete - loading form...');
$data = array();
$headers = array();
$r = do_req($test_url . "/op/settings/wh/list", $data, $headers);
if ($r === FALSE) {
	rg_log("Cannot load list form.");
	exit(1);
}
if (!isset($r['tokens']['wh_list'])) {
	rg_log_ml('tokens: ' . print_r($r['tokens'], TRUE));
	rg_log('Cannot find wh_list token!');
	exit(1);
}
$good_token = $r['tokens']['wh_list'];
$data = array( 'delete' => 1,
	'token' => $good_token,
	'delete_list[' . $wh_id1 . ']' => 'on');
$r = do_req($test_url . "/op/settings/wh/list", $data, $headers);
if (!strstr($r['body'], 'success')) {
	rg_log_ml('r[body]: ' . print_r($r['body'], TRUE));
	rg_log("Cannot delete webhook!");
	exit(1);
}
$sql = "SELECT id FROM webhooks WHERE id = " . $wh_id1;
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
	rg_log('Cannot do query!');
	exit(1);
}
$rows = rg_sql_num_rows($res);
rg_sql_free_result($res);
if ($rows != 0) {
	rg_log("Cannot delete webhook - sql still returns data!");
	exit(1);
}
$key = 'user::' . $rg_ui['uid'] . '::wh::' . $wh_id1;
rg_cache_core_unset($key); // else we will get data from local mem!
$r = rg_cache_get($key);
if (strcmp($r, '') != 0) {
	rg_log_ml($key . ': ' . print_r($r, TRUE));
	rg_log('Deleted webhooks are still in cache!');
	exit(1);
}
rg_log_exit();


rg_log('OK!');
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master