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> / inc / rights.inc.php (f4442b0c20c9c7c456e5a101ac9c0c881c1dc63e) (5,753B) (mode 100644) [raw]
<?php
require_once($INC . "/util.inc.php");
require_once($INC . "/log.inc.php");
require_once($INC . "/sql.inc.php");
require_once($INC . "/user.inc.php");
require_once($INC . "/git.inc.php");

define("RG_RIGHTS_FILL_EXISTS", 1);

$rg_rights = array();

$rg_rights_error = "";

function rg_rights_set_error($str)
{
	global $rg_rights_error;

	rg_log("\tError: $str");
	$rg_rights_error = $str;
}

function rg_rights_error()
{
	global $rg_rights_error;
	return $rg_rights_error;
}

/*
 * Register a set of rights
 */
function rg_rights_register($type, $rights)
{
	global $rg_rights;

	$rg_rights[$type] = $rights;
}

/*
 * Enforce correct chars
 */
function rg_rights_fix($rights)
{
	return preg_replace("/[^A-Za-z0-9]/", "", $rights);
}

/*
 * Combine two repo rights strings
 */
function rg_rights_combine($a, $b)
{
	$len = strlen($b);
	for ($i = 0; $i < $len; $i++)
		if (!strstr($a, $b[$i]))
			$a .= $b[$i];

	return $a;
}

/*
 * Returns all possible rights
 */
function rg_rights_all($type)
{
	global $rg_rights;

	if (!isset($rg_rights[$type])) {
		rg_log("WARN: type [$type] is not registered!");
		return "";
	}

	$ret = "";
	foreach ($rg_rights[$type] as $letter => $junk)
		$ret = rg_rights_combine($ret, $letter);

	return $ret;
}

/*
 * Rights -> form
 */
function rg_rights_checkboxes($type, $passed_rights)
{
	global $rg_rights;

	if (!isset($rg_rights[$type])) {
		rg_log("[$type] is not registered! " . print_r(debug_backtrace(), TRUE));
		return "";
	}

	$ret = "";
	foreach ($rg_rights[$type] as $right => $info) {
		$add = "";
		if (strstr($passed_rights, $right))
			$add = " checked=\"checked\"";
		$ret .= "<input type=\"checkbox\" name=\"rights[$right]\""
			. $add . " />$info<br />\n";
	}

	return $ret;
}

/*
 * List rights as text
 */
function rg_rights_text($type, $rights)
{
	global $rg_rights;

	$ret = array();

	$len = strlen($rights);
	if ($len == 0)
		return array("None");

	for ($i = 0; $i < $len; $i++) {
		if (isset($rg_rights[$type][$rights[$i]]))
			$ret[] = $rg_rights[$type][$rights[$i]];
		else
			$ret[] = "?" . $rights[$i] . "?";
	}

	return $ret;
}

/*
 * Transforms rights array into a string
 */
function rg_rights_a2s($a)
{
	$rights = "";

	// TODO - log backtrace instead being silent
	if (is_array($a))
		foreach ($a as $right => $junk)
			$rights .= $right;

	return rg_rights_fix($rights);
}


/*
 * Get rights for an object
 */
function rg_rights_get($db, $type, $obj_id, $uid)
{
	global $rg_rights;

	rg_log("rg_rights_get: type=$type obj_id=$obj_id uid=$uid...");

	$ret = array();
	$ret['ok'] = 0;
	$ret['rights'] = "";

	$sql = "SELECT rights FROM rights"
		. " WHERE type = '$type'"
		. " AND uid = $uid"
		. " AND obj_id = $obj_id"
		. " LIMIT 1";
	$res = rg_sql_query($db, $sql);
	if ($res === FALSE) {
		rg_rights_set_error("Cannot get info (" . rg_sql_error() . ")!");
		return $ret;
	}

	$ret['ok'] = 1;
	$ret['exists'] = 0;
	$rows = rg_sql_num_rows($res);
	if ($rows > 0)
		$row = rg_sql_fetch_array($res);
	rg_sql_free_result($res);
	if ($rows > 0) {
		$ret['rights'] = $row['rights'];
		$ret['exists'] = 1;
	}

	rg_log("\tdb rights: " . $ret['rights'] . ".");

	return $ret;
}

/*
 * Set rights for an object
 */
function rg_rights_set($db, $type, $obj_id, $uid, $rights)
{
	rg_log("rg_rights_set: type=$type obj_id=$obj_id"
		. ", uid=$uid, rights=$rights...");

	$cond = " type = '$type' AND uid = $uid AND obj_id = $obj_id";

	if (empty($rights)) {
		$sql = "DELETE FROM rights"
			. " WHERE $cond";
	} else {
		$r = rg_rights_get($db, $type, $obj_id, $uid);
		if ($r['ok'] != 1)
			return $r;
		rg_log("r: " . print_r($r, TRUE));

		if ($r['exists'] == 1) {
			$sql = "UPDATE rights"
				. " SET rights = '$rights'"
				. " WHERE $cond";
		} else {
			$itime = time();

			$sql = "INSERT INTO rights (type, uid, obj_id, rights"
				. ", itime)"
				. " VALUES ('$type', $uid, $obj_id, '$rights'"
				. ", $itime)";
		}
	}

	$res = rg_sql_query($db, $sql);
	if ($res === FALSE) {
		rg_rights_set_error("Cannot alter rights (" . rg_sql_error() . ")!");
		return FALSE;
	}
	rg_sql_free_result($res);

	return TRUE;
}

/*
 * List rights for a repo
 */
function rg_rights_list($db, $type, $obj_id, $url)
{
	global $rg_rights;

	rg_log("rg_rights_list: type=$type obj_id=$obj_id url=$url");

	$ret = "";

	$sql = "SELECT * FROM rights WHERE type = '$type' AND obj_id = $obj_id";
	$res = rg_sql_query($db, $sql);
	if ($res === FALSE) {
		rg_rights_set_error("Cannot get info (" . rg_sql_error() . ")!");
		return FALSE;
	}

	$ret .= "<table>\n";
	$ret .= "<tr>\n";
	$ret .= "	<th>User</th>\n";
	$ret .= "	<th>Rights</th>\n";
	$ret .= "	<th>Operations</th>\n";
	$ret .= "</tr>\n";
	while (($row = rg_sql_fetch_array($res))) {
		$ret .= "<tr>\n";

		$_u = $row['uid'];
		$_ui = rg_user_info($db, $row['uid'], "", "");
		if ($_ui['exists'] == 1)
			$_u = $_ui['username'];

		$ret .= "	<td>" . $_u . "</td>\n";

		$_r = rg_rights_text($type, $row['rights']);
		$_r = implode("<br />\n", $_r);
		$ret .= "	<td>" . $_r . "</td>\n";

		// operations
		//	remove
		$ret .= "	<td>";
		$_url = $url . "&amp;subop=2";
		$v = $row['uid'];
		$ret .= "[<a href=\"$_url&amp;remove_uid=$v\">Remove</a>]";
		$ret .= "	</td>";
		$ret .= "</tr>\n";
	}
	$ret .= "</table>\n";
	rg_sql_free_result($res);

	return $ret;
}

/*
 * Filters var using mask
 * Example ("ABCDE", "AEZ") => "AE"
 */
function rg_rights_mask($val, $mask)
{
	$ret = "";
	$len = strlen($val);
	for ($i = 0; $i < $len; $i++)
		if (strstr($mask, $val[$i]))
			$ret .= $val[$i];

	return $ret;
}

/*
 * Returns TRUE if all 'needed_rights' are included in 'rights'
 */
function rg_rights_allow($rights, $needed_rights)
{
	$r = rg_rights_mask($rights, $needed_rights);
	if (strcmp($r, $needed_rights) != 0)
		return FALSE;

	return TRUE;
}
?>
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