<?php

/**
 * Copyright (c) 2006, 2023 Eclipse Foundation and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *    Denis Roy (Eclipse Foundation)- initial API and implementation
 *    Christopher Guindon (Eclipse Foundation) - Bug 440590 - Improve the flexibility of session.class.php
 *    Christopher Guindon (Eclipse Foundation) - Refactoring to avoid Friend() seriazilation in database
 *
 * SPDX-License-Identifier: EPL-2.0
 */

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";
}

/**
 * Session class.
 */
class Session {

  /**
  * Cookie name for flag that enforce HTTPS redirects.
  *
  * @var string
  */
  const ENV = "ECLIPSE_ENV";

  /**
  * The session name.
  *
  * @var string
  */
  const SESSION_NAME = "ECLIPSESESSION";

  /**
   * An instance of App() from eclipse.org-common.
   *
   * @var App
   */
  private $App = NULL;

  /**
   * Bugzilla ID linked to the session.
   *
   * @var int
   */
  private $bugzilla_id = 0;

  /**
   * Flag to check if cookies were already sent.
   *
   * @var bool
   */
  private $cookies_sent = FALSE;

  /**
   * Session cookie's domain.
   *
   * To make cookies visible on all subdomains then the
   * domain must be prefixed with a dot.
   *
   * @var string
   */
  private $domain = ".eclipse.org";

  /**
   * Eclipse session email.
   *
   * @var string
   */
  private $email = "";

  /**
   * Instance of EvtLog from eclipse.org-common.
   *
   * @var EvtLog
   */
  private $EvtLog = NULL;

  /**
   * Instance of Friend from eclipse.org-common.
   *
   * @var Friend
   */
  private $Friend = NULL;

  /**
   * Unique Session Identifier.
   *
   * @var string
   */
  private $gid = "";

  /**
   * URL for redirection to login page.
   *
   * @var string
   */
  private $login_page = "https://accounts.eclipse.org/user/login";

  /**
   * Subnet IP range for current session.
   *
   * @var string
   */
  private $subnet = "";

  /**
   * Update time used for expiring stale session.
   *
   * @var string
   */
  private $updated_at = "";

  /**
   * Eclipse session username.
   *
   * @var string
   */
  private $username = "";

  /**
   * Default constructor.
   *
   * @param int $persistent
   *   Determine if the session is persistent (default is 0).
   * @param array $configs
   *   Configuration values to overwrite defaults.
   *
   * @return NULL
   */
  public function __construct($persistent = 0, $configs = array()) {
    $this->App = new App();
    $this->EvtLog = new EvtLog();
    $this->initializeConfigurations($configs);
    $this->validate();
  }

  /**
   * Initialize default configurations.
   *
   * @param array $configs
   *   Overwriting configurations.
   */
  private function initializeConfigurations($configs) {
    // Update defaults based on the environment.
    $domainData = $this->App->getEclipseDomain();

    $defaults = array(
        'domain' => $domainData['cookie'],
        'login_page' => 'https://' . $domainData['accounts'] . '/user/login'
    );

    foreach ($defaults as $key => $value) {
      if (!empty($configs[$key]) && is_string($configs[$key])) {
        ${$key} = $configs[$key];
      }
      else {
        ${$key} = $value;
      }
    }

    $this->setDomain($domain);
    $this->setLoginPage($login_page);
  }

  /**
   * Retrieve the stored Bugzilla ID.
   *
   * @return int
   *   Returns the Bugzilla ID.
   */
  public function getBugzillaID() {
    return $this->bugzilla_id;
  }

  /**
   * Set the Bugzilla ID if it's a valid digit.
   *
   * @param mixed $bugzilla_id
   *   The Bugzilla ID to be set.
   *
   * @return void
   */
  public function setBugzillaID($bugzilla_id) {
    if (is_numeric($bugzilla_id)) {
      $this->bugzilla_id = $bugzilla_id;
    }
  }

  /**
   * Retrieve the status of whether cookies were sent or not.
   *
   * @return bool
   *   Returns true if cookies were sent, false otherwise.
   */
  public function getCookiesSent() {
    return $this->cookies_sent;
  }

  /**
   * Set the status for the `cookies_sent` property.
   *
   * @param bool $cookies_sent
   *   Status to indicate if cookies were sent.
   *
   * @return void
   */
  public function setCookiesSent($cookies_sent) {
    $this->cookies_sent = (bool) $cookies_sent;
  }

  /**
   * Retrieves an instance of the Friend() class.
   *
   * This method used to unserialized data from the
   * eclipse.session data column. This was changed to better support
   * different versions of PHP.
   *
   * @return mixed
   *   The unserialized data.
   *
   * @deprecated
   *   Call getFriend() instead.
   */
  public function getData() {
    trigger_error("Deprecated function called.", E_USER_NOTICE);
    return $this->getFriend();
  }

  /**
   * Serializes and sets the data.
   *
   * @param mixed $data
   *   The data to be serialized and stored.
   *
   * @deprecated
   */
  public function setData($data) {
    trigger_error("Deprecated function called.", E_USER_NOTICE);
  }

  /**
   * Retrieve the current cookie domain.
   *
   * @return string
   *   Returns the cookie domain.
   */
  public function getDomain() {
    return $this->domain;
  }

  /**
   * Set the value for the `$domain` property.
   *
   * @param string $domain
   *   The domain value to be set for cookies.
   *
   * @return void
   */
  public function setDomain($domain) {
    if (is_string($domain)) {
      $this->domain = $domain;
    }
  }

  /**
   * Sets the Session email.
   *
   * We need this set when creating a session to fetch
   * the bugzilla id of the user. If this is not set,
   * the user bugzilla_id will always be zero.
   *
   * @param string $email
   *   The email address to set.
   *
   * @return void
   */
  public function setEmail($email) {
    $this->email = $email;
  }

  /**
   * Retrives the Session email.
   *
   * @return string Returns the email address.
   */
  public function getEmail() {
    return $this->email;
  }

  /**
   * Retrieves the Friend instance.
   *
   * If the Friend instance hasn't been set or isn't of the correct type,
   * it initializes a new one.
   *
   * @return Friend
   *   The Friend instance.
   */
  public function getFriend() {
    $username = $this->getUsername();
    if (!is_null($this->Friend)) {
      return $this->Friend;
    }
    else if (is_null($this->Friend) && !empty($username)) {
      $this->Friend = new Friend();
      $this->Friend->setUID($username);
      $this->Friend->selectFriend($this->Friend->selectFriendID("uid", $username));
      $this->Friend->updateFriendFromLdap();
      $this->Friend->setBugzillaID($this->getBugzillaID());
      return $this->Friend;
    }
    return new Friend();
  }

  /**
   * Sets the Friend instance.
   *
   * @param Friend $friend
   *   The Friend instance to set.
   *
   * @return void
   *
   * @deprecated
   */
  public function setFriend($friend) {
    trigger_error("Deprecated function called.", E_USER_NOTICE);
  }

  /**
   * Retrieves the Generated Session Id.
   *
   * @return string
   *   The generated session id.
   */
  public function getGID() {
    return $this->gid;
  }

  /**
   * Sets the Generated Session Id.
   *
   * @param string $gid
   *   The generated session id to set.
   */
  public function setGID($gid) {
    $this->gid = $gid;
  }

  /**
   * Generates a unique Session ID.
   *
   * The method combines a unique ID and a random number to generate
   * a hash which serves as a session ID.
   *
   * @return string
   *   The generated session ID.
   *
   * @todo Consider using a more secure hashing algorithm than md5
   * in future revisions.
   */
  public function generateGID() {
    return md5(uniqid(mt_rand(), TRUE));
  }

  /**
   * Retrieve the login page URL.
   *
   * @return string
   *   The URL of the login page.
   */
  public function getLoginPageURL() {
    return $this->login_page;
  }

  /**
   * Set the value for the `login_page` property.
   *
   * @param string $login_page
   *   The URL to be set for the login page.
   *
   * @return void
   */
  public function setLoginPage($login_page) {
    if (is_string($login_page) && filter_var($login_page, FILTER_VALIDATE_URL)) {
      $this->login_page = $login_page;
    }
  }

  /**
   * Redirect the client to the login page.
   *
   * This method prevents caching and sends a 303 See Other
   * HTTP status code to indicate a non-permanent redirect.
   *
   * @return void
   */
  public function redirectToLogin() {
    $this->App->preventCaching();
    header("Location: " . $this->login_page, TRUE, 303);
    exit;
  }

  /**
   * Retrieves the subnet associated with the session.
   *
   * @return string
   *   The associated subnet.
   */
  public function getSubnet() {
    return $this->subnet;
  }

  /**
   * Sets the subnet associated with the session.
   *
   * @param string $subnet
   *   The subnet to associate with the session.
   */
  public function setSubnet($subnet) {
    $this->subnet = $subnet;
  }

  /**
   * Retrieve the Class-C subnet of the client's IP address.
   *
   * Class-C subnet masks the last octet of the IP address to .0.
   *
   * @return string
   *   Class-C subnet of the client's IP address.
   */
  public function getClientSubnet() {
    $ipAddress = $this->App->getRemoteIPAddress();
    return substr($ipAddress, 0, strrpos($ipAddress, ".")) . ".0";
  }

  /**
   * Retrieves the last update time for the session.
   *
   * @return string
   *   The date/time of the last update on the session.
   *   Format is "Y-m-d H:i:s.u".
   */
  public function getUpdatedAt() {
    return $this->updated_at;
  }

  /**
   * Sets the last update time for the session.
   *
   * @param string $updated_at
   *   The date/time to set as the last update time.
   *   Expected format is "Y-m-d H:i:s.u".
   */
  public function setUpdatedAt($updated_at) {
    $this->updated_at = $updated_at;
  }

  /**
   * Retrieve the Eclipse username.
   *
   * @return string
   *   The Eclipse username, or empty string if not set.
   */
  public function getUsername() {
    return $this->username;
  }

  /**
   * Set the Eclipse username.
   *
   * @param string $username
   *   The username to be set.
   *
   * @return string
   *   The Eclipse username, or empty string if not set.
   */
  public function setUsername($username) {
    if (is_string($username)) {
      $this->username = $username;
    }
    return $this->username;
  }

  /**
   * Check if user has given consent to use cookies.
   *
   * @return bool
   *   True if the user has given consent, false otherwise.
   */
  public function hasCookieConsent() {
    return $this->App->hasCookieConsent();
  }

  /**
   * Determine if the user is logged in.
   *
   * @return bool
   *   True if the user is logged in, false otherwise.
   *
   * @deprecated use $this->isLoggedIn() instead.
   */
  public function getIsLoggedIn() {
    trigger_error("Deprecated function called.", E_USER_NOTICE);
    return $this->isLoggedIn();
  }

  /**
   * Determine if this session is logged in.
   *
   * @author droy
   * @since 2014-07-03
   *
   * @return bool
   */
  public function isLoggedIn() {
    return $this->getGID() != "";
  }

  /**
   * Check if session is persistent.
   *
   * Assumes session is persistent only if the user has provided cookie consent.
   *
   * @return int
   *   Returns 1 if session is persistent, otherwise 0.
   */
  public function getIsPersistent() {
    return $this->hasCookieConsent() ? 1 : 0;
  }

  /**
   * Set session persistence.
   *
   * @param mixed $_is_persistent
   *   Deprecated parameter.
   *
   * @deprecated This method is deprecated and should not be used.
   */
  public function setIsPersistent($_is_persistent) {
    trigger_error("Deprecated function called.", E_USER_NOTICE);
  }

  /**
   * Validate session based on browser cookie.
   *
   * @return bool
   *   Returns TRUE if the session is valid, FALSE otherwise.
   */
  public function validate() {
    if (!isset($_COOKIE[self::SESSION_NAME])) {
      return FALSE;
    }

    $cookie = $_COOKIE[self::SESSION_NAME];

    if ($this->load($cookie)) {
      $this->maintenance();
      return TRUE;
    }

    return FALSE;
  }

  /**
   * Load session based on GID.
   * The user must be in the same subnet for session to be valid.
   *
   * @param string $_gid
   *   The GID to use for session retrieval.
   *
   * @return bool
   *   Returns TRUE if session is successfully loaded, FALSE otherwise.
   */
  public function load($_gid) {
    if (empty($_gid)) {
      return FALSE;
    }

    // Sanitize the inputs.
    $gid = $this->App->quoteAndSanitize($_gid);
    $subnet = $this->App->quoteAndSanitize($this->getClientSubnet());

    $sql = "SELECT /* USE MASTER */ gid, bugzilla_id, subnet, updated_at, is_persistent, username
          FROM sessions
          WHERE gid = $gid
          AND subnet = $subnet";

    $result = $this->App->eclipse_sql($sql);

    if ($result && mysql_num_rows($result) > 0) {
      $myrow = mysql_fetch_assoc($result);

      $this->setGID($_gid);
      $this->setBugzillaID($myrow['bugzilla_id']);
      $this->setSubnet($myrow['subnet']);
      $this->setUpdatedAt($myrow['updated_at']);
      $this->setUsername($myrow['username']);
      $is_persistent = $this->App->quoteAndSanitize($this->getIsPersistent());
      $sql = "UPDATE sessions SET updated_at = NOW(), is_persistent = $is_persistent WHERE gid = $gid";

      $this->App->eclipse_sql($sql);
      $this->setEclipseSessionCookies();

      return TRUE;
    }

    return FALSE;
  }

  /**
   * Destroys the session.
   *
   * @param @deprecated bool $flush_all_sessions
   *   Whether to flush all sessions associated with the current user.
   */
  public function destroy($flush_all_sessions = TRUE) {
    $Friend = $this->getFriend();
    $username = $this->getUsername();
    $gid = $this->getGID();

    // Delete session by username as the user may have more than 1 session.
    if (!empty($username)) {
      $sql = "DELETE FROM sessions WHERE username = " . $this->App->quoteAndSanitize($username);
      $this->App->eclipse_sql($sql);
    }

    // Delete session by guid as fallback for compability with older versions.
    if (!empty($gid)) {
      $sql = "DELETE FROM sessions WHERE gid = " . $this->App->quoteAndSanitize($this->getGID()) . " LIMIT 1";
      $this->App->eclipse_sql($sql);
    }

    // Clear cookies.
    setcookie("TAKEMEBACK", "", 0, "/", ".eclipse.org");
    setcookie("fud_session_2015", "", 0, "/forums/", ".eclipse.org");
    setcookie(self::SESSION_NAME, "", 0, "/", $this->getDomain(), 1, TRUE);
    setcookie(self::ENV, "", 0, "/", $this->getDomain(), 0, TRUE);
  }

  /**
   * Create an Eclipse Session.
   *
   * @param string $mail
   *
   * @return void
   */
  public function create() {

    // Initializing session attributes.
    $this->setGID($this->generateGID());
    $this->setSubnet($this->getClientSubnet());
    $this->setUpdatedAt($this->App->getCURDATE());

    $Friend = new Friend();
    $this->setBugzillaID($Friend->getBugzillaIDFromEmail($this->getEmail()));

    // Construct SQL query.
    $sql = "INSERT INTO sessions (
          gid, bugzilla_id, subnet, updated_at, is_persistent, username)
          VALUES (
            {$this->App->quoteAndSanitize($this->getGID())},
            {$this->App->quoteAndSanitize($this->getBugzillaID())},
            {$this->App->quoteAndSanitize($this->getSubnet())},
            NOW(),
            {$this->App->quoteAndSanitize($this->getIsPersistent())},
            {$this->App->quoteAndSanitize($this->getUsername())})";

    $this->App->eclipse_sql($sql);

    // Log event if not in development mode.
    if (!$this->App->devmode) {
      $this->EvtLog->setLogTable("sessions");
      $this->EvtLog->setPK1($Friend->getBugzillaID());
      $this->EvtLog->setPK2($this->App->getRemoteIPAddress());
      $this->EvtLog->setLogAction("INSERT");
      $this->EvtLog->insertModLog("apache");
    }

    $this->setEclipseSessionCookies();
  }

  /**
   * Set Eclipse Session Cookies.
   *
   * @return bool
   *   Returns TRUE if the cookies were successfully set, FALSE otherwise.
   */
  public function setEclipseSessionCookies() {
    $gid = $this->getGID();

    // If GID is not set or cookies have already been sent, return FALSE.
    if (empty($gid) || $this->getCookiesSent()) {
      return FALSE;
    }

    $this->setCookiesSent(TRUE);

    // By default, cookies expire at the end of the session.
    $cookie_expiry = 0;

    // If the session is persistent, set the cookie to expire in a week.
    if ($this->getIsPersistent()) {
      // 7 days in seconds.
      $cookie_expiry = time() + (3600 * 24 * 7);
    }

    // Set the session cookie.
    setcookie(self::SESSION_NAME, $gid, $cookie_expiry, "/", $this->getDomain(), TRUE, TRUE);

    // Set an environment cookie. This ensures the session remains consistent between HTTP and HTTPS.
    // Using "S" for Secure. Further environment data can be appended as needed.
    setcookie(self::ENV, "S", $cookie_expiry, "/", $this->getDomain(), FALSE, TRUE);

    return TRUE;
  }

  /**
   * Performs maintenance tasks for sessions.
   *
   * Removes stale sessions that haven't been updated for more than 8 days.
   * This ensures that the sessions database table does not grow indefinitely
   * with old unused sessions.
   */
  public function maintenance() {
    $App = new App();

    // Delete sessions that haven't been updated for more than 8 days.
    // Users can regenerate sessions by visiting accounts.eclipse.org.
    $sql = "DELETE FROM sessions
          WHERE updated_at < DATE_SUB(NOW(), INTERVAL 8 DAY)";

    $App->eclipse_sql($sql);
  }

  /**
   * Update Friend object in Sessions table.
   *
   * @param Friend|null $Friend
   *   @deprecated The Friend object to update.
   *   We don't serialize Friend() instances anymore.
   *
   * @return bool
   *   Returns TRUE if the update is successful, FALSE otherwise.
   */
  public function updateSessionData($Friend = NULL) {
    $session_gid = $this->getGID();
    if ($session_gid) {
      $gid = $this->App->quoteAndSanitize($session_gid);

      // Update session timestamp.
      $sql = "UPDATE sessions SET updated_at = NOW(),
              WHERE gid = {$gid}";

      $this->App->eclipse_sql($sql);
      return TRUE;
    }

    return FALSE;
  }

}
