My bad. Of course an exception InvalidDomainObjectException would be thrown if you pass an ObjectIdentityInterface object to the ObjectIdentity::fromDomainObject method, because it doesn't have an getId() method. I've changed AclVoter::vote method to only call $this->objectIdentityRetrievalStrategy->getObjectIdentity($object) if it's not already an ObjectIdentityInterface object.
Pull request: https://github.com/symfony/symfony/pull/381 Best regards. On Thu, Mar 24, 2011 at 7:48 PM, Gustavo Adrian <[email protected] > wrote: > I think it's better to add this check directly on the > ObjectIdentity::fromDomainObject method so you don't have to do this check > everytime you call this method. Also, if we wouldn't add this check inside > this method, we should throw an exception for this case so we prevent > unexpected behaviour like the described before. What do you think? I'll wait > for your feedback about this to make the pull request. > > I've added this check and a corresponding unit test: > > https://github.com/comfortablynumb/symfony/tree/acl-fix > > > Thanks. > > > On Thu, Mar 24, 2011 at 5:27 PM, Johannes Schmitt <[email protected]>wrote: > >> It would indeed be a good addition. Could you add something like >> >> if (!$domainObject instanceof ObjectIdentityInterface) { >> $domainObject = >> $oidRetrievalStrategy->getObjectIdentity($domainObject); >> } >> >> to the AclVoter class; please also add a unit test to verify this >> behavior. >> >> Thanks, >> Johannes >> >> >> >> On Thu, Mar 24, 2011 at 4:03 PM, Gustavo Adrian < >> [email protected]> wrote: >> >>> Can anyone verify this? if this is indeed a bug then I'll create a pull >>> request. If not, what I am doing wrong? >>> >>> >>> Thanks. >>> >>> On Wed, Mar 23, 2011 at 4:55 PM, Gustavo Adrian < >>> [email protected]> wrote: >>> >>>> Ok, I think I've found the reason for this behaviour. On the >>>> "ObjectIdentityRetrievalStrategy" class the "getObjectIdentity" method >>>> >>>> public function getObjectIdentity($domainObject) >>>> { >>>> try { >>>> return ObjectIdentity::fromDomainObject($domainObject); >>>> } catch (InvalidDomainObjectException $failed) { >>>> return null; >>>> } >>>> } >>>> >>>> So, if it already receives an ObjectIdentity instance (like it does if I >>>> pass a new ObjectIdentity instance to the isGranted method of the >>>> SecurityContext object), it pass it anyway to the fromDomainObject method, >>>> so it returns an ObjectIdentity instance for the original ObjectIdentity I >>>> passed to the isGranted method. If I change the method to look like: >>>> >>>> public function getObjectIdentity($domainObject) >>>> { >>>> try { >>>> if ( get_class( $domainObject ) !== >>>> 'Symfony\Component\Security\Acl\Domain\ObjectIdentity' ) { >>>> return ObjectIdentity::fromDomainObject($domainObject); >>>> } else { >>>> return $domainObject; >>>> } >>>> } catch (InvalidDomainObjectException $failed) { >>>> return null; >>>> } >>>> } >>>> >>>> It works like I want and it successfully denies me the creation of a >>>> Comment object. What I still don't know if I'm doing the right thing when I >>>> try to check If a user has a class-scope permission to CREATE a Comment, >>>> like in the example I've shown before. >>>> >>>> >>>> >>>> Thanks :) >>>> >>>> On Wed, Mar 23, 2011 at 4:44 PM, Gustavo Adrian < >>>> [email protected]> wrote: >>>> >>>>> Another thing that it recently came up is this. Having no ACL or even >>>>> an entry for this ObjectIdentity, if I try this: >>>>> >>>>> // $comment domain object was loaded from DB >>>>> >>>>> if ( $securityContext->isGranted( 'UPDATE', $comment ) === false ) >>>>> { >>>>> throw new AccessDeniedException( 'Some error message' ); >>>>> } >>>>> >>>>> It successfully denies me to update the object as expected. >>>>> >>>>> Logs show this: >>>>> >>>>> 2011-03-24T00:01:45-03:00 INFO: SELECT a.ancestor_id >>>>> FROM acl_object_identities o >>>>> INNER JOIN acl_classes c ON c.id = o.class_id >>>>> INNER JOIN acl_object_identity_ancestors a ON >>>>> a.object_identity_id = o.id >>>>> WHERE ((o.object_identifier = '24435' AND c.class_type = >>>>> 'MyCommentClass')) ([]) >>>>> 2011-03-24T00:01:45-03:00 DEBUG: No ACL found for the object identity. >>>>> Voting to deny access. >>>>> >>>>> Just what I was expecting. But When I try to create a new object: >>>>> >>>>> // A new ObjectIdentity representing the Comment class for class-scope >>>>> ACE's >>>>> $commentClassOID = new ObjectIdentity( -1, 'MyCommentClass' ); >>>>> >>>>> if ( $securityContext->isGranted( 'CREATE', $commentClassOID ) === >>>>> false ) >>>>> { >>>>> throw new AccessDeniedException( 'Some error message' ); >>>>> } >>>>> >>>>> It doesn't throw an exception, and the logs show this: >>>>> >>>>> 2011-03-24T00:05:12-03:00 DEBUG: Object identity unavailable. Voting to >>>>> grant access >>>>> >>>>> What I don't know is what's the default behaviour of the ACL feature if >>>>> it doesn't have an ACL for an ObjectIdentity, or if it doesn't have any >>>>> object identity on the DB referring to the ObjectIdentity passed to the >>>>> isGrant method. So I still don't know which of both cases is wrong. >>>>> >>>>> >>>>> >>>>> Thanks in advance! >>>>> >>>>> On Wed, Mar 23, 2011 at 12:14 PM, Gustavo Adrian < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Johannes, >>>>>> >>>>>> 1) My scenario is the following: >>>>>> >>>>>> a BusinessUnit has many Departments >>>>>> a Department has many Users >>>>>> >>>>>> So, having this example tree: >>>>>> >>>>>> BusinessUnit 1 >>>>>> |_ Department 1 >>>>>> |_ User 1 >>>>>> |_ User 2 >>>>>> |_ Deparment 2 >>>>>> |_ User 3 >>>>>> >>>>>> What I would like is to define rules in BusinessUnit's, and inherit >>>>>> them from Departments. The same with my Users. I'd like them to inherit >>>>>> their rules from Departments. So, if I want an ALLOW rule for the VIEW >>>>>> permission in some "Article" class, I'd create a class-scope ACE for that >>>>>> rule on BusinessUnit 1, and then every child of BusinessUnit 1 would >>>>>> inherit >>>>>> from it. So, for this case, I'd create an ACL for BusinessUnit 1, create >>>>>> all >>>>>> the ACEs I want in it (in this case, an ALLOW rule for the VIEW >>>>>> class-scope >>>>>> permission for the "Article" class) , and then create an ACL without ACEs >>>>>> (or with specific ACEs if I want, for example, to DENY the previous ALLOW >>>>>> permission) for the other entities, and inherit the ACL's to create a >>>>>> tree >>>>>> just like my entity tree. For example, create an ACL for Department 1 and >>>>>> make it inherit from the BusinessUnit 1's ACL I recently created. Then >>>>>> create an ACL for User 1, and make it inherit from the ACL of Deparment >>>>>> 1, >>>>>> etc. Is this scenario valid? having Department 1, to inherit permissions >>>>>> from BusinessUnit 1, all I need to do is to create an ACL for Department >>>>>> 1 >>>>>> and make it inherit from the ACL of BusinessUnit 1, and only create ACE's >>>>>> for Deparment 1's ACL in case I want to customize the inherited >>>>>> permissions? >>>>>> >>>>>> 2) Great! I'll give it a try today. >>>>>> >>>>>> 3) That seems really useful. audit_success being true means that it >>>>>> will call the AuditLogger when someone is granted for that rule? so, if >>>>>> "granting" is true and audit_success is true, it will call my AuditLogger >>>>>> when someone call the "isGranted" method? the same goes for granting >>>>>> being >>>>>> false and audit_failure true? >>>>>> >>>>>> >>>>>> >>>>>> Thanks a lot for your help Johannes :) >>>>>> >>>>>> >>>>>> >>>>>> On Tue, Mar 22, 2011 at 6:16 PM, Johannes Schmitt < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> 1) Yes, granting specifies whether the entry is granting (true) or >>>>>>> denying (false). Depending on the order of ACL entries, and the SIDs to >>>>>>> which the ACEs have been assigned, this can be used to implement >>>>>>> scenarios >>>>>>> like "grant access to all users, but for this specific user deny >>>>>>> access". >>>>>>> >>>>>>> 2) The index is the index of the entry in the array. You can retrieve >>>>>>> the array via ->getXXXAces() method, and then loop over it to get the >>>>>>> correct index for your entry. Do not call methods directly on the ACE >>>>>>> instances, these changes will not be persisted to the database. >>>>>>> >>>>>>> 3) Since the order in which the entries are checked is significant, >>>>>>> "ace_order" is used to preserve the order of the entries in the array. >>>>>>> audit_success/_failure are only relevant if you have set-up an >>>>>>> AuditLogger >>>>>>> which then can log if someone has been granted permissions through the >>>>>>> ACL >>>>>>> system, based on which entry permissions was granted, to which object >>>>>>> permission was granted, etc. The AuditLogger is only called if the >>>>>>> value of >>>>>>> audit_success/_failure is true. >>>>>>> >>>>>>> Kind regards, >>>>>>> Johannes >>>>>>> >>>>>>> >>>>>>> On Tue, Mar 22, 2011 at 9:42 PM, Gustavo Adrian < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> After implementing class-scope permissions thanks to Christophe's >>>>>>>> tip, I now have more questions :) >>>>>>>> >>>>>>>> I've been looking at the ACE schema and I see a couple of >>>>>>>> interesting things that I'd like to know how to use them. >>>>>>>> >>>>>>>> 1) First I see a "granting" boolean field and a "grant_strategy" >>>>>>>> field (with value "all" in my case in each row) on the "acl_entries" >>>>>>>> table. >>>>>>>> Looking then at the MutableAclInterface I see that the method >>>>>>>> "insertClassAce" has these signature: >>>>>>>> >>>>>>>> *function insertClassAce(SecurityIdentityInterface $sid, $mask, >>>>>>>> $index = 0, $granting = true, $strategy = null);* >>>>>>>> >>>>>>>> Does the $granting field allow me to use something like a DENY >>>>>>>> permission if I pass "false" to it? if that's the case, could I use it >>>>>>>> to >>>>>>>> DENY a privilege that has an ALLOW permission somewhere up on the >>>>>>>> hierarchy? >>>>>>>> >>>>>>>> 2) I've noticed that I can insert multiple Class Ace's using the >>>>>>>> same object identity and the same security identity, but it increases >>>>>>>> the >>>>>>>> "ace_order" for each row I insert. I have a form for each type of >>>>>>>> entity on >>>>>>>> my app to give class-scope permissions to specific users. Each time a >>>>>>>> user >>>>>>>> updates them, how can I update the corresponding ACE? I see in the >>>>>>>> MutableAclInterface that it has a updateClassAce method, but it needs >>>>>>>> an >>>>>>>> $index parameter and I don't know what it is. Is this the primary key >>>>>>>> of the >>>>>>>> ACE? if this is the case, should I query myself the DB using the class >>>>>>>> ID >>>>>>>> and the SID ID to retrieve the corresponding ACE's PK or is there a >>>>>>>> method >>>>>>>> to update ACE's based on the SID and OID that I haven't found? >>>>>>>> >>>>>>>> 3) What's the purpose of the following fields on the "acl_entries" >>>>>>>> table?: ace_order, audit_success, audit_failure. I've seen the >>>>>>>> AuditableAclInterface. How methods like updateClassAuditing (with >>>>>>>> $auditSuccess and $auditFailure parameters) works? >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Thanks in advance and sorry if I asked too many questions, but this >>>>>>>> is a wonderful feature and I'd love to know all its possibilities :) >>>>>>>> >>>>>>>> On Mon, Mar 21, 2011 at 4:26 PM, Gustavo Adrian < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Great! even easier than I thought. I'm beginning to love this >>>>>>>>> feature :) >>>>>>>>> >>>>>>>>> >>>>>>>>> Thanks a lot! >>>>>>>>> >>>>>>>>> >>>>>>>>> On Mon, Mar 21, 2011 at 4:22 PM, Christophe COEVOET <[email protected] >>>>>>>>> > wrote: >>>>>>>>> >>>>>>>>>> Le 21/03/2011 20:11, Gustavo Adrian a écrit : >>>>>>>>>> >>>>>>>>>> Hi all, >>>>>>>>>>> >>>>>>>>>>> I'm starting to implement the ACL feature on my app and, for what >>>>>>>>>>> I''ve read and what I've already implemented, I must say: it's >>>>>>>>>>> BEAUTIFUL. >>>>>>>>>>> Great job guys. It's just what I was looking for :) >>>>>>>>>>> >>>>>>>>>>> I have one question about this wonderful feature: >>>>>>>>>>> >>>>>>>>>>> 1) I've already implemented object scope permissions using the >>>>>>>>>>> ObjectIdentifier class. What I don't know is: How to grant a class >>>>>>>>>>> scope and >>>>>>>>>>> class-field scope permissions to a user? I didn't find how to do it >>>>>>>>>>> in the >>>>>>>>>>> docs and I didn't find in the API something like ClassIdentifier. >>>>>>>>>>> Which is >>>>>>>>>>> the right way to grant a class scope permission to a user? Do I >>>>>>>>>>> have to >>>>>>>>>>> check this permissions the same way I do it with object-scope >>>>>>>>>>> permissions? >>>>>>>>>>> ($securityContext->isGranted( 'UPDATE', $objectIdentity ) ) >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> the key to create a class Ace is to use the insertClassAce method: >>>>>>>>>> >>>>>>>>>> $oid = new ObjectIdentity('whatever_you_want', 'Class\\Name'); >>>>>>>>>> $acl = $provider->createAcl($oid); >>>>>>>>>> $sid = UserSecurityIdentity::fromAccount($user); >>>>>>>>>> $acl->insertClassAce($sid, MaskBuilder::MASK_OWNER); >>>>>>>>>> >>>>>>>>>> And then your user will have OWNER rights for all instances of the >>>>>>>>>> Class\Name class. The way to check does not change. >>>>>>>>>> >>>>>>>>>> Regards >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Christophe | Stof >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> If you want to report a vulnerability issue on symfony, please >>>>>>>>>> send it to security at symfony-project.com >>>>>>>>>> >>>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>>> Groups "symfony users" group. >>>>>>>>>> To post to this group, send email to >>>>>>>>>> [email protected] >>>>>>>>>> To unsubscribe from this group, send email to >>>>>>>>>> [email protected] >>>>>>>>>> For more options, visit this group at >>>>>>>>>> http://groups.google.com/group/symfony-users?hl=en >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> -- >>>>>>>> If you want to report a vulnerability issue on symfony, please send >>>>>>>> it to security at symfony-project.com >>>>>>>> >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups "symfony users" group. >>>>>>>> To post to this group, send email to [email protected] >>>>>>>> To unsubscribe from this group, send email to >>>>>>>> [email protected] >>>>>>>> For more options, visit this group at >>>>>>>> http://groups.google.com/group/symfony-users?hl=en >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> If you want to report a vulnerability issue on symfony, please send >>>>>>> it to security at symfony-project.com >>>>>>> >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups "symfony users" group. >>>>>>> To post to this group, send email to [email protected] >>>>>>> To unsubscribe from this group, send email to >>>>>>> [email protected] >>>>>>> For more options, visit this group at >>>>>>> http://groups.google.com/group/symfony-users?hl=en >>>>>>> >>>>>> >>>>>> >>>>> >>>> >>> -- >>> If you want to report a vulnerability issue on symfony, please send it to >>> security at symfony-project.com >>> >>> You received this message because you are subscribed to the Google >>> Groups "symfony users" group. >>> To post to this group, send email to [email protected] >>> To unsubscribe from this group, send email to >>> [email protected] >>> For more options, visit this group at >>> http://groups.google.com/group/symfony-users?hl=en >>> >> >> -- >> If you want to report a vulnerability issue on symfony, please send it to >> security at symfony-project.com >> >> You received this message because you are subscribed to the Google >> Groups "symfony users" group. >> To post to this group, send email to [email protected] >> To unsubscribe from this group, send email to >> [email protected] >> For more options, visit this group at >> http://groups.google.com/group/symfony-users?hl=en >> > > -- If you want to report a vulnerability issue on symfony, please send it to security at symfony-project.com You received this message because you are subscribed to the Google Groups "symfony users" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/symfony-users?hl=en
