CakePHP Access Allocation on Role Based specific D

2020-07-30 02:19发布

My project requirement is something like this:

On Top, there will be Administrator, who will have all d access, first level

Under Administrator, there will be Department Heads, who will have all d access, apart from Creating Department Heads

Under Department Head, there will Other Members, who will be managing their allocated department wise data.

Now, all different department heads will have their own information and members, and all department heads / Members will have access to their own specific records, which they are entering / managing.

Now, with CakePHP's ACL Component, I can divide the roles and their access level, but all department heads can see the other department head's information, as they will have same level of access, and All Other Members can see the other members information on diff departments, as of they will have same level of access.

My project complexity is that - they should be visible only their assigned or created information / data, though they have same level / role assignments as of others.

Can anyone suggest me best suitable option, to manage all these things with already available plug-ins with CakePHP.

I can work by customizing the default ACL Component, but that will take some more amount of time, than what is expected.

Any better ideas / suggestions would be appreciated !

1条回答
闹够了就滚
2楼-- · 2020-07-30 02:57

the way i see it, ACL is not that magical. For exemple: ACL could manage the permissions to tell who has access to add/edit/remove a product.. but it wont be able to change a query to filter the products accordingly to the defined permissions (like "users from department A can only see products from department A").. well actually that's a lie, ACL could manage that but it might not be practical, because every time you add a product you'd have to create an ACO, and set the permission in the AROS_ACOS table and since the AROS is a tree structure, so it could easily become a nigthmare, if your planning to query your data

I'd use a group-only ACL to control the access to certain pages/actions and make rules like:

  • "Department Head can access the page 'products list' and add/delete/modify products"
  • "Administrators can access all pages"
  • "Other users can access 'products list' and they can add products but not delete them"

and i'd adjust my queries accordingly to the connected user, so in the controller of 'products list' page, i'd do something like:

  • If connected user blongs to Department Head then select all products where product.department_id=connected_user.department_id
  • If connected user is Admin then select all products

if you have too much queries and you dont want to do thousands of if's sentences, you could create a component, a behavior or maybe extend the find() method in the app_model. The idea is to catch all queries and check if one of the models used on the query have field called "department_id", if they do then add the model.department_id=connected_user.department_id condition to the query.

I did that for one website that can be seen in multiple languages and each language has it's own users, data, logs, etc., and there's one Admin that can see all the info.. and it's working great for me =)

Good Luck!

EDITED: the behavior i use is:

<?php 
class LocalizableBehavior extends ModelBehavior { 

    /** 
     * Filter query conditions with the correct `type' field condition. 
     */ 
    function beforeFind(&$model, $query) 
    {
        /**
         * Condition for the paginators that uses joins
        */
        if(isset($query['joins']) && !empty($query['joins'])){
            foreach($query['joins'] as $key => $joinTable){
                if(ClassRegistry::init($joinTable['alias'])->hasField('lang')){
                    $query['joins'][$key]['conditions'][] = $joinTable['alias'].".lang = '".$_SESSION['lang']."'";
                }
            }
        }

        /**
         * condition for the normal find queries
        */
        if($model->hasField('lang') && $model->name != "User"){
                $query['conditions'][$model->name.'.lang'] = $_SESSION['lang'];
        }
        return $query;
    }

} 
?>

it's quite simple really, i change the query to add a condition to match to the current language ($_SESSION['lang']). In the controller all i need to do is to attach the LocalizableBehavior and use find method as usual:

$this->Products->find('all');
查看更多
登录 后发表回答