TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 09-02-2009, 12:52 PM   #1 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default Access Control List(s)?

Hey!

I'm wondering how to best achieve this thing that I want for my CMS.

First of all, I want to be able to via the code decide what pages that can be viewed by what user based on usergroup and userstatus.

An example is that some pages I want everyone to be able to see. Some pages I want only logged in members to see. And some pages I want logged in members with the usergroup of premium member(and higher) to see.

Secondly, I want to be able to decide what features that can be USED by what user based on usergroup.

An example is that .. say I have a feature called image statistic that shows the latest users who viewed another user's image in his gallery. I maybe only want admins to be able to use this feature.

And thirdly, I want the users to decide the permissions they want to use on their profile/gallery aswell.

And example is.. Say I've activated the feature image statistic for members(and higher). Then they will have access to that part of the control panel in their usercp. But I want to allow them to set who can view that "widget" on their profile/gallery. Some of the users might only want themselves to be able to see it. Some might want their friends to be able to see it. Some might want logged in users to see it. And some might want to allow this widget to be seen on their profile/gallery by guests(not logged in) - obviously only possible if the page is allowed to be viewed by guests.

Obviously, I want the users to be able to set who can view their gallery/profile aswell.

So basically, it's 4 lines of access controls.
1. I want to define what pages can be viewed by what user based on usergroup and userstatus.
2. I want to define what widgets can be used by what user based on usergroup.
3. I want users to be able to define what members can view their profile/gallery.
4. I want users to be able to define what widgets they want to use from a list of available widgets they are ALLOWED to use(read #2).

Okay, long post that leads to nothing.. or does it?
I'm wondering how I can create this the best way that provides easy to use functions that runs the checks matching the criterias above.
__________________
Tanax is offline  
Reply With Quote
Old 09-02-2009, 02:16 PM   #2 (permalink)
The Contributor
 
ioan1k's Avatar
 
Join Date: Mar 2009
Location: US
Posts: 76
Thanks: 0
ioan1k is on a distinguished road
Default

ACL lists can be quite simple to use for a basis such as this,

Here is a breakdown of how it works

All pages, widgets, features etc etc .. that you want to limit access would be considered resources

Each usergroup would be considered as roles

It would then be written in a manner such as
Code:
if (role A) can access (resource B)
    grant access
else
    deny access
Here it is in PHP ,

php Code:
class Acl {
   
    /**
     * List of roles
     */

    protected $_roles = array();
   
    /**
     * List of resources
     */

    protected $_resources = array();
   
    /**
     * List of resources with mapping for allowed roles
     */

    protected $_resourceAllow = array();
   
   
    /**
     * Instance sel of resources with mapping for allowed roles
     */

    private static $_instance = null;
   
    const ADMIN = 3;
   
    const USER = 2;
   
    const GUEST = 1;
   
    /*
     * Constructor
     *
     * Add list of roles and resources
     *
     * @param  array  roles            Array of roles
     * @param  array  resources        Array of resources
     * @param  array  resourcesAllow  Array of key => value for resource ID -> role ID allowed maps
     *
     * @return  this
     */

    private function __construct($roles, $resources, $resourceAllow)
    {
       
        if (null == $roles && null == $this->_roles) {
            throw new Exception('You must define the role, resource and allow list for first ACL call');
        }
       
        $this->_roles = $roles;
       
        $this->_resources = $resources;
       
        $this->_resourceAllow = $resourceAllow;
       
        return $this;
    }
   
    /*
     * Returns Instance of ACL
     *
     * First Call must include list of roles, resources and resourcesAllow therafter it is no longer required
     *
     * @param  array  roles            Array of roles
     * @param  array  resources        Array of resources
     * @param  array  resourcesAllow  Array of key => value for resource ID -> role ID allowed maps
     *
     * @return  this
     */

   
    public function getInstance($roles = null, $resources = null, $resourceAllow = null)
    {
        if (self::$_instance == null) {
            self::$_instance = new self();
        }
       
        return self::$_instance;
    }
   
    /*
     * Checks if role has access to resource
     *
     * @param  array  roleID      Name of role
     * @param  array  resource    Name of resource
     *
     * @return boolean
     */

    public function isAllowed($role, $resource)
    {
        // ERROR CHECKING
        if (is_string($role)) {
            $role = array_search($role, $this->_roles);
        }
       
        if (is_string($resource)) {
            $resource = array_search($resource, $this->_resources);
        }
       
        if (!is_int($role)) {
            throw new Exception('isAllowed Role expected integer for role '.gettype($role).' given');
        }
       
        if (!is_int($resource)) {
            throw new Exception('isAllowed Resource expected integer for resource '.gettype($role).' given');
        }
       
        if (!array_key_exists($role, $this->_roles)) {
            throw new Exception('Unknown RoleID given : '.$role);
        }
       
        if (!array_key_exists($resource, $this->_resources)) {
            throw new Exception('Unknown ResourceID given : '.$role);
        }
       
        // NOW FOR PERMISSION CHECKS
        if (!array_key_exists($resource, $this->_resourceAllow))
        {
            // THIS IS WHERE WE COULD SET A DEFAULT ON TO ALLOW OR DENY BASED
            // ON THIS ROLE HAVING NO ACCESS LEVELS DEFINED
           
            return true;
           
        } else {
           
            // HERE WE WILL USE A DESCENDING LEVEL FOR EXAMPLE
            // USERGROUP ROLES ARE ID
            // GUEST 1
            // USER  2
            // ADMIN 3
           
            if (!array_key_exists($role, $this->_resourceAllow[$resource])) {
                // ALLWAYS GRANT ADMIN PERMISSION THIS CAN BE REMOVED
                if ($role == self::ADMIN) {
                    return true;
                } else {
                    // deny
                    return false;
                }
            } else {
               
                // ADMINS HAVE ACCESS TO ALL
                if ($role == self::ADMIN) {
                    return true;
                }
               
                // HERE WE USE A DESCENDING CHECK
                // EVERYONE HAS ACCESS TO GUEST RESOURCES
               
                if (in_array($role, $this->_resourceAllow[$resource]) || ($role >= self::GUEST && count($this->_resourceAllow[$resource]) == 1 && $this->_resourceAllow[$resource][0] == self::GUEST) {
                    return true;
                }
               
                return true;
            }
        }
    }
}

To use this you would do the following

Have a 3 mysql tables that contain the following, assuming you already have the usergroup table you would need the following two

resources
----------------------------------------
resourceId name

resourcesAllow
----------------------------------------
resourceId roleId

Map the role that are allowed to view each resource

Example for roles

roles
------------------------------------------
roleId name


For the first call to the ACL you would do the following

php Code:
// GET ROLES
$sql = mysql_query('SELECT roleId, name FROM roles');
$roles = array();
while ($v = mysql_fetch_assoc($roles)) {
    $roles[$v['roleId']] = $v;
}
$sql = null;

// GET RESOURCES
$sql = mysql_query('SELECT resourceId, name FROM resource');
$resource = array();
while ($v = mysql_fetch_assoc($roles)) {
    $roles[$v['resourceId']] = $v;
}
$sql = null;

// GET LIST OF PERMISSIONs

$perm = array();
$sql = mysql_query('SELECT * FROM resourcesAllow');
while ($v = mysql_fetch_assoc($roles)) {
    if (array_key_exists($v['resourceId'])) {
        $perm[$v['resourceId']][] = $v['roleId'];
    } else {
        $perm[$v['resourceId']] = array();
    }
}

// INIT
$acl = Acl::getInstance($roles, $resource, $perm);

// CHECK EPRMISSION
if ($acl->isAllowed($user->groupId, 'contact_me_page')) {
    // do stuff
} else {
    // no access
}

There after it would only be
php Code:
$acl = Acl::getInstance();

// CHECK EPRMISSION
if ($acl->isAllowed($user->groupId, 'contact_me_page')) {
    // do stuff
} else {
    // no access
}

This is a very basic ACL ....

Adding a removing resources, permissions would be quite simple through the administration and users could even create their own :)

Hope this get u on a good start
__________________
My Portfolio - Work - Need freelance Work?
I've been developing 5 years now, and I learn something new everyday
ioan1k is offline  
Reply With Quote
The Following 2 Users Say Thank You to ioan1k For This Useful Post:
gamer13 (09-02-2009), Tanax (09-02-2009)
Old 09-02-2009, 03:22 PM   #3 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Thanks! I think I have a basic idea of a structure I want to use for this that will accomplish this quite easially.

The difficult part is the part to allow users to add their own permissions..

Perhaps something like this as a syntax.
php Code:
<?php

    // Create the permissionlist
    $permList = new PermissionList();
   
    // Add some roles
    $permList->addRole('admin');
    $permList->addRole('moderator');
    $permList->addRole('member');
    $permList->addRole('banned');
    // $permList->addRole(array('admin', 'moderator', 'member', 'banned'));
   
    // Add pages
    $permList->addPage('usercp', array('member', 'moderator', 'admin'));
    $permList->addPage('gallery', array('member', 'moderator', 'admin'));
    // Add a feature
    $permList->addFeature('image_statistic', array('moderator', 'admin'));
   
    // Create the permissions for the user
    $perm = new Permission($permList);
    $perm->set($user);

That's for adding pages, features and roles. Will probably fetch all the roles, features and pages from the database and iterate through the result and add them automatically.

We set the user by passing in the user object of the user so we can access the current users' usergroup for instance.

php Code:
// if user can view usercp
    if($perm->canView('usercp'))
    {
   
        // echo some usercp stuff
       
        // if user can use the image statistic feature
        if($perm->canUse('image_statistic'))
        {
       
            // echo the image statistic feature control panel
       
        }
   
    }

To see if the user viewing the page is allowed to view usercp. If they can, it checks if the user logged in can use the image statistic feature(where they will be able to set their own permissions for who can see the image statistic on their gallery).

php Code:
if($perm->canView('gallery'))
    {
   
        // echo some gallery stuff
       
        if($perm->canSee('image_statistic', $idOfGallery))
        {
       
            // echo the image statistic
       
        }
   
    }

Again, checks if the user viewing the page has access to view the page gallery. Then they check if they can see the feature image statistic in the current gallery(so we pass through the gallery id so we can check the permissions the gallery owner has set).

Does that look OK?
__________________
Tanax is offline  
Reply With Quote
Old 09-02-2009, 04:45 PM   #4 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Here's the classes. Do you see any potential problems with this setup, please tell me! And if you know how to fix it, please say that too xD

PermissionList.php
php Code:
<?php

class PermissionList
{

    private $roles = array();
    private $pages = array();
    private $features = array();

    public function addRole($role)
    {
   
        if(is_string($role))
        {
       
            $this->roles[] = $role;
       
        }
   
    }
   
    public function addPage($page, $allowedRoles)
    {
   
        if(is_string($page))
        {
       
            $this->pages[$page] = $allowedRoles;
       
        }
   
    }
   
    public function addFeature($feature, $allowedRoles)
    {
   
        if(is_string($feature))
        {
       
            $this->features[$feature] = $allowedRoles;
       
        }
   
    }
   
    public function getPermission($type, $name)
    {
   
        switch($type)
        {
       
            case 'page':
                if(array_key_exists($name, $this->pages)
                {
               
                    return $this->pages[$name];
                   
                ]
                return false;
                break;
               
            case 'feature':
                if(array_key_exists($name, $this->features)
                {
               
                    return $this->features[$name];
                   
                }
                return false;
                break;
       
        }
   
    }

}

PermissionUser.php
php Code:
<?php

class PermissionUser
{

    private $permList;
    private $user;

    public function __construct(PermissionList $object)
    {
   
        if(is_object($object))
        {
       
            $this->permList = $object;
       
        }
   
    }
   
    public function set(User $user)
    {
   
        if(is_object($user))
        {
       
            $this->user = $user;
       
        }
   
    }
   
    public function canSee($feature, $id)
    {
   
        if(is_string($feature) && is_numeric($id))
        {
       
            $query = mysql_query("SELECT * FROM `Gallery_Feature_Permissions` WHERE `g_id` = '" . $id . "' AND g_feature = '" . $feature . "'");
            $fetch = mysql_fetch_object($query);
           
            $allowedRoles = split(', ', $fetch->g_allowedRoles);
           
            foreach($allowedRoles as $role)
            {
           
                if($role == $this->user->usergroup())
                {
               
                    return true;
               
                }
           
            }
       
        }
       
        return false;
   
    }
   
    public function canView($page)
    {
   
        if(is_string($page))
        {
       
            $allowedRoles = $this->permList->getPermission('page', $page);
            $isAllowed = $this->isAllowed($allowedRoles);
           
            if($isAllowed)
            {
           
                return true;
           
            }
           
            return false;
           
        }
   
    }
   
    public function canUse($feature)
    {
   
        if(is_string($feature))
        {
       
            $allowedRoles = $this->permList->getPermission('feature', $feature);
            $isAllowed = $this->isAllowed($allowedRoles);
           
            if($isAllowed)
            {
           
                return true;
           
            }
           
            return false;
           
        }
   
    }
   
    private function isAllowed($allowedRoles)
    {
   
        if($allowedRoles != false)
        {
           
            $usergroup = $this->user->usergroup();
            if(is_array($allowedRoles))
            {
               
                foreach($allowedRoles as $role)
                {
                   
                    if($role == $usergroup)
                    {
                       
                        return true;
                       
                    }
                   
                }
                   
                return false;
               
            }
               
            if($allowedRoles == $usergroup)
            {
               
                return true;
               
            }
           
        }
       
        return false;
       
    }
       

}

usage.php
php Code:
<?php

    // Create the permissionlist
    $permList = new PermissionList();
   
    // Add some roles
    $permList->addRole('admin');
    $permList->addRole('moderator');
    $permList->addRole('member');
    $permList->addRole('banned');
    // $permList->addRole(array('admin', 'moderator', 'member', 'banned'));
   
    // Add a page
    $permList->addPage('usercp', array('member', 'moderator', 'admin'));
    $permList->addPage('gallery', array('member', 'moderator', 'admin'));
    // Add a feature
    $permList->addFeature('image_statistic', array('moderator', 'admin'));
   
    // Create the permissions for the user
    $perm = new Permission($permList);
    $perm->set($user);
   
    // if user can view usercp
    if($perm->canView('usercp'))
    {
   
        // echo some usercp stuff
       
        // if user can use the image statistic feature
        if($perm->canUse('image_statistic'))
        {
       
            // echo the image statistic feature control panel
       
        }
   
    }
   
    //
    //
    // In the gallery..
   
    if($perm->canView('gallery'))
    {
   
        // echo some gallery stuff
       
        if($perm->canSee('image_statistic', $idOfGallery))
        {
       
            // echo the image statistic
       
        }
   
    }

This way I can:
1. Manage access on pages based on usergroups
2. Manage access to certain features that the users can activate in the gallery
3. Manage access to view certain features in the gallery based on the permissions set by the owner of the gallery(of course they can only set permissions on those features that the user is allowed to activate; read #2).

I haven't tested it, because.. I don't have a user class to test it with yet, nor a database for this.. nor a website to actually test the different permissions. I just want to know if you see any problems in this solution, if it can be done better and if you think this is a good solution.

Edit: Already spot a problem with this.
I want the users to be able to have the option of allowing only users on their friendslist access a feature.. how would I do that? I can't really add that into a seperate ROLE..
__________________
Tanax is offline  
Reply With Quote
Old 09-02-2009, 06:20 PM   #5 (permalink)
Super Moderator
Inquisitive 
 
codefreek's Avatar
 
Join Date: Sep 2007
Location: Near you.
Posts: 791
Thanks: 241
codefreek is on a distinguished road
Default

at PermissionList.php,

PHP Code:
public function getPermission($type$name)
    {
    
        switch(
$type)
        {
        
            case 
'page':
                if(
array_key_exists($name$this->pages
                {
                
                    return 
$this->pages[$name];
                    
      ---->        ]
                return 
false;
                break;
                
            case 
'feature':
                if(
array_key_exists($name$this->features)
                {
                
                    return 
$this->features[$name];
                    
                }
                return 
false;
                break;
        
        }
    
    }


you have a ] when it should be } might be just a small typo when posting it on the forums just thought you should know.
codefreek is offline  
Reply With Quote
Old 09-02-2009, 06:41 PM   #6 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Quote:
Originally Posted by codefreek View Post
at PermissionList.php,

PHP Code:
public function getPermission($type$name)
    {
    
        switch(
$type)
        {
        
            case 
'page':
                if(
array_key_exists($name$this->pages
                {
                
                    return 
$this->pages[$name];
                    
      ---->        ]
                return 
false;
                break;
                
            case 
'feature':
                if(
array_key_exists($name$this->features)
                {
                
                    return 
$this->features[$name];
                    
                }
                return 
false;
                break;
        
        }
    
    }


you have a ] when it should be } might be just a small typo when posting it on the forums just thought you should know.
Hehe, it was a typo in my file aswell as on the forums, so thanks!
__________________
Tanax is offline  
Reply With Quote
Old 09-02-2009, 07:03 PM   #7 (permalink)
The Contributor
 
ioan1k's Avatar
 
Join Date: Mar 2009
Location: US
Posts: 76
Thanks: 0
ioan1k is on a distinguished road
Default

Why separate the resources into three types and have three separate methods for each one as they are doing the same thing?

Here are the files to a more advanced ACL System

It has the ability to do the following
  1. Assign resources on a level (1-4) 1 being Guest, 4 being Admin
  2. Create a parent child relationship for roles and resources
  3. Resource access is based on the following criteria.
  4. Role Group Level
  5. Specific roles granted access or denied access
  6. Specific users granted access or denied access
  7. Inherited Permissions for any parent roles
  8. Inherited permission for any parent resources
You should be able to go through and see how everything works as it is commented very well ... if you have any questions let me know
Attached Files
File Type: zip ACL.zip (44.8 KB, 19 views)
__________________
My Portfolio - Work - Need freelance Work?
I've been developing 5 years now, and I learn something new everyday
ioan1k is offline  
Reply With Quote
Old 09-02-2009, 07:55 PM   #8 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Quote:
Originally Posted by ioan1k View Post
Why separate the resources into three types and have three separate methods for each one as they are doing the same thing?
Because I think that will be the best solution for what I want to accomplish.

What if I have a feature called "blog", that would go into the resource "blog". Then also, I have a page called "blog", that would also be a resource "blog" - but wait, that won't work.. It already exists!

And lastly, how do I store the permissions set by the owner of the blog into the "blog"(as used in $perm->canSee() function which checks if the viewing user can see the "blog" in this case, based on the permission set by the owner)? I can't store it as a resource.. because there are already 2 other "blog" resources..

That is, in my opinion, a flawed system. But maybe I've misunderstood how to use this..

Quote:
Originally Posted by ioan1k View Post
Here are the files to a more advanced ACL System

It has the ability to do the following
  1. Assign resources on a level (1-4) 1 being Guest, 4 being Admin
  2. Create a parent child relationship for roles and resources
  3. Resource access is based on the following criteria.
  4. Role Group Level
  5. Specific roles granted access or denied access
  6. Specific users granted access or denied access
  7. Inherited Permissions for any parent roles
  8. Inherited permission for any parent resources
You should be able to go through and see how everything works as it is commented very well ... if you have any questions let me know
Thanks! I'll check it out!
__________________
Tanax is offline  
Reply With Quote
Old 09-02-2009, 08:09 PM   #9 (permalink)
The Contributor
 
ioan1k's Avatar
 
Join Date: Mar 2009
Location: US
Posts: 76
Thanks: 0
ioan1k is on a distinguished road
Default

Quote:
Originally Posted by Tanax View Post
Because I think that will be the best solution for what I want to accomplish.

What if I have a feature called "blog", that would go into the resource "blog". Then also, I have a page called "blog", that would also be a resource "blog" - but wait, that won't work.. It already exists!

And lastly, how do I store the permissions set by the owner of the blog into the "blog"(as used in $perm->canSee() function which checks if the viewing user can see the "blog" in this case, based on the permission set by the owner)? I can't store it as a resource.. because there are already 2 other "blog" resources..

That is, in my opinion, a flawed system. But maybe I've misunderstood how to use this..



Thanks! I'll check it out!
Yes this is true,

But you would only need to setup the resources in a different named manner.

For your blog example

feature_blog
page_blog

Each blog "owner would have say"
23_blog - 23 being their userId

Which then permissions can be set, it may seem a bit more complicated but it would be fairly the same as a naming convention that can be easily modified to suit your needs rather than having multiple methods that perform the same logic, which once your code starts scaling could lead to future bugs.

A few more examples would be

"23_blog_post_415_comment_edit" -> Resource:: UserId -> 23 Blog PostId -> 415 Comment editing

"page_aboutme_view" -> Resource:: About me page viewing

"widget_25_15_view" -> Resource:: WidgetId->25 UserId -> 15 Viewing
__________________
My Portfolio - Work - Need freelance Work?
I've been developing 5 years now, and I learn something new everyday
ioan1k is offline  
Reply With Quote
Old 09-02-2009, 08:34 PM   #10 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Quote:
Originally Posted by ioan1k View Post
Yes this is true,

But you would only need to setup the resources in a different named manner.

For your blog example

feature_blog
page_blog

Each blog "owner would have say"
23_blog - 23 being their userId

Which then permissions can be set, it may seem a bit more complicated but it would be fairly the same as a naming convention that can be easily modified to suit your needs rather than having multiple methods that perform the same logic, which once your code starts scaling could lead to future bugs.

A few more examples would be

"23_blog_post_415_comment_edit" -> Resource:: UserId -> 23 Blog PostId -> 415 Comment editing

"page_aboutme_view" -> Resource:: About me page viewing

"widget_25_15_view" -> Resource:: WidgetId->25 UserId -> 15 Viewing
Ahhh! Actually that sounds very good.

My only concern about that is.. won't there be like.. TONS of entries in that database table that has the resources?? And won't it be quite resource-demanding to search through the table if it contains tens of thousands of permission sets?
__________________
Tanax is offline  
Reply With Quote
Old 09-02-2009, 08:47 PM   #11 (permalink)
The Contributor
 
ioan1k's Avatar
 
Join Date: Mar 2009
Location: US
Posts: 76
Thanks: 0
ioan1k is on a distinguished road
Default

No it would not be of any issue you can index the resource titles, I have dealt with database tables with a over a million entries and have not seen a noticeable performance hit due to queries as long you have the database properly indexed it
__________________
My Portfolio - Work - Need freelance Work?
I've been developing 5 years now, and I learn something new everyday
ioan1k is offline  
Reply With Quote
Old 09-02-2009, 08:55 PM   #12 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Aha, that sounds great.

One more thing though. I looked through the ACL system you zipped.
First of all, it is far too advanced for me.
But I got an idea from that system, that I want for my system.

That is allowedUsers and disallowedUsers.

Basically my tables would look something like this:
Code:
Usergroups:
group_id, group_name

Resources:
res_id, res_name

Permissions:
perm_id, perm_resource, perm_allowedGroups, perm_allowedUsers, perm_disallowedUsers
My "permissions" table would basically be like your "resourcesAllow".
My "usergroups" table would basically be like your "roles".
My "perm_allowedGroups" would basically be like your "roleId" in your "resourcesAllow" table.

As you see, I added allowedUsers and disallowedUsers.
"allowedUsers" is so I can grant access to a specific user to a specific resource even if they are in a usergroup that originally DOESN'T have access to that resource.

"disallowedUsers" is so I can remove access from a specific user to a specific resource even if they are in a usergroup that originally HAVE access to that resource.

All that is good.
But how would I do that in the PHP(in the ACL class) ??
__________________
Tanax is offline  
Reply With Quote
Old 09-02-2009, 09:17 PM   #13 (permalink)
The Contributor
 
ioan1k's Avatar
 
Join Date: Mar 2009
Location: US
Posts: 76
Thanks: 0
ioan1k is on a distinguished road
Default

To check for users that are in specific allow deny situations, you can quite easily use an array of users allowed / users denied for each role so a perm array might look something like
Code:
rray(4) {
  ["Allowed Groups"]=>
  array(3) {
    [0]=>
    string(1) "1"
    [1]=>
    string(1) "2"
    [2]=>
    string(1) "3"
  }
  ["Allowed Users"]=>
  array(3) {
    [0]=>
    string(2) "45"
    [1]=>
    string(2) "34"
    [2]=>
    string(3) "123"
  }
  ["Disallowed Groups"]=>
  array(3) {
    [0]=>
    string(2) "54"
    [1]=>
    string(2) "32"
    [2]=>
    string(2) "12"
  }
  ["Disallowed Users"]=>
  array(5) {
    [0]=>
    string(2) "56"
    [1]=>
    string(2) "12"
    [2]=>
    string(3) "123"
    [3]=>
    string(2) "12"
    [4]=>
    string(2) "89"
  }
You would then simply compare them against the user you are checking just the same as you would for the groups

And you would do that logic at the same time you perform the group checking, just make sure that the user check are performed last to ensure the inheritance of permissions is correct
__________________
My Portfolio - Work - Need freelance Work?
I've been developing 5 years now, and I learn something new everyday
ioan1k is offline  
Reply With Quote
Old 09-03-2009, 08:39 AM   #14 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Yea, the inheritance of permissions is the hard part..

How would I store an array in the database btw?? You can't really store an array as it is, can you? I was thinking of storing it as a string like "54, 32, 12" and then use split(', ') on the result when I fetch the string from database.. Can that be done any better?
__________________
Tanax is offline  
Reply With Quote
Old 09-03-2009, 09:31 AM   #15 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Nevermind. I just learned about serialize and unserialize.

Here's the function I did for isAllowed.
php Code:
public function isAllowed($resource)
    {
   
        $isAllowed = false;
   
        if(is_string($resource))
        {
       
            $permissions = $this->permList->getPermission($resource);
           
            $usergroup = $this->user->group();
            $userid = $this->user->id();
           
            // If the usergroup id exists in the allowed groups
            if(array_search($usergroup->id(), $permissions['AllowedGroups']))
            {
           
                $isAllowed = true;
               
                // If the user id exists in the disallowed users
                if(array_search($userid, $permissions['DisallowedUsers']))
                {
               
                    $isAllowed = false;
               
                }
           
            }
           
            // If the usergroup id did not exist in the allowed groups
            else
            {
           
                $isAllowed = false;
               
                // If the user id exists in the allowed users
                if(array_search($userid, $permissions['AllowedUsers']))
                {
               
                    $isAllowed = true;
               
                }
           
            }
       
        }
       
        return $isAllowed;
   
    }

That way I can check
1. If the usergroup exists in AllowedGroups - allow
but if the userid exists in DisallowedUsers - deny
2. If the usergroup does not exist in AllowedGroups - deny
but if the userid exists in AllowedUsers - allow

I think..

My only question now is.. how would I let my users set a permission that only users on their friendlist is allowed to see something??
__________________
Tanax is offline  
Reply With Quote
Old 09-03-2009, 01:20 PM   #16 (permalink)
The Contributor
 
ioan1k's Avatar
 
Join Date: Mar 2009
Location: US
Posts: 76
Thanks: 0
ioan1k is on a distinguished road
Default

You should check the deny for users individually outside both checking for user allow and group allow access as the deny permission is more strict it should override an allow for specific users, other than that it looks good

To set it to where users only on the friend list can view the resource when loading the page simply append the friend list ID's to the allowed users array
__________________
My Portfolio - Work - Need freelance Work?
I've been developing 5 years now, and I learn something new everyday
ioan1k is offline  
Reply With Quote
Old 09-03-2009, 01:54 PM   #17 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Quote:
Originally Posted by ioan1k View Post
You should check the deny for users individually outside both checking for user allow and group allow access as the deny permission is more strict it should override an allow for specific users, other than that it looks good
True.. but that scenario would only occur if I set a user on the allowed list and then on the disallowed list aswell..

How would I reorganize my if-statements to do it your way then? *too tired*

Quote:
Originally Posted by ioan1k View Post
To set it to where users only on the friend list can view the resource when loading the page simply append the friend list ID's to the allowed users array
Ahhyee.. of course. Stupid me.
But when I check the allowed users array, how would I know that the ID is a friendlist or a userid ??

By the way, thanks for all the help! I'm learning tons every day about this thanks to you
__________________
Tanax is offline  
Reply With Quote
Old 09-03-2009, 02:00 PM   #18 (permalink)
The Contributor
 
ioan1k's Avatar
 
Join Date: Mar 2009
Location: US
Posts: 76
Thanks: 0
ioan1k is on a distinguished road
Default

You would simply take the if statement for the deny check and drop it below the if statement for the group and user allow check puesdo code would be

Code:
if usergroup in allowlist:
     access is true
elseif user in allowlist:
     access is true

if user in denyuserlist:
    access is false

return access
For the friends list you are going to need to add the user'sId that references their account in the database along with the friendlistID such as

Code:
FriendsList Table
---------------------------
friendID        userId
EDIT:

Quote:
True.. but that scenario would only occur if I set a user on the allowed list and then on the disallowed list aswell..
Yes this is true, but if the access is to a very critical system resource and you happen to forget that the code works this way and forget to remove them from the allow listing, they will still have access, a good basis to follow is that if someone is going to be denied something specifically for their account there is likely a good reason so you always
__________________
My Portfolio - Work - Need freelance Work?
I've been developing 5 years now, and I learn something new everyday
ioan1k is offline  
Reply With Quote
Old 09-03-2009, 03:02 PM   #19 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

Quote:
Originally Posted by ioan1k View Post
You would simply take the if statement for the deny check and drop it below the if statement for the group and user allow check puesdo code would be

Code:
if usergroup in allowlist:
     access is true
elseif user in allowlist:
     access is true

if user in denyuserlist:
    access is false

return access
Ah! I understand now. Wouldn't this be a little more efficient?
Code:
if usergroup in allowedgroups_list OR userid in allowedusers_list
     access is true

if userid in disallowedusers_list
     access is false
Quote:
Originally Posted by ioan1k View Post
For the friends list you are going to need to add the user'sId that references their account in the database along with the friendlistID such as

Code:
FriendsList Table
---------------------------
friendID        userId
EDIT:



Yes this is true, but if the access is to a very critical system resource and you happen to forget that the code works this way and forget to remove them from the allow listing, they will still have access, a good basis to follow is that if someone is going to be denied something specifically for their account there is likely a good reason so you always
Yes, I know how I would store the friendlists in the database.
Like: friendlist- userid, friendid

The problem I have though, is.. you remember this?
Code:
["Allowed Users"]=>
  array(3) {
    [0]=>
    string(2) "45"
    [1]=>
    string(2) "34"
    [2]=>
    string(3) "123"
  }
How would I know if 45, 34 and 123 are user ids or friendlist ids?? Since I store the "permissions" in a column "Allowed Users" ?

Like..

Your example about
"23_blog_post_415_comment_edit"

What if I want that user with id 23 to be allowed to have the option to allow the users on his friendlist to be able to edit the comments on his blogpost with id 415?

My tables looks like this
Code:
Usergroups:
group_id
group_name

Resources:
res_id
res_name

Permissions:
perm_id
perm_resource (<- the ID of the resource, not the name)
perm_allowedGroups
perm_allowedUsers
perm_disallowedUsers
Where would the friendlist ID's then be stored? If I store the friendlist ID in allowedUsers, the ids would be treated as user id's since it's in that column..

I'm TRYING to explain, but I'm not sure I'm explaining very good.. do you understand what I mean?
__________________
Tanax is offline  
Reply With Quote
Old 09-03-2009, 03:37 PM   #20 (permalink)
The Contributor
 
ioan1k's Avatar
 
Join Date: Mar 2009
Location: US
Posts: 76
Thanks: 0
ioan1k is on a distinguished road
Default

You wouldn't have to worry about storing the friendlist ID, you would could set an option to allow a user to set a blog post comment editing for users on his friendslist.

Then once you parse out the friendlist add the userId from the friendlist table to the allowedUsers array

So it would be something like

Code:
Fetch user friendlist
Fetch comment_edit permissions

if user allow friend edit
      append friendlist->userId's to comment_edit->userAllow

__________________
My Portfolio - Work - Need freelance Work?
I've been developing 5 years now, and I learn something new everyday
ioan1k is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
Class-Object visibility through Properties-Methods Access Modifiers sohdubom Advanced PHP Programming 7 08-21-2009 06:23 PM
PHP Access Date problems. mtsang Absolute Beginners 4 06-27-2009 04:59 PM
How do I design my access control system ? amitdgr General 4 04-21-2009 09:21 AM
MS Access via FTP Jenski Advanced PHP Programming 3 02-04-2009 03:27 PM
Building an Apache-like Access Control List (ACL) Wildhoney General 2 12-14-2007 02:03 PM


All times are GMT. The time now is 02:29 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design