getPlugin('ktcore.plugin'); class KTDocumentPermissionsAction extends KTDocumentAction { var $sBuiltInAction = 'editDocumentPermissions'; var $sDisplayName = 'Permissions'; var $sName = 'ktcore.actions.document.permissions'; function do_main() { $oTemplate = $this->oValidator->validateTemplate("ktcore/document/document_permissions"); $oPO = KTPermissionObject::get($this->oDocument->getPermissionObjectID()); $aPermissions = KTPermission::getList(); $aMapPermissionGroup = array(); $aMapPermissionRole = array(); foreach ($aPermissions as $oPermission) { $oPA = KTPermissionAssignment::getByPermissionAndObject($oPermission, $oPO); if (PEAR::isError($oPA)) { continue; } $oDescriptor = KTPermissionDescriptor::get($oPA->getPermissionDescriptorID()); $iPermissionID = $oPermission->getID(); $aIDs = $oDescriptor->getGroups(); $aMapPermissionGroup[$iPermissionID] = array(); foreach ($aIDs as $iID) { $aMapPermissionGroup[$iPermissionID][$iID] = true; } $aIds = $oDescriptor->getRoles(); $aMapPermissionRole[$iPermissionID] = array(); foreach ($aIds as $iId) { $aMapPermissionRole[$iPermissionID][$iId] = true; } } $oInherited = KTPermissionUtil::findRootObjectForPermissionObject($oPO); if ($oInherited === $this->oDocument) { $bEdit = true; } else { $iInheritedFolderID = $oInherited->getID(); /* $sInherited = displayFolderPathLink(Folder::getFolderPathAsArray($iInheritedFolderID), Folder::getFolderPathNamesAsArray($iInheritedFolderID), "$default->rootUrl/control.php?action=editFolderPermissions");*/ $sInherited = join(" » ", $oInherited->getPathArray()); $bEdit = false; } $aTemplateData = array( "context" => $this, "permissions" => $aPermissions, "groups" => Group::getList(), "roles" => Role::getList(), "iDocumentID" => $_REQUEST['fDocumentID'], "aMapPermissionGroup" => $aMapPermissionGroup, "aMapPermissionRole" => $aMapPermissionRole, "edit" => $bEdit, "inherited" => $sInherited, ); return $oTemplate->render($aTemplateData); } } $oPlugin->registerAction('documentaction', 'KTDocumentPermissionsAction', 'ktcore.actions.document.permissions'); class KTRoleAllocationPlugin extends KTFolderAction { var $sDisplayName = 'Allocate Roles'; var $sName = 'ktcore.actions.folder.roles'; var $_sShowPermission = "ktcore.permissions.write"; var $bAutomaticTransaction = true; function do_main() { $this->oPage->setTitle(_("Allocate Roles")); $this->oPage->setBreadcrumbDetails(_("Allocate Roles")); $oTemplating = new KTTemplating; $oTemplate = $oTemplating->loadTemplate("ktcore/folder/roles"); // we need to have: // - a list of roles // - with their users / groups // - and that allocation id $aRoles = array(); // stores data for display. $aRoleList = Role::getList(); foreach ($aRoleList as $oRole) { $iRoleId = $oRole->getId(); $aRoles[$iRoleId] = array("name" => $oRole->getName()); $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($this->oFolder->getId(), $iRoleId); $u = array(); $g = array(); $aid = null; $raid = null; if ($oRoleAllocation == null) { ; // nothing. } else { $raid = $oRoleAllocation->getId(); // real_alloc_id if ($oRoleAllocation->getFolderId() == $this->oFolder->getId()) { $aid = $oRoleAllocation->getid(); // alloc_id } $oPermDesc = KTPermissionDescriptor::get($oRoleAllocation->getPermissionDescriptorId()); if (!PEAR::isError($oPermDesc)) { $aAllowed = $oPermDesc->getAllowed(); if (!empty($aAllowed['user'])) { $u = $aAllowed['user']; } if (!empty($aAllowed['group'])) { $g = $aAllowed['group']; } } } $aRoles[$iRoleId]['users'] = $u; $aRoles[$iRoleId]['groups'] = $g; $aRoles[$iRoleId]['allocation_id'] = $aid; $aRoles[$iRoleId]['real_allocation_id'] = $raid; } /* print '
';
        var_dump($aRoles);
        print '
'; */ // FIXME this is test data. /* $aRoles = array( 1 => array('name' => 'Manager', 'users' => array(1), 'groups' => array(1), 'allocation_id' => 1), 2 => array('name' => 'Peasant', 'users' => array(1), 'groups' => array(), 'allocation_id' => 2), 3 => array('name' => 'Inherited', 'users' => array(), 'groups' => array(1), 'allocation_id' => null), ); */ // final step. // map to users, groups. foreach ($aRoles as $key => $role) { /* $_users = array(); foreach ($aRoles[$key]['users'] as $iUserId) { $oUser = User::get($iUserId); if (!(PEAR::isError($oUser) || ($oUser == false))) { $_users[] = $oUser->getName(); } } if (empty($_users)) { $aRoles[$key]['users'] = ' ' . _('no users') . ''; } else { $aRoles[$key]['users'] = join(', ',$_users); } */ $_groups = array(); foreach ($aRoles[$key]['groups'] as $iGroupId) { $oGroup = Group::get($iGroupId); if (!(PEAR::isError($oGroup) || ($oGroup == false))) { $_groups[] = $oGroup->getName(); } } if (empty($_groups)) { $aRoles[$key]['groups'] = ' ' . _('no groups') . ''; } else { $aRoles[$key]['groups'] = join(', ',$_groups); } } $aTemplateData = array( 'context' => &$this, 'roles' => $aRoles, ); return $oTemplate->render($aTemplateData); } function do_overrideParent() { $role_id = KTUtil::arrayGet($_REQUEST, 'role_id', null); $oRole = Role::get($role_id); if (PEAR::isError($oRole)) { $this->errorRedirectToMain(_('Invalid Role.')); } // FIXME do we need to check that this role _isn't_ allocated? $oRoleAllocation = new RoleAllocation(); $oRoleAllocation->setFolderId($this->oFolder->getId()); $oRoleAllocation->setRoleId($role_id); // create a new permission descriptor. // FIXME we really want to duplicate the original (if it exists) $aAllowed = array(); // no-op, for now. $this->startTransaction(); $oRoleAllocation->setAllowed($aAllowed); $res = $oRoleAllocation->create(); if (PEAR::isError($res) || ($res == false)) { $this->errorRedirectToMain(_('Failed to create the role allocation.') . print_r($res, true), sprintf('fFolderId=%d', $this->oFolder->getId())); } $this->renegeratePermissionsForRole($oRoleAllocation->getRoleId()); $this->successRedirectToMain(_('Role allocation created.'), sprintf('fFolderId=%d', $this->oFolder->getId())); } function do_useParent() { $role_id = KTUtil::arrayGet($_REQUEST, 'role_id', null); $oRole = Role::get($role_id); if (PEAR::isError($oRole)) { $this->errorRedirectToMain(_('Invalid Role.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } $role_id = $oRole->getId(); // numeric, for various testing purposes. $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($this->oFolder->getId(), $role_id); if ($oRoleAllocation->getFolderId() != $this->oFolder->getId()) { $this->errorRedirectToMain(_('Already using a different descriptor.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } $this->startTransaction(); $res = $oRoleAllocation->delete(); if (PEAR::isError($res) || ($res == false)) { $this->errorRedirectToMain(_('Unable to change role allocation.') . print_r($res, true), sprintf('fFolderId=%d',$this->oFolder->getId())); exit(0); } $this->renegeratePermissionsForRole($oRoleAllocation->getRoleId()); $this->successRedirectToMain(_('Role now uses parent.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } function do_editRoleUsers() { $role_allocation_id = KTUtil::arrayGet($_REQUEST, 'alloc_id'); $oRoleAllocation = RoleAllocation::get($role_allocation_id); if ((PEAR::isError($oRoleAllocation)) || ($oRoleAllocation=== false)) { $this->errorRedirectToMain(_('No such role allocation.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } $this->oPage->setBreadcrumbDetails(_('Manage Users for Role')); $this->oPage->setTitle(sprintf(_('Manage Users for Role'))); $initJS = 'var optGroup = new OptionTransfer("userSelect","chosenUsers"); ' . 'function startTrans() { var f = getElement("userroleform"); ' . ' optGroup.saveNewRightOptions("userFinal"); ' . ' optGroup.init(f); }; ' . ' addLoadEvent(startTrans); '; $this->oPage->requireJSStandalone($initJS); $aInitialUsers = $oRoleAllocation->getUsers(); $aAllUsers = User::getList(); // FIXME this is massively non-performant for large userbases.. $aRoleUsers = array(); $aFreeUsers = array(); foreach ($aInitialUsers as $oUser) { $aRoleUsers[$oUser->getId()] = $oUser; } foreach ($aAllUsers as $oUser) { if (!array_key_exists($oUser->getId(), $aRoleUsers)) { $aFreeUsers[$oUser->getId()] = $oUser; } } $oTemplating = new KTTemplating; $oTemplate = $oTemplating->loadTemplate("ktcore/folder/roles_manageusers"); $aTemplateData = array( "context" => $this, "edit_rolealloc" => $oRoleAllocation, 'unused_users' => $aFreeUsers, 'role_users' => $aRoleUsers, ); return $oTemplate->render($aTemplateData); } function do_editRoleGroups() { $role_allocation_id = KTUtil::arrayGet($_REQUEST, 'alloc_id'); $oRoleAllocation = RoleAllocation::get($role_allocation_id); if ((PEAR::isError($oRoleAllocation)) || ($oRoleAllocation=== false)) { $this->errorRedirectToMain(_('No such role allocation.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } $this->oPage->setBreadcrumbDetails(_('Manage Groups for Role')); $this->oPage->setTitle(sprintf(_('Manage Groups for Role'))); $initJS = 'var optGroup = new OptionTransfer("groupSelect","chosenGroups"); ' . 'function startTrans() { var f = getElement("grouproleform"); ' . ' optGroup.saveNewRightOptions("groupFinal"); ' . ' optGroup.init(f); }; ' . ' addLoadEvent(startTrans); '; $this->oPage->requireJSStandalone($initJS); $aInitialUsers = $oRoleAllocation->getGroups(); $aAllUsers = Group::getList(); // FIXME this is massively non-performant for large userbases.. $aRoleUsers = array(); $aFreeUsers = array(); foreach ($aInitialUsers as $oGroup) { $aRoleUsers[$oGroup->getId()] = $oGroup; } foreach ($aAllUsers as $oGroup) { if (!array_key_exists($oGroup->getId(), $aRoleUsers)) { $aFreeUsers[$oGroup->getId()] = $oGroup; } } $oTemplating = new KTTemplating; $oTemplate = $oTemplating->loadTemplate("ktcore/folder/roles_managegroups"); $aTemplateData = array( "context" => $this, "edit_rolealloc" => $oRoleAllocation, 'unused_groups' => $aFreeUsers, 'role_groups' => $aRoleUsers, ); return $oTemplate->render($aTemplateData); } function do_setRoleUsers() { $role_allocation_id = KTUtil::arrayGet($_REQUEST, 'allocation_id'); $oRoleAllocation = RoleAllocation::get($role_allocation_id); if ((PEAR::isError($oRoleAllocation)) || ($oRoleAllocation=== false)) { $this->errorRedirectToMain(_('No such role allocation.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } $users = KTUtil::arrayGet($_REQUEST, 'userFinal', ''); $aUserIds = explode(',', $users); // check that its not corrupt.. $aFinalUserIds = array(); foreach ($aUserIds as $iUserId) { $oUser =& User::get($iUserId); if (!(PEAR::isError($oUser) || ($oUser == false))) { $aFinalUserIds[] = $iUserId; } } if (empty($aFinalUserIds)) { $aFinalUserIds = null; } // hack straight in. $oPD = $oRoleAllocation->getPermissionDescriptor(); $aAllowed = $oPD->getAllowed(); // now, grab the existing allowed and modify. $aAllowed['user'] = $aFinalUserIds; $oRoleAllocation->setAllowed($aAllowed); $res = $oRoleAllocation->update(); if (PEAR::isError($res) || ($res == false)) { $this->errorRedirectToMain(_('Failed to change the role allocation.') . print_r($res, true), sprintf('fFolderId=%d', $this->oFolder->getId())); } $this->renegeratePermissionsForRole($oRoleAllocation->getRoleId()); $this->successRedirectToMain(_('Allocation changed.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } function do_setRoleGroups() { $role_allocation_id = KTUtil::arrayGet($_REQUEST, 'allocation_id'); $oRoleAllocation = RoleAllocation::get($role_allocation_id); if ((PEAR::isError($oRoleAllocation)) || ($oRoleAllocation=== false)) { $this->errorRedirectToMain(_('No such role allocation.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } $groups = KTUtil::arrayGet($_REQUEST, 'groupFinal', ''); $aGroupIds = explode(',', $groups); // check that its not corrupt.. $aFinalGroupIds = array(); foreach ($aGroupIds as $iGroupId) { $oGroup =& Group::get($iGroupId); if (!(PEAR::isError($oGroup) || ($oGroup == false))) { $aFinalGroupIds[] = $iGroupId; } } if (empty($aFinalGroupIds)) { $aFinalGroupIds = null; } // hack straight in. $oPD = $oRoleAllocation->getPermissionDescriptor(); $aAllowed = $oPD->getAllowed(); // now, grab the existing allowed and modify. $aAllowed['group'] = $aFinalGroupIds; $oRoleAllocation->setAllowed($aAllowed); $res = $oRoleAllocation->update(); if (PEAR::isError($res) || ($res == false)) { $this->errorRedirectToMain(_('Failed to change the role allocation.') . print_r($res, true), sprintf('fFolderId=%d', $this->oFolder->getId())); } $this->renegeratePermissionsForRole($oRoleAllocation->getRoleId()); $this->successRedirectToMain(_('Allocation changed.'), sprintf('fFolderId=%d',$this->oFolder->getId())); } function renegeratePermissionsForRole($iRoleId) { $iStartFolderId = $this->oFolder->getId(); $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($iStartFolderId, $iRoleId); /* * 1. find all folders & documents "below" this one which use the role * definition _active_ (not necessarily present) at this point. * 2. tell permissionutil to regen their permissions. * * The find algorithm is: * * folder_queue <- (iStartFolderId) * while folder_queue is not empty: * active_folder = * for each folder in the active_folder: * find folders in _this_ folder without a role-allocation on the iRoleId * add them to the folder_queue * update the folder's permissions. * find documents in this folder: * update their permissions. */ $sQuery = 'SELECT f.id as `id` FROM ' . Folder::_table() . ' AS f LEFT JOIN ' . RoleAllocation::_table() . ' AS ra ON (f.id = ra.folder_id) WHERE f.parent_id = ? AND ra.role_id '; if ($oRoleAllocation == null) { // no alloc. $sQuery .= ' IS NULL '; $hasId = false; } else { $sQuery .= ' = ? '; $aId = $oRoleAllocation->getId(); $hasId = true; } $folder_queue = array($iStartFolderId); while (!empty($folder_queue)) { $active_folder = array_pop($folder_queue); $aParams = array($active_folder); if ($hasId) { $aParams[] = $aId; } $aNewFolders = DBUtil::getResultArrayKey(array($sQuery, $aParams), 'id'); if (PEAR::isError($aNewFolders)) { $this->errorRedirectToMain(_('Failure to generate folderlisting.')); } $folder_queue = array_merge ($folder_queue, $aNewFolders); // push. // update the folder. $oFolder =& Folder::get($active_folder); if (PEAR::isError($oFolder) || ($oFolder == false)) { $this->errorRedirectToMain(_('Unable to locate folder: ') . $active_folder); } KTPermissionUtil::updatePermissionLookup($oFolder); $aDocList =& Document::getList(array('folder_id = ?', $active_folder)); if (PEAR::isError($aDocList) || ($aDocList == false)) { $this->errorRedirectToMain(_('Unable to get documents in folder: ') . $active_folder); } foreach ($aDocList as $oDoc) { KTPermissionUtil::updatePermissionLookup($oDoc); } } } } $oPlugin->registerAction('folderaction', 'KTRoleAllocationPlugin', 'ktcore.actions.folder.roles');