public function getTreePermissionsAction() { $this->removeViewRenderer(); $user = User::getById($this->_getParam("user")); if ($this->_getParam("xaction") == "update") { $data = json_decode($this->_getParam("data")); if (!empty($data->id)) { $nodes[] = $data; } else { $nodes = $data; } //loop through store nodes = objects to edit if (is_array($nodes)) { foreach ($nodes as $node) { $object = Object_Abstract::GetById($node->id); $parent = Object_Abstract::getById($object->getParentId()); $objectPermission = $object->getPermissionsForUser($user); if ($objectPermission instanceof Object_Permissions) { $found = true; if (!$node->permissionSet) { //reset permission by deleting it if ($objectPermission->getCid() == $object->getId()) { $objectPermission->delete(); $permissions = $object->getPermissions(); } break; } else { if ($objectPermission->getCid() != $object->getId() or $objectPermission->getUser()->getId() != $user->getId()) { //we got a parent's permission create new permission //or we got a usergroup permission, create a new permission for specific user $objectPermission = new Object_Permissions(); $objectPermission->setUser($user); $objectPermission->setUserId($user->getId()); $objectPermission->setUsername($user->getUsername()); $objectPermission->setCid($object->getId()); $objectPermission->setCpath($object->getFullPath()); } //update object_permission $permissionNames = $objectPermission->getValidPermissionKeys(); foreach ($permissionNames as $name) { //check if parent allows list if ($parent) { $parent->getPermissionsForUser($user); $parentList = $parent->isAllowed("list"); } else { $parentList = true; } $setterName = "set" . ucfirst($name); if (isset($node->{$name}) and $node->{$name} and $parentList) { $objectPermission->{$setterName}(true); } else { if (isset($node->{$name})) { $objectPermission->{$setterName}(false); //if no list permission set all to false if ($name == "list") { foreach ($permissionNames as $n) { $setterName = "set" . ucfirst($n); $objectPermission->{$setterName}(false); } break; } } } } $objectPermission->save(); if ($node->evictChildrenPermissions) { $successorList = new Object_List(); $successorList->setOrderKey("o_key"); $successorList->setOrder("asc"); if ($object->getParentId() < 1) { $successorList->setCondition("o_parentId > 0"); } else { $successorList->setCondition("o_path like '" . $object->getFullPath() . "/%'"); } $successors = $successorList->load(); foreach ($successors as $successor) { $permission = $successor->getPermissionsForUser($user); if ($permission->getId() > 0 and $permission->getCid() == $successor->getId()) { $permission->delete(); } } } } } } $this->_helper->json(array("success" => true)); } } else { if ($this->_getParam("xaction") == "destroy") { //ignore } else { //read if ($user instanceof User) { $userPermissionsNamespace = new Zend_Session_Namespace('objectUserPermissions'); if (!isset($userPermissionsNamespace->expandedNodes) or $userPermissionsNamespace->currentUser != $user->getId()) { $userPermissionsNamespace->currentUser = $user->getId(); $userPermissionsNamespace->expandedNodes = array(); } if (is_numeric($this->_getParam("anode")) and $this->_getParam("anode") > 0) { $node = $this->_getParam("anode"); $object = Object_Abstract::getById($node); $objects = array(); if ($user instanceof User and $object->hasChilds()) { $total = $object->getChildAmount(); $list = new Object_List(); $list->setCondition("o_parentId = ?", $object->getId()); $list->setOrderKey("o_key"); $list->setOrder("asc"); $childsList = $list->load(); $requestedNodes = array(); foreach ($childsList as $childObject) { $requestedNodes[] = $childObject->getId(); } $userPermissionsNamespace->expandedNodes = array_merge($userPermissionsNamespace->expandedNodes, $requestedNodes); } } else { $userPermissionsNamespace->expandedNodes = array_merge($userPermissionsNamespace->expandedNodes, array(1)); } //load all nodes which are open in client $objectList = new Object_List(); $objectList->setOrderKey("o_key"); $objectList->setOrder("asc"); $queryIds = "'" . implode("','", $userPermissionsNamespace->expandedNodes) . "'"; $objectList->setCondition("o_id in (" . $queryIds . ")"); $o = $objectList->load(); $total = count($o); foreach ($o as $object) { if ($object->getParentId() > 0) { $parent = Object_Abstract::getById($object->getParentId()); } else { $parent = null; } // get current user permissions $object->getPermissionsForUser($this->getUser()); // only display object if listing is allowed for the current user if ($object->isAllowed("list") and $object->isAllowed("permissions")) { $treeNodePermissionConfig = $this->getTreeNodePermissionConfig($user, $object, $parent, true); $objects[] = $treeNodePermissionConfig; $tmpObjects[$object->getId()] = $treeNodePermissionConfig; } } //only visible nodes and in the order how they should be displayed ... doesn't make sense but seems to fix bug of duplicate nodes $objectsForFrontend = array(); $visible = $this->_getParam("visible"); if ($visible) { $visibleNodes = explode(",", $visible); foreach ($visibleNodes as $nodeId) { $objectsForFrontend[] = $tmpObjects[$nodeId]; if ($nodeId == $this->_getParam("anode") and is_array($requestedNodes)) { foreach ($requestedNodes as $nId) { $objectsForFrontend[] = $tmpObjects[$nId]; } } } $objects = $objectsForFrontend; } } $this->_helper->json(array("total" => $total, "data" => $objects, "success" => true)); } } }
/** * get recursively the permissions for the passed user under consideration of the parent user group * * @param User $user * @return Object_Permissions */ public function getPermissionsForUser(User $user) { $pathParts = explode("/", $this->model->getO_Path() . $this->model->getO_Key()); unset($pathParts[0]); $tmpPathes = array(); $pathConditionParts[] = "cpath = '/'"; foreach ($pathParts as $pathPart) { $tmpPathes[] = $pathPart; $pathConditionParts[] = $this->db->quoteInto("cpath = ?", "/" . implode("/", $tmpPathes)); } $pathCondition = implode(" OR ", $pathConditionParts); $permissionRaw = $this->db->fetchRow("SELECT id FROM objects_permissions WHERE (" . $pathCondition . ") AND userId = ? ORDER BY cpath DESC LIMIT 1", $user->getId()); //path condition for parent object $parentObjectPathParts = array_slice($pathParts, 0, -1); $parentObjectPathConditionParts[] = "cpath = '/'"; foreach ($parentObjectPathParts as $parentObjectPathPart) { $parentObjectTmpPaths[] = $parentObjectPathPart; $parentObjectPathConditionParts[] = $this->db->quoteInto("cpath = ?", "/" . implode("/", $parentObjectTmpPaths)); } $parentObjectPathCondition = implode(" OR ", $parentObjectPathConditionParts); $parentObjectPermissionRaw = $this->db->fetchRow("SELECT id FROM objects_permissions WHERE (" . $parentObjectPathCondition . ") AND userId = ? ORDER BY cpath DESC LIMIT 1", $user->getId()); $parentObjectPermissions = new Object_Permissions(); if ($parentObjectPermissionRaw["id"]) { $parentObjectPermissions = Object_Permissions::getById($parentObjectPermissionRaw["id"]); } $parentUser = $user->getParent(); if ($parentUser instanceof User and $parentUser->isAllowed("objects")) { $parentPermission = $this->getPermissionsForUser($parentUser); } else { $parentPermission = null; } $permission = new Object_Permissions(); if ($permissionRaw["id"] and $parentPermission instanceof Object_Permissions) { //consider user group permissions $permission = Object_Permissions::getById($permissionRaw["id"]); $permissionKeys = $permission->getValidPermissionKeys(); foreach ($permissionKeys as $key) { $getter = "get" . ucfirst($key); $setter = "set" . ucfirst($key); if (!$permission->getList() and !$parentPermission->getList() or !$parentObjectPermissions->getList()) { //no list - return false for all $permission->{$setter}(false); } else { if ($parentPermission->{$getter}()) { //if user group allows -> return true, it overrides the user permission! $permission->{$setter}(true); } } } } else { if ($permissionRaw["id"]) { //use user permissions, no user group to override anything $permission = Object_Permissions::getById($permissionRaw["id"]); //check parent object's list permission and current list permission if (!$parentObjectPermissions->getList() or !$permission->getList()) { $permissionKeys = $permission->getValidPermissionKeys(); foreach ($permissionKeys as $key) { $setter = "set" . ucfirst($key); $permission->{$setter}(false); } } } else { if ($parentPermission instanceof Object_Permissions and $parentPermission->getId() > 0) { //use user group permissions - no permission found for user at all $permission = $parentPermission; if (!$parentObjectPermissions->getList() or !$permission->getList()) { $permissionKeys = $permission->getValidPermissionKeys(); foreach ($permissionKeys as $key) { $setter = "set" . ucfirst($key); $permission->{$setter}(false); } } } else { //neither user group nor user has permissions set -> use default all allowed $permission->setUser($user); $permission->setUserId($user->getId()); $permission->setUsername($user->getUsername()); $permission->setCid($this->model->getId()); $permission->setCpath($this->model->getFullPath()); } } } $this->model->setO_UserPermissions($permission); return $permission; }