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 / sess.inc.php (00d60b0e1508b4650d918c5d3ebcf6a1da9feae2) (4,339B) (mode 100644) [raw]
<?php
require_once($INC . "/log.inc.php");
require_once($INC . "/sql.inc.php");
require_once($INC . "/token.inc.php");
require_once($INC . "/prof.inc.php");

/*
 * Add a session
 */
function rg_sess_add($db, $uid, $sid, $session_time, $lock_ip)
{
	rg_prof_start("sess_add");
	rg_log_enter("sess_add: uid=$uid, sid=$sid, session_time=$session_time"
		. " lock_ip=$lock_ip");

	if ($lock_ip == 1)
		$ip = @$_SERVER['REMOTE_ADDR'];
	else
		$ip = "";
	$now = time();

	$ret = FALSE;
	while (1) {
		$params = array("sid" => $sid,
			"uid" => $uid,
			"expire" => $now + $session_time,
			"session_time" => $session_time,
			"ip" => $ip);
		$sql = "INSERT INTO sess (sid, uid, expire, session_time, ip)"
			. " VALUES (@@sid@@, @@uid@@, @@expire@@"
			. ", @@session_time@@, @@ip@@)";
		$res = rg_sql_query_params($db, $sql, $params);
		if ($res === FALSE) {
			rg_log("Cannot insert (" . rg_sql_error() . ")!");
			break;
		}
		rg_sql_free_result($res);

		$params['last_db_write'] = $now;
		rg_cache_set('sess' . '::' . $sid . '::' . 'info',
			$params, RG_SOCKET_NO_WAIT);

		$ret = TRUE;
		break;
	}

	rg_log_exit();
	rg_prof_end("sess_add");
	return $ret;
}

/*
 * Tests if a session is still valid. Will return FALSE on error or session
 * info.
 */
function rg_sess_valid($db, $sid)
{
	rg_prof_start("sess_valid");
	rg_log_enter("sess_valid: sid=$sid...");

	$ret = FALSE;
	while (1) {
		$r = rg_cache_get('sess' . '::' . $sid . '::' . 'info');
		if ($r === FALSE) {
			$params = array("sid" => $sid);
			$sql = "SELECT * FROM sess WHERE sid = @@sid@@";
			$res = rg_sql_query_params($db, $sql, $params);
			if ($res === FALSE) {
				rg_log("Cannot select (" . rg_sql_error() . ")!");
				break;
			}
			$rows = rg_sql_num_rows($res);
			if ($rows > 0) {
				$r = rg_sql_fetch_array($res);
				$r['last_db_write'] = $r['expire'] - $r['session_time'];
				rg_cache_set('sess' . '::' . $sid . '::' . 'info',
					$r, RG_SOCKET_NO_WAIT);
			}
			rg_sql_free_result($res);
		}

		if ($r === FALSE) {
			rg_log("Session not found.");
			break;
		}

		$now = time();
		if ($r['expire'] < $now) {
			rg_log("Session too old (" . ($now - $r['expire']) . "s).");
			break;
		}

		$ip = @$_SERVER['REMOTE_ADDR'];
		if (!empty($r['ip']) && (strcmp($r['ip'], $ip) != 0)) {
			rg_log("Session invalid because of IP"
				. " login=" . $r['ip'] . " now=$ip.");
			break;
		}

		$uid = $r['uid'];
		rg_log("Session valid, uid=$uid, expire=+"
			. ($r['expire'] - $now) . "s");
		$ret = $r;
		break;
	}

	rg_log_exit();
	rg_prof_end("sess_valid");
	return $ret;
}

/*
 * Refreshes a session.
 * Because of performance reasons, we will not update database
 * every time.
 */
function rg_sess_update($db, $sess)
{
	rg_prof_start("sess_update");
	rg_log_enter("sess_update: sess=" . rg_array2string($sess));

	$now = time();

	$ret = FALSE;
	while (1) {
		if ($sess['last_db_write'] + 60 > $now) {
			$_diff = $now - $sess['last_db_write'];
			rg_log("DEBUG: last_db_write is fresh enough (" . $_diff . "s).");
			$ret = TRUE;
			break;
		}

		$sess['expire'] = $now + $sess['session_time'];
		$sql = "UPDATE sess SET expire = @@expire@@"
			. " WHERE sid = @@sid@@";
		$res = rg_sql_query_params($db, $sql, $sess);
		if ($res === FALSE) {
			rg_log("Cannot update (" . rg_sql_error() . ")!");
			// We will not exit here. At least in cache to be ok
		} else {
			$sess['last_db_write'] = $now;
			rg_sql_free_result($res);
		}

		rg_cache_set('sess' . '::' . $sess['sid'] . '::' . 'info',
			$sess, RG_SOCKET_NO_WAIT);

		$ret = TRUE;
		break;
	}

	rg_log_exit();
	rg_prof_end("sess_update");
	return $ret;
}

/*
 * Destroy session
 */
function rg_sess_destroy($db, $sid, &$ui)
{
	rg_prof_start("sess_destroy");
	rg_log_enter("sess_destroy: sid=$sid...");

	$ret = FALSE;
	while (1) {
		$params = array("sid" => $sid);
		$sql = "DELETE FROM sess WHERE sid = @@sid@@";
		$res = rg_sql_query_params($db, $sql, $params);
		if ($res === FALSE) {
			rg_log("Cannot delete (" . rg_sql_error() . ")!");
			break;
		}
		rg_sql_free_result($res);

		// Delete all tokens associated with this session
		rg_token_delete($db, $sid, '');

		$ui = array();
		$ui['uid'] = 0;
		$ui['is_admin'] = 0;

		rg_cache_unset('sess' . '::' . $sid . '::'. 'info',
			RG_SOCKET_NO_WAIT);

		$ret = TRUE;
		break;
	}

	rg_log_exit();
	rg_prof_end("sess_destroy");
	return $ret;
}

?>
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