-
Notifications
You must be signed in to change notification settings - Fork 0
sentry
A simple security system [work in progress].
The sentry system uses a configurable database table, which is configurable and only saves minimal information to the session. It makes use of the [url=http://www.thzero.com/programming/nativesession.php]NativeSession library[/url]. I use the Sentry class in conjunction with the Filter system.
I would recommend installing the NativeSession and Sentry libraries to the system\libraries folder so that is is available across applications. The init script can handle the sentry system being in either the application or system libraries folder. Both the NativeSession and Sentry libraries should be set as autoloaded core libraries.
The Sentry system is made up of the following components:
- SentryLib core library class in the system\library\Sentry.php
- The initializer in the system\init\init_sentry.php
- The configuration in the system\application\config\sentry.php
- The sentry helper file in system\helper\sentry.php
- The Sentry controller class in the system\application\controllers\sentry.php
- The sample index view in the system\application\views\sentry\index.php
- The sample sentry filter filter in the system\application\filters\sentry.php
SentryLib core library handles the heavy lifting of performing the security functions. [code] <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /**
- Code Igniter
- An open source application development framework for PHP 4.3.2 or newer
- @package CodeIgniter
- @author Rick Ellis
- @copyright Copyright (c) 2006, pMachine, Inc.
- @license http://www.codeignitor.com/user_guide/license.html
- @link http://www.codeigniter.com
- @since Version 1.0
- @filesource */
// ------------------------------------------------------------------------
/**
- SentryLib Class
- Security handler that provides functionality to handle logins and logout
- requests. It also can verify the logged in status of a user and permissions.
- The class requires the use of the Database and Encrypt CI libraries and the
- URL CI helper. It also requires the use of the 3rd party NativeSession
- library. It is recommend that the Sentry and NativeSession libraries be placed
- in the system\libraries folder and the init files be placed in the system\init
- folder. The Sentry library should be auto loaded in the core classes section
- of the autoloader.
- @package CodeIgniter
- @subpackage Libraries
- @category Security
- @author Chris Schletter
*/
class SentryLib { function SentryLib() { $this->obj =& get_instance();
log_message('debug', "SentryLib Class Initialized");
$this->obj->load->library('encrypt');
$this->obj->load->library('nativesession');
$this->obj->load->helper('url');
}
//
// Checks to see if a user has an explicit permission.
// Returns true if sentry system is not activated.
// Returns the true if the permission is granted, otherwise false.
//
function hasPermission($permission_id)
{
if (!$this->obj->config->item('sentry'))
return true;
// Stub function.
return true;
}
//
// Checks to see if a user is an administrator.
// Returns true if sentry system is not activated.
// Returns true if admin, otherwise false.
//
function isAdmin()
{
if (!$this->obj->config->item('sentry'))
return true;
// Stub function.
return true;
}
//
// Checks to see if a user is logged in.
// Returns true if sentry system is not activated.
// Returns the user_id if valid, otherwise false.
//
function isValidUser()
{
if (!$this->obj->config->item('sentry'))
return true;
if ($this->obj->session)
{
$user_id = $this->obj->session->userdata('user_id');
if ($user_id != false)
return $user_id;
}
return false;
}
//
// Performs the login procedure.
//
function login()
{
if (!$this->obj->config->item('sentry'))
return;
if ($this->obj->session)
{
$username = $this->obj->input->post($this->obj->config->item('sentry_user_name_field'), TRUE);
$password = $this->obj->input->post($this->obj->config->item('sentry_user_password_field'));
if (($username != false) && ($password != false))
{
$password = $this->obj->encrypt->hash($password, 'md5');
//Use the input username and password and check against 'users' table
$this->obj->db->where($this->obj->config->item('sentry_user_name_field'), $username);
$this->obj->db->where($this->obj->config->item('sentry_user_password_field'), $password);
$query = $this->obj->db->get($this->obj->config->item('sentry_user_table_name'));
//die("[".$username."][".$password."][".$query->num_rows()."]");
if ($query->num_rows() > 0)
{
$row = $query->row();
$user_id = $row->id;
$credentials = array('user_id' => $user_id);
$this->obj->session->set_userdata($credentials);
$this->obj->db->set('last_visit', date ("Y-m-d H:i:s"));
$this->obj->db->where($this->obj->config->item('sentry_user_id_field'), $user_id);
$this->obj->db->update($this->obj->config->item('sentry_user_table_name'));
$this->obj->session->set_flashdata('sentry_status', $this->obj->config->item('sentry_login_message'), 2);
redirect($this->obj->config->item('sentry_success_action'), 'location'); //On success redirect user to default page
}
}
}
//On error send user back to login page, and add error message
$this->obj->session->set_flashdata('sentry_status', $this->obj->config->item('sentry_invalid_user_message'), 1);
redirect($this->obj->config->item('sentry_fail_action'), 'location');
}
//
// Performs the logout procedure.
//
function logout()
{
if (!$this->obj->config->item('sentry'))
return;
if ($this->obj->session)
{
$user_id = $this->obj->session->userdata('user_id');
if ($user_id != false)
$this->obj->session->unset_userdata('user_id');
}
$this->obj->session->set_flashdata('sentry_status', $this->obj->config->item('sentry_logout_message'));
redirect($this->obj->config->item('sentry_success_action'), 'location');
}
}
?> [/code]
The Sentry installation script installs the sentry class once and only once. [code] <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /**
- Code Igniter
- An open source application development framework for PHP 4.3.2 or newer
- @package CodeIgniter
- @author Rick Ellis
- @copyright Copyright (c) 2006, pMachine, Inc.
- @license http://www.codeignitor.com/user_guide/license.html
- @link http://www.codeigniter.com
- @since Version 1.0
- @filesource */
// ------------------------------------------------------------------------
/**
- Loads and instantiates sentry class and loads the configuration.
- It is recommend to place the file in the system\init folder and the Sentry
- class in the system\library folder. The file can also reside in the
- application\init folder.
- Configuration script should be placed in the application\config folder.
- @package CodeIgniter
- @subpackage Libraries
- @category Security
- @author Chris Schletter
*/
log_message('debug', "init_sentry"); if (!class_exists('SentryLib')) { require_once((file_exists(APPPATH.'libraries/sentry'.EXT) ? APPPATH : BASEPATH).'libraries/sentry'.EXT);
$obj =& get_instance();
if (file_exists(APPPATH.'config/sentry'.EXT))
{
$config =& $obj->config->config;
include_once(APPPATH.'config/sentry'.EXT);
}
$obj->sentry = new SentryLib();
$obj->ci_is_loaded[] = 'sentry';
} ?> [/code]
The configuration allows you to set various configuration options and tailor the sentry library to your system without a lot of reworking of code. [code] <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
| /* |
|---|
| Sentry |
| -------------------------------------------------------------------------- |
| | 'sentry' = TRUE/FALSE (boolean). Whether the sentry system is turned on. | 'sentry_user_table_name' = The name of the table that stores user information. | 'sentry_user_id_field' = The name of the primary key field. | 'sentry_user_name_field' = The name of the user name field. | 'sentry_user_password_field' = The name of the password field. | 'sentry_index_action' = The action to display the login. | 'sentry_login_action' = The action to perform login. | 'sentry_success_action' = The action after successful logon or logout. | 'sentry_fail_action' = The action on login failure. | 'sentry_logon_label' = Label for the logon anchor. | 'sentry_logout_label' = Label for the logout anchor. | 'sentry_invalid_user_message' = Flash message on login failure. | 'sentry_login_message' = Flash message on login success. | 'sentry_logout_message' = Flash message on logout success. | */ $config['sentry'] = TRUE; $config['sentry_user_table_name'] = 'user'; $config['sentry_user_id_field'] = 'id'; $config['sentry_user_name_field'] = 'user_name'; $config['sentry_user_password_field'] = 'password'; $config['sentry_random_image_key'] = TRUE; $config['sentry_index_action'] = 'sentry/index'; $config['sentry_login_action'] = 'sentry/login'; $config['sentry_success_action'] = ''; $config['sentry_fail_action'] = 'sentry/index'; $config['sentry_logout_action'] = 'sentry/logout'; $config['sentry_logon_label'] = 'Logon'; $config['sentry_logout_label'] = 'Logoff'; $config['sentry_invalid_user_message'] = 'Invalid user.'; $config['sentry_login_message'] = 'You have successfully logged in.'; $config['sentry_logout_message'] = 'You have successfully logged out.'; ?> [/code]
Sentry helper wraps SentryLib calls to make them easier to use from views. [code] <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /**
- Code Igniter
- An open source application development framework for PHP 4.3.2 or newer
- @package CodeIgniter
- @author Rick Ellis
- @copyright Copyright (c) 2006, pMachine, Inc.
- @license http://www.codeignitor.com/user_guide/license.html
- @link http://www.codeigniter.com
- @since Version 1.0
- @filesource */
// ------------------------------------------------------------------------
/**
- Sentry Helpers
- @package CodeIgniter
- @subpackage Helpers
- @category Security
- @author Chris Schletter */
// ------------------------------------------------------------------------
//
// Checks to see if a user has an explicit permission.
// Returns true if sentry system is not activated.
// Returns the true if the permission is granted, otherwise false.
//
function hasPermission($permission_id)
{
$obj =& get_instance();
return $obj->sentry->hasPermission($permission_id);
}
//
// Checks to see if a user is an administrator.
// Returns true if sentry system is not activated.
// Returns true if admin, otherwise false.
//
function isAdmin()
{
$obj =& get_instance();
return $obj->sentry->isAdmin();
}
//
// Checks to see if a user is logged in.
// Returns true if sentry system is not activated.
// Returns the user_id if valid, otherwise false.
//
function isValidUser()
{
$obj =& get_instance();
return $obj->sentry->isValidUser();
}
function loginAnchor($logout_attributes = null, $login_attributes = null) { $obj =& get_instance(); return (isValidUser() ? anchor($obj->config->item('sentry_logout_action'), $obj->config->item('sentry_logout_label'), $logout_attributes) : anchor($obj->config->item('sentry_index_action'), $obj->config->item('sentry_logon_label'), $login_attributes)); }
?> [/code]
System controller class routes calls to the SentryLib library. [code] <?php /**
- Code Igniter
- An open source application development framework for PHP 4.3.2 or newer
- @package CodeIgniter
- @author Rick Ellis
- @copyright Copyright (c) 2006, pMachine, Inc.
- @license http://www.codeignitor.com/user_guide/license.html
- @link http://www.codeigniter.com
- @since Version 1.0
- @filesource */
// ------------------------------------------------------------------------
/**
- Sentry Controller Class
- Security controller that provides functionality to handle logins and logout
- requests. It also can verify the logged in status of a user and permissions.
- The class requires the use of the NativeSession and Sentry libraries.
- @package CodeIgniter
- @subpackage Libraries
- @category Security
- @author Chris Schletter
*/ class Sentry extends Controller { function __construct() { parent::Controller(); $this->obj =& get_instance(); }
function index()
{
$this->load->view($this->obj->config->item('sentry_index_action'));
}
function login()
{
$this->sentry->login();
}
function logout()
{
$this->sentry->logout();
}
function forgot_password()
{
}
} ?> [/code]
Sample index.php view for the sentry library. [code] <form id="loginform" method="post" action="<?=site_url($this->config->item('sentry_login_action'))?>">
Username: <input type="text" name="<?=$this->config->item('sentry_user_name_field')?>" id="<?=$this->config->item('sentry_user_name_field')?>" maxlength="30" class="loginitem" size="30"/>
Password: <input type="password" name="<?=$this->config->item('sentry_user_password_field')?>" id="<?=$this->config->item('sentry_user_password_field')?>" maxlength="30" class="loginitem" size="30"/>
<input type="submit" name="login" id="login" value="login" class="submitbutton" />
</form> [/code]A sample filter for the Filter library. [code] <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /**
-
Authentication filter */ class Sentry_filter extends Filter { function before($class = null, $method = null) { $obj =& get_instance();
!$obj->sentry->check($class, $method));} } ?> [/code]
Sample filter config for the Filter library. [code] $filter['sentry'] = array('exclude', array('/', 'sentry/*')); [/code]
- Original author: Derek Jones
- How to extend helpers: See User Guide
- Modified by: Thomas Stapleton (id, classes, selected country option and all option)
- Modified by: Bradley De-Lar (construct, setLayout example)