We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Need an advice for fine grained access

Hi,

Saying that I've got: 1/ categories: category_1, category_2, category_3 ... each category has many posts 2/ user roles: role_A, role_B, role_C

I know that I can use phalcon built in ACL system to define role access to controllers / actions.

But how can I set access restrictions one some particular categories ? Something like this:

1/ role_A can read post in categories category_1, category_2 (saying they are reader on this categories) 2/ role_B same as role_A but can also CRUD his own posts in category_1 (saying this role is publisher in this category) and read posts in category_3 3/ role_C has full CRUD rights on categories category_2, category_3 (saying role-C is admin on category_2 and category_3) 4/ ....

My first thought is to use cross ( many_many) tables between roles and categories: 1/ category_reader 2/ category_pulisher 3/ category_admin

Well ... I did not know if it's the best way to achieve what I want and I do not know how to implement this !

All advices are welcome.



36.0k

Look here: https://github.com/phalcon/cphalcon/issues/351

Feature you want is RLS (Row Level Security). They don't want to implement such functionallity.



98.9k

Assuming you have two entities for Categories and Roles similar to these:

mysql> select * from roles;
+----+--------+
| id | name   |
+----+--------+
|  1 | role_A |
|  2 | role_B |
|  3 | role_C |
+----+--------+
3 rows in set (0.00 sec)
mysql> select * from categories;
+----+------------+
| id | name       |
+----+------------+
|  1 | category_1 |
|  2 | category_2 |
|  3 | category_3 |
+----+------------+
3 rows in set (0.00 sec)

You could set up an entity to define what roles are allowed to specific categories:

mysql> select * from roles_categories;
+----+----------+---------------+
| id | roles_id | categories_id |
+----+----------+---------------+
|  1 |        1 |             1 |
|  2 |        1 |             2 |
|  3 |        1 |             3 |
|  4 |        2 |             1 |
|  5 |        2 |             3 |
+----+----------+---------------+
5 rows in set (0.00 sec)

Then you could set up the following method to get the allowed categories for a role:

class Roles extends Phalcon\Mvc\Model
{
        public function getAllowedCategories()
        {
                return $this->getModelsManager()
                            ->createBuilder()
                            ->from('Categories')
                            ->join('RolesCategories')
                            ->where('RolesCategories.roles_id = ?0')
                            ->getQuery()
                            ->execute(array($this->id));
        }

        public function initialize()
        {
                $this->hasMany('id', 'RolesCategories', 'roles_id');
        }

}

Usage:

$role = Roles::findFirst();
foreach ($role->getAllowedCategories() as $category) {
        echo $category->id, PHP_EOL;
}


43.9k

thank you for reply, more or less, DB design above is what I've planned to do. I realize that I can use only one table roles_categories table but with an additionnal column: "acces" (reader, publisher, admin ...) But, in fact what I want is some kind of methods for my Post model (wich belongs_to Category): isReadAble, isEditAble, isDeleteAble wich will check user's roles authorizations depending on roles_categories .