<?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 && mysqli_num_rows($result) > 0) {
      $myrow = mysqli_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;
  }

}
