Welcome Guest, Not a member yet? Register   Sign In
Help with RBAC System / User Authentication - Permissions
#1

[eluser]eclectic01[/eluser]
I'm trying to develop an RBAC model for a content management system we are developing.

The company I work for has a very agile approach towards developing web applications and the core specification often gets rewritten several times during the development phase and we end up with a project vastly different from what we started with. The idea with this CMS is to develop something flexible enough to not warrant starting from scratch with every project.

With that in mind, apart from the core CMS features (authentication, templating etc) everything else will fall into modules that can be plugged in if desired.

I've decided to handle the permissions / roles problem first before any further development.

Here is the database schema that I've gone for:

Database Schema

# Resources contains a list of modules e.g. 'Blog', each with a unique module id.
# To reduce the number of queries, I've used a Modified Preorder Tree Traversal way of storing the groups information in the database and I'm using a bit of code I found in the wiki to do with nested sets to organise and display this information.

My check_permissions function looks a little like this:

Code:
function check_permissions($user_id, $resource_id, $action)
    {
        // Getting the variables from the URI for testing purposes

        $user_id = $this->uri->segment(3,1);
        $resource_id = $this->uri->segment(4,1);
        $action = $this->uri->segment(5,1);
        
        // The join and ordering by left val is done to return the groups in order of
        // hierarchy in the tree

        $this->db->select('*');
        $this->db->from('users_to_groups');
        $this->db->join('groups', 'users_to_groups.group_id = groups.group_id');
        $this->db->where('user_id', $user_id);
        $this->db->order_by("leftval", "asc");
        $group_query = $this->db->get();
        
        // by default access is denied
        $access = false;

        foreach($group_query->result() as $row):
            
            $this->db->where('resource_id', $resource_id);
            $this->db->where('group_id', $row->group_id);
            $this->db->where('description', $action);
            $permissions_query = $this->db->get('permissions');
            
            // if permission is found - access is given
            if($permissions_query->num_rows() > 0):
                $access = true;
            endif;
        
        endforeach;    
        
        if($access):
            echo 'Permission Granted';
        else:
            echo 'Permission Denied';
        endif;
    
    }

The only problem that I can see with this system at the moment is that if the group structure was similar to this:

Admins
--Super Admin
--Normal Admin

and a specific permission was applied to the Admin group, my permissions function would not grant access to the user who was part of the Super Admin because the rules are not cascaded down.

Does anyone know how I could modify the code above to achieve this?

the MPTT code that I'm using is available here: http://codeigniter.com/wiki/Nested_sets/
#2

[eluser]eclectic01[/eluser]
Had a thought about this last night, does anyone forsee any problems with this method:

Code:
// if permission is found - access is given
      if($permissions_query->num_rows() > 0):
           $access = true;
      else:
          // whilst parent_node != root node
             // get parent node
                // run the check to see if rules exist
                   // if rules exist, set access = true


      endif;

The only problem is the number of queries I have to run to go through each parent node in the group tree. Considering the whole permissions function only executes 2 queries so far, it seems a shame to introduce so many of them now.
#3

[eluser]eclectic01[/eluser]
Think I've got it, code commented in case anyone else requires it:

Code:
function check_permissions($user_id, $resource_id, $action)
    {
        $user_id = $this->uri->segment(3,1);
        $resource_id = $this->uri->segment(4,1);
        $action = $this->uri->segment(5,1);
        
        // query to get groups user belongs to
        $this->db->select('*');
        $this->db->from('users_to_groups');
        $this->db->join('groups', 'users_to_groups.group_id = groups.group_id');
        $this->db->where('user_id', $user_id);
        $this->db->order_by("leftval", "asc");
        $group_query = $this->db->get();
        
        // by default access is denied
        $access = false;
        
        // begin permissions check
        foreach($group_query->result() as $row):
            
            // if not root node
            if($row->leftval != 1):
                
                // get ancestors
                $this->db->where('leftval < ', $row->leftval);
                $this->db->where('rightval > ', $row->rightval);
                $this->db->order_by('leftval', 'desc');
                $ancestor_group_query = $this->db->get('groups');
                
                // start permissions query
                $query_str = "SELECT * FROM (`permissions`)
                              WHERE
                                `resource_id` = '" . $resource_id . "' AND
                                `description` = '" . $action . "' AND
                                (`group_id` = '" . $row->group_id .  "'";
                              
                // now include ancestor groups
                foreach($ancestor_group_query->result() as $ancestor_row):
                    $query_str .= " OR `group_id` = '" . $ancestor_row->group_id . "'";
                endforeach;
                
                $query_str .= ")";
                
                // get query                
                $permissions_query = $this->db->query($query_str);
                
                // if permission exists - set access to true
                if($permissions_query->num_rows() > 0):
                    $access = true;
                else:
                    $access = false;
                endif;

            endif;
            
        endforeach;    
        
        if($access):
            echo 'Permission Granted';
        else:
            echo 'Permission Denied';
        endif;
    
    }
#4

[eluser]Unknown[/eluser]
hi i am interested in implementing ACL User Access
could you please explain the relationship of the tables I am somewhat
confused

greetings I hope is not too much trouble




Theme © iAndrew 2016 - Forum software by © MyBB