<?php /******************************************************************************* * Copyright (c) 2007-2014 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 * Christopher Guindon (Eclipse Foundation) - Bug 440590 - Improve the flexibility of session.class.php *******************************************************************************/ require_once(realpath(dirname(__FILE__) . "/../classes/friends/friend.class.php")); require_once("app.class.php"); if (!class_exists("EvtLog")) { require_once("evt_log.class.php"); } class Session { private $App = NULL; private $gid = ""; private $bugzilla_id = 0; private $subnet = ""; private $updated_at = ""; private $Friend = NULL; private $data = ""; private $session_name = ""; private $domain = ""; private $env = ""; private $login_page = ""; private $cookies_sent = FALSE; /** * Default constructor * * @return NULL */ public function __construct($persistent=0, $configs = array()) { $this->App = new App(); $domain = $this->App->getEclipseDomain(); $default = array( 'domain' => $domain['cookie'] , 'session_name' => 'ECLIPSESESSION', 'env' => 'ECLIPSE_ENV', 'login_page' => 'https://' . $domain['accounts'] . '/user/login', ); # Set default config values. foreach ($default as $key => $value) { $this->{$key} = $value; if (!empty($configs[$key]) && is_string($configs[$key])) { $this->{$key} = $configs[$key]; } } $this->validate(); } 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() { if ($this->hasCookieConsent()) { return 1; } return 0; } function getLoginPageURL() { return $this->login_page; } function getIsLoggedIn() { return $this->getGID() !== ""; } /** * Verify if consent was given to use cookies * * @return boolean */ public function hasCookieConsent() { $App = new App(); return $App->hasCookieConsent(); } function setGID($_gid) { $this->gid = $_gid; } function setBugzillaID($_bugzilla_id) { if (ctype_digit($_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); } /** * Set is_persistent * * @deprecated */ function setIsPersistent($_is_persistent) { trigger_error("Deprecated function called.", E_USER_NOTICE); } /** * Validate session based on browser cookie * * @return boolean */ function validate() { $cookie = (isset($_COOKIE[$this->session_name]) ? $_COOKIE[$this->session_name] : ""); $rValue = FALSE; if ($this->load($cookie)) { # TODO: update session? $rValue = TRUE; $this->maintenance(); $this->setFriend($this->getData()); } return $rValue; } function destroy($flush_all_sessions = FALSE) { $App = new App(); $Friend = $this->getFriend(); if ($flush_all_sessions && $Friend->getBugzillaID() > 0) { $sql = "DELETE FROM sessions WHERE bugzilla_id = '" . $App->sqlSanitize($Friend->getBugzillaID(), 0) . "'"; } else { $sql = "DELETE FROM sessions WHERE gid = '" . $App->sqlSanitize($this->getGID(), NULL) . "' LIMIT 1"; } $App->eclipse_sql($sql); # Remove the TAKEMEBACK cookie # Should these also be in session() ? setcookie("TAKEMEBACK", "", 0, "/", ".eclipse.org"); setcookie("fud_session_2015", "", 0, "/forums/", ".eclipse.org"); setcookie($this->session_name, "", 0, "/", $this->domain, 1, TRUE); setcookie($this->env, "", 0, "/", $this->domain, 0, TRUE); if (!$App->devmode) { # Log this event $EvtLog = new EvtLog(); $EvtLog->setLogTable("sessions"); $EvtLog->setPK1($Friend->getBugzillaID()); $EvtLog->setPK2($App->getRemoteIPAddress()); $EvtLog->setLogAction("DELETE"); $EvtLog->insertModLog("apache"); } } function create() { # create session in the database. $Friend = $this->getFriend(); $this->setData($Friend); # need to have a LDAP ID to log in. if ($Friend->getUID()) { $App = new App(); $this->setGID(md5(uniqid(rand(), TRUE))); $this->setSubnet($this->getClientSubnet()); $this->setUpdatedAt($App->getCURDATE()); // Bugzilla id is missing, let's try to find it. if (!$Friend->getBugzillaID() && $Friend->getEmail()) { $Friend->setBugzillaID($Friend->getBugzillaIDFromEmail($Friend->getEmail())); } $this->setBugzillaID($Friend->getBugzillaID()); //$Friend->insertUpdateFriend(); $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($Friend->getBugzillaID()); $EvtLog->setPK2($App->getRemoteIPAddress()); $EvtLog->setLogAction("INSERT"); $EvtLog->insertModLog("apache"); } $this->setEclipseSessionCookies(); } } /** * Set Eclipse Session Cookies * * @return boolean */ public function setEclipseSessionCookies(){ $gid = $this->getGID(); if (empty($gid) || $this->cookies_sent) { return FALSE; } $this->cookies_sent = TRUE; $cookie_time = 0; if ($this->getIsPersistent()) { $cookie_time = time()+3600*24*7; } setcookie($this->session_name, $this->getGID(), $cookie_time, "/", $this->domain, 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($this->env, "S", $cookie_time, "/", $this->domain, 0, TRUE); return TRUE; } function load($_gid) { # need to have a bugzilla ID to log in $rValue = FALSE; if (!empty($_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']; # touch this session $sql = "UPDATE sessions SET updated_at = NOW(), is_persistent = '" . $App->sqlSanitize($this->getIsPersistent(), NULL) . "' WHERE gid = '" . $App->sqlSanitize($_gid, NULL) . "'"; $App->eclipse_sql($sql); $this->setEclipseSessionCookies(); } } return $rValue; } function maintenance() { $App = new App(); // Sessions are re-generated by visiting accounts.eclipse.org $sql = "DELETE FROM sessions WHERE updated_at < DATE_SUB(NOW(), INTERVAL 8 DAY)"; $App->eclipse_sql($sql); } function getClientSubnet() { # return class-c subnet $App = new App(); return substr($App->getRemoteIPAddress(), 0, strrpos($App->getRemoteIPAddress(), ".")) . ".0"; } function redirectToLogin() { $this->App->preventCaching(); header("Location: " . $this->login_page, 303); exit; } /** * Determine if this session is logged in. * @author droy * @since 2014-07-03 * @return boolean */ function isLoggedIn() { return $this->getGID() != ""; } /** * Update Friend object in Sessions table. * * @param object $Friend * @return boolean */ function updateSessionData($Friend = NULL) { if (is_null($Friend)) { $Friend = $this->getFriend(); } if (is_a($Friend, 'Friend') && $gid = $this->getGID()) { $this->setFriend($Friend); $this->setData($Friend); $sql = "UPDATE sessions SET updated_at = NOW(), data = '" . $this->App->sqlSanitize($this->data) . "' WHERE gid = '" . $this->App->sqlSanitize($gid, NULL) . "'"; $this->App->eclipse_sql($sql); return TRUE; } return FALSE; } }