<?php
/*******************************************************************************
 * Copyright (c) 2007-2011 Eclipse Foundation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Denis Roy (Eclipse Foundation)- initial API and implementation
 *******************************************************************************/

define('ECLIPSE_SESSION', 'ECLIPSESESSION');
define('ECLIPSE_ENV', 'ECLIPSE_ENV');
define('HTACCESS', '/home/data/httpd/friends.eclipse.org/html/.htaccess');
define('LOGINPAGE', 'https://dev.eclipse.org/site_login/');

require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/classes/friends/friend.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php");
if (!class_exists("EvtLog")) {
	require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/evt_log.class.php");
}


class Session {

	private $gid		= "";
	private $bugzilla_id= 0;
	private $subnet		= "";
	private $updated_at	= "";
	private $is_persistent	= 0;
	private $Friend		= null;
	private $data		= "";
	
	/**
	 * Default constructor
	 *
	 * @return null
	 */
	function Session($persistent=0) {
		$this->validate();
		$this->setIsPersistent($persistent);
	}

	
	function getGID() {
		return $this->gid;
	}
	function getBugzillaID() {
		return $this->bugzilla_id;
	}
	function getSubnet() {
		return $this->subnet;
	}
	function getUpdatedAt() {
		return $this->updated_at;
	}
	function getFriend() {
		if($this->Friend == null) {
			$this->Friend = new Friend();
		}
		return $this->Friend;
	}
	function getData() {
		return unserialize($this->data);
	}
	function getIsPersistent() {
		return $this->is_persistent == null ? 0 : $this->is_persistent;
	}
	function getLoginPageURL() {
		return LOGINPAGE;
	}
	function getIsLoggedIn() {
		return $this->getGID() !== "";
	}
	
	function setGID($_gid) {
		$this->gid = $_gid;
	}
	function setBugzillaID($_bugzilla_id) {
		$this->bugzilla_id = $_bugzilla_id;
	}
	function setSubnet($_subnet) {
		$this->subnet = $_subnet;
	}
	function setUpdatedAt($_updated_at) {
		$this->updated_at = $_updated_at;
	}
	function setFriend($_friend) {
		$this->Friend = $_friend;
	}
	function setData($_data) {
		$this->data = serialize($_data);
	}
	function setIsPersistent($_is_persistent) {
		$this->is_persistent = $_is_persistent;
	}

	
	/**
	 * Validate session based on browser cookie
	 *
	 * @return boolean
	 */
	function validate() {
		$cookie = (isset($_COOKIE[ECLIPSE_SESSION]) ? $_COOKIE[ECLIPSE_SESSION] : "");
		$rValue = false;
		if ( (!$this->load($cookie))) {
        	# Failed - no such session, or session no match.  Need to relogin
        	# Bug 257675
        	# setcookie(ECLIPSE_SESSION, "", time() - 3600, "/", ".eclipse.org");
        	$rValue = false;
        }
        else {
			# TODO: update session?
			$rValue = true;
        	$this->maintenance();
        	$this->setFriend($this->getData());
        }
        return $rValue;
	}

	function destroy() {
		$App = new App();
		$sql = "DELETE FROM sessions WHERE gid = '" . $App->sqlSanitize($this->getGID(), null) . "' LIMIT 1";
        $App->eclipse_sql($sql);
		setcookie(ECLIPSE_SESSION, "", time() - 3600, "/", ".eclipse.org", 1, TRUE);
		setcookie(ECLIPSE_ENV, 	   "", time() - 3600, "/", ".eclipse.org", 0, TRUE);
		if(!$App->devmode) {
			# Log this event
			$EvtLog = new EvtLog();
			$EvtLog->setLogTable("sessions");
			$EvtLog->setPK1($this->getBugzillaID());
			$EvtLog->setPK2($_SERVER['REMOTE_ADDR']);
			$EvtLog->setLogAction("DELETE");
			$EvtLog->insertModLog("apache");
		}
	}

	function create() {
		# create session on the database
		$Friend = $this->getFriend();
		$this->setData($Friend);
		
		# need to have a bugzilla ID to log in
		if($Friend->getBugzillaID() > 0) {
			$App = new App();
			$this->setGID(md5(uniqid(rand(),true)));
			$this->setSubnet($this->getClientSubnet());
			$this->setUpdatedAt($App->getCURDATE());
			$this->setBugzillaID($Friend->getBugzillaID());
			
			$sql = "INSERT INTO sessions (
						gid,
						bugzilla_id,
						subnet,
						updated_at,
						data,
						is_persistent)
						VALUES (
							" . $App->returnQuotedString($this->getGID()) . ",
							" . $App->sqlSanitize($Friend->getBugzillaID(), null) . ",
							" . $App->returnQuotedString($this->getSubnet()) . ",
							NOW(),
							'" . $App->sqlSanitize($this->data) . "',
							'" . $App->sqlSanitize($this->getIsPersistent(), null) . "')";

			$App->eclipse_sql($sql);
			
			if(!$App->devmode) {
				# Log this event
				$EvtLog = new EvtLog();
				$EvtLog->setLogTable("sessions");
				$EvtLog->setPK1($this->getBugzillaID());
				$EvtLog->setPK2($_SERVER['REMOTE_ADDR']);
				$EvtLog->setLogAction("INSERT");
				$EvtLog->insertModLog("apache");

				# add session to the .htaccess file
				# TODO: implement a smart locking
				if($Friend->getIsBenefit()) {
					$fh = fopen(HTACCESS, 'a') or die("can't open file");
					$new_line = "SetEnvIf Cookie \"" . $this->getGID() . "\" eclipsefriend=1\n";
					fwrite($fh, $new_line);
					fclose($fh);
				}
			}
			
			$cookie_time = 0;
			if($this->getIsPersistent()) {
				$cookie_time = time()+3600*24*365;
			}

			setcookie(ECLIPSE_SESSION, $this->getGID(), $cookie_time, "/", ".eclipse.org", 1, TRUE);
			
			# 422767 Session broken between http and https
			# Set to "S" for Secure.  We could eventually append more environment data, separated by semicolons and such
			setcookie(ECLIPSE_ENV, 	   "S", 			$cookie_time, "/", ".eclipse.org", 0, TRUE);

			# uncomment for local dev
			# setcookie(ECLIPSE_SESSION, $this->getGID(), $cookie_time, "/");
		}
	}

	function load($_gid) {
		# need to have a bugzilla ID to log in
		
		$rValue = false;
		if($_gid != "") {
			$App = new App();
			$sql = "SELECT /* USE MASTER */ gid, bugzilla_id, subnet, updated_at, data,	is_persistent
					FROM sessions
					WHERE gid = " . $App->returnQuotedString($App->sqlSanitize($_gid, null));
						# " AND subnet = " . $App->returnQuotedString($this->getClientSubnet());
			
			$result = $App->eclipse_sql($sql);
			if($result && mysql_num_rows($result) > 0) {
				$rValue = true;
				$myrow = mysql_fetch_assoc($result);
				$this->setGID($_gid);
				$this->setBugzillaID($myrow['bugzilla_id']);
				$this->setSubnet($myrow['subnet']);
				$this->setUpdatedAt($myrow['updated_at']);
				$this->data = $myrow['data'];
				$this->setIsPersistent($myrow['is_persistent']);
			}
		}		
		return $rValue;
	}

	function maintenance() {
		$App = new App();
			
		$sql = "DELETE FROM sessions
				WHERE (updated_at < DATE_SUB(NOW(), INTERVAL 7 DAY) AND is_persistent = 0) 
				OR (subnet = '" . $this->getClientSubnet() . "' AND gid <> '" . $App->sqlSanitize($this->getGID(), null) . "')
				OR updated_at < DATE_SUB(NOW(), INTERVAL 1 YEAR)"; 

		$App->eclipse_sql($sql);
		
		# 1/500 of each maintenance calls will perform htaccess cleanup	
		if(rand(0, 500) < 1) {
			$this->regenrate_htaccess();
		}
	}
	
	private function regenrate_htaccess() {
		$App = new App();
		
		if(!$App->devmode) {
			
			$sql = "SELECT gid 
					FROM sessions AS S 
						INNER JOIN friends AS F ON F.bugzilla_id = S.bugzilla_id 
					WHERE F.is_benefit = 1"; 
	
			$result = $App->eclipse_sql($sql);
			$new_file = "";
			while($myrow = mysql_fetch_assoc($result)) {
				$new_file .= "SetEnvIf Cookie \"" . $myrow['gid'] . "\" eclipsefriend=1\n";	
			}
			
			if($new_file != "") {
				$fh = fopen(HTACCESS, 'w') or die("can't open file");
				fwrite($fh, $new_file);
				fclose($fh);
			}
		}
	}
		
	function getClientSubnet() {
		# return class-c subnet
		return substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], ".")) . ".0";
	}
	
	function redirectToLogin() {
		header("Location: " . LOGINPAGE);
		exit;
	}
}
?>