diff --git a/core/src/core/classes/class.AJXP_Node.php b/core/src/core/classes/class.AJXP_Node.php index c15f6bd5be..17e04d2ac5 100644 --- a/core/src/core/classes/class.AJXP_Node.php +++ b/core/src/core/classes/class.AJXP_Node.php @@ -415,6 +415,10 @@ public function getUser(){ */ public function setUser($userId){ $this->_user = $userId; + $this->urlParts["user"] = $userId; + // Update url with a user@workspaceID + $crt = $this->getScheme()."://".$this->getRepositoryId(); + $this->_url = str_replace($crt, $this->getScheme()."://".$this->_user."@".$this->getRepositoryId(), $this->_url); } /** diff --git a/core/src/core/classes/class.AJXP_VarsFilter.php b/core/src/core/classes/class.AJXP_VarsFilter.php index 1b01ea6344..2a52a505fe 100644 --- a/core/src/core/classes/class.AJXP_VarsFilter.php +++ b/core/src/core/classes/class.AJXP_VarsFilter.php @@ -33,22 +33,27 @@ class AJXP_VarsFilter * Calls the vars.filter hooks. * @static * @param $value + * @param AbstractAjxpUser $resolveUser * @return mixed|string */ - public static function filter($value) + public static function filter($value, $resolveUser = null) { if (is_string($value) && strpos($value, "AJXP_USER")!==false) { if (AuthService::usersEnabled()) { - $loggedUser = AuthService::getLoggedUser(); - if ($loggedUser != null) { - if ($loggedUser->hasParent() && $loggedUser->getResolveAsParent()) { - $loggedUserId = $loggedUser->getParent(); + if($resolveUser != null){ + $value = str_replace("AJXP_USER", $resolveUser->getId(), $value); + }else{ + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser != null) { + if ($loggedUser->hasParent() && $loggedUser->getResolveAsParent()) { + $loggedUserId = $loggedUser->getParent(); + } else { + $loggedUserId = $loggedUser->getId(); + } + $value = str_replace("AJXP_USER", $loggedUserId, $value); } else { - $loggedUserId = $loggedUser->getId(); + return ""; } - $value = str_replace("AJXP_USER", $loggedUserId, $value); - } else { - return ""; } } else { $value = str_replace("AJXP_USER", "shared", $value); @@ -56,7 +61,11 @@ public static function filter($value) } if (is_string($value) && strpos($value, "AJXP_GROUP_PATH")!==false) { if (AuthService::usersEnabled()) { - $loggedUser = AuthService::getLoggedUser(); + if($resolveUser != null){ + $loggedUser = $resolveUser; + }else{ + $loggedUser = AuthService::getLoggedUser(); + } if ($loggedUser != null) { $gPath = $loggedUser->getGroupPath(); $value = str_replace("AJXP_GROUP_PATH_FLAT", str_replace("/", "_", trim($gPath, "/")), $value); diff --git a/core/src/core/classes/class.Repository.php b/core/src/core/classes/class.Repository.php index 44436fda05..abed616c1b 100644 --- a/core/src/core/classes/class.Repository.php +++ b/core/src/core/classes/class.Repository.php @@ -306,9 +306,10 @@ public function addOption($oName, $oValue) * Get the repository options, filtered in various maners * @param string $oName * @param bool $safe Do not filter + * @param AbstractAjxpUser $resolveUser * @return mixed|string */ - public function getOption($oName, $safe=false) + public function getOption($oName, $safe=false, $resolveUser = null) { if (!$safe && $this->inferOptionsFromParent) { if (!isset($this->parentTemplateObject)) { @@ -324,7 +325,7 @@ public function getOption($oName, $safe=false) } if (isSet($this->options[$oName])) { $value = $this->options[$oName]; - if(!$safe) $value = AJXP_VarsFilter::filter($value); + if(!$safe) $value = AJXP_VarsFilter::filter($value, $resolveUser); return $value; } if ($this->inferOptionsFromParent) { diff --git a/core/src/plugins/access.fs/class.fsAccessWrapper.php b/core/src/plugins/access.fs/class.fsAccessWrapper.php index e08831e9f3..013833f83d 100644 --- a/core/src/plugins/access.fs/class.fsAccessWrapper.php +++ b/core/src/plugins/access.fs/class.fsAccessWrapper.php @@ -78,6 +78,13 @@ protected static function initPath($path, $streamType, $storeOpenContext = false if($split && $streamType == "file" && $split[1] != "/") $insideZip = true; if($split && $streamType == "dir") $insideZip = true; if($skipZip) $insideZip = false; + + $resolveUser = null; + if(isSet($url["user"]) && AuthService::usersEnabled()){ + $resolveUser = ConfService::getConfStorageImpl()->createUserObject($url["user"]); + } + $resolvedPath = realpath(SystemTextEncoding::toStorageEncoding($repoObject->getOption("PATH", false, $resolveUser))); + //var_dump($path); //var_dump($skipZip); // Inside a zip : copy the file to a tmp file and return a reference to it @@ -93,7 +100,7 @@ protected static function initPath($path, $streamType, $storeOpenContext = false $tmpFileName = $tmpDir.DIRECTORY_SEPARATOR.basename($localPath); AJXP_Logger::debug(__CLASS__,__FUNCTION__,"Tmp file $tmpFileName"); register_shutdown_function(array("fsAccessWrapper", "removeTmpFile"), $tmpDir, $tmpFileName); - $crtZip = new PclZip(AJXP_Utils::securePath(realpath(SystemTextEncoding::toStorageEncoding($repoObject->getOption("PATH"))).$repoObject->resolveVirtualRoots($zipPath))); + $crtZip = new PclZip(AJXP_Utils::securePath($resolvedPath.$repoObject->resolveVirtualRoots($zipPath))); $content = $crtZip->listContent(); foreach ($content as $item) { $fName = AJXP_Utils::securePath($item["stored_filename"]); @@ -116,7 +123,7 @@ protected static function initPath($path, $streamType, $storeOpenContext = false } } } else { - $crtZip = new PclZip(AJXP_Utils::securePath(realpath(SystemTextEncoding::toStorageEncoding($repoObject->getOption("PATH"))).$repoObject->resolveVirtualRoots($zipPath))); + $crtZip = new PclZip(AJXP_Utils::securePath($resolvedPath.$repoObject->resolveVirtualRoots($zipPath))); $liste = $crtZip->listContent(); if($storeOpenContext) self::$crtZip = $crtZip; $folders = array(); $files = array();$builtFolders = array(); @@ -178,7 +185,7 @@ protected static function initPath($path, $streamType, $storeOpenContext = false return -1; } } - return realpath(SystemTextEncoding::toStorageEncoding($repoObject->getOption("PATH"))).$repoObject->resolveVirtualRoots($url["path"]); + return $resolvedPath.$repoObject->resolveVirtualRoots($url["path"]); } } diff --git a/core/src/plugins/action.share/class.ShareCenter.php b/core/src/plugins/action.share/class.ShareCenter.php index 8b092e3698..6196315454 100644 --- a/core/src/plugins/action.share/class.ShareCenter.php +++ b/core/src/plugins/action.share/class.ShareCenter.php @@ -604,11 +604,18 @@ private function findMirrorNodesInShares($node, $direction){ if($node->getRepository()->hasParent()){ $parentRepoId = $node->getRepository()->getParentId(); $currentRoot = $node->getRepository()->getOption("PATH"); - $parentRoot = ConfService::getRepositoryById($parentRepoId)->getOption("PATH"); + $owner = $node->getRepository()->getOwner(); + $resolveUser = null; + if($owner != null){ + $resolveUser = ConfService::getConfStorageImpl()->createUserObject($owner); + } + $parentRoot = ConfService::getRepositoryById($parentRepoId)->getOption("PATH", false, $resolveUser); $relative = substr($currentRoot, strlen($parentRoot)); $parentNodeURL = $node->getScheme()."://".$parentRepoId.$relative.$node->getPath(); $this->logDebug("action.share", "Should trigger on ".$parentNodeURL); - $result[$parentRepoId] = array(new AJXP_Node($parentNodeURL), "UP"); + $parentNode = new AJXP_Node($parentNodeURL); + if($owner != null) $parentNode->setUser($owner); + $result[$parentRepoId] = array($parentNode, "UP"); } } return $result; diff --git a/core/src/plugins/core.mq/class.MqManager.php b/core/src/plugins/core.mq/class.MqManager.php index 976c03de74..115ebdc812 100755 --- a/core/src/plugins/core.mq/class.MqManager.php +++ b/core/src/plugins/core.mq/class.MqManager.php @@ -86,15 +86,17 @@ public function consumeQueue($action, $httpVars, $fileVars) } /** - * @param null AJXP_Node $origNode - * @param null AJXP_Node $newNode - * @param bool bool $copy + * @param AJXP_Node $origNode + * @param AJXP_Node $newNode + * @param bool $copy */ public function publishNodeChange($origNode = null, $newNode = null, $copy = false) { - $content = "";$repo = ""; + $content = "";$repo = "";$targetUserId=null; + $update = false; if ($newNode != null) { $repo = $newNode->getRepositoryId(); + $targetUserId = $newNode->getUser(); $update = false; $data = array(); if ($origNode != null && !$copy) { @@ -107,11 +109,12 @@ public function publishNodeChange($origNode = null, $newNode = null, $copy = fal } if ($origNode != null && ! $update && !$copy) { $repo = $origNode->getRepositoryId(); + $targetUserId = $origNode->getUser(); $content = AJXP_XMLWriter::writeNodesDiff(array("REMOVE" => array($origNode->getPath()))); } if (!empty($content) && $repo != "") { - $this->sendInstantMessage($content, $repo); + $this->sendInstantMessage($content, $repo, $targetUserId); } @@ -124,7 +127,8 @@ public function sendInstantMessage($xmlContent, $repositoryId, $targetUserId = n } else { $scope = ConfService::getRepositoryById($repositoryId)->securityScope(); if ($scope == "USER") { - $userId = AuthService::getLoggedUser()->getId(); + if($targetUserId) $userId = $targetUserId; + else $userId = AuthService::getLoggedUser()->getId(); } else if ($scope == "GROUP") { $gPath = AuthService::getLoggedUser()->getGroupPath(); } else if (isSet($targetUserId)) { diff --git a/core/src/plugins/core.notifications/class.AJXP_NotificationCenter.php b/core/src/plugins/core.notifications/class.AJXP_NotificationCenter.php index b782a349e2..aa48d158dc 100755 --- a/core/src/plugins/core.notifications/class.AJXP_NotificationCenter.php +++ b/core/src/plugins/core.notifications/class.AJXP_NotificationCenter.php @@ -91,8 +91,14 @@ public function persistChangeHookToFeed(AJXP_Node $oldNode = null, AJXP_Node $ne $n = ($oldNode == null ? $newNode : $oldNode); $repoId = $n->getRepositoryId(); - $userId = AuthService::getLoggedUser()->getId(); - $userGroup = AuthService::getLoggedUser()->getGroupPath(); + if($n->getUser()){ + $userId = $n->getUser(); + $obj = ConfService::getConfStorageImpl()->createUserObject($userId); + if($obj) $userGroup = $obj->getGroupPath(); + }else{ + $userId = AuthService::getLoggedUser()->getId(); + $userGroup = AuthService::getLoggedUser()->getGroupPath(); + } $repository = ConfService::getRepositoryById($repoId); $repositoryScope = $repository->securityScope(); $repositoryScope = ($repositoryScope !== false ? $repositoryScope : "ALL"); diff --git a/core/src/plugins/index.lucene/class.AjxpLuceneIndexer.php b/core/src/plugins/index.lucene/class.AjxpLuceneIndexer.php index ea8037b67c..564d14e137 100644 --- a/core/src/plugins/index.lucene/class.AjxpLuceneIndexer.php +++ b/core/src/plugins/index.lucene/class.AjxpLuceneIndexer.php @@ -39,10 +39,10 @@ public function init($options) parent::init($options); set_include_path(get_include_path().PATH_SEPARATOR.AJXP_INSTALL_PATH."/plugins/index.lucene"); $metaFields = $this->getFilteredOption("index_meta_fields"); - $specKey = $this->getFilteredOption("repository_specific_keywords"); if (!empty($metaFields)) { $this->metaFields = explode(",",$metaFields); } + $specKey = $this->getFilteredOption("repository_specific_keywords"); if (!empty($specKey)) { $this->specificId = "-".str_replace(array(",", "/"), array("-", "__"), AJXP_VarsFilter::filter($specKey)); } @@ -411,7 +411,7 @@ public function updateNodeIndexMeta($node) if (isSet($this->currentIndex)) { $index = $this->currentIndex; } else { - $index = $this->loadIndex($node->getRepositoryId()); + $index = $this->loadIndex($node->getRepositoryId(), true, $node->getUser()); } Zend_Search_Lucene_Analysis_Analyzer::setDefault( new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive()); @@ -453,9 +453,9 @@ public function updateNodeIndex($oldNode, $newNode = null, $copy = false, $recur $index = $this->currentIndex; } else { if($oldNode == null){ - $index = $this->loadIndex($newNode->getRepositoryId()); + $index = $this->loadIndex($newNode->getRepositoryId(), true, $newNode->getUser()); }else{ - $index = $this->loadIndex($oldNode->getRepositoryId()); + $index = $this->loadIndex($oldNode->getRepositoryId(), true, $newNode->getUser()); } } $this->setDefaultAnalyzer(); @@ -687,11 +687,19 @@ protected function releaseLock($repositoryId) * @param bool $create * @return Zend_Search_Lucene_Interface the index */ - protected function loadIndex($repositoryId, $create = true) + protected function loadIndex($repositoryId, $create = true, $resolveUserId = null) { require_once("Zend/Search/Lucene.php"); $mainCacheDir = (defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR); - $iPath = $mainCacheDir."/indexes/index-$repositoryId".$this->specificId; + $specificId = $this->specificId; + if($resolveUserId != null){ + $specKey = $this->getFilteredOption("repository_specific_keywords"); + if (!empty($specKey)) { + $specKey = str_replace("AJXP_USER", $resolveUserId, $specKey); + $specificId = "-".str_replace(array(",", "/"), array("-", "__"), AJXP_VarsFilter::filter($specKey)); + } + } + $iPath = $mainCacheDir."/indexes/index-$repositoryId".$specificId; if(!is_dir($mainCacheDir."/indexes")) mkdir($mainCacheDir."/indexes",0755,true); if (is_dir($iPath)) { $index = Zend_Search_Lucene::open($iPath); diff --git a/core/src/plugins/meta.syncable/class.ChangesTracker.php b/core/src/plugins/meta.syncable/class.ChangesTracker.php index b1be113579..368a94c3fb 100644 --- a/core/src/plugins/meta.syncable/class.ChangesTracker.php +++ b/core/src/plugins/meta.syncable/class.ChangesTracker.php @@ -292,13 +292,22 @@ protected function filterRow(&$previousRow, $filter = null){ * @param Repository $repository * @return String */ - protected function computeIdentifier($repository) + protected function computeIdentifier($repository, $resolveUserId = null) { $parts = array($repository->getId()); if ($repository->securityScope() == 'USER') { - $parts[] = AuthService::getLoggedUser()->getId(); + if($resolveUserId != null) { + $parts[] = $resolveUserId; + } else { + $parts[] = AuthService::getLoggedUser()->getId(); + } } else if ($repository->securityScope() == 'GROUP') { - $parts[] = AuthService::getLoggedUser()->getGroupPath(); + if($resolveUserId != null) { + $userObject = ConfService::getConfStorageImpl()->createUserObject($resolveUserId); + if($userObject != null) $parts[] = $userObject->getGroupPath(); + }else{ + $parts[] = AuthService::getLoggedUser()->getGroupPath(); + } } return implode("-", $parts); } @@ -335,7 +344,7 @@ public function updateNodesIndex($oldNode = null, $newNode = null, $copy = false } } if ($newNode == null) { - $repoId = $this->computeIdentifier($oldNode->getRepository()); + $repoId = $this->computeIdentifier($oldNode->getRepository(), $oldNode->getUser()); // DELETE dibi::query("DELETE FROM [ajxp_index] WHERE [node_path] LIKE %like~ AND [repository_identifier] = %s", $oldNode->getPath(), $repoId); } else if ($oldNode == null || $copy) { @@ -346,10 +355,10 @@ public function updateNodesIndex($oldNode = null, $newNode = null, $copy = false "bytesize" => $stat["size"], "mtime" => $stat["mtime"], "md5" => $newNode->isLeaf()? md5_file($newNode->getUrl()):"directory", - "repository_identifier" => $repoId = $this->computeIdentifier($newNode->getRepository()) + "repository_identifier" => $repoId = $this->computeIdentifier($newNode->getRepository(), $newNode->getUser()) )); } else { - $repoId = $this->computeIdentifier($oldNode->getRepository()); + $repoId = $this->computeIdentifier($oldNode->getRepository(), $oldNode->getUser()); if ($oldNode->getPath() == $newNode->getPath()) { // CONTENT CHANGE clearstatcache(); diff --git a/core/src/plugins/metastore.serial/class.SerialMetaStore.php b/core/src/plugins/metastore.serial/class.SerialMetaStore.php index c3d4345195..ba8f7a6c4d 100644 --- a/core/src/plugins/metastore.serial/class.SerialMetaStore.php +++ b/core/src/plugins/metastore.serial/class.SerialMetaStore.php @@ -137,7 +137,7 @@ public function enrichNode(&$ajxpNode) $ajxpNode->mergeMetadata($allMeta); } - protected function updateSecurityScope($metaFile, $repositoryId) + protected function updateSecurityScope($metaFile, $repositoryId, $resolveUserId = null) { $repo = ConfService::getRepositoryById($repositoryId); if (!is_object($repo)) { @@ -145,8 +145,17 @@ protected function updateSecurityScope($metaFile, $repositoryId) } $securityScope = $repo->securityScope(); if($securityScope == false) return $metaFile; - - if (AuthService::getLoggedUser() != null) { + if($resolveUserId != null){ + if ($securityScope == "USER") { + $metaFile .= "_".$resolveUserId; + }else if($securityScope == "GROUP"){ + $uObj= ConfService::getConfStorageImpl()->createUserObject($resolveUserId); + if($uObj != null){ + $u = str_replace("/", "__", $uObj->getGroupPath()); + $metaFile.= "_".$u; + } + } + }else if (AuthService::getLoggedUser() != null) { if ($securityScope == "USER") { $u = AuthService::getLoggedUser(); if($u->getResolveAsParent()) $id = $u->getParent(); @@ -186,7 +195,7 @@ protected function loadMetaFileData($ajxpNode, $scope, $userId) $fileKey = basename($fileKey); } else { $metaFile = $this->globalMetaFile."_".$ajxpNode->getRepositoryId(); - $metaFile = $this->updateSecurityScope($metaFile, $ajxpNode->getRepositoryId()); + $metaFile = $this->updateSecurityScope($metaFile, $ajxpNode->getRepositoryId(), $ajxpNode->getUser()); } self::$metaCache = array(); if (!isSet(self::$fullMetaCache[$metaFile])) { @@ -237,7 +246,7 @@ protected function saveMetaFileData($ajxpNode, $scope, $userId) mkdir(dirname($this->globalMetaFile), 0755, true); } $metaFile = $this->globalMetaFile."_".$repositoryId; - $metaFile = $this->updateSecurityScope($metaFile, $ajxpNode->getRepositoryId()); + $metaFile = $this->updateSecurityScope($metaFile, $ajxpNode->getRepositoryId(), $ajxpNode->getUser()); } if($scope==AJXP_METADATA_SCOPE_REPOSITORY || (@is_file($metaFile) && call_user_func(array($this->accessDriver, "isWriteable"), $metaFile))