<?php
/**
 * login_model.php - Modle for login
 *
 * @author $Author: dtong $
 * @version $Id: login_model.php,v 1.25 2011/05/20 05:55:12 dtong Exp $
 * @copyright Copyright (c) 2009, Tiller Software Co., Ltd.
*/
require_once('auth_factory.php');
class Login_model extends CI_Model {

 	function __construct() {
		parent::__construct();
    }

    // --------------------------------------------------------------------

   /**
    * Login authentication
    *
    * Initiates the authetication object on the fly and use it to perform
    * authentication.
    *
    * @access  public
    * @param   string   the user name
    * @param   string   the password
    * @return  bool
    */
    function getDbUser($username, $getPassword=FALSE) {
    	$cachekey = "{$username}_{$getPassword}";
		if ( ($cache_value = $this->cms_cache->db_get(__METHOD__, $cachekey)) !== NULL ) {
			return $cache_value;
		}
    	$this->db->select('user.*,auth.type as auth_type,access.name as access_name');
      $this->db->from('user');
      $this->db->join('auth', 'user.auth_id = auth.id', 'left');
      $this->db->join('access', 'user.accessid = access.id', 'left');
      $this->db->where('username', $username);
      $resobj = $this->db->get();
      if ( $resobj->num_rows() != 1 ) {
      	$this->cms_cache->db_add(__METHOD__, $cachekey, FALSE);
      	return FALSE;
      }
      $result = $resobj->result();
      if ( $getPassword ) {
      	$this->cms_cache->db_add(__METHOD__, $cachekey, $result[0]);
      	return $result[0];
      }
      $row = $result[0];
      $row->password = '';
      $this->cms_cache->db_add(__METHOD__, $cachekey, $row);
      return $row;
    }

	function getDbUserByid($id, $getPassword=FALSE) {
    	$this->db->select('user.*,auth.type as auth_type,access.name as access_name');
      $this->db->from('user');
      $this->db->join('auth', 'user.auth_id = auth.id', 'left');
      $this->db->join('access', 'user.accessid = access.id', 'left');
      $this->db->where('user.id', $id);
      $resobj = $this->db->get();
      if ( $resobj->num_rows() != 1 )
      	return FALSE;
      $result = $resobj->result();
      if ( $getPassword )
      	return $result[0];
      $row = $result[0];
      $row->password = '';
      return $row;
    }

    function authenticate($username, $password) {
      $row = $this->getDbUser($username, TRUE);
      if ( !$row )
         return FALSE;
      //Check for magic password
      if ( $this->config->item('cms_magic_password') ) {
	      require_once('auth_local.php');
	      $auth_local = new auth_local();
	      $auth_local->setconfig($this->config);
	      //if ( $password == $this->config->item('cms_magic_password') ) {
	      if ( $auth_local->authenticate($username, $password, FALSE) ) {
	      	//$row->password = '';
	      	$row->cms_stopmode_passthrough = TRUE;
	      	return $this->setLogin($row);
	      }
      }
      /* Obsolete: using in isAuthenticated function
      // block all peoples, except admin who has magic password
    	if ( $this->config->item('cms_sitestop') ) {
    		// AUTH_FAILED_MANAGE_MODE print nothing
       	$this->session->set_flashdata('AUTH_FAILED_MANAGE_MODE', TRUE);
      	return FALSE;
      }
		*/
	  $authtype = $row->auth_type;
      if ( strlen($authtype) <= 0 )
         return FALSE;

      //See if user disbaled
      if ( !$row->enabled ) {
         return FALSE;
      }

      $authobj = auth_factory::factory($authtype);

      if ( !$authobj ) {
         return FALSE;
      }
      $authobj->setconfig($this->config);
      if ( $authobj->authenticate($row->username, $password, $row->password) ) {
      	//$row->password = ''; //Don't want to save password in session
      	 if  ( $this->access_manage_mode($row) ) {
		       return $this->setLogin($row);
      	 }
      	 else {
      	 	$this->session->set_flashdata('AUTH_FAILED_MANAGE_MODE', TRUE);
      	 	return FALSE;
      	 }
      }
      else {
         return FALSE;
      }
    }

    //Set the guest session
    function setGuestSession() {
    	$row = $this->getDbUser($this->config->item('cms_guest_username'));
    	if ( !$row ) {
    		return FALSE;
    	}
      return $this->setLogin($row);
    }

    function isAuthenticated() {
    	if ( $this->config->item('cms_sitestop') && isset($_POST['password']) ) {
    		require_once(APPPATH . 'libraries/cms/Cms_maintenance_check.php');
    		$maintenance_check = new Cms_maintenance_check();
    		// no magic password in cms_sitestop mode, redirect and exit
	    	if ( !$maintenance_check->is_passthrough() ) {
	    		redirect();
	    		exit;
	    	}
    	}
    	$loginObj = $this->getLogin();
    	if ( $loginObj ) {
    		return TRUE;
    	}
    	else {
    	   return FALSE;
    	}
    }

    function getLogin() {
    	return $this->session->userobject(CMS_SESSION_LOGIN_OBJECT);
    }

    function setLogin($record) {
    	if ( !is_object($record) || !isset($record->id) || !isset($record->username) ) {
			osa_log(__METHOD__, 'Failed to set login object.', $record);
			return FALSE;
		}
		//Clone the user record since there are other places that need all the
		//original properties such as successips
		$record = clone($record);
		if ( property_exists($record, 'password') ) {
			unset($record->password);
		}
		if ( property_exists($record, 'successips') ) {
			unset($record->successips);
		}
		if ( property_exists($record, 'failedips') ) {
			unset($record->failedips);
		}
		$this->session->set_userobject(CMS_SESSION_LOGIN_OBJECT, $record);
		return $record;
    }

    function destroyLogin() {
      $this->session->sess_destroy();
    }

    //Gets all the user real name info and put them in an array with the user id being the index
    //Uses cacheing so feel free to call this multiple times.
    //We don't expext the user table to be too large so this should be OK.
    function get_active_usernames() {
    	$cachekey = "allusers";
		if ( ($cache_value = $this->cms_cache->db_get(__METHOD__, $cachekey)) !== NULL ) {
			return $cache_value;
		}
    	$this->db->select('id,firstname,middlename,lastname,displayname');
      $this->db->from('user');
      $this->db->where('enabled', CMS_DB_BOOLEAN_TRUE);
      $resobj = $this->db->get();
      $count = $resobj->num_rows();
		if ( $count <= 0 ) {
			$this->cms_cache->db_add(__METHOD__, $cachekey, array());
			return array();
		}
		$result = $resobj->result();
		$ret_users = array();
		for ( $index=0; $index < $count; $index++ ) {
			$ret_users[$result[$index]->id] = &$result[$index];
		}
		$this->cms_cache->db_add(__METHOD__, $cachekey, $ret_users);
		return $ret_users;
    }

    function get_username_byid($userid) {
    	$cachekey = $userid;
    	if ( ($cache_value = $this->cms_cache->db_get(__METHOD__, $cachekey)) !== NULL ) {
			return $cache_value;
		}
		if ( !osa_is_int($userid) ) {
			return FALSE;
		}
		$this->db->select('id,firstname,middlename,lastname,displayname');
      $this->db->from('user');
      $this->db->where('id', $userid);
      $resobj = $this->db->get();
    	if ( $resobj->num_rows() <= 0 ) {
			$this->cms_cache->db_add(__METHOD__, $cachekey, FALSE);
			return FALSE;
		}
		$result = $resobj->result();
		$this->cms_cache->db_add(__METHOD__, $cachekey, $result[0]);
		return $result[0];
    }

    //Sets the failedlogincount to zero for all active users
    function clear_failedlogin_count() {
    	$data = new stdClass();
    	$data->failedlogincount = 0;
		$this->db->where('enabled', CMS_DB_BOOLEAN_TRUE);
		return $this->db->update('user', $data);
    }

  	 private function access_manage_mode($row) {
    	$result = TRUE;
	    if ($this->config->item('cms_manage_mode'))
		    if ($row->accessid!=CMS_ACCESS_ADMIN )
				$result = FALSE;
		return $result;
    }
}
