297 lines
9.8 KiB
PHP
297 lines
9.8 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* $Id$
|
||
|
|
*
|
||
|
|
* KnowledgeTree Community Edition
|
||
|
|
* Document Management Made Simple
|
||
|
|
* Copyright (C) 2008, 2009 KnowledgeTree Inc.
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* This program is free software; you can redistribute it and/or modify it under
|
||
|
|
* the terms of the GNU General Public License version 3 as published by the
|
||
|
|
* Free Software Foundation.
|
||
|
|
*
|
||
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||
|
|
* details.
|
||
|
|
*
|
||
|
|
* You should have received a copy of the GNU General Public License
|
||
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
*
|
||
|
|
* You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
|
||
|
|
* California 94120-7775, or email info@knowledgetree.com.
|
||
|
|
*
|
||
|
|
* The interactive user interfaces in modified source and object code versions
|
||
|
|
* of this program must display Appropriate Legal Notices, as required under
|
||
|
|
* Section 5 of the GNU General Public License version 3.
|
||
|
|
*
|
||
|
|
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||
|
|
* these Appropriate Legal Notices must retain the display of the "Powered by
|
||
|
|
* KnowledgeTree" logo and retain the original copyright notice. If the display of the
|
||
|
|
* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
|
||
|
|
* must display the words "Powered by KnowledgeTree" and retain the original
|
||
|
|
* copyright notice.
|
||
|
|
* Contributor( s): ______________________________________
|
||
|
|
*/
|
||
|
|
|
||
|
|
require_once(KT_LIB_DIR . "/ktentity.inc");
|
||
|
|
require_once(KT_LIB_DIR . "/util/ktutil.inc");
|
||
|
|
require_once(KT_LIB_DIR . "/database/dbutil.inc");
|
||
|
|
|
||
|
|
require_once(KT_LIB_DIR . "/permissions/permissiondescriptor.inc.php");
|
||
|
|
require_once(KT_LIB_DIR . "/permissions/permissionutil.inc.php");
|
||
|
|
require_once(KT_LIB_DIR . "/users/User.inc");
|
||
|
|
require_once(KT_LIB_DIR . "/groups/Group.inc");
|
||
|
|
require_once(KT_LIB_DIR . "/groups/GroupUtil.php");
|
||
|
|
require_once(KT_LIB_DIR . "/documentmanagement/Document.inc");
|
||
|
|
require_once(KT_LIB_DIR . "/documentmanagement/documentcore.inc.php");
|
||
|
|
|
||
|
|
require_once(KT_LIB_DIR . "/roles/roleallocation.inc.php");
|
||
|
|
|
||
|
|
|
||
|
|
class DocumentRoleAllocation extends KTEntity {
|
||
|
|
|
||
|
|
/** role object primary key */
|
||
|
|
var $iId=-1;
|
||
|
|
var $iDocumentId;
|
||
|
|
var $iRoleId;
|
||
|
|
var $iPermissionDescriptorId;
|
||
|
|
|
||
|
|
var $_bUsePearError = true;
|
||
|
|
|
||
|
|
var $_aFieldToSelect = array(
|
||
|
|
'iId' => 'id',
|
||
|
|
'iRoleId' => 'role_id',
|
||
|
|
'iDocumentId' => 'document_id',
|
||
|
|
'iPermissionDescriptorId' => 'permission_descriptor_id',
|
||
|
|
);
|
||
|
|
|
||
|
|
function setDocumentId($iDocumentId) { $this->iDocumentId = $iDocumentId; }
|
||
|
|
function setRoleId($iRoleId) { $this->iRoleId = $iRoleId; }
|
||
|
|
function setPermissionDescriptorId($iPermissionDescriptorId) { $this->iPermissionDescriptorId = $iPermissionDescriptorId; }
|
||
|
|
function getDocumentId() { return $this->iDocumentId; }
|
||
|
|
function getRoleId() { return $this->iRoleId; }
|
||
|
|
function getPermissionDescriptorId() { return $this->iPermissionDescriptorId; }
|
||
|
|
|
||
|
|
// aggregate: set (for this alloc) the array('user' => array(), 'group' => array()).
|
||
|
|
function setAllowed($aAllowed) {
|
||
|
|
$oDescriptor = KTPermissionUtil::getOrCreateDescriptor($aAllowed); // fully done, etc.
|
||
|
|
$this->iPermissionDescriptorId = $oDescriptor->getId();
|
||
|
|
}
|
||
|
|
|
||
|
|
function getAllowed() {
|
||
|
|
if (!is_null($this->iPermissionDescriptorId)) {
|
||
|
|
$oDescriptor = KTPermissionDescriptor::get($this->iPermissionDescriptorId); // fully done, etc.
|
||
|
|
$aAllowed = $oDescriptor->getAllowed();
|
||
|
|
} else {
|
||
|
|
$aAllowed = array();
|
||
|
|
}
|
||
|
|
// special case "document owner".
|
||
|
|
if ($this->iRoleId == -2) {
|
||
|
|
|
||
|
|
$oDoc = KTDocumentCore::get($this->iDocumentId);
|
||
|
|
|
||
|
|
/* ! NBM Please Review
|
||
|
|
*
|
||
|
|
* This should never be an error - we were called by PermissionUtil
|
||
|
|
* to get the details for a document, but it _is_ be a DocumentCore
|
||
|
|
* object during _add.
|
||
|
|
*
|
||
|
|
* When we try to grab the Document, it blows up on the MetadataVersion,
|
||
|
|
* so we have to use a DocumentCore to avoid a fail-out on the initial
|
||
|
|
* on-add permission check.
|
||
|
|
*
|
||
|
|
* Is this bad/evil/not appropriate in some way? I can't see a major
|
||
|
|
* issue with it...
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
if (PEAR::isError($oDoc)) {
|
||
|
|
return $aAllowed;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ! NBM Please review
|
||
|
|
// we cascade "owner" from the folder (if, for some _bizarre_ reason the
|
||
|
|
// owner role is allocated to users/groups/etc. this can be disabled
|
||
|
|
// with the CRACK_IS_BAD flag, or removed entirely. I am undecided.
|
||
|
|
//
|
||
|
|
// There is some argument to be made for the consistency, but it may not be
|
||
|
|
// that big. I think it _may_ lead to easily misconfigured setups, but I
|
||
|
|
// really don't know.
|
||
|
|
$CRACK_IS_BAD = false;
|
||
|
|
if ((!$CRACK_IS_BAD) && is_null($this->iPermissionDescriptorId)) {
|
||
|
|
$oDerivedAlloc = RoleAllocation::getAllocationsForFolderAndRole($oDoc->getFolderID(), $this->iRoleId);
|
||
|
|
if (!(PEAR::isError($oDerivedAlloc) || is_null($oDerivedAlloc))) {
|
||
|
|
$aAllowed = $oDerivedAlloc->getAllowed();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$owner_id = $oDoc->getOwnerId();
|
||
|
|
if (is_null($aAllowed['user'])) {
|
||
|
|
$aAllowed['user'] = array($owner_id);
|
||
|
|
} else if (array_search($owner_id, $aAllowed['user']) === false) {
|
||
|
|
$aAllowed['user'][] = $owner_id;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return $aAllowed;
|
||
|
|
}
|
||
|
|
|
||
|
|
function _fieldValues () { return array(
|
||
|
|
'role_id' => $this->iRoleId,
|
||
|
|
'document_id' => $this->iDocumentId,
|
||
|
|
'permission_descriptor_id' => $this->iPermissionDescriptorId,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* getAllocationForDocumentAndRole($iFolderId, $iRoleId)
|
||
|
|
*
|
||
|
|
* this is the key function: for a given document and role,
|
||
|
|
* returns either a RoleAllocation object, or null
|
||
|
|
* (if there is none). IT DOES NOT SCAN UP THE HIERACHY (Use RoleAllocation)
|
||
|
|
*/
|
||
|
|
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);
|
||
|
|
}
|
||
|
|
|
||
|
|
// static, boilerplate.
|
||
|
|
function _table () { return KTUtil::getTableName('document_role_allocations'); }
|
||
|
|
function & get($iRoleId) { return KTEntityUtil::get('DocumentRoleAllocation', $iRoleId); }
|
||
|
|
function & getList($sWhereClause = null) { return KTEntityUtil::getList2('DocumentRoleAllocation', $sWhereClause); }
|
||
|
|
function & createFromArray($aOptions) { return KTEntityUtil::createFromArray('DocumentRoleAllocation', $aOptions); }
|
||
|
|
|
||
|
|
function getPermissionDescriptor() {
|
||
|
|
// could be an error - return as-is.
|
||
|
|
$oDescriptor =& KTPermissionDescriptor::get($this->iPermissionDescriptorId);
|
||
|
|
return $oDescriptor;
|
||
|
|
}
|
||
|
|
|
||
|
|
// setting users and groups needs to use permissionutil::getOrCreateDescriptor
|
||
|
|
function getUsers() {
|
||
|
|
$aAllowed = $this->getAllowed();
|
||
|
|
if ($aAllowed['user'] !== null) {
|
||
|
|
$aUsers = $aAllowed['user'];
|
||
|
|
}
|
||
|
|
|
||
|
|
// now we want to map to oUsers, since that's what groups do.
|
||
|
|
$aFullUsers = array();
|
||
|
|
foreach ($aUsers as $iUserId) {
|
||
|
|
$oUser = User::get($iUserId);
|
||
|
|
if (!(PEAR::isError($oUser) || ($oUser == false))) {
|
||
|
|
$aFullUsers[$iUserId] = $oUser;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $aFullUsers;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getGroups() {
|
||
|
|
$aAllowed = $this->getAllowed();
|
||
|
|
if (is_null($aAllowed['group'])) {
|
||
|
|
return array(); // nothing here, move on.
|
||
|
|
} else {
|
||
|
|
$aGroups = $aAllowed['group'];
|
||
|
|
}
|
||
|
|
|
||
|
|
// now we want to map to oUsers, since that's what groups do.
|
||
|
|
$aFullGroups = array();
|
||
|
|
foreach ($aGroups as $iGroupId) {
|
||
|
|
$oGroup = Group::get($iGroupId);
|
||
|
|
if (!(PEAR::isError($oGroup) || ($oGroup == false))) {
|
||
|
|
$aFullGroups[$iGroupId] = $oGroup;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $aFullGroups;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getUserIds() {
|
||
|
|
$aAllowed = $this->getAllowed();
|
||
|
|
if ($aAllowed['user'] !== null) {
|
||
|
|
$aUsers = $aAllowed['user'];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $aUsers;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getGroupIds() {
|
||
|
|
$aAllowed = $this->getAllowed();
|
||
|
|
if ($aAllowed['group'] !== null) {
|
||
|
|
$aGroups = $aAllowed['group'];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $aGroups;
|
||
|
|
}
|
||
|
|
|
||
|
|
// utility function to establish user membership in this allocation.
|
||
|
|
// FIXME nbm: is there are more coherent way to do this ITO your PD infrastructure?
|
||
|
|
function hasMember($oUser) {
|
||
|
|
$aAllowed = $this->getAllowed();
|
||
|
|
$iUserId = $oUser->getId();
|
||
|
|
|
||
|
|
if ($aAllowed['user'] != null) {
|
||
|
|
if (array_search($iUserId, $aAllowed['user']) !== false) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// now we need the group objects.
|
||
|
|
// FIXME this could accelerated to a single SQL query on group_user_link.
|
||
|
|
$aGroups = $this->getGroups();
|
||
|
|
if (PEAR::isError($aGroups) || ($aGroups == false)) {
|
||
|
|
return false;
|
||
|
|
} else {
|
||
|
|
foreach ($aGroups as $oGroup) {
|
||
|
|
$reason = GroupUtil::getMembershipReason($oUser, $oGroup);
|
||
|
|
if (PEAR::isError($reason) || is_null($reason)) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
return true; // don't bother continuing - short-circuit for performance.
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
?>
|