Cakephp 2.0 row/record-level Acl - acl

i am messing around with the cakephp 2.0's access lists,
so far i created a very simple example following the documentation.
I have set up a users table and the most important functions like index, add, login ecc. and is related to a groups table (every user belongs to a group).
I've also created a "houses" table wich contain different contents (houses).
Then i've set up auth in combination with the acl-component in crud mode,
including the aco and aro tree.
So far so good, everything is working so far, i can allow or deny single actions for every user.
But, i want further access control, that for instance a user can manage only a specific house.
So i've set up an aco for every house, allowed only read-access to the houses to the user and allowed update access only for the desired house.
But it won't work! No matter what i do.. i don't get access to the edit action.
Here my trees:
Aco:
[1] Houses
[5] House.1
[6] House.2
[2] Users
Aro:
[1] superadmin
[4] User.1
[1] admin
[5] User.2
[7] User.4
[3] customer
[6] User.3
And finally the aros_acos table:
id aro_id aco_id _create _read _update _delete
4 1 1 1 1 1 1
5 1 2 1 1 1 1
6 2 1 1 1 1 1
7 3 1 0 1 0 0
8 7 1 -1 1 1 -1
9 7 5 1 1 1 1
Fact is, that, if i try to do a quick check with:
var_dump($this->Acl->check(
array('model' => 'User',
'foreign_key' => 4),
array('model' => 'House',
'foreign_key' => 1),
'update'));
It gives back true!
Strange... Am i doing something wrong? Is there any way to decently debug the acl component (with information wich acos and aros the component is checking, seeing ecc.)?

Based on your aro_aco table, it looks like this is correct behavior. User.4 belongs to the admins group which has update permission. set to true in row 8. You have a rule in row 8 specifically for User.4, but you have granted update permission specifically to that user in that row. It appears that the ACL rules are working exactly as you have them setup. To prevent User.4 from using the update permission, run this at the cake command line to update your rules for User.4:
cake acl deny User.4 House.1 update
It should then return false when you run a check:
cake acl check User.4 House.1 update
EDIT
I'm going to attempt to revise this based on comments left below. I think that you may still be setting up the rules incorrectly. I am going to use the command line examples (because it's either to both type and to do in practice) but you can just as easily write the PHP to do this. My examples below also focus on admin, but you could use for the superadmin and users groups too.
First, deny everything to admins since we want to grant permissions individually:
cake acl deny admin Houses all
Then, grant the read only permission to admin so they can all read Houses:
cake acl grant admin Houses read
Lastly, grant the update permission to the specific user that gets update privileges:
cake acl grant User.4 Houses.1 update
These permissions should allow User.4 to read and update the House record. Keep in mind that if you have already created deny or allow records for User.4 then this example may not work. You may want to truncate your aco_aro table and start over since it's small at this point.
If all acl checks work, but the behavior is still incorrect, then you may have an issue with how the ACL component is authorizing an action. You may have to tweak those settings in $beforeFilter or your $components array.

Related

Changes to /etc/phpmyadmin/config.inc.php do not have effect

I would like to configure PhpMyAdmin to access only one database through one user.
I tried before to restrict access via .htaccess using this answer from 2013 but it did not work:
phpMyAdmin Block Access to Single Database
I hence tried by adding deny,allow rules as stated in this answer:
How do I restrict access to specific database user accounts in phpMyAdmin?
But it did not work too. I continue to access all users. I have read the documentation and rewrote the lines in config.inc.php as
$cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';
$cfg['Servers'][$i]['AllowDeny']['rules'] = array(
'deny root from all',
'deny user1 from all',
'deny user2 from all',
'allow user3 from all',
);
where user1 and user2 are users to deny, and user2 is user to allow. But I can still access with all users. I hence tried only
$cfg['Servers'][$i]['AllowDeny']['order'] = 'explicit';
that should block access to all users, but I can still access with all users. I hence believe that /etc/phpmyadmin/config.inc.php is being overwritten in some way, since no change has effect, but I do not understand how.
Any idea on where to check?
Looks like you are allowing access to all users and then again you are trying to restrict some of the users, seems bit confusing.
$cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';
The correct pattern should be deny access to all users and then provide explicit access to the specific user
$cfg['Servers'][$i]['AllowDeny']['order'] = 'explicit';
Please refer the official document
https://docs.phpmyadmin.net/en/latest/config.html#cfg_Servers_AllowDeny_order
The correct configuration should be something like this
$cfg['Servers'][$i]['AllowDeny']['order'] = 'explicit';
$cfg['Servers'][$i]['AllowDeny']['rules'] = [
'allow user3 from all'
];
hope it works for you!

Google Data Studio filter by email and allow all access

I'm creating a Google Data Studio dashboard with the filter by email option. It's easy to do it when you want to allow the user to see only one option, for example
user region
alice A
bob F
charlie Z
But how can I do to give access to some user to all regions from A to Z? Is there a better way to do it than simply creating 26 rows for every user with this admin access?
I'd like to avoid creating this table:
user region
admin A
admin B
admin C
...
admin Z
and instead do something similar to this
user region
admin *
In bigquery connector, you can write custom query like -
select *
FROM table_name
where
case when #DS_USER_EMAIL IN (select distinct map_field from table_name )
then #DS_USER_EMAIL
else 'all' end = map_field
You will have to create a mapping for 'all' one time. But this works. No need to use feature - filter by email id

OpenLDAP : ACL : Allow users to manager their own groups

I need your advice on a LDAP structure and associated ACL.
Our LDAP will manage 10 (number may vary) organizations which contains users (total of 250 users)
I want 1 user by organization to be allowed to manage all the users of his own organization.
Users will also be attached to custom groups.
What is the best LDAP structure for that ?
My first idea is the following :
Groups :
dn: cn=Manager,ou=Roles,ou=Groups
objectClass: posixGroup
objectClass: top
cn: Manager
gidNumber: 10100
memberUid: user1
memberUid: user3
dn: cn=Structure1,ou=Structures,ou=Groups
objectClass: posixGroup
cn: Structure1
gidNumber: 10000
description: Structure1
memberUid: user1
memberUid: user2
dn: cn=Structure2,ou=Structures,ou=Groups
objectClass: posixGroup
cn: Structure2
gidNumber: 10001
description: Structure2
memberUid: user3
memberUid: user4
user1 should be allowed to edit user user2 but not user3 or user4
user3 should be allowed to edit user1 but not user2
I actually get stuck on ACL because I don't success to user the groups of an entry using ACL set method.
I would like doing something like this :
{1}to dn.children="ou=Users" by set="[cn=]+this/groups+[,ou=Structures,ou=Groups]/memberUid & user/uid" write by * read
I am able to use groupOfNames if better than posixGroup
I've already read :
http://www.openldap.org/doc/admin24/access-control.html
http://www.openldap.org/faq/data/cache/1133.html
http://www.openldap.org/faq/data/cache/1134.html
My contribution is one option to solve this situation. I know it's been a while, but i hope this helps to someone out there.
- Change to groupofnames or organizationalrole (the last one support empty groups) both require a dn as member.
- Enable memberof overlay, to enable the memberof operational attribute on the user (this will add the list of groups where the user is a member of, to an attribute in the user entry)
olcMemberOfGroupOC: organizationalRole
olcMemberOfMemberAD: roleOccupant
olcMemberOfMemberOfAD: groups ("groups" is the operational attribute added to the user)
Once both actions where performed and you're sure the users has values on the groups operational attribute, according to the original question, here are 2 scenarios:
1st scenario - user1 is allowed to write user3,ou=users as they belongs to cn=Manager,ou=Roles,ou=Groups
2nd scenario - user1 is allowed to write user2,ou=users as they belongs to cn=Structure1,ou=Structures,ou=Groups
by set="this/groups & user/groups" write
This acl allows write whenever both users (the modified and the modifier) have the same group, the the acl will set write privileges.
user=user1,ou=users
"user/groups" get the values of the modifier groups attribute. cn=Manager,ou=Roles,ou=Groups - cn=Structure1,ou=Structures,ou=Groups.
this=user3,ou=users
"this/groups" get the values of the modified object groups attribute. cn=Manager,ou=Roles,ou=Groups and cn=Structure2,ou=Structures,ou=Groups
this=user2,ou=users
"this/groups" get the values of the modified object groups attribute. cn=Manager,ou=Roles,ou=Groups and cn=Structure1,ou=Structures,ou=Groups
I hope this solves the question and be useful to anyone struggling with openldap acl's as i did some days ago.
Best regards!!

delete message for one user but not for the other

hello I have a database with 3 tables.
USERS('user_id','name','surname')
MESSAGE_GROUP('user_one','user_two', 'hash')
MESSAGES('from_id','group_hash', 'messages')
My php code enables me to send messages between users. My question is how to enable a user to delete a message from its mailbox but the other user still watching the message. The messages must be full deleted only if both users delete the message. I am not interesting about the code, I am interesting only in finding the logic behind this. Any proposals that includes mysql code are welcome. thanks
I think you should follow this. :)
You can keep an extra field in message_group table something like 'deleted_from' which will be initially 0
If user one deletes it make the value of 'deleted_from'=1, if user two deletes it, make the value of 'deleted_from' = 2.
When you go to delete the message for a user, and you find the value 'deleted_from' other than 0, delete the message completely, else mark the value of 'deleted_from' as '1' or '2'.
You will need to either:
Make a new table that specifies the mailboxes the message resides in, so that you can connect it to both users mailboxes
Or duplicate the message so that each user has their own copy that can be deleted
Add flags to the message table (not recommended) indicating whether the sender or recipient has deleted it. This I would avoid as it will not scale well if you have (or intend to add) group messaging.
add to MESSAGE_GROUP a status field with values :
0 no owner and should be deleted
1 only the sender owns the message
2 only the reciever owns the message
3 both sender and recievers own it
I would change the fields from the table in between like this (example that every user only can send a message to one person at a time):
USERS('user_id','name','surname')
MESSAGE_GROUP('user_id','message_id')
MESSAGES('from_id', 'to_id', 'messages')
So every user that has a message, will have a row in the MESSAGE_GROUP. When one user deletes the post, delete that row in MESSAGE_GROUP

What is the best way to store 10 options in a mysql database?

I am modifying my PHP network's code to have "user roles" like wordpress here is my plan so far
0 = registred non email verified user
1 = registed and verified email
2 = moderator
3-9 = nothing yet
10= admin
In my PHP code I will use an array like this that will set what a role number does.
$user_role['10']
I was thinking of storing which value a user has in my mysql DB, would this be the best way to store the 10 different role options as an enum or is there a better way or faster way? I read that enum is not the fastest sometimes.
enum('0','1','2','3','4','5','6','7','8','9','10')
I guess INT or TINYINT is enough to store user level (role). Also you may consider multiplting the numbers by 10, so you'll have a space to add more levels in future.
Use bitmasks for permissions / user levels.
See example.