<?php
/*****************************************************************************
 * Session.php
 * Contains the key class Session.
 *
 * Kabuki CMS (C) 2013-2023, Aaron van Geffen
 *****************************************************************************/

class Session
{
	public static function clear()
	{
		$_SESSION = [];
	}

	public static function start()
	{
		session_start();

		if (!isset($_SESSION['session_token_key'], $_SESSION['session_token']))
			self::generateSessionToken();

		return true;
	}

	public static function generateSessionToken()
	{
		$_SESSION['session_token'] = sha1(session_id() . mt_rand());
		$_SESSION['session_token_key'] = substr(preg_replace('~^\d+~', '', sha1(mt_rand() . session_id() . mt_rand())), 0, rand(7, 12));
		return true;
	}

	public static function getSessionToken()
	{
		if (empty($_SESSION['session_token']))
			trigger_error('Call to getSessionToken without a session token being set!', E_USER_ERROR);

		return $_SESSION['session_token'];
	}

	public static function getSessionTokenKey()
	{
		if (empty($_SESSION['session_token_key']))
			trigger_error('Call to getSessionTokenKey without a session token key being set!', E_USER_ERROR);

		return $_SESSION['session_token_key'];
	}

	public static function resetSessionToken()
	{
		// Old interface; now always true.
		return true;
	}

	public static function validateSession($method = 'post')
	{
		// First, check whether the submitted token and key match the ones in storage.
		if (($method === 'post' && (!isset($_POST[$_SESSION['session_token_key']]) || $_POST[$_SESSION['session_token_key']] !== $_SESSION['session_token'])) ||
			($method === 'get' && (!isset($_GET[$_SESSION['session_token_key']]) || $_GET[$_SESSION['session_token_key']] !== $_SESSION['session_token'])))
			throw new UserFacingException('Session failed to verify (' . $method . '). Please reload the page and try again.');

		// Check the referring site, too -- should be the same site!
		$referring_host = isset($_SERVER['HTTP_REFERER']) ? parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) : '';
		if (!empty($referring_host))
		{
			if (strpos($_SERVER['HTTP_HOST'], ':') !== false)
				$current_host = substr($_SERVER['HTTP_HOST'], 0, strpos($_SERVER['HTTP_HOST'], ':'));
			else
				$current_host = $_SERVER['HTTP_HOST'];

			$base_url_host = parse_url(BASEURL, PHP_URL_HOST);

			// The referring_host must match either the base_url_host or the current_host.
			if (strtolower($referring_host) !== strtolower($base_url_host) && strtolower($referring_host) !== strtolower($current_host))
				throw new UserFacingException('Invalid referring URL. Please reload the page and try again.');
		}

		// All looks good from here!
		return true;
	}
}