blob: 93313408fa129047aed59afb3c0c80ad0ee523b4 [file] [log] [blame]
<?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;
}
}
?>