<?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 (ctype_digit($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;
  }

}
