ACL – How to make $user->isAllowed(…) consider ownership as well

Notice: This thread is very old.
BugsBunny
Member | 5
+
0
-

I'd like my ACL to handle ownership as well. Instead of calling

$user->isAllowed($resource, $privilege)

I'd like to be able to call

$user->isAllowed($resource, $privilege, $userId, $resourceId)

and check whether this user owns the reource in question.

I edited Authorizator.php in my /app/modules folder accordingly and it works just fine. What bugs me is that I also had to edit /nette/security/src/Security/User.php, which is baaad! I do NOT want to edit core parts of framework (for too many obviuos reasons).

What would be the best solution for me?

Last edited by BugsBunny (2015-02-16 07:14)

Filip Klimeš
Nette Blogger | 156
+
-1
-

Nette\Security\User represents a single signed in user. You shouldn't check other users privileges via this class as it violates SRP. You could create your own service for checking privileges and inject it where you need it.

BugsBunny
Member | 5
+
0
-

I am not trying to check other users privileges, I am trying to check whether the resource in question belongs to the single signed in user. No other users privileges involved.

Last edited by BugsBunny (2015-02-16 10:07)

BugsBunny
Member | 5
+
0
-

Example: Forum where user is allowed to edit only his/her own posts. I guess $user->isAllowed($resource, $privilege, $resourceId); would be enough ($userId is redundant).

Filip Klimeš
Nette Blogger | 156
+
0
-

Oh, I'm sorry, I got mislead by the $userId – which really is redundant.

Last edited by FilipKlimeš (2015-02-16 14:34)

looky
Member | 99
+
0
-

Both $userId and $resourceId seem redundant. If you really need User in your authorizator, you can fetch it from container (but I wouldn't recommend it, see previous answers). If you need $resourceId, make you resources implement Nette\Security\IResource.

echo
Member | 134
+
0
-
class User implements IIdentity, IRole {

	public function getRoles()
	{
		return [$this, ...];
	}

	...
}
class Authorizator implements IAuthorizator {

	public function isAllowed($role, $resource, $privilege)
	{
		if ($role instanceof User) {
			...
		}
	}

}
Šaman
Member | 2661
+
+2
-

This way. I use ORM, so i have true entities. In Nette\Database you must create some your own resources.

My User extends my IRole, so i can get ID of role owner.
And all my entities extends my IRole, so i can get ID of their owner.

To check rights you can't use $user->isAllowed(), because this method ged only users roles, not instance od User.

Inject ACL to your presenter (or any class where you need check) and use:

<?php
$this->acl->isAllowed($userEntity, $resource, $privilege);
// User entity is instance implements IRole and Resource is instance implements IRole.
?>

P.S. This is used in project, where user has only one role!

Last edited by Šaman (2015-02-16 13:14)

BugsBunny
Member | 5
+
0
-

This seems pretty cool to me. I'll give it a shot!

Last edited by BugsBunny (2015-02-16 17:17)

BugsBunny
Member | 5
+
0
-

Implemented. I basically had the solution in front of me the whole time (my own /app/model/Authorizator.php implemeting Nette\Security\IAuthorizator), I was just stuck with using it through $this->user->isAllowed(…) instead of straight $this->acl->isAllowed(…). Thanks everyone!