Permalink
Browse files

CHANGE Added removePermissions which works as an undoing of what gran…

…t() does, in that it will delete specific permissions from an AccessAuthority setting
  • Loading branch information...
1 parent 861ecc3 commit 79abc0592e5b98e4baaed0a405af0fe231c31fd9 Marcus Nyeholt committed Apr 13, 2012
View
44 code/dataobjects/AccessRole.php
@@ -72,28 +72,30 @@ public function onBeforeWrite() {
$removed = array_diff($original, $after);
$appliedTo = DataObject::get('AccessAuthority', '"Role" = \'' . Convert::raw2sql($this->Title).'\'');
- foreach ($appliedTo as $applied) {
- $perms = $applied->Perms->getValues();
- $clear = array();
- foreach ($added as $toAdd) {
- $perms[] = $toAdd;
- $clear[] = $toAdd;
-
- }
- foreach ($removed as $toRemove) {
- $index = array_search($toRemove, $perms);
- if ($index !== false) {
- $clear[] = $toRemove;
- unset($perms[$index]);
+ if ($appliedTo) {
+ foreach ($appliedTo as $applied) {
+ $perms = $applied->Perms->getValues();
+ $clear = array();
+ foreach ($added as $toAdd) {
+ $perms[] = $toAdd;
+ $clear[] = $toAdd;
+
}
- }
-
- if (count($clear)) {
- $applied->Perms = $perms;
- $applied->write();
-
- foreach ($clear as $permToClear) {
- singleton('PermissionService')->clearPermCacheFor($applied->getItem(), $permToClear);
+ foreach ($removed as $toRemove) {
+ $index = array_search($toRemove, $perms);
+ if ($index !== false) {
+ $clear[] = $toRemove;
+ unset($perms[$index]);
+ }
+ }
+
+ if (count($clear)) {
+ $applied->Perms = $perms;
+ $applied->write();
+
+ foreach ($clear as $permToClear) {
+ singleton('PermissionService')->clearPermCacheFor($applied->getItem(), $permToClear);
+ }
}
}
}
View
50 code/services/PermissionService.php
@@ -177,6 +177,56 @@ public function grant(DataObject $node, $perm, DataObject $to, $grant = 'GRANT')
}
/**
+ * Removes a set of permissions applied on an object to a particular user/group
+ *
+ * @param DataObject $node
+ * @param type $perm
+ * @param DataObject $to
+ * @param type $grant
+ */
+ public function removePermissions(DataObject $node, $perm, DataObject $userOrGroup, $grant = 'GRANT') {
+ if (!$this->checkPerm($node, 'ChangePermissions')) {
+ throw new PermissionDeniedException("You do not have permission to do that");
+ }
+
+ $composedOf = $perm;
+ if (!is_array($perm)) {
+ $role = DataObject::get_one('AccessRole', '"Title" = \'' . Convert::raw2sql($perm) . '\'');
+ $composedOf = array($perm);
+ if ($role && $role->exists()) {
+ $composedOf = $role->Composes->getValues();
+ }
+ }
+
+ $type = $userOrGroup instanceof Member ? 'Member' : 'Group';
+ $filter = array(
+ 'Type =' => $type,
+ 'AuthorityID =' => $userOrGroup->ID,
+ 'ItemID =' => $node->ID,
+ 'ItemType =' => $node->class,
+ 'Grant =' => $grant,
+ );
+
+ $existing = DataObject::get_one('AccessAuthority', singleton('SiteUtils')->dbQuote($filter));
+
+ if (!$existing || !$existing->exists()) {
+ return;
+ }
+
+ $current = $existing->Perms->getValues();
+ if (is_array($current) && count($current)) {
+ $new = array_diff($current, $composedOf);
+ $existing->Perms = $new;
+ $existing->write();
+
+ foreach ($composedOf as $remove) {
+ $key = $this->permCacheKey($node, $remove);
+ $this->getCache()->remove($key);
+ }
+ }
+ }
+
+ /**
* Return true or false as to whether a given user can access an object
*
* @param type $perm
View
4 code/tests/TestRestrictedObject.php
@@ -96,6 +96,10 @@ public function testCheckPerm() {
// but can still edit at that level
$this->assertTrue($otherItem->checkPerm('Publish'));
+
+ // now try just deleting the permission
+ singleton('PermissionService')->removePermissions($item, 'Publish', Member::currentUser());
+ $this->assertFalse($item->checkPerm('Publish'));
}
function testOwnership() {
View
3 code/tests/TestTransactionManager.php
@@ -17,7 +17,10 @@ public function setUpOnce() {
}
public function testRunAs() {
+ Restrictable::set_enabled(false);
$this->logInWithPermission('FIRST');
+ Restrictable::set_enabled(true);
+
$first = $this->cache_generatedMembers['FIRST'];
// cerate an object, it should be by the second user

0 comments on commit 79abc05

Please sign in to comment.