<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /** * MX_Acl - Access Control library * * Save this file as application/libraries/MX_Acl.php * $autoload['libraries'] = array('mx_acl', ... ); * $config['cache_path'] must be set * * @copyright Copyright (c) Wiredesignz & Maxximus 2009-04-20 * @version 0.12 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ class MX_Acl { var $uri, $config, $session, $cache_path;
function __construct($config = array()) { $ci =& get_instance(); $ci->load->helper('url'); $ci->load->library('session');
/* previous flashdata is available to views */ $ci->load->vars($config['error_var'], $this->session->flashdata($config['error_var']));
/* run the access control check now */ ($config['check_uri']) AND $this->check_uri(); }
/** * Check the current uri and user privileges against the cached ACL array * Redirect if access is denied * * @return void */ function check_uri() {
/* Load the cached access control list or show error */ (is_file($cached_acl = $this->cache_path.'mx_acl'.EXT)) OR show_error($this->config['error_msg']);
$acl = include $cached_acl;
/* Match current url to access list */ if (is_array($acl) AND $acl = $this->match_uri($this->current_uri(), $acl)) {
/* Check session group against access level group */ $allow_access = (bool)(in_array($this->session->userdata($this->config['session_var']), $acl['allowed']));
/* Additional check to allow IP addresses in range */ if ( ! $allow_access AND isset($acl['ipl'])) $allow_access = $this->check_ip($acl['ipl']);
if ($allow_access == FALSE) {
/* Set a return url into the session */ $this->session->set_userdata('return_url', $this->uri->uri_string());
/* set the error message... */ $error_msg = (isset($acl['error_msg'])) ? $acl['error_msg'] : $this->config['error_msg'];
/* set a flash message... */ $this->session->set_flashdata($this->config['error_var'], $error_msg);
/** * Return the access control profile for a given url * * @return string * @param string $current_uri * @param array $acl */ function match_uri($current_uri, $acl) { if (array_key_exists($current_uri, $acl)) { return $acl[$current_uri]; } else { if ($pos = strripos($current_uri, '/')) { return $this->match_uri(substr($current_uri, 0, $pos), $acl); } } }
/** * Returns the first 2 or 3 segments from the current uri * * @return string */ function current_uri() { if ($this->uri->total_segments() == 2) { return $this->uri->slash_rsegment(1).$this->uri->rsegment(2); } return $this->uri->slash_rsegment(1).$this->uri->slash_rsegment(2).$this->uri->rsegment(3); }
/** * Checks the remote IP address against the specified $ipl array * * @return bool * @param array $ipl * @param string $remote_ip[optional] */ function check_ip($ipl, $remote_ip = NULL) {
/* Convert ip address into a double (for lousy OSes)*/ $remote_ip = floatval(ip2long(($this->session->userdata('ip_address'))));
/* Loop through the ip list array */ foreach ($ipl as $allowed_ip) {
/* Replace '*' (for IP ranges) with a suitable range number */ $min = str_replace("*", "0", $allowed_ip); $max = str_replace("*", "255", $allowed_ip);
/* Check for a match */ if (($remote_ip >= floatval(ip2long($min))) AND ($remote_ip <= floatval(ip2long($max)))) { return TRUE; } } } }
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /** * MX_Acl configuration * * Save this file as application/config/mx_acl.php */ $config = array( 'check_uri' => TRUE, 'error_var' => 'error', 'error_msg' => 'You don\'t have sufficient access rights to view this page!', 'session_var' => 'role_id', );
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /** * This is the cached access control list * * save this file as {cache_path}/mx_acl.php */ return array( 'setting/update' => array( // the "module/controller/method" to protect 'allowed' => array(1), // the allowed user role_id array 'ipl' => array('127.0.0.1'), // the allowed IP range array 'error_uri' => site_url('secure/setting'), // the url to redirect to on failure 'error_msg' => 'You do not have permission to update this page!', ), 'page/update' => array( 'allowed' => array(1, 2, 3), 'ipl' => array('127.0.0.0','127.0.0.*'), 'error_uri' => (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : site_url('secure/page'), 'error_msg' => 'You do not have permission to update this page!', ), );
MX_Acl does not require any interaction from your controllers.
MX_Acl checks the URI and session userdata “role_id” (and IP address) against its cached access control list and automatically redirects if access is denied to that user.
Session flashdata is set with your access denied “error_msg” and session userdata “return_url” is set with the current URI in case you wish to return to the same location after a login procedure.
Most of the configuration variable names are customizable to suit your own application.
Actually, the much preferred way would be for you to create the cached access control list file each time you add or edit the acl information in the database.
The script you use to edit the database would create the file. File access is much faster than database. And not all applications have a full blown user management system, so MX_Acl lists can be added/updated manually also.
Best of both worlds.
EDIT:
Another possibility to investigate would be an “access_rules” method in your controller, similar to the method used by Yii framework.
The MX_Acl library would then call the current controller to obtain the acl array rather than use a cached file.
Just out of curiosity: Why are you using php4 code here and php5 at hmvc?
Ofcourse it’s easy to upgrade to php5, wich i will do.
Thank you for the library:)
Off-topic:
I think not everybody is realising php6 is not backward compatible with php4,
php5 is compatible with php6, so writing php5 code only is good practise if you are using php5.
I know your answer is going to be: to support people who have a php4 server only.
But i’m curious how many people on this forum don’t have the possibility to upgrade to php5.
I don’t think there are many.
And i think not everybody is realising the fact that if they are using php4 custom code in codeigniter,
while they are having php5 server,
they have to upgrade all the code when they are going to upgrade to php6…
Because when an update of codeigniter comes wich is compatible to php6 they don’t rewrite your custom code for you!
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /** * MX_ACL - Access Control Library PHP5 * * Notes: * $config['cache_path'] must be set * * Install this file as application/libraries/MX_ACL.php * * @copyright Copyright (c) Wiredesignz & Maxximus 2009-11-03 * @version 1.1 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ class MX_ACL { private $_config, $_cache_path;
/* previous flashdata is available to views */ $this->load->vars($this->_config['error_var'], $this->session->flashdata($this->_config['error_var']));
/* run the access control check now */ ($this->_config['check_uri']) AND $this->check_uri(); }
/** * Check the current uri and user privileges against the cached ACL array * Redirect if access is denied * * @return void */ public function check_uri() {
/* Load the cached access control list or show error */ (is_file($cached_acl = $this->_cache_path.'mx_acl'.EXT)) OR show_error($this->_config['error_msg']);
$acl = include $cached_acl;
/* Match current url to access list */ if (is_array($acl) AND $acl = $this->match_uri($this->current_uri(), $acl)) {
/* Check session group against access level group */ $allow_access = (bool)(in_array($this->session->userdata($this->_config['session_var']), $acl['allowed']));
/* Additional check to allow IP addresses in range */ if ( ! $allow_access AND isset($acl['ipl'])) $allow_access = $this->check_ip($acl['ipl']);
if ($allow_access == FALSE) {
/* Set a return url into the session */ $this->session->set_userdata('return_url', $this->uri->uri_string());
/* set the error message... */ $error_msg = (isset($acl['error_msg'])) ? $acl['error_msg'] : $this->_config['error_msg'];
/* set a flash message... */ $this->session->set_flashdata($this->_config['error_var'], $error_msg);
/** * Return the access control profile for a given url * * @return string * @param string $current_uri * @param array $acl */ private function match_uri($current_uri, $acl) { if (array_key_exists($current_uri, $acl)) { return $acl[$current_uri]; } else { if ($pos = strripos($current_uri, '/')) { return $this->match_uri(substr($current_uri, 0, $pos), $acl); } } }
/** * Returns the current uri string from segments * * @return string */ private function current_uri() { return implode('/', $this->uri->rsegments); }
/** * Checks the remote IP address against the specified $ipl array * * @return bool * @param array $ipl * @param string $remote_ip[optional] */ private function check_ip($ipl, $remote_ip = NULL) {
/* Convert ip address into a double (for lousy OSes)*/ $remote_ip = floatval(ip2long(($this->session->userdata('ip_address'))));
/* Loop through the ip list array */ foreach ($ipl as $allowed_ip) {
/* Replace '*' (for IP ranges) with a suitable range number */ $min = str_replace("*", "0", $allowed_ip); $max = str_replace("*", "255", $allowed_ip);
/* Check for a match */ if (($remote_ip >= floatval(ip2long($min))) AND ($remote_ip <= floatval(ip2long($max)))) { return TRUE; } } }
public function __get($var) { static $CI; (is_object($CI)) OR $CI = get_instance(); return $CI->$var; } } /* End of file MX_ACL.php */ /* Location: ./application/libraries/MX_ACL.php */