function allowTransition($oDocument, $oUser) { if (!$this->isLoaded()) { return true; } $iRoleId = $this->aConfig['role_id']; $oRole = Role::get($this->aConfig['role_id']); if (PEAR::isError($oRole)) { return true; // fail safe for cases where the role is deleted. } $bHaveRole = true; if ($iRoleId) { $bHaveRole = false; // handle the magic roles if ($iRoleId == -3) { // everyone: just accept $bHaveRole = true; } else { if ($iRoleId == -4 && !$oUser->isAnonymous()) { // authenticated $bHaveRole = true; } else { $bHaveRole = true; $oRoleAllocation = DocumentRoleAllocation::getAllocationsForDocumentAndRole($oDocument->getId(), $iRoleId); if ($oRoleAllocation == null) { // no role allocation on the doc - check the folder. $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($oDocument->getParentID(), $iRoleId); } // if that's -also- null if ($oRoleAllocation == null) { // no role allocation, no fulfillment. $bHaveRole = false; } else { if (!$oRoleAllocation->hasMember($oUser)) { $bHaveRole = false; } } } } } return $bHaveRole; }
/** * Update's the permission lookup on one folder or document, * non-recursively. */ function updatePermissionLookup(&$oFolderOrDocument, $aOptions = null) { $is_a_folder = is_a($oFolderOrDocument, 'Folder'); $is_a_document = is_a($oFolderOrDocument, 'Document') || is_a($oFolderOrDocument, 'KTDocumentCore'); //ensure that the document shortcut is being updated. if ($is_a_document && $oFolderOrDocument->isSymbolicLink()) { $oFolderOrDocument->switchToRealCore(); } $oChannel = null; $aMapPermAllowed = null; $oPermLookup = null; if (!is_null($aOptions)) { $oChannel = $aOptions['channel']; $aMapPermAllowed = $aOptions['map_allowed']; $oPermLookup = $aOptions['perm_lookup']; } if (!$is_a_folder && !$is_a_document) { return; // we occasionally get handed a PEAR::raiseError. Just ignore it. } if (is_null($oChannel)) { $oChannel =& KTPermissionChannel::getSingleton(); } if ($is_a_folder) { $msg = sprintf("Updating folder %s", join('/', $oFolderOrDocument->getPathArray())); } else { if (is_a($oFolderOrDocument, 'Document')) { //modify the message to reflect that a shortcut is begin updated if ($oFolderOrDocument->isSymbolicLink()) { $msg = sprintf("Updating shortcut to %s", $oFolderOrDocument->getName()); } else { $msg = sprintf("Updating document %s", $oFolderOrDocument->getName()); } } else { $msg = sprintf("Updating document %d", $oFolderOrDocument->getId()); } } $oChannel->sendMessage(new KTPermissionGenericMessage($msg)); //var_dump($msg); $iPermissionObjectId = $oFolderOrDocument->getPermissionObjectID(); if (empty($iPermissionObjectId)) { return; } $oPO = KTPermissionObject::get($iPermissionObjectId); if (is_null($aMapPermAllowed)) { $aPAs = KTPermissionAssignment::getByObjectMulti($oPO); $aMapPermAllowed = array(); foreach ($aPAs as $oPA) { $oPD = KTPermissionDescriptor::get($oPA->getPermissionDescriptorID()); $aGroupIDs = $oPD->getGroups(); $aUserIDs = array(); $aRoleIDs = $oPD->getRoles(); $aAllowed = array('group' => $aGroupIDs, 'user' => $aUserIDs, 'role' => $aRoleIDs); $aMapPermAllowed[$oPA->getPermissionID()] = $aAllowed; } } if (!$is_a_folder) { $aDynamicConditions = KTPermissionDynamicCondition::getByPermissionObject($oPO); if (!PEAR::isError($aDynamicConditions)) { foreach ($aDynamicConditions as $oDynamicCondition) { $iConditionId = $oDynamicCondition->getConditionId(); if (KTSearchUtil::testConditionOnDocument($iConditionId, $oFolderOrDocument)) { $iGroupId = $oDynamicCondition->getGroupId(); $aPermissionIds = $oDynamicCondition->getAssignment(); foreach ($aPermissionIds as $iPermissionId) { $aCurrentAllowed = KTUtil::arrayGet($aMapPermAllowed, $iPermissionId, array()); $aCurrentAllowed['group'][] = $iGroupId; $aMapPermAllowed[$iPermissionId] = $aCurrentAllowed; } } } } } if (!$is_a_folder) { $oState = KTWorkflowUtil::getWorkflowStateForDocument($oFolderOrDocument); if (!(PEAR::isError($oState) || is_null($oState) || $oState == false)) { $aWorkflowStatePermissionAssignments = KTWorkflowStatePermissionAssignment::getByState($oState); foreach ($aWorkflowStatePermissionAssignments as $oAssignment) { $iPermissionId = $oAssignment->getPermissionId(); $iPermissionDescriptorId = $oAssignment->getDescriptorId(); $oPD = KTPermissionDescriptor::get($iPermissionDescriptorId); $aGroupIDs = $oPD->getGroups(); $aUserIDs = array(); $aRoleIDs = $oPD->getRoles(); $aAllowed = array('group' => $aGroupIDs, 'user' => $aUserIDs, 'role' => $aRoleIDs); $aMapPermAllowed[$iPermissionId] = $aAllowed; } } } // if we have roles: nearest folder. $iRoleSourceFolder = null; if ($is_a_document) { $iRoleSourceFolder = $oFolderOrDocument->getFolderID(); } else { $iRoleSourceFolder = $oFolderOrDocument->getId(); } // very minor perf win: map role_id (in context) to PD. $_roleCache = array(); foreach ($aMapPermAllowed as $iPermissionId => $aAllowed) { $aAfterRoles = array(); if (array_key_exists('role', $aAllowed)) { foreach ($aAllowed['role'] as $k => $iRoleId) { // store the PD <-> RoleId map // special-case "all" or "authenticated". if ($iRoleId == -3 || $iRoleId == -4) { $aAfterRoles[] = $iRoleId; continue; } if (!array_key_exists($iRoleId, $_roleCache)) { $oRoleAllocation = null; if ($is_a_document) { $oRoleAllocation =& DocumentRoleAllocation::getAllocationsForDocumentAndRole($oFolderOrDocument->getId(), $iRoleId); if (PEAR::isError($oRoleAllocation)) { $oRoleAllocation = null; } } // if that's null - not set _on_ the document, then if (is_null($oRoleAllocation)) { $oRoleAllocation =& RoleAllocation::getAllocationsForFolderAndRole($iRoleSourceFolder, $iRoleId); } $_roleCache[$iRoleId] = $oRoleAllocation; } // roles are _not_ always assigned (can be null at root) if (!is_null($_roleCache[$iRoleId])) { $aMapPermAllowed[$iPermissionId]['user'] = kt_array_merge($aMapPermAllowed[$iPermissionId]['user'], $_roleCache[$iRoleId]->getUserIds()); $aMapPermAllowed[$iPermissionId]['group'] = kt_array_merge($aMapPermAllowed[$iPermissionId]['group'], $_roleCache[$iRoleId]->getGroupIds()); // naturally, roles cannot be assigned roles, or madness follows. } unset($aAllowed['role'][$k]); } } unset($aMapPermAllowed[$iPermissionId]['role']); if (!empty($aAfterRoles)) { $aMapPermAllowed[$iPermissionId]['role'] = $aAfterRoles; } } /* print '<pre>'; print '=======' . $oFolderOrDocument->getName(); print '<br />'; var_dump($aMapPermAllowed); print '</pre>'; */ //if (is_null($oPermLookup)) { $aMapPermDesc = array(); foreach ($aMapPermAllowed as $iPermissionId => $aAllowed) { $oLookupPD = KTPermissionUtil::getOrCreateDescriptor($aAllowed); $aMapPermDesc[$iPermissionId] = $oLookupPD->getID(); } $oPermLookup = KTPermissionLookupAssignment::findOrCreateLookupByPermissionDescriptorMap($aMapPermDesc); //} $oFolderOrDocument->setPermissionLookupID($oPermLookup->getID()); $oFolderOrDocument->update(); }
function informUsersForState($oState, $aInformed, $oDocument, $oUser, $sComments) { // say no to duplicates. KTWorkflowNotification::clearNotificationsForDocument($oDocument); $aUsers = array(); $aGroups = array(); $aRoles = array(); foreach (KTUtil::arrayGet($aInformed, 'user', array()) as $iUserId) { $oU = User::get($iUserId); if (PEAR::isError($oU) || $oU == false) { continue; } else { $aUsers[$oU->getId()] = $oU; } } foreach (KTUtil::arrayGet($aInformed, 'group', array()) as $iGroupId) { $oG = Group::get($iGroupId); if (PEAR::isError($oG) || $oG == false) { continue; } else { $aGroups[$oG->getId()] = $oG; } } foreach (KTUtil::arrayGet($aInformed, 'role', array()) as $iRoleId) { $oR = Role::get($iRoleId); if (PEAR::isError($oR) || $oR == false) { continue; } else { $aRoles[] = $oR; } } // FIXME extract this into a util - I see us using this again and again. // start with roles ... roles _only_ ever contain groups. foreach ($aRoles as $oRole) { // do NOT alert anonymous or Everyone roles - that would be very scary. $iRoleId = KTUtil::getId($oRole); if ($iRoleId == -3 || $iRoleId == -4) { continue; } // first try on the document, then the folder above it. $oRoleAllocation = DocumentRoleAllocation::getAllocationsForDocumentAndRole($oDocument->getId(), $iRoleId); if (is_null($oRoleAllocation)) { // if we don't get a document role, try folder role. $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($oDocument->getFolderID(), $oRole->getId()); } if (is_null($oRoleAllocation) || PEAR::isError($oRoleAllocation)) { continue; } $aRoleUsers = $oRoleAllocation->getUsers(); $aRoleGroups = $oRoleAllocation->getGroups(); foreach ($aRoleUsers as $id => $oU) { $aUsers[$id] = $oU; } foreach ($aRoleGroups as $id => $oGroup) { $aGroups[$id] = $oGroup; } } // we now have a (potentially overlapping) set of groups, which may // have subgroups. // // what we need to do _now_ is build a canonical set of groups, and then // generate the singular user-base. $aGroupMembershipSet = GroupUtil::buildGroupArray(); $aAllIds = array_keys($aGroups); foreach ($aGroups as $id => $oGroup) { $aAllIds = kt_array_merge($aGroupMembershipSet[$id], $aAllIds); } foreach ($aAllIds as $id) { if (!array_key_exists($id, $aGroups)) { $aGroups[$id] = Group::get($id); } } // now, merge this (again) into the user-set. foreach ($aGroups as $oGroup) { $aNewUsers = $oGroup->getMembers(); foreach ($aNewUsers as $oU) { $id = $oU->getId(); if (!array_key_exists($id, $aUsers)) { $aUsers[$id] = $oU; } } } // and done. foreach ($aUsers as $oU) { if (!PEAR::isError($oU)) { KTWorkflowNotification::newNotificationForDocument($oDocument, $oU, $oState, $oUser, $sComments); } } }
function &getAllocationsForDocumentAndRole($iDocumentId, $iRoleId) { $raTable = KTUtil::getTableName('document_role_allocations'); $dTable = KTUtil::getTableName('documents'); $sQuery = "SELECT ra.id as `id` FROM " . $raTable . " AS ra " . ' LEFT JOIN ' . $dTable . ' AS d ON (d.id = ra.document_id) ' . ' WHERE d.id = ?' . ' AND ra.role_id = ?'; $aParams = array($iDocumentId, $iRoleId); $iAllocId = DBUtil::getOneResultKey(array($sQuery, $aParams), 'id'); if (PEAR::isError($iAllocId)) { return null; } if (false) { print '<pre>'; var_dump($iAllocId); print ''; print $sQuery; print '</pre>'; } // magic for the Owner role here. if (empty($iAllocId) && $iRoleId == -2) { $permDescriptor = null; // THIS OBJECT MUST NEVER BE MODIFIED, without first calling CREATE. $oFakeAlloc = new DocumentRoleAllocation(); $oFakeAlloc->setDocumentId($iDocumentId); $oFakeAlloc->setRoleId($iRoleId); $oFakeAlloc->setPermissionDescriptorId($permDescriptor); //var_dump($oFakeAlloc); return $oFakeAlloc; } else { if (empty($iAllocId)) { return null; } } return DocumentRoleAllocation::get($iAllocId); }
function do_assistance() { $sSubject = $this->oValidator->validateString($_REQUEST['subject']); $sDetails = $this->oValidator->validateString($_REQUEST['details']); $aUsers = array(); $aGroups = array(); $aRoles = array(); foreach (Group::getAdministratorGroups() as $oGroup) { $aGroups[$oGroup->getId()] =& $oGroup; } foreach (Unit::getUnitsForFolder($this->oDocument->getFolderId()) as $oUnit) { foreach (Group::getUnitAdministratorGroupsByUnit($oUnit) as $oGroup) { $aGroups[$oGroup->getId()] =& $oGroup; } } $aRoles[-2] = Role::get(-2); $oDocument =& $this->oDocument; foreach ($aRoles as $oRole) { // Ignore anonymous or Everyone roles $iRoleId = KTUtil::getId($oRole); if ($iRoleId == -3 || $iRoleId == -4) { continue; } // first try on the document, then the folder above it. $oRoleAllocation = DocumentRoleAllocation::getAllocationsForDocumentAndRole($oDocument->getId(), $iRoleId); if (is_null($oRoleAllocation)) { // if we don't get a document role, try folder role. $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($oDocument->getFolderID(), $oRole->getId()); } if (is_null($oRoleAllocation) || PEAR::isError($oRoleAllocation)) { continue; } $aRoleUsers = $oRoleAllocation->getUsers(); $aRoleGroups = $oRoleAllocation->getGroups(); foreach ($aRoleUsers as $id => $oU) { $aUsers[$id] = $oU; } foreach ($aRoleGroups as $id => $oGroup) { $aGroups[$id] = $oGroup; } } $aGroupMembershipSet = GroupUtil::buildGroupArray(); $aAllIds = array_keys($aGroups); foreach ($aGroups as $id => $oGroup) { $aAllIds = kt_array_merge($aGroupMembershipSet[$id], $aAllIds); } foreach ($aAllIds as $id) { if (!array_key_exists($id, $aGroups)) { $aGroups[$id] = Group::get($id); } } // now, merge this (again) into the user-set. foreach ($aGroups as $oGroup) { $aNewUsers = $oGroup->getMembers(); foreach ($aNewUsers as $oU) { $id = $oU->getId(); if (!array_key_exists($id, $aUsers)) { $aUsers[$id] = $oU; } } } foreach ($aUsers as $oU) { if (!PEAR::isError($oU)) { KTAssistNotification::newNotificationForDocument($this->oDocument, $oU, $this->oUser, $sSubject, $sDetails); } } $this->commitTransaction(); $params = 'fDocumentId=' . $oDocument->getId(); $url = generateControllerLink('viewDocument', $params); exit(redirect($url)); }
function do_main() { $this->oPage->setTitle(_kt("View Roles")); $this->oPage->setBreadcrumbDetails(_kt("View Roles")); $oTemplating = new KTTemplating(); $oTemplate = $oTemplating->loadTemplate("ktcore/action/view_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 = DocumentRoleAllocation::getAllocationsForDocumentAndRole($this->oDocument->getId(), $iRoleId); if (is_null($oRoleAllocation)) { $oRoleAllocation = RoleAllocation::getAllocationsForFolderAndRole($this->oDocument->getFolderID(), $iRoleId); } $u = array(); $g = array(); $aid = null; $raid = null; if (is_null($oRoleAllocation)) { // nothing. } else { //var_dump($oRoleAllocation); $raid = $oRoleAllocation->getId(); // real_alloc_id $aAllowed = $oRoleAllocation->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]['real_allocation_id'] = $raid; } // 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'] = '<span class="descriptiveText"> ' . _kt('no users') . '</span>'; } else { $aRoles[$key]['users'] = implode(', ', $_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'] = '<span class="descriptiveText"> ' . _kt('no groups') . '</span>'; } else { $aRoles[$key]['groups'] = implode(', ', $_groups); } } $aTemplateData = array('context' => &$this, 'roles' => $aRoles); return $oTemplate->render($aTemplateData); }