<?php
include_once CARABI_DIR . '/classes/wave_editor/class.WaveEditorUtils.php';

/**
* @todo помимио функции webAJAXAuthorize (которая сама авторизует пользователя
* по паре логин/пароль через AJAX) сделать функцию для полного цикла авторизации.
* Т.е. вызываемая функция создаёт редирект на страницу авторизации, проводит
* необходимые для авторизации дейстия и редиректит обратно на страницу с
* которой был произведён ее вызов.
*
* @todo реализовать "Напомнить пароль"
*
*
*/


class WebUserAuth
{
	protected $token;
	protected $userId;
	protected $contactID;
	protected $userRole;
	protected $userName;
	protected $userNameShort;
	protected $systemUserId;
	protected $permissions;

	public function __construct()
	{
	}

	/**
	 * Авторизация по токену-идентификатору, привязанному к пользователю при
	 * авторизации по паролю. Отправляется браузером в cookie.
	 * @param string $token Токен для подмены отправленного пользователем
	 * (например, при переключении схемы на лету).
	 * @return type
	 */
	public function tokenAuthorize($token = null)
	{
		$this->userId = $_SESSION['WEB_USER_ID'];
		if (!empty($this->userId) && empty($token)) return;
		if (empty($token)) {
			$this->token = $_COOKIE['at'];
		} else {
			$this->token = $token;
		}
		$this->userId = Auth::getTokenOwner($this->token);
		if (!$this->userId) {
			$this->userId = null;
			$this->token = null;
			$this->systemUserId = null;
		} else {
			$_SESSION['WEB_USER_ID'] = $this->userId;
			$expired = time()+60*60*24*30;
			Auth::updateToken($this->token, $expired);
		}
	}

	public function webAJAXAuthorize()
	{
		try {
			if ($this->isAuthorized()) {
				throw new Exception('You are already logged in!', 2);
			} else {
				$l = $_REQUEST['l']; // TODO: sanitize
				$p = $_REQUEST['p']; // TODO: sanitize
				$userId = $this->authorize($l, $p);
				if (!$userId) {
					throw new Exception('Wrong login or password', 1);
				}
				$answer = array('status' => true, 'userId' => $userId);
				unset($_SESSION["REDIRECT_TO_AFTER_LOGIN"]);
			}
		} catch (Exception $e) {
			$answer = array('status' => false, 'errCode' => $e->getCode());
		}
		echo json_encode($answer);
	}

	public function isAuthorized()
	{
		return ($this->userId ? true : false);
	}

	public function authorize($login, $password, $setToken=true)
	{
		try {
			$userId = Auth::testLoginAndPassword($login, $password);
			if ($userId) {
				$this->userId = $userId;
				$_SESSION['WEB_USER_ID'] = $this->userId;
				if ($setToken) {
					$this->generateToken();
					$this->setTokenToClient();
				}
			}
		} catch (Exception $e) {
			$userId = false;
			throw $e;
		}
		return $userId;
	}


	public function unauthorize($sessionKill = true)
	{
		try {
			$this->userId = null;
			$_SESSION['WEB_USER_ID'] = $this->userId;
			$this->deleteClientToken();
			if ($sessionKill) {
				setcookie(session_name(), '', time() - 42000, '/');
				session_destroy();
			}
		} catch (Exception $e) {
		}
	}


	public function userId()
	{
		return $this->userId;
	}

	public function contactID()
	{
		if (empty($this->contactID) && !empty($this->userId)) {
			$this->contactID = ora_func("GET_REF($this->userId, 'SYSTEM_USER-BREF-CONTACT_INFO', 'SYSTEM_USER')");
		}
		return $this->contactID;
	}

	public function actAsCommonUser()
	{
		Auth::actAs(COMMONUSER_NOAUTH);
	}

	public function actAsSelf()
	{
		if (!empty($this->userId)) {
			Auth::actAs($this->userId);
		}
	}



	public function getUserRole()
	{
		utls::logStr('WEBAUTH::getUserRole()');
		try {
			if (!$this->isAuthorized())
				throw new Exception('Not authorized!');

			if (!$this->userRole)
				$this->userRole = ora_func("appl_web_user.get_user_role({$this->userId})", false);

		} catch (Exception $e) {
			$this->userRole = null;
		}

		return $this->userRole;
	}



	public function getUserName()
	{
		utls::logStr('WEBAUTH::getUserName()');
		try {
			if (!$this->isAuthorized())
				throw new Exception('Not authorized!');
			if (!$this->userName)
				$this->userName = ora_func("appl_web_user.GET_NAME({$this->userId})", false);
		} catch (Exception $e) {
			$this->userName = null;
		}

		return $this->userName;
	}

	public function getUserNameShort()
	{
		utls::logStr('WEBAUTH::getUserNameShort()');
		try {
			if (!$this->isAuthorized())
				throw new Exception('Not authorized!');
			if (!$this->userNameShort)
				$this->userNameShort = ora_func("appl_web_user.GET_NAME_SHORT({$this->userId})", false);
		} catch (Exception $e) {
			$this->userNameShort = null;
		}

		return $this->userNameShort;
	}


	public function getSystemUserId()
	{
		utls::logStr('WEBAUTH::getSystemUserId()');
		try {
			//echo '<li>', "appl_sys_user.get_user_id({$this->userId})";
			if (!$this->isAuthorized())
				throw new Exception('Not authorized!');
			if (!$this->systemUserId)
				$this->systemUserId = ora_func("appl_web_user.get_user_id({$this->userId})", false);
			//echo "appl_sys_user.get_user_id({$this->userId})";
		} catch (Exception $e) {
			//throw $e;
			$this->systemUserId = null;
		}

		return $this->systemUserId;
	}


	protected function generateToken()
	{
		$this->token = md5(uniqid() . " " . microtime(true));
	}
	
	public function getToken()
	{
		return $this->token;
	}

	protected function setTokenToClient()
	{
		//if (headers_sent())
		//    return;
		$expired = time()+60*60*24*30;
		Auth::addToken($this->userId, $this->token, $expired);
		setcookie('at', $this->token, $expired, '/');
	}

	protected function deleteClientToken()
	{
		//if (headers_sent())
		//    return;
		$expired = time() - 3600;
		Auth::deleteToken($this->userId);
		setcookie('at', $this->token, $expired, '/');
	}

	/**
	 * функция возвращает права пользователя (набор из словаря SysUser_Permissions)
	 */
	public function getUserPermissions() {
		if (!isset($this->permissions)) {
			if (!empty($this->userId)) {
				$this->permissions = WaveEditorUtils::getMultiField($this->userId, "SYSTEM_USER", "PERM");
			} else {
				$this->permissions = array();
			}
		}
		return $this->permissions;
	}

}
?>