[eluser]Twisted1919[/eluser]
Hi, these days i was faced to implement a kind of ACL to a project , to be more specific , there will be more groups , and every group will have it's access rights on controller actions .
I've never implemented an ACL system before and i can't use a library because the project is in an advanced phase .
I came up with a "library" for this , and i would like to know your thoughts about it .
It's not very advanced , but it works .
Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Acl{
private static $ci ;
private static $message = array();
private static $tbl_ugp ; //Permissions db table.
private static $tbl_us ; //Sections db table.
private static $info = array() ;
public function __construct()
{
self::$ci =& get_instance();
self::$tbl_ugp = config_item('tbl_users_groups_permissions');
self::$tbl_us = config_item('tbl_users_sections');
self::$message['SECTION_NO_VIEW'] = "You don't have enough privileges to view this section";
self::$message['SECTION_NO_ACCESS'] = "You don't have enough privileges to access this section";
self::$message['SECTION_NO_ADD'] = "You don't have enough privileges to add content to this section";
self::$message['SECTION_NO_EDIT'] = "You don't have enough privileges to edit content in this section";
self::$message['SECTION_NO_DELETE'] = "You don't have enough privileges to delete content from this section";
}
/*
* @param array $info
* */
public static function set_data($info)
{
if( is_array($info) && count($info) > 0 )
{
foreach($info AS $key=>$value)
{
self::$info[$key] = $value ;
}
}
}
/*
* @param string $key
* @return mixed bool|string
* */
public function get_data($key)
{
if( array_key_exists($key,self::$info) )
{
return self::$info[$key] ;
}
return FALSE ;
}
/*
* @param string $section
* @param string $action
* */
public static function check_access($section,$action)
{
$section = strtolower($section);
$action = strtolower($action);
$sql = 'SELECT ug.allow
FROM '.self::$tbl_ugp.' ug
INNER JOIN '.self::$tbl_us.' us ON us.section_id=ug.section_id
WHERE ug.group_id="'.(int)self::get_data('group_id').'" AND
us.name="'.self::$ci->db->escape_str($section).'" AND
ug.action="'.self::$ci->db->escape_str($action).'" LIMIT 1';
$query = self::$ci->db->query($sql);
if( $query->num_rows() > 0 )
{
$row = $query->row();
switch($action)
{
case 'view':
if( $row->allow == 'no' ){ show_error(self::$message['SECTION_NO_VIEW']); }
break;
case 'add':
if( $row->allow == 'no' ){ show_error(self::$message['SECTION_NO_ADD']); }
break;
case 'edit':
if( $row->allow == 'no' ){ show_error(self::$message['SECTION_NO_EDIT']); }
break;
case 'delete':
if( $row->allow == 'no' ){ show_error(self::$message['SECTION_NO_DELETE']); }
break;
}
}
else
{
show_error(self::$message['SECTION_NO_ACCESS']);
}
}
/*
* @param string $section
* @param string $action
* @return bool
* */
public static function has_access($section,$action)
{
$section = strtolower($section);
$action = strtolower($action);
$sql = 'SELECT ug.allow
FROM '.self::$tbl_ugp.' ug
INNER JOIN '.self::$tbl_us.' us ON us.section_id=ug.section_id
WHERE ug.group_id="'.(int)self::get_data('group_id').'" AND
us.name="'.self::$ci->db->escape_str($section).'" AND
ug.action="'.self::$ci->db->escape_str($action).'" LIMIT 1';
$query = self::$ci->db->query($sql);
if( $query->num_rows() > 0 )
{
$row = $query->row();
switch($action)
{
case 'view':
if( $row->allow == 'no' ){ return FALSE; }else{ return TRUE ; }
break;
case 'add':
if( $row->allow == 'no' ){ return FALSE; }else{ return TRUE ; }
break;
case 'edit':
if( $row->allow == 'no' ){ return FALSE; }else{ return TRUE ; }
break;
case 'delete':
if( $row->allow == 'no' ){ return FALSE; }else{ return TRUE ; }
break;
default:
return FALSE ;
break;
}
}
else
{
return FALSE;
}
}
/*
* @param string $key
* @return mixed bool|string
* */
public function show_message($key)
{
if( array_key_exists($key,self::$message) )
{
return self::$message[$key] ;
}
return FALSE ;
}
}
Now , i have my MX_Controller(bc i am using HMVC) in which i set the $info array with required data, such as user_id and group_id .
In my controllers/methods i have something like :
Code:
public function __construct()
{
parent::__construct();
Acl::check_access('cms-pages','view');
}
//
public function create()
{
[...]
if( ! Acl::has_access('cms-pages','add') )
{
show_error( Acl::show_message('SECTION_NO_ADD') );
}
[...]
}
In my database , i have the users/groups tables and also i have a table where i store my
"sections" and one in which i set the permission for each section,if need i can provide the tables structure .
Is this a good approach ?
If you have any advices, please let me know .
Thanks .