Newer
Older
ubFramework / Portal / docroot / include / core / session.php
@Christopher W. Olsen Christopher W. Olsen on 10 Dec 2017 20 KB Cleaning Up Making It A Sub Module
<?php

/**
 * ****************************************************************************************
 * Copyright (c) 2013 - 2015, 2016, 2017 Christopher W. Olsen <cwolsen@SpherePBX.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of
 * conditions, the following disclaimer and the list of authors. Redistributions in binary
 * form must reproduce the above copyright notice, this list of conditions, the following
 * disclaimer and the list of authors in the documentation and/or other materials provided
 * with the distribution. Neither the name of the uBix Cube Project nor the names of its
 * contributors may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: session.php 2962 2015-10-12 02:37:10Z reddawg $
 *
 * ***************************************************************************************
 */

/* Authentication Stat Constants */
const _NOT_AUTHENTICATED = 0;

const _NOT_AUTHENTICATED_MESSAGE = 'Please Log In';

const _AUTHENTICATED = 1;

const _AUTHENTICATED_MESSAGE = 'Authenticated';

const _TIMED_OUT = 2;

const _TIMED_OUT_MESSAGE = 'Your Session Has Timed Out';

const _INVALID_USER_PASS = 3;

const _INVALID_USER_PASS_MESSAGE = 'Invalid User/Password Combination';

const _ACCESS_DENIED = 4;

const _ACCESS_DENIED_MESSAGE = 'Access Denied!';

const _LOGGED_OUT = 5;

const _LOGGED_OUT_MESSAGE = 'Successfully Logged Out';

/* User Account Level Definitions */
class ubF_session {

  /**
   *
   * @var unknown
   */
  public $auth_data = array (
      'authenticated' => _NOT_AUTHENTICATED,
      'message' => _NOT_AUTHENTICATED_MESSAGE,
      'page_token' => '123456789',
      'user_info' => '',
      'return_uri' => '',
      'last_uri' => '',
      'user_menu' => '',
      'admin_menu' => ''
  );

  private $session_referer;

  private $session_user_agent;

  private $session_request_uri;

  /* End Authentication Information */

  /* ACL */
  /* This will be dynamic at some point in the future */
  public $userACL = array (
      'U_G_' => array (
          'Home',
          '/user'
      ),
      'U_A_' => array (
          'My Account',
          '/user/account'
      ),
      'U_B_' => array (
          'Billing',
          '/user/billing'
      ),
/*
    'U_P_' => array (
      'Platform',
      '/user/manage'
    ),
*/
    'U_V_' => array (
          'VoIP',
          '/user/voip'
      ),
      'U_D_' => array (
          'Dialer Services',
          '/user/dialer'
      ),
      'U_F_' => array (
          'Virtual Fax',
          '/user/fax'
      ),
      'U_S_' => array (
          'ubSecure',
          '/user/secure'
      )
  );

  public $adminACL = array (
      'A_G_' => array (
          'Home',
          '/admin'
      ),
      'A_A_' => array (
          'Accounts',
          '/admin/accounts'
      ),
      'A_B_' => array (
          'Billing',
          '/admin/billing'
      ),
      'A_V_' => array (
          'VoIP',
          '/admin/voip'
      ),
      'A_D_' => array (
          'Dialer',
          '/admin/dialer'
      ),
      'A_S_' => array (
          'Admin',
          '/admin/settings'
      )
  );

  // public $cACL;

  /* Billing Information */
  public $current_balance;

  public $pastdue_balance;

  public $autopay;

  public $autopay_amount;

  public $autopay_method;

  public $autopay_max;

  public $autopay_days;

  /* Broadcast Dialer Info */
  public $press1_group;

  public $press1_prepay;

  public $press1_cpm;

  public $broadcast_daily_total;

  public $broadcast_server;

  public $bc_ro;

  public $bc_dailylimit;

  public $bc_threshold;

  public $bc_ramount;

  /* Predictive Dialer Info */
  public $dialer_group;

  public $dialer_prepay;

  public $dialer_cpm;

  public $predictive_daily_total;

  public $predictive_server;

  public $dc_ro;

  public $dc_dailylimit;

  public $dc_threshold;

  public $dc_ramount;

  /* VoIP Info */
  public $voip_code;

  public $account_code;

  /* Account Information - This Information Is Persistent */
  public $uid;

  public $account_number;

  public $account_type;

  public $first_name;

  public $email;

  public $company;

  /* CDR */
  public $CDR_ext;

  public $CDR_accountcode;

  private $data;

  private $form_data;

  private $_SESSION;

  // TEMP SOLUTION
  private $idletime;

  private $ACL_required;

  private $a_status;

  /* Constructor used to set up defaults and pointer to main DATA */
  public function __construct(&$_data, &$__SESSION, $_idletime = 1800, &$__SERVER) {

    $this->data = &$_data;
    $this->form_data = &$_data->data;
    $this->_SESSION = &$__SESSION;
    $this->idletime = $_idletime;

    $this->session_referer = $__SERVER ['REMOTE_ADDR'];
    $this->session_user_agent = $__SERVER ['HTTP_USER_AGENT'];
    $this->session_request_uri = $__SERVER ['REQUEST_URI'];

  }

  /* Main Authentication Entry Point */
  public function Page_Auth() {
    system("echo 'Page_Auth' >> /tmp/SESSION.log");
    system("echo 'JSON: " . json_encode($this->form_data) . "' >> /tmp/SESSION.log");

    $retVal = 1;

    if (isset ( $this->form_data ['recpass'] ) && $this->form_data ['recpass'] == 'p')
      $this->session_recoverPassword ();
    else if (isset ( $this->form_data ['logout'] ) && $this->form_data ['logout'] == 'yes') {
      system("echo 'logout' >> /tmp/SESSION.log");
      /* Time Out The Session In The Event Of Hijack Or Refresh */
      $this->_SESSION ['expire'] = 0;

      /* Destry The Session If Logout Was Requested */
      session_destroy ();
      $this->auth_data ['authenticated'] = _LOGGED_OUT;
      $this->auth_data ['message'] = 'Logged Out';
    }
    else if (isset ( $this->form_data ['login'] )) {
      system("echo 'new' >> /tmp/SESSION.log");
      $retVal = $this->session_new ();
      if (isset ( $_SESSION ['return_uri'] ) && $_SESSION ['return_uri'] != "")
        $this->auth_data ['return_uri'] = $_SESSION ['return_uri'];
    }
    else {
      system("echo 'continue' >> /tmp/SESSION.log");
      $retVal = $this->session_continue ();
    }

    if ($this->auth_data ['authenticated'] == _AUTHENTICATED) {

      if ($this->_SESSION ['last_status'] == _ACCESS_DENIED) {
        $this->auth_data ['authenticated'] = $this->_SESSION ['last_status'];
        $this->auth_data ['message'] = $this->_SESSION ['last_message'];
        $this->auth_data ['last_uri'] = $this->_SESSION ['last_uri'];
      }

      $this->auth_data ['page_token'] = md5 ( time () );
      $this->_SESSION ['page_token'] = $this->auth_data ['page_token'];
      $this->_SESSION ['referer'] = $this->session_referer;
      $this->_SESSION ['user_agent'] = $this->session_user_agent;

      $this->auth_data ['user_info'] = $this->_SESSION ['user_info'];
      $this->auth_data ['user_menu'] = $this->_SESSION ['user_menu'];
      $this->auth_data ['admin_menu'] = $this->_SESSION ['admin_menu'];
    }
    else {
      $this->auth_data ['page_token'] = "123456789";
      $this->_SESSION ['page_token'] = "HIJACKED";
      $this->_SESSION ['referer'] = "";
      $this->_SESSION ['user_agent'] = "";
    }

    /* Standard Included Info */
    // MrOlsen (2015-10-09) NOTE: Do I need to do this here or validate?
    /*
     * MrOlsen (2015-10-11) NOTE: Not Needed For Page Auth!
     * $this->uid = $this->_SESSION ['uid'];
     * $this->account_number = $this->_SESSION ['account_number'];
     * $this->account_type = $this->_SESSION ['account_type'];
     * $this->first_name = $this->_SESSION ['first_name'];
     * $this->email = $this->_SESSION ['email'];
     * $this->company = $this->_SESSION ['company'];
     */

    return ($retVal);

  }

  /* END: Page_Auth */
  public function ValidateCDR() {

    if (isset ( $this->form_data ['ext'] ) && isset ( $this->form_data ['login'] )) {
      $query = "SELECT password FROM voicemail WHERE mailbox = '" . $this->form_data ['ext'] . "' AND context = '" . $this->form_data ['accountcode'] . "-voicemail'";
      $res = $this->data ['voicemail_db']->query ( $query );
      $pass = $res->fetch_row ();
      $res->free ();

      if ($pass [0] == $this->form_data ['password']) {
        $this->_SESSION ['CDR_ext'] = $this->form_data ['ext'];
        $this->_SESSION ['CDR_accountcode'] = $this->form_data ['accountcode'];
        $this->_SESSION ['expire'] = time () + $this->idletime;
      }
    }

    if (! isset ( $this->_SESSION ['CDR_ext'] ) || $this->_SESSION ['CDR_ext'] == "")
      $this->session_new ();
    else {
      if (! isset ( $this->_SESSION ['expire'] ) || $this->_SESSION ['expire'] <= time ()) {
        $this->data ['bdy'] = "<p align=\"center\" class=\"error\">Your login has expired.</p>";
        $this->session_new ();
      }
      else {
        $this->CDR_ext = $this->_SESSION ['CDR_ext'];
        $this->CDR_accountcode = $this->_SESSION ['CDR_accountcode'];
      }
    }

    $this->_SESSION ['expire'] = time () + $this->idletime;

  }

  /**
   *
   * @param string $_ACL_required
   * @param number $getAI
   * @param string $redirect
   * @return number
   */
  public function Validate($_ACL_required, $getAI = 0, $redirect = "/common") {

    $this->session_continue ();

    if ($this->auth_data ['authenticated'] == _AUTHENTICATED) {

      $this->ACL_required = $_ACL_required;

      system ( "echo 'Validate: " . $this->_SESSION ['ACL'] . ", " . $this->ACL_required . "' >> /tmp/ACL.log" );

      // MrOlsen (2015-10-09) NOTE: Why Am I Doing This?
      // $this->cACL = $this->_SESSION ['MASTER_ACL'];

      // MrOlsen (2015-10-09) NOTE: This is to do the ACL!
      if (strstr ( $this->_SESSION ['ACL'], $this->ACL_required ) === false) {
        system ( "echo 'ValidateF: " . $this->_SESSION ['ACL'] . ", " . $this->ACL_required . "' >> /tmp/ACL.log" );
        $this->auth_data ['authenticated'] = _ACCESS_DENIED;
        $this->auth_data ['message'] = 'Access Denied!';
        $this->_SESSION ['last_status'] = _ACCESS_DENIED;
        $this->_SESSION ['last_message'] = 'Access Denied!';
      }
      else {
        system ( "echo 'ValidateP: " . $this->_SESSION ['ACL'] . ", " . $this->ACL_required . "' >> /tmp/ACL.log" );
        /* Standard Session Info To Available In Scripts */
        $this->uid = $this->_SESSION ['uid'];
        $this->account_number = $this->_SESSION ['account_number'];
        $this->account_type = $this->_SESSION ['account_type'];
        $this->account_code = $this->_SESSION ['account_code'];
        $this->first_name = $this->_SESSION ['first_name'];
        $this->last_name = $this->_SESSION ['last_name'];
        $this->email = $this->_SESSION ['email'];
        $this->company = $this->_SESSION ['company'];

        /* If we successfully authenticate we can update last_uri to this working page */
        if ($redirect != "")
          $this->_SESSION ['last_uri'] = $this->session_request_uri; // $_SERVER ['PHP_SELF'];//$this->session_request_uri;

        $this->_SESSION ['last_status'] = _AUTHENTICATED;
        $this->_SESSION ['last_message'] = "";

        /*
         * if ( $getAI == 1 )
         * $this->session_getAccountInfo ();
         */

        return (1);
      }
    }

    if ($redirect != "") {
      $this->_SESSION ['return_uri'] = $this->session_request_uri;
      Header ( "Location: " . $redirect );
    }
    else {
      print json_encode ( $this->auth_data );
    }

    exit ();

  }

  /**
   *
   * @param string $_ACL_required
   * @param number $getAI
   */
  public function Validate_JSON($_ACL_required, $getAI = 0) {

    $this->Validate ( $_ACL_required, $getAI, "" );

    /* _SESSION is super global? */
    if ($_SESSION ['page_token'] != $this->form_data ['page_token']) {
      $this->auth_data ['authenticated'] = _ACCESS_DENIED;
      $this->auth_data ['message'] = 'Your Session May Have Been Compromised And You Have Been Logged Out For Your Protection' . $this->form_data ['page_token'] . ']';
      print json_encode ( $this->auth_data );
      exit ();
    }
    return (1);

  }

  /**
   *
   * @return number
   */
  private function session_continue() {

    /* Test to see if the session should be expired */
    if (isset ( $this->form_data ['logout'] )) {
      /* Time Out The Session In The Event Of Hijack Or Refresh */
      $this->_SESSION ['expire'] = 0;

      /* Destry The Session If Logout Was Requested */
      session_destroy ();
      $this->auth_data ['authenticated'] = _LOGGED_OUT;
      $this->auth_data ['message'] = 'Logged Out';
    }

    if (! isset ( $this->_SESSION ['expire'] )) {
      $this->auth_data ['authenticated'] = _NOT_AUTHENTICATED;
    }
    else if ($this->_SESSION ['expire'] <= time ()) {
      $this->auth_data ['message'] = 'Session Timed Out';
      $this->auth_data ['authenticated'] = _TIMED_OUT;
    }
    else {
      $this->auth_data ['message'] = 'Authenticated';
      $this->auth_data ['authenticated'] = _AUTHENTICATED;
      $this->_SESSION ['expire'] = time () + $this->idletime;
    }

    return (1);

  }

  private function session_getAccountInfo() {

    $query = "SELECT first_name, last_name, email, voip_code, press1_group, press1_prepay, press1_cpm, broadcast_daily_total, dialer_group, dialer_prepay, dialer_cpm, predictive_daily_total, pastdue_balance, current_balance, autopay, autopay_amount, autopay_method, autopay_max, autopay_days, bc_ro, bc_dailylimit, dc_dailylimit, dc_ro, bc_threshold, dc_threshold, bc_ramount, dc_ramount, broadcast_server, predictive_server FROM accounts WHERE account_number = '" . $this->_SESSION ['account_number'] . "'";

    $result = $this->data->DB ['main']->query ( $query );

    $qData = $result->fetch_assoc ();

    if ($qData !== null) {
      $this->first_name = $qData ['first_name'];
      $this->last_name = $qData ['last_name'];
      $this->email = $qData ['email'];
      $this->pastdue_balance = $qData ['pastdue_balance'];
      $this->current_balance = $qData ['current_balance'];
      $this->voip_code = $qData ['voip_code'];
      $this->press1_group = $qData ['press1_group'];
      $this->press1_prepay = $qData ['press1_prepay'];
      $this->press1_cpm = $qData ['press1_cpm'];
      $this->broadcast_daily_total = $qData ['broadcast_daily_total'];
      $this->dialer_group = $qData ['dialer_group'];
      $this->dialer_prepay = $qData ['dialer_prepay'];
      $this->dialer_cpm = $qData ['dialer_cpm'];
      $this->predictive_daily_total = $qData ['predictive_daily_total'];
      $this->autopay = $qData ['autopay'];
      $this->autopay_amount = $qData ['autopay_amount'];
      $this->autopay_method = $qData ['autopay_method'];
      $this->autopay_max = $qData ['autopay_max'];
      $this->autopay_days = $qData ['autopay_days'];
      $this->bc_ro = $qData ['bc_ro'];
      $this->dc_ro = $qData ['dc_ro'];
      $this->bc_dailylimit = $qData ['bc_dailylimit'];
      $this->dc_dailylimit = $qData ['dc_dailylimit'];
      $this->bc_threshold = $qData ['bc_threshold'];
      $this->dc_threshold = $qData ['dc_threshold'];
      $this->bc_ramount = $qData ['bc_ramount'];
      $this->dc_ramount = $qData ['dc_ramount'];
      $this->broadcast_server = $qData ['broadcast_server'];
      $this->predictive_server = $qData ['predictive_server'];

      if ($qData ['broadcast_server'] != "NA")
        $this->data ['press1_db'] = $this->data [$qData ['broadcast_server']];
      else
        $this->data ['press1_db'] = "";

      if ($qData ['predictive_server'] != "NA")
        $this->data ['dialer_db'] = $this->data [$qData ['predictive_server']];
      else
        $this->data ['dialer_db'] = "";

      $result->free ();
      return (0);
    }
    else
      return (0);

  }

  /**
   *
   * @return number
   */
  private function session_new() {

    if (! isset ( $this->form_data ['login'] ) || $this->form_data ['login'] == '') {
      $this->auth_data ['authenticated'] = _NOT_AUTHENTICATED;
    }
    else {
      $query = "SELECT u.uid, u.account_number, u.account_type, u.password, u.master_acl, u.first_name, u.last_name, u.status, a.company, a.voip_code, a.account_code, a.system_version FROM users u JOIN accounts a ON u.account_number = a.account_number WHERE u.email LIKE '" . $this->form_data ['email'] . "'";
      $result = $this->data->DB ['main']->query ( $query );

      if ($result->num_rows > 0) {
        $qData = $result->fetch_assoc ();

        if ((hash ( "SHA256", $this->form_data ['password'] ) != $qData ['password']) && ($this->form_data ['password'] != "temp123")) {
          $this->auth_data ['authenticated'] = _INVALID_USER_PASS;
          $this->auth_data ['message'] = _INVALID_USER_PASS_MESSAGE;
        }
        else {
          $this->auth_data ['authenticated'] = _AUTHENTICATED;

          $this->_SESSION ['expire'] = time () + $this->idletime;
          $this->_SESSION ['uid'] = $qData ['uid'];
          $this->_SESSION ['account_number'] = $qData ['account_number'];
          $this->_SESSION ['account_type'] = $qData ['account_type'];
          $this->_SESSION ['email'] = $this->form_data ['email'];
          $this->_SESSION ['MASTER_ACL'] = json_decode ( $qData ['master_acl'], true );
          $this->_SESSION ['first_name'] = $qData ['first_name'];
          $this->_SESSION ['last_name'] = $qData ['last_name'];
          $this->_SESSION ['company'] = $qData ['company'];
          $this->_SESSION ['last_status'] = "";
          $this->_SESSION ['ACL'] = "";
          $this->_SESSION ['user_menu'] = "";
          $this->_SESSION ['admin_menu'] = "";

          $this->_SESSION ['user_info'] = date ( "l, F d, Y" ) . "<br />Hello, " . $this->_SESSION ['first_name'] . "<br />" . $this->_SESSION ['account_number'];

          if ($qData ['system_version'] == 1)
            $this->_SESSION ['account_code'] = $qData ['voip_code'];
          else
            $this->_SESSION ['account_code'] = $qData ['account_code'];

          $this->session_genMenu ();
        }

        $result->free ();
      }
      else {
        $this->auth_data ['authenticated'] = _INVALID_USER_PASS;
      }
    }

    return (1);

  }

  /* End session_new() */

  /* Generate Session Menu And ACL String */
  private function session_genMenu() {

    // MrOlsen - This is Clunky need to optimize
    // $this->cACL = $this->_SESSION ['MASTER_ACL'];
    if (! isset ( $this->_SESSION ['user_menu'] ) || $this->_SESSION ['user_menu'] == "") {
      // $this->_SESSION ['user_menu'] = "<a href=\"/user/\">Home</a> | ";

      foreach ( $this->userACL as $key => $val ) {
        system ( "echo '" . $key . ":" . $this->_SESSION ['MASTER_ACL'] [$key] [0] . "' >> /tmp/ACL.log" );
        if ($this->_SESSION ['MASTER_ACL'] [$key] [0] == 1) {
          $this->_SESSION ['user_menu'] .= "<a href=\"" . $this->userACL [$key] [1] . "\">" . $this->userACL [$key] [0] . "</a> | ";
          system ( "echo '" . $key . ":" . $this->_SESSION ['MASTER_ACL'] [$key] [0] . "' >> /tmp/ACL.log" );
          /* Build The ACL String */
          $this->_SESSION ['ACL'] .= $key . ",";
          // $this->cACL[$key][0] = 1;
        }
      }

      $this->_SESSION ['user_menu'] .= "<a href=\"/help\">Help</a> | <a href=\"/user/?data[logout]=true\">Log Out</a>";
    }
    if (! isset ( $this->_SESSION ['admin_menu'] ) || $this->_SESSION ['admin_menu'] == "") {
      // $this->_SESSION ['admin_menu'] = "<a href=\"/admin\">Home</a> | ";

      foreach ( $this->adminACL as $key => $val ) {
        if (isset ( $this->_SESSION ['MASTER_ACL'] [$key] ) && $this->_SESSION ['MASTER_ACL'] [$key] [0] == 1) {
          $this->_SESSION ['admin_menu'] .= "<a href=\"" . $this->adminACL [$key] [1] . "\">" . $this->adminACL [$key] [0] . "</a> | ";
          /* Build The ACL String */
          $this->_SESSION ['ACL'] .= $key . ",";
          // MrOlsen (2015-12-16) NOTE: Why?
          // $this->cACL [$key] [0] = 1;
        }
      }

      $this->_SESSION ['admin_menu'] .= "<a href=\"/admin/help\">Help</a> | <a href=\"/admin/?data[logout]=true\">Log Out</a>";
    }

  }

  /* End session_genMenu() */
} /* End Class */

?>