ACL System

Post modules, themes or any other code you want to share with the community.

Moderator: Developers

webwolfi
Posts: 616
Joined: Sat May 27, 2006 7:54 am
Location: Vienna/Austria

ACL System

Postby webwolfi » Tue May 15, 2007 7:25 am

Can anyone give me a very small overview about the ACL system?

How are read/write permissions set and stored?

Thanks a lot!
mschering
Site Admin
Site Admin
Posts: 8154
Joined: Tue Apr 20, 2004 1:06 pm
Location: The Netherlands - Den Bosch
Contact:

Postby mschering » Tue May 15, 2007 7:49 am

It's really simple.

You want permissions on an addressbook.

Then you give the address book an acl_read and acl_write id.
You can get them with:

$acl_read=$GO_SECURITY->get_new_acl();

Then you add a user to it:

$GO_SECURITY->add_user_to_acl($user_id, $acl_read);

or group:

$GO_SECURITY->add_group_to_acl($group_id, $acl_read);


What does this do in the database?

Create a entry in acl_items
Create entries in acl

The add_user_to_acl does:

Table acl

acl_id/user_id/group_id
$acl_read/$user_id/0

The add_group_to_acl does:

Table acl

acl_id/user_id/group_id
$acl_read/0/$group_id


If you want to check if a user has access to that acl id you can do:

$GO_SECURITY->has_permission($GO_SECURITY->user_id, $acl_read);

$GO_SECURITY->user_id = the current logged in user

That's all :)
Best regards,

Merijn Schering
Intermesh
webwolfi
Posts: 616
Joined: Sat May 27, 2006 7:54 am
Location: Vienna/Austria

Postby webwolfi » Tue May 15, 2007 9:17 am

you are simply the best!
sven-teichmann
Posts: 11
Joined: Fri Aug 12, 2011 8:45 am
Location: Germany
Contact:

Re: ACL System

Postby sven-teichmann » Fri Sep 30, 2011 5:23 pm

Lets say I want to check if a user has access to my self written module. How to do that?

I think this has to be done with the function has_permission($user_id, $acl_id, $groups_only=false) but I don't know where to get the acl_id.
Sven Teichmann
mschering
Site Admin
Site Admin
Posts: 8154
Joined: Tue Apr 20, 2004 1:06 pm
Location: The Netherlands - Den Bosch
Contact:

Re: ACL System

Postby mschering » Mon Oct 10, 2011 7:05 am

The module acl can be accesed with:

$GO_MODULES->modules['yourmodule']['acl_id'];

BUt you also have:

$GO_MODULES->modules['yourmodule']['write_permission']
$GO_MODULES->modules['yourmodule']['read_permission']
Best regards,



Merijn Schering

Intermesh
richarddodd
Posts: 66
Joined: Fri Jun 21, 2013 2:55 pm

Re: ACL System

Postby richarddodd » Fri May 16, 2014 5:18 pm

As far as I can tell this has changed quite a bit, and it took some digging to find all the relevant bits of code. Here's the syntax you need now:

#### Per-module permissions
To check a user's permission for a module, do something like

Code: Select all


GO
::user()->getModulePermissionLevel('module_name');
 


#### Per-model permissions
To check a user's permission for a model, do something like

Code: Select all


GO_Base_Model_Acl
::hasPermission($model->getPermissionLevel(), GO_Base_Model_Acl::CREATE_PERMISSION);
 

or

Code: Select all


$model
->checkPermissionLevel(GO_Base_Model_Acl::SOME_PERMISSION);
 

where `$model` is an instance of `GO_Base_Db_ActiveRecord`.

Normally though the acl condition/values will be automatically added to the sql query. This is better as it is faster than checking the permission for each model, but sometimes you do need these functions.
mschering
Site Admin
Site Admin
Posts: 8154
Joined: Tue Apr 20, 2004 1:06 pm
Location: The Netherlands - Den Bosch
Contact:

Re: ACL System

Postby mschering » Mon May 19, 2014 3:13 pm

Yes, my previous examples are outdated indeed. Thanks for sharing!
Best regards,



Merijn Schering

Intermesh
richarddodd
Posts: 66
Joined: Fri Jun 21, 2013 2:55 pm

Re: ACL System

Postby richarddodd » Thu May 22, 2014 12:28 pm

There have also been some times when I have had to write some custom SQL whilst respecting ACL.

This can be done as part of the SQL, for example to select contacts from `ab_contacts` you would do: (sql_calc_found_rows and limit start, limit are optional, used for paging)

Code: Select all

SELECT DISTINCT SQL_CALC_FOUND_ROWS `contact`.`id`, ...<more fields here>... FROM `ab_contacts` `contact`
INNER JOIN `ab_addressbooks` `addressbook`
    ON `addressbook`.`id` = `contact`.`addressbook_id`
INNER JOIN `go_acl` `acl`
    ON `addressbook`.`acl_id` = `acl`.`acl_id`
LEFT JOIN `go_users_groups` `group`
    ON `acl`.`group_id` = `group`.`group_id`
WHERE (
    `acl`.`user_id` = :userid
    OR `group`.`user_id` = :userid
) ...<custom wheres>...
LIMIT :start, :limit


The parameters :start and :limit are just numbers chosen somehow, and :userid is `GO::user()->id`. If you want a specific permission add

Code: Select all

AND `acl`.`level` >= :level

to the where clause, where :level is a constant from `GO_Base_Model_Acl` e.g. `GO_Base_Model_Acl::READ_PERMISSION`.

Explanation:
Join the table with the ACL field (there may/will be more than 1 acl field per record), then join with the usergroups many-many field. The acl for users will have a 0 for the group id, so we do a `LEFT` join to make sure those aren't discarded. Then we see if the user either has an acl for himself, or is in a group with an acl. The `DISTINCT` at the top makes sure that if there is more than 1 acl record, we discard all but 1.

The advantage of this over the programmatic method is that it will be MUCH FASTER as there is only 1 query.
richarddodd
Posts: 66
Joined: Fri Jun 21, 2013 2:55 pm

Re: ACL System

Postby richarddodd » Thu May 22, 2014 12:30 pm

@Merijn

Maybe the programmatic stuff should be on the wiki? I know it took me a long time to figure all this stuff out.

Rich

Return to “Contributed development”

Who is online

Users browsing this forum: No registered users and 1 guest