zerodine / MongoDBAclBundle

This bundle allows the use of MongoDB as the storage layer for the Symfony ACLs component.
21 stars 32 forks source link

Deviation: classAce not connected to object identity #9

Open Narretz opened 11 years ago

Narretz commented 11 years ago

Using MongoDB, $acl->insertClassAce($securityIdentity, MaskBuilder::MASK_OWNER); etc. results in an acl_entity that is disconnected from the class object identity. Result is, that the aclProvider does not get the classAces if you pass an $object to ->isGranted.

Using ->insertobjectAce, the reference to the oid is saved in the ace. Missing altogether is a way to identify an ace as being of type class.

Using mysql, this is done by setting object_identity_id to NULL, and I guess the reference is then established with the class_id (type in MongoDB).

Mongodbacl deviation

aborjesson-zz commented 11 years ago

I have the same problem. Any new on this?

iampersistent commented 11 years ago

Unfortunately, I haven't looked into this yet.

aborjesson-zz commented 11 years ago

I did look in to this. if instead of: $acl->insertClassAce($securityIdentity, MaskBuilder::MASK_OWNER); does $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER); You will have the reference between acl_entry and o_id, but however the Permission Flow doesn't work. If no objectAce exists, it should normally fall back on classAce. But since we do not use classAce it will of course fail.

Why it isn't set for classAce: (MutableAclProvider) 1. $objectIdentityId = $name === 'classAces' ? null : $ace->getAcl()->getId(); 2. $aceId = (string)$this->insertAccessControlEntry($objectIdentityId, null, $i, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure()); 3. if (isset($objectIdentityId)) { $criteria['objectIdentity'] = array( '$ref' => $this->options['oid_collection'], '$id' => new \MongoId($objectIdentityId), ); }

The objectIdentity property will not be set in DB.

Narretz commented 11 years ago

aborjessen pointed out one part of the problem: In updateAclProperty, no objectIdentity or other reference is set for classAces.

Later, when checking access, the AclProvider will try to get all acl_entries associated with the acl_oid in lookupObjectIdentities with this query:

$entryQuery = array('objectIdentity.$id' => array('$in' => $oids));
$entryCursor = $this->connection->selectCollection($this->options['entry_collection'])->find($entryQuery);

Now the query can obviously not get any aces that do not have an objectIdentity set.

So we need two things a) Association of classAce with its class in the db b) A way to query for these class Aces that doesn't have to much overhead

One option is to add a class field to the Ace (always or only if it actually is a classAce), and query for that additionally .