09-01-2018, 11:51 AM (This post was last modified: 09-01-2018, 12:11 PM by jreklund.)
Here's how I'm building it.
Code:
Position, department and security are a group type. And I'm loading different acl_categories based on type.
position
IT
Economy
Marketing
department
Sweden
Norway
Finland
Denmark
security
Admin
Sysadmin
Useradmin
jreklund
IT [position]
Marketing [position]
menu.create
menu.read
menu.update (this ACL can change your documents as well)
menu.delete
Sweden [department]
menu.read (You can only be a member, using the menu.read for member here)
Sysadmin [security]
users.crud
accounting.crud
...
Main-menu-name [IT,Economy,Marketing,Sweden...]
(Sub-menus here)
Economy [IT,Economy,Sweden,Norway]
(folders here)
Folder1 [IT]
(These documents are only I able to see)
Folder2 (no group specified, using parents group)
(Both you and I can see these documents)
Staff
...
Here is what I found limited.
ACL can only be assigned to a user.
- I need to create ACL access on groups. So that I can assign menus, folders, documents etc to a group.
- I then assign users CRUD to that specific group. So it will give me Delete access on some documents, but not all.
Levels and roles + Groups
- I need to be able to have ~3000 groups. So I guess I would have to create (generate from db) an array of 0-5000 with e.g. IT, Economy etc in your $config['levels_and_roles']. And assign value 4319 (or w/e it have been incremented into) to a user, as it can't be a duplicate.
- Change $config['groups'] so that it would be $config['groups'] = '4319' => '10,154,890,2940' so that one user can be in multiple groups.
- Now I can somewhat use require_group() to see if they are in multiple groups. But it would be very hard to track.
I would also need to assign CRUD (up to 4pcs action_id) on every menu item (e.g. 30 pcs) = 4 x30 = 120. So I need 120 action_code's and assign them to a user. And I got around 500 of them. 60 0000 for just menu items. :-)
And that's not something you can create a if statement on. As everything are dynamic.
So now I got
acl_categories [menu]
acl_actions [create|read|update|delete]
acl_users_and_groups [user_id,group_id,action_id | ... ]
Now I only need to assign a user to a group and define CRUD.
menu
menu_groups
acl_users_and_groups
Now I can use acl_group_permits('menu.read', $menu_groups, $menu_id) and it will check if my user are in that group and have read permissions. If It can't find a group, it will look for a user_id and object_id (also stored in acl_users_and_groups). So that I can store user specific CRUD for a specific menu item.
____________________________________________
Hopefully this will make this clearer on how I'm building my SAAS application with multiple companies (with ~10 users) that are naming their Groups, Menus, Documents etc all different.
So for everyday use I would like to see a:
users
groups
user_group*
acl [user_id,group_id,action_id]
*I skipped this and used menu.read as membership. But that's not really good for general usage.
So that you can assign ACL to a group and not to every single member.
Personally I would get rid of "Levels and roles" and "Groups" as they are right now. Maybe leave just "Roles" with admin, manager, customer for small application usage. And not forcing the user to use require_min_level() for checking if you are logged in.
I have also made some small changes here and there, but at this time of writing I can't think it will have any impact on general use. Just modifying it into my application.
- Stripping out: tokens, serialization, encryption, cookie, require_min_level, require_group, require_role etc
A taste of how my controller looks for my attached image.
I'm using UUIDv4 for all auto_incremented values. So that a user can't guess another group_id, action_id etc. And I'm of course checking that they match what the controller generated.
PHP Code:
public function groups( $user_id ) { $this->VALID_UUIDv4($user_id); $this->load->model('acl_model'); $this->load->model('group_model');
// Make sure that "read" action are always selected for a group $acl = $this->acl_model->_acl_action_code_required($acl, $this->data['acl_menu'], 'read');
// Validate ACL. Show 404 in case a user have changed the values. if( $acl === FALSE) { show_404(); }
// What groups have we received $acl_groups = array_keys($acl);
// Validate groups. Show 404 in case a user have changed the values. if( !empty(array_diff($acl_groups, $groups)) ) { show_404(); }
// Make an ACL array so that we can just save it $data = $this->acl_model->_get_data_user_group($user_id, $acl);