Exemplo n.º 1
0
 /**
  * @param Array $httpVars
  * @param Repository $repository
  * @param AbstractAccessDriver $accessDriver
  * @param null $uniqueUser
  * @throws Exception
  * @return int|Repository
  */
 public function createSharedRepository($httpVars, $repository, $accessDriver, $uniqueUser = null)
 {
     // ERRORS
     // 100 : missing args
     // 101 : repository label already exists
     // 102 : user already exists
     // 103 : current user is not allowed to share
     // SUCCESS
     // 200
     if (!isset($httpVars["repo_label"]) || $httpVars["repo_label"] == "") {
         return 100;
     }
     $foldersharing = $this->getFilteredOption("ENABLE_FOLDER_SHARING", $this->repository->getId());
     if (isset($foldersharing) && $foldersharing === false) {
         return 103;
     }
     $loggedUser = AuthService::getLoggedUser();
     $actRights = $loggedUser->mergedRole->listActionsStatesFor($repository);
     if (isset($actRights["share"]) && $actRights["share"] === false) {
         return 103;
     }
     $users = array();
     $uRights = array();
     $uPasses = array();
     $groups = array();
     $index = 0;
     $prefix = $this->getFilteredOption("SHARED_USERS_TMP_PREFIX", $this->repository->getId());
     while (isset($httpVars["user_" . $index])) {
         $eType = $httpVars["entry_type_" . $index];
         $rightString = ($httpVars["right_read_" . $index] == "true" ? "r" : "") . ($httpVars["right_write_" . $index] == "true" ? "w" : "");
         if ($this->watcher !== false) {
             $uWatch = $httpVars["right_watch_" . $index] == "true" ? true : false;
         }
         if (empty($rightString)) {
             $index++;
             continue;
         }
         if ($eType == "user") {
             $u = AJXP_Utils::decodeSecureMagic($httpVars["user_" . $index], AJXP_SANITIZE_EMAILCHARS);
             if (!AuthService::userExists($u) && !isset($httpVars["user_pass_" . $index])) {
                 $index++;
                 continue;
             } else {
                 if (AuthService::userExists($u) && isset($httpVars["user_pass_" . $index])) {
                     throw new Exception("User {$u} already exists, please choose another name.");
                 }
             }
             if (!AuthService::userExists($u, "r") && !empty($prefix) && strpos($u, $prefix) !== 0) {
                 $u = $prefix . $u;
             }
             $users[] = $u;
         } else {
             $u = AJXP_Utils::decodeSecureMagic($httpVars["user_" . $index]);
             if (strpos($u, "/AJXP_TEAM/") === 0) {
                 $confDriver = ConfService::getConfStorageImpl();
                 if (method_exists($confDriver, "teamIdToUsers")) {
                     $teamUsers = $confDriver->teamIdToUsers(str_replace("/AJXP_TEAM/", "", $u));
                     foreach ($teamUsers as $userId) {
                         $users[] = $userId;
                         $uRights[$userId] = $rightString;
                         if ($this->watcher !== false) {
                             $uWatches[$userId] = $uWatch;
                         }
                     }
                 }
                 $index++;
                 continue;
             } else {
                 $groups[] = $u;
             }
         }
         $uRights[$u] = $rightString;
         $uPasses[$u] = isset($httpVars["user_pass_" . $index]) ? $httpVars["user_pass_" . $index] : "";
         if ($this->watcher !== false) {
             $uWatches[$u] = $uWatch;
         }
         $index++;
     }
     $label = AJXP_Utils::decodeSecureMagic($httpVars["repo_label"]);
     $description = AJXP_Utils::decodeSecureMagic($httpVars["repo_description"]);
     if (isset($httpVars["repository_id"])) {
         $editingRepo = ConfService::getRepositoryById($httpVars["repository_id"]);
     }
     // CHECK USER & REPO DOES NOT ALREADY EXISTS
     if ($this->getFilteredOption("AVOID_SHARED_FOLDER_SAME_LABEL", $this->repository->getId()) == true) {
         $repos = ConfService::getRepositoriesList();
         foreach ($repos as $obj) {
             if ($obj->getDisplay() == $label && (!isset($editingRepo) || $editingRepo != $obj)) {
                 return 101;
             }
         }
     }
     $confDriver = ConfService::getConfStorageImpl();
     foreach ($users as $userName) {
         if (AuthService::userExists($userName)) {
             // check that it's a child user
             $userObject = $confDriver->createUserObject($userName);
             if (ConfService::getCoreConf("ALLOW_CROSSUSERS_SHARING", "conf") != true && (!$userObject->hasParent() || $userObject->getParent() != $loggedUser->id)) {
                 return 102;
             }
         } else {
             if ($httpVars["create_guest_user"] != "true" && !ConfService::getCoreConf("USER_CREATE_USERS", "conf") || AuthService::isReservedUserId($userName)) {
                 return 102;
             }
             if (!isset($httpVars["shared_pass"]) || $httpVars["shared_pass"] == "") {
                 return 100;
             }
         }
     }
     // CREATE SHARED OPTIONS
     $options = $accessDriver->makeSharedRepositoryOptions($httpVars, $repository);
     $customData = array();
     foreach ($httpVars as $key => $value) {
         if (substr($key, 0, strlen("PLUGINS_DATA_")) == "PLUGINS_DATA_") {
             $customData[substr($key, strlen("PLUGINS_DATA_"))] = $value;
         }
     }
     if (count($customData)) {
         $options["PLUGINS_DATA"] = $customData;
     }
     if (isset($editingRepo)) {
         $newRepo = $editingRepo;
         if ($editingRepo->getDisplay() != $label) {
             $newRepo->setDisplay($label);
             ConfService::replaceRepository($httpVars["repository_id"], $newRepo);
         }
         $editingRepo->setDescription($description);
     } else {
         if ($repository->getOption("META_SOURCES")) {
             $options["META_SOURCES"] = $repository->getOption("META_SOURCES");
             foreach ($options["META_SOURCES"] as $index => $data) {
                 if (isset($data["USE_SESSION_CREDENTIALS"]) && $data["USE_SESSION_CREDENTIALS"] === true) {
                     $options["META_SOURCES"][$index]["ENCODED_CREDENTIALS"] = AJXP_Safe::getEncodedCredentialString();
                 }
             }
         }
         $newRepo = $repository->createSharedChild($label, $options, $repository->id, $loggedUser->id, null);
         $gPath = $loggedUser->getGroupPath();
         if (!empty($gPath) && !ConfService::getCoreConf("CROSSUSERS_ALLGROUPS", "conf")) {
             $newRepo->setGroupPath($gPath);
         }
         $newRepo->setDescription($description);
         ConfService::addRepository($newRepo);
     }
     $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
     if (isset($editingRepo)) {
         $currentRights = $this->computeSharedRepositoryAccessRights($httpVars["repository_id"], false, $this->urlBase . $file);
         $originalUsers = array_keys($currentRights["USERS"]);
         $removeUsers = array_diff($originalUsers, $users);
         if (count($removeUsers)) {
             foreach ($removeUsers as $user) {
                 if (AuthService::userExists($user)) {
                     $userObject = $confDriver->createUserObject($user);
                     $userObject->personalRole->setAcl($newRepo->getUniqueId(), "");
                     $userObject->save("superuser");
                 }
             }
         }
         $originalGroups = array_keys($currentRights["GROUPS"]);
         $removeGroups = array_diff($originalGroups, $groups);
         if (count($removeGroups)) {
             foreach ($removeGroups as $groupId) {
                 $role = AuthService::getRole("AJXP_GRP_" . AuthService::filterBaseGroup($groupId));
                 if ($role !== false) {
                     $role->setAcl($newRepo->getUniqueId(), "");
                     AuthService::updateRole($role);
                 }
             }
         }
     }
     foreach ($users as $userName) {
         if (AuthService::userExists($userName, "r")) {
             // check that it's a child user
             $userObject = $confDriver->createUserObject($userName);
         } else {
             if (ConfService::getAuthDriverImpl()->getOption("TRANSMIT_CLEAR_PASS")) {
                 $pass = $uPasses[$userName];
             } else {
                 $pass = md5($uPasses[$userName]);
             }
             $limit = $loggedUser->personalRole->filterParameterValue("core.conf", "USER_SHARED_USERS_LIMIT", AJXP_REPO_SCOPE_ALL, "");
             if (!empty($limit) && intval($limit) > 0) {
                 $count = count(ConfService::getConfStorageImpl()->getUserChildren($loggedUser->getId()));
                 if ($count >= $limit) {
                     $mess = ConfService::getMessages();
                     throw new Exception($mess['483']);
                 }
             }
             AuthService::createUser($userName, $pass);
             $userObject = $confDriver->createUserObject($userName);
             $userObject->personalRole->clearAcls();
             $userObject->setParent($loggedUser->id);
             $userObject->setGroupPath($loggedUser->getGroupPath());
             $userObject->setProfile("shared");
             if (isset($httpVars["minisite"])) {
                 $mess = ConfService::getMessages();
                 $userObject->personalRole->setParameterValue("core.conf", "USER_DISPLAY_NAME", "[" . $mess["share_center.109"] . "] " . $newRepo->getDisplay());
             }
             AJXP_Controller::applyHook("user.after_create", array($userObject));
         }
         // CREATE USER WITH NEW REPO RIGHTS
         $userObject->personalRole->setAcl($newRepo->getUniqueId(), $uRights[$userName]);
         if (isset($httpVars["minisite"])) {
             $newRole = new AJXP_Role("AJXP_SHARED-" . $newRepo->getUniqueId());
             $r = AuthService::getRole("MINISITE");
             if (is_a($r, "AJXP_Role")) {
                 if ($httpVars["disable_download"]) {
                     $f = AuthService::getRole("MINISITE_NODOWNLOAD");
                     if (is_a($f, "AJXP_Role")) {
                         $r = $f->override($r);
                     }
                 }
                 $allData = $r->getDataArray();
                 $newData = $newRole->getDataArray();
                 if (isset($allData["ACTIONS"][AJXP_REPO_SCOPE_SHARED])) {
                     $newData["ACTIONS"][$newRepo->getUniqueId()] = $allData["ACTIONS"][AJXP_REPO_SCOPE_SHARED];
                 }
                 if (isset($allData["PARAMETERS"][AJXP_REPO_SCOPE_SHARED])) {
                     $newData["PARAMETERS"][$newRepo->getUniqueId()] = $allData["PARAMETERS"][AJXP_REPO_SCOPE_SHARED];
                 }
                 $newRole->bunchUpdate($newData);
                 AuthService::updateRole($newRole);
                 $userObject->addRole($newRole);
             }
         }
         $userObject->save("superuser");
         if ($this->watcher !== false) {
             // Register a watch on the current folder for shared user
             if ($uWatches[$userName] == "true") {
                 $this->watcher->setWatchOnFolder(new AJXP_Node($this->urlBase . $file), $userName, MetaWatchRegister::$META_WATCH_USERS_CHANGE, array(AuthService::getLoggedUser()->getId()));
             } else {
                 $this->watcher->removeWatchFromFolder(new AJXP_Node($this->urlBase . $file), $userName, true);
             }
         }
     }
     if ($this->watcher !== false) {
         // Register a watch on the new repository root for current user
         if ($httpVars["self_watch_folder"] == "true") {
             $this->watcher->setWatchOnFolder(new AJXP_Node($this->baseProtocol . "://" . $newRepo->getUniqueId() . "/"), AuthService::getLoggedUser()->getId(), MetaWatchRegister::$META_WATCH_BOTH);
         } else {
             $this->watcher->removeWatchFromFolder(new AJXP_Node($this->baseProtocol . "://" . $newRepo->getUniqueId() . "/"), AuthService::getLoggedUser()->getId());
         }
     }
     foreach ($groups as $group) {
         $grRole = AuthService::getRole("AJXP_GRP_" . AuthService::filterBaseGroup($group), true);
         $grRole->setAcl($newRepo->getUniqueId(), $uRights[$group]);
         AuthService::updateRole($grRole);
     }
     if (array_key_exists("minisite", $httpVars) && $httpVars["minisite"] != true) {
         AJXP_Controller::applyHook("node.share.create", array('type' => 'repository', 'repository' => &$repository, 'accessDriver' => &$accessDriver, 'new_repository' => &$newRepo));
     }
     return $newRepo;
 }
Exemplo n.º 2
0
 /**
  * Main callback for all share- actions.
  * @param string $action
  * @param array $httpVars
  * @param array $fileVars
  * @return null
  * @throws Exception
  */
 public function switchAction($action, $httpVars, $fileVars)
 {
     if (strpos($action, "sharelist") === false && !isset($this->accessDriver)) {
         throw new Exception("Cannot find access driver!");
     }
     if (strpos($action, "sharelist") === false && $this->accessDriver->getId() == "access.demo") {
         $errorMessage = "This is a demo, all 'write' actions are disabled!";
         if ($httpVars["sub_action"] == "delegate_repo") {
             return AJXP_XMLWriter::sendMessage(null, $errorMessage, false);
         } else {
             print $errorMessage;
         }
         return null;
     }
     switch ($action) {
         //------------------------------------
         // SHARING FILE OR FOLDER
         //------------------------------------
         case "share":
             $subAction = isset($httpVars["sub_action"]) ? $httpVars["sub_action"] : "";
             // REST API COMPATIBILITY
             if (empty($subAction) && isset($httpVars["simple_share_type"])) {
                 $subAction = "create_minisite";
                 if (!isset($httpVars["simple_right_read"]) && !isset($httpVars["simple_right_download"])) {
                     $httpVars["simple_right_read"] = $httpVars["simple_right_download"] = "true";
                 }
                 $httpVars["create_guest_user"] = "******";
                 if ($httpVars["simple_share_type"] == "private" && !isset($httpVars["guest_user_pass"])) {
                     throw new Exception("Please provide a guest_user_pass for private link");
                 }
             }
             $userSelection = new UserSelection(ConfService::getRepository(), $httpVars);
             $ajxpNode = $userSelection->getUniqueNode();
             if (!file_exists($ajxpNode->getUrl())) {
                 throw new Exception("Cannot share a non-existing file: " . $ajxpNode->getUrl());
             }
             $this->updateToMaxAllowedValue($httpVars, "downloadlimit", "FILE_MAX_DOWNLOAD");
             $this->updateToMaxAllowedValue($httpVars, "expiration", "FILE_MAX_EXPIRATION");
             $httpHash = null;
             $originalHash = null;
             if (!isset($httpVars["share_scope"]) || !in_array($httpVars["share_scope"], array("public", "private"))) {
                 $httpVars["share_scope"] = "private";
             }
             $shareScope = $httpVars["share_scope"];
             $plainResult = 'unknown sub_action';
             if ($subAction == "delegate_repo") {
                 $auth = $this->getAuthorization("folder", "workspace");
                 if (!$auth) {
                     $mess = ConfService::getMessages();
                     throw new Exception($mess["351"]);
                 }
                 $users = array();
                 $groups = array();
                 $this->getRightsManager()->createUsersFromParameters($httpVars, $users, $groups);
                 $result = $this->createSharedRepository($httpVars, $isUpdate, $users, $groups);
                 if (is_a($result, "Repository")) {
                     if (!$isUpdate) {
                         $this->getShareStore()->storeShare($this->repository->getId(), array("REPOSITORY" => $result->getUniqueId(), "OWNER_ID" => AuthService::getLoggedUser()->getId()), "repository");
                     }
                     AJXP_Controller::applyHook($isUpdate ? "node.share.update" : "node.share.create", array('type' => 'repository', 'repository' => &$this->repository, 'accessDriver' => &$this->accessDriver, 'new_repository' => &$result));
                     if ($ajxpNode->hasMetaStore() && !$ajxpNode->isRoot()) {
                         $this->getShareStore()->getMetaManager()->addShareInMeta($ajxpNode, "repository", $result->getUniqueId(), $shareScope == "public", $originalHash);
                     }
                     $plainResult = 200;
                 } else {
                     $plainResult = $result;
                 }
             } else {
                 if ($subAction == "create_minisite") {
                     if (isset($httpVars["hash"]) && !empty($httpVars["hash"])) {
                         $httpHash = $httpVars["hash"];
                     }
                     $result = $this->createSharedMinisite($httpVars, $isUpdate);
                     if (!is_array($result)) {
                         $url = $result;
                     } else {
                         list($hash, $url) = $result;
                         if ($ajxpNode->hasMetaStore() && !$ajxpNode->isRoot()) {
                             $this->getShareStore()->getMetaManager()->addShareInMeta($ajxpNode, "minisite", $hash, $shareScope == "public", $httpHash != null && $hash != $httpHash ? $httpHash : null);
                         }
                     }
                     $plainResult = $url;
                 } else {
                     if ($subAction == "share_node") {
                         $httpVars["return_json"] = true;
                         if (isset($httpVars["hash"]) && !empty($httpVars["hash"])) {
                             $httpHash = $httpVars["hash"];
                         }
                         $ajxpNode->loadNodeInfo();
                         $results = $this->shareNode($ajxpNode, $httpVars, $isUpdate);
                         if (is_array($results) && $ajxpNode->hasMetaStore() && !$ajxpNode->isRoot()) {
                             foreach ($results as $shareObject) {
                                 if ($shareObject instanceof \Pydio\OCS\Model\TargettedLink) {
                                     $hash = $shareObject->getHash();
                                     $this->getShareStore()->getMetaManager()->addShareInMeta($ajxpNode, "ocs_remote", $hash, $shareScope == "public", $hash);
                                 } else {
                                     if (is_a($shareObject, "ShareLink")) {
                                         $hash = $shareObject->getHash();
                                         $this->getShareStore()->getMetaManager()->addShareInMeta($ajxpNode, "minisite", $hash, $shareScope == "public", $httpHash != null && $hash != $httpHash ? $httpHash : null);
                                     } else {
                                         if (is_a($shareObject, "Repository")) {
                                             $this->getShareStore()->getMetaManager()->addShareInMeta($ajxpNode, "repository", $shareObject->getUniqueId(), $shareScope == "public", null);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             AJXP_Controller::applyHook("msg.instant", array("<reload_shared_elements/>", ConfService::getRepository()->getId()));
             /*
              * Send IM to inform that node has been shared or unshared.
              * Should be done only if share scope is public.
              */
             if ($shareScope == "public") {
                 $ajxpNode->loadNodeInfo();
                 $content = AJXP_XMLWriter::writeNodesDiff(["UPDATE" => array($ajxpNode->getPath() => $ajxpNode)]);
                 AJXP_Controller::applyHook("msg.instant", array($content, $ajxpNode->getRepositoryId(), null, null, [$ajxpNode->getPath()]));
             }
             if (!isset($httpVars["return_json"])) {
                 header("Content-Type: text/plain");
                 print $plainResult;
             } else {
                 $compositeShare = $this->getShareStore()->getMetaManager()->getCompositeShareForNode($ajxpNode);
                 header("Content-type:application/json");
                 if (!empty($compositeShare)) {
                     echo json_encode($this->compositeShareToJson($compositeShare));
                 } else {
                     echo json_encode(array());
                 }
             }
             // as the result can be quite small (e.g error code), make sure it's output in case of OB active.
             flush();
             break;
         case "toggle_link_watch":
             $userSelection = new UserSelection($this->repository, $httpVars);
             $shareNode = $selectedNode = $userSelection->getUniqueNode();
             $watchValue = $httpVars["set_watch"] == "true" ? true : false;
             $folder = false;
             if (isset($httpVars["element_type"]) && $httpVars["element_type"] == "folder") {
                 $folder = true;
                 $selectedNode = new AJXP_Node("pydio://" . AJXP_Utils::sanitize($httpVars["repository_id"], AJXP_SANITIZE_ALPHANUM) . "/");
             }
             $shares = array();
             $this->getShareStore()->getMetaManager()->getSharesFromMeta($shareNode, $shares, false);
             if (!count($shares)) {
                 break;
             }
             if (isset($httpVars["element_id"]) && isset($shares[$httpVars["element_id"]])) {
                 $elementId = $httpVars["element_id"];
             } else {
                 $sKeys = array_keys($shares);
                 $elementId = $sKeys[0];
             }
             if ($this->watcher !== false) {
                 if (!$folder) {
                     if ($watchValue) {
                         $this->watcher->setWatchOnFolder($selectedNode, AuthService::getLoggedUser()->getId(), MetaWatchRegister::$META_WATCH_USERS_READ, array($elementId));
                     } else {
                         $this->watcher->removeWatchFromFolder($selectedNode, AuthService::getLoggedUser()->getId(), true, $elementId);
                     }
                 } else {
                     if ($watchValue) {
                         $this->watcher->setWatchOnFolder($selectedNode, AuthService::getLoggedUser()->getId(), MetaWatchRegister::$META_WATCH_BOTH);
                     } else {
                         $this->watcher->removeWatchFromFolder($selectedNode, AuthService::getLoggedUser()->getId());
                     }
                 }
             }
             $mess = ConfService::getMessages();
             AJXP_XMLWriter::header();
             AJXP_XMLWriter::sendMessage($mess["share_center.47"], null);
             AJXP_XMLWriter::close();
             break;
         case "load_shared_element_data":
             $node = null;
             if (isset($httpVars["hash"]) && $httpVars["element_type"] == "file") {
                 // LEGACY LINKS
                 $parsedMeta = array($httpVars["hash"] => array("type" => "file"));
                 $jsonData = array();
                 foreach ($parsedMeta as $shareId => $shareMeta) {
                     $jsonData[] = $this->shareToJson($shareId, $shareMeta, $node);
                 }
                 header("Content-type:application/json");
                 echo json_encode($jsonData);
             } else {
                 $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
                 $node = new AJXP_Node($this->urlBase . $file);
                 $loggedUser = AuthService::getLoggedUser();
                 if (isset($httpVars["owner"]) && $loggedUser->isAdmin() && $loggedUser->getGroupPath() == "/" && $loggedUser->getId() != AJXP_Utils::sanitize($httpVars["owner"], AJXP_SANITIZE_EMAILCHARS)) {
                     // Impersonate the current user
                     $node->setUser(AJXP_Utils::sanitize($httpVars["owner"], AJXP_SANITIZE_EMAILCHARS));
                 }
                 if (!file_exists($node->getUrl())) {
                     $mess = ConfService::getMessages();
                     throw new Exception(str_replace('%s', "Cannot find file " . $file, $mess["share_center.219"]));
                 }
                 if (isset($httpVars["tmp_repository_id"]) && AuthService::getLoggedUser()->isAdmin()) {
                     $compositeShare = $this->getShareStore()->getMetaManager()->getCompositeShareForNode($node, true);
                 } else {
                     $compositeShare = $this->getShareStore()->getMetaManager()->getCompositeShareForNode($node);
                 }
                 if (empty($compositeShare)) {
                     $mess = ConfService::getMessages();
                     throw new Exception(str_replace('%s', "Cannot find share for node " . $file, $mess["share_center.219"]));
                 }
                 header("Content-type:application/json");
                 $json = $this->compositeShareToJson($compositeShare);
                 echo json_encode($json);
             }
             break;
         case "unshare":
             $mess = ConfService::getMessages();
             $userSelection = new UserSelection($this->repository, $httpVars);
             if (isset($httpVars["hash"])) {
                 $sanitizedHash = AJXP_Utils::sanitize($httpVars["hash"], AJXP_SANITIZE_ALPHANUM);
                 $ajxpNode = $userSelection->isEmpty() ? null : $userSelection->getUniqueNode();
                 $result = $this->getShareStore()->deleteShare($httpVars["element_type"], $sanitizedHash, false, false, $ajxpNode);
                 if ($result !== false) {
                     AJXP_XMLWriter::header();
                     AJXP_XMLWriter::sendMessage($mess["share_center.216"], null);
                     AJXP_XMLWriter::close();
                 }
             } else {
                 $userSelection = new UserSelection($this->repository, $httpVars);
                 $ajxpNode = $userSelection->getUniqueNode();
                 $shares = array();
                 $this->getShareStore()->getMetaManager()->getSharesFromMeta($ajxpNode, $shares, false);
                 if (isset($httpVars["element_id"]) && isset($shares[$httpVars["element_id"]])) {
                     $elementId = $httpVars["element_id"];
                     if (isset($shares[$elementId])) {
                         $shares = array($elementId => $shares[$elementId]);
                     }
                 }
                 if (count($shares)) {
                     $res = true;
                     foreach ($shares as $shareId => $share) {
                         $t = isset($share["type"]) ? $share["type"] : "file";
                         try {
                             $result = $this->getShareStore()->deleteShare($t, $shareId, false, true);
                         } catch (Exception $e) {
                             if ($e->getMessage() == "repo-not-found") {
                                 $result = true;
                             } else {
                                 throw $e;
                             }
                         }
                         $this->getShareStore()->getMetaManager()->removeShareFromMeta($ajxpNode, $shareId);
                         $res = $result && $res;
                     }
                     if ($res !== false) {
                         AJXP_XMLWriter::header();
                         AJXP_XMLWriter::sendMessage($mess["share_center.216"], null);
                         AJXP_XMLWriter::close();
                         AJXP_Controller::applyHook("msg.instant", array("<reload_shared_elements/>", ConfService::getRepository()->getId()));
                         if (isset($httpVars["share_scope"]) && $httpVars["share_scope"] == "public") {
                             $ajxpNode->loadNodeInfo();
                             $content = AJXP_XMLWriter::writeNodesDiff(["UPDATE" => [$ajxpNode->getPath() => $ajxpNode]]);
                             AJXP_Controller::applyHook("msg.instant", array($content, $ajxpNode->getRepositoryId(), null, null, [$ajxpNode->getPath()]));
                         }
                     }
                 }
             }
             break;
         case "reset_counter":
             if (isset($httpVars["hash"])) {
                 $userId = AuthService::getLoggedUser()->getId();
                 if (isset($httpVars["owner_id"]) && $httpVars["owner_id"] != $userId) {
                     if (!AuthService::getLoggedUser()->isAdmin()) {
                         throw new Exception("You are not allowed to access this resource");
                     }
                     $userId = $httpVars["owner_id"];
                 }
                 $this->getShareStore()->resetDownloadCounter($httpVars["hash"], $userId);
             } else {
                 $userSelection = new UserSelection($this->repository, $httpVars);
                 $ajxpNode = $userSelection->getUniqueNode();
                 $metadata = $this->getShareStore()->getMetaManager()->getNodeMeta($ajxpNode);
                 if (!isset($metadata["shares"]) || !is_array($metadata["shares"])) {
                     return null;
                 }
                 if (isset($httpVars["element_id"]) && isset($metadata["shares"][$httpVars["element_id"]])) {
                     $this->getShareStore()->resetDownloadCounter($httpVars["element_id"], $httpVars["owner_id"]);
                 } else {
                     $keys = array_keys($metadata["shares"]);
                     foreach ($keys as $key) {
                         $this->getShareStore()->resetDownloadCounter($key, null);
                     }
                 }
             }
             break;
         case "update_shared_element_data":
             if (!in_array($httpVars["p_name"], array("counter", "tags"))) {
                 return null;
             }
             $hash = AJXP_Utils::decodeSecureMagic($httpVars["element_id"]);
             $userSelection = new UserSelection($this->repository, $httpVars);
             $ajxpNode = $userSelection->getUniqueNode();
             if ($this->getShareStore()->shareIsLegacy($hash)) {
                 // Store in metadata
                 $metadata = $this->getShareStore()->getMetaManager()->getNodeMeta($ajxpNode);
                 if (isset($metadata["shares"][$httpVars["element_id"]])) {
                     if (!is_array($metadata["shares"][$httpVars["element_id"]])) {
                         $metadata["shares"][$httpVars["element_id"]] = array();
                     }
                     $metadata["shares"][$httpVars["element_id"]][$httpVars["p_name"]] = $httpVars["p_value"];
                     // Set Private=true by default.
                     $this->getShareStore()->getMetaManager()->setNodeMeta($ajxpNode, $metadata, true);
                 }
             } else {
                 // TODO: testUserCanEditShare ?
                 $this->getShareStore()->updateShareProperty($hash, $httpVars["p_name"], $httpVars["p_value"]);
             }
             break;
         case "sharelist-load":
             $parentRepoId = isset($httpVars["parent_repository_id"]) ? $httpVars["parent_repository_id"] : "";
             $userContext = $httpVars["user_context"];
             $currentUser = true;
             if ($userContext == "global" && AuthService::getLoggedUser()->isAdmin()) {
                 $currentUser = false;
             } else {
                 if ($userContext == "user" && AuthService::getLoggedUser()->isAdmin() && !empty($httpVars["user_id"])) {
                     $currentUser = AJXP_Utils::sanitize($httpVars["user_id"], AJXP_SANITIZE_EMAILCHARS);
                 }
             }
             $nodes = $this->listSharesAsNodes("/data/repositories/{$parentRepoId}/shares", $currentUser, $parentRepoId);
             AJXP_XMLWriter::header();
             if ($userContext == "current") {
                 AJXP_XMLWriter::sendFilesListComponentConfig('<columns template_name="ajxp_user.shares">
                 <column messageId="ajxp_conf.8" attributeName="ajxp_label" sortType="String"/>
                 <column messageId="share_center.132" attributeName="shared_element_parent_repository_label" sortType="String"/>
                 <column messageId="3" attributeName="share_type_readable" sortType="String"/>
                 </columns>');
             } else {
                 AJXP_XMLWriter::sendFilesListComponentConfig('<columns switchDisplayMode="list" switchGridMode="filelist" template_name="ajxp_conf.repositories">
                 <column messageId="ajxp_conf.8" attributeName="ajxp_label" sortType="String"/>
                 <column messageId="share_center.159" attributeName="owner" sortType="String"/>
                 <column messageId="3" attributeName="share_type_readable" sortType="String"/>
                 <column messageId="share_center.52" attributeName="share_data" sortType="String"/>
                 </columns>');
             }
             foreach ($nodes as $node) {
                 AJXP_XMLWriter::renderAjxpNode($node);
             }
             AJXP_XMLWriter::close();
             break;
         case "sharelist-clearExpired":
             $accessType = ConfService::getRepository()->getAccessType();
             $currentUser = $accessType != "ajxp_conf" && $accessType != "ajxp_admin";
             $count = $this->getShareStore()->clearExpiredFiles($currentUser);
             AJXP_XMLWriter::header();
             if ($count) {
                 AJXP_XMLWriter::sendMessage("Removed " . count($count) . " expired links", null);
             } else {
                 AJXP_XMLWriter::sendMessage("Nothing to do", null);
             }
             AJXP_XMLWriter::close();
             break;
         default:
             break;
     }
     return null;
 }
Exemplo n.º 3
0
 /**
  * @param Array $httpVars
  * @param Repository $repository
  * @param AbstractAccessDriver $accessDriver
  * @param null $uniqueUser
  * @throws Exception
  * @return int|Repository
  */
 public function createSharedRepository($httpVars, $repository, $accessDriver, $uniqueUser = null)
 {
     // ERRORS
     // 100 : missing args
     // 101 : repository label already exists
     // 102 : user already exists
     // 103 : current user is not allowed to share
     // SUCCESS
     // 200
     if (!isset($httpVars["repo_label"]) || $httpVars["repo_label"] == "") {
         return 100;
     }
     /*
     // FILE IS ALWAYS THE PARENT FOLDER SO WE NOW CHECK FOLDER_SHARING AT A HIGHER LEVEL
     $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
     $foldersharing = $this->getFilteredOption("ENABLE_FOLDER_SHARING", $this->repository->getId());
     $foldersharingDisabled = isset($foldersharing) && ($foldersharing === false || (is_string($foldersharing) && $foldersharing == "disable"));
     if (is_dir($this->urlBase.$file) && $foldersharingDisabled) {
         return 103;
     }
     */
     $loggedUser = AuthService::getLoggedUser();
     $actRights = $loggedUser->mergedRole->listActionsStatesFor($repository);
     if (isset($actRights["share"]) && $actRights["share"] === false) {
         return 103;
     }
     $users = array();
     $uRights = array();
     $uPasses = array();
     $groups = array();
     $uWatches = array();
     $index = 0;
     $prefix = $this->getFilteredOption("SHARED_USERS_TMP_PREFIX", $this->repository->getId());
     while (isset($httpVars["user_" . $index])) {
         $eType = $httpVars["entry_type_" . $index];
         $uWatch = false;
         $rightString = ($httpVars["right_read_" . $index] == "true" ? "r" : "") . ($httpVars["right_write_" . $index] == "true" ? "w" : "");
         if ($this->watcher !== false) {
             $uWatch = $httpVars["right_watch_" . $index] == "true" ? true : false;
         }
         if (empty($rightString)) {
             $index++;
             continue;
         }
         if ($eType == "user") {
             $u = AJXP_Utils::decodeSecureMagic($httpVars["user_" . $index], AJXP_SANITIZE_EMAILCHARS);
             if (!AuthService::userExists($u) && !isset($httpVars["user_pass_" . $index])) {
                 $index++;
                 continue;
             } else {
                 if (AuthService::userExists($u, "w") && isset($httpVars["user_pass_" . $index])) {
                     throw new Exception("User {$u} already exists, please choose another name.");
                 }
             }
             if (!AuthService::userExists($u, "r") && !empty($prefix) && strpos($u, $prefix) !== 0) {
                 $u = $prefix . $u;
             }
             $users[] = $u;
         } else {
             $u = AJXP_Utils::decodeSecureMagic($httpVars["user_" . $index]);
             if (strpos($u, "/AJXP_TEAM/") === 0) {
                 $confDriver = ConfService::getConfStorageImpl();
                 if (method_exists($confDriver, "teamIdToUsers")) {
                     $teamUsers = $confDriver->teamIdToUsers(str_replace("/AJXP_TEAM/", "", $u));
                     foreach ($teamUsers as $userId) {
                         $users[] = $userId;
                         $uRights[$userId] = $rightString;
                         if ($this->watcher !== false) {
                             $uWatches[$userId] = $uWatch;
                         }
                     }
                 }
                 $index++;
                 continue;
             } else {
                 $groups[] = $u;
             }
         }
         $uRights[$u] = $rightString;
         $uPasses[$u] = isset($httpVars["user_pass_" . $index]) ? $httpVars["user_pass_" . $index] : "";
         if ($this->watcher !== false) {
             $uWatches[$u] = $uWatch;
         }
         $index++;
     }
     $label = AJXP_Utils::sanitize(AJXP_Utils::securePath($httpVars["repo_label"]), AJXP_SANITIZE_HTML);
     $description = AJXP_Utils::sanitize(AJXP_Utils::securePath($httpVars["repo_description"]), AJXP_SANITIZE_HTML);
     if (isset($httpVars["repository_id"])) {
         $editingRepo = ConfService::getRepositoryById($httpVars["repository_id"]);
     }
     // CHECK USER & REPO DOES NOT ALREADY EXISTS
     if ($this->getFilteredOption("AVOID_SHARED_FOLDER_SAME_LABEL", $this->repository->getId()) == true) {
         $count = 0;
         $similarLabelRepos = ConfService::listRepositoriesWithCriteria(array("display" => $label), $count);
         if ($count && !isset($editingRepo)) {
             return 101;
         }
         if ($count && isset($editingRepo)) {
             foreach ($similarLabelRepos as $slr) {
                 if ($slr->getUniqueId() != $editingRepo->getUniqueId()) {
                     return 101;
                 }
             }
         }
         /*
         $repos = ConfService::getRepositoriesList();
         foreach ($repos as $obj) {
             if ($obj->getDisplay() == $label && (!isSet($editingRepo) || $editingRepo != $obj)) {
             }
         }
         */
     }
     $confDriver = ConfService::getConfStorageImpl();
     foreach ($users as $userName) {
         if (AuthService::userExists($userName)) {
             // check that it's a child user
             $userObject = $confDriver->createUserObject($userName);
             if (ConfService::getCoreConf("ALLOW_CROSSUSERS_SHARING", "conf") != true && (!$userObject->hasParent() || $userObject->getParent() != $loggedUser->id)) {
                 return 102;
             }
         } else {
             if ($httpVars["create_guest_user"] != "true" && !ConfService::getCoreConf("USER_CREATE_USERS", "conf") || AuthService::isReservedUserId($userName)) {
                 return 102;
             }
             if (!isset($httpVars["shared_pass"]) || $httpVars["shared_pass"] == "") {
                 return 100;
             }
         }
     }
     // CREATE SHARED OPTIONS
     $options = $accessDriver->makeSharedRepositoryOptions($httpVars, $repository);
     $customData = array();
     foreach ($httpVars as $key => $value) {
         if (substr($key, 0, strlen("PLUGINS_DATA_")) == "PLUGINS_DATA_") {
             $customData[substr($key, strlen("PLUGINS_DATA_"))] = $value;
         }
     }
     if (count($customData)) {
         $options["PLUGINS_DATA"] = $customData;
     }
     if (isset($editingRepo)) {
         $this->getShareStore()->testUserCanEditShare($editingRepo->getOwner());
         $newRepo = $editingRepo;
         $replace = false;
         if ($editingRepo->getDisplay() != $label) {
             $newRepo->setDisplay($label);
             $replace = true;
         }
         if ($editingRepo->getDescription() != $description) {
             $newRepo->setDescription($description);
             $replace = true;
         }
         if ($replace) {
             ConfService::replaceRepository($httpVars["repository_id"], $newRepo);
         }
     } else {
         if ($repository->getOption("META_SOURCES")) {
             $options["META_SOURCES"] = $repository->getOption("META_SOURCES");
             foreach ($options["META_SOURCES"] as $index => &$data) {
                 if (isset($data["USE_SESSION_CREDENTIALS"]) && $data["USE_SESSION_CREDENTIALS"] === true) {
                     $options["META_SOURCES"][$index]["ENCODED_CREDENTIALS"] = AJXP_Safe::getEncodedCredentialString();
                 }
                 if ($index == "meta.syncable" && (!isset($data["REPO_SYNCABLE"]) || $data["REPO_SYNCABLE"] === true)) {
                     $data["REQUIRES_INDEXATION"] = true;
                 }
             }
         }
         $newRepo = $repository->createSharedChild($label, $options, $repository->id, $loggedUser->id, null);
         $gPath = $loggedUser->getGroupPath();
         if (!empty($gPath) && !ConfService::getCoreConf("CROSSUSERS_ALLGROUPS", "conf")) {
             $newRepo->setGroupPath($gPath);
         }
         $newRepo->setDescription($description);
         $newRepo->options["PATH"] = SystemTextEncoding::fromStorageEncoding($newRepo->options["PATH"]);
         if (isset($httpVars["filter_nodes"])) {
             $newRepo->setContentFilter(new ContentFilter($httpVars["filter_nodes"]));
         }
         ConfService::addRepository($newRepo);
         if (!isset($httpVars["minisite"])) {
             $this->getShareStore()->storeShare($repository->getId(), array("REPOSITORY" => $newRepo->getUniqueId(), "OWNER_ID" => $loggedUser->getId()), "repository");
         }
     }
     $sel = new UserSelection($this->repository, $httpVars);
     $file = $sel->getUniqueFile();
     $newRepoUniqueId = $newRepo->getUniqueId();
     if (isset($editingRepo)) {
         $currentRights = $this->computeSharedRepositoryAccessRights($httpVars["repository_id"], false, $this->urlBase . $file);
         $originalUsers = array_keys($currentRights["USERS"]);
         $removeUsers = array_diff($originalUsers, $users);
         if (count($removeUsers)) {
             foreach ($removeUsers as $user) {
                 if (AuthService::userExists($user)) {
                     $userObject = $confDriver->createUserObject($user);
                     $userObject->personalRole->setAcl($newRepoUniqueId, "");
                     $userObject->save("superuser");
                 }
                 if ($this->watcher !== false) {
                     $this->watcher->removeWatchFromFolder(new AJXP_Node($this->urlBase . $file), $user, true);
                 }
             }
         }
         $originalGroups = array_keys($currentRights["GROUPS"]);
         $removeGroups = array_diff($originalGroups, $groups);
         if (count($removeGroups)) {
             foreach ($removeGroups as $groupId) {
                 $role = AuthService::getRole($groupId);
                 if ($role !== false) {
                     $role->setAcl($newRepoUniqueId, "");
                     AuthService::updateRole($role);
                 }
             }
         }
     }
     foreach ($users as $userName) {
         if (AuthService::userExists($userName, "r")) {
             // check that it's a child user
             $userObject = $confDriver->createUserObject($userName);
         } else {
             if (ConfService::getAuthDriverImpl()->getOptionAsBool("TRANSMIT_CLEAR_PASS")) {
                 $pass = $uPasses[$userName];
             } else {
                 $pass = md5($uPasses[$userName]);
             }
             if (!isset($httpVars["minisite"])) {
                 // This is an explicit user creation - check possible limits
                 AJXP_Controller::applyHook("user.before_create", array($userName, null, false, false));
                 $limit = $loggedUser->personalRole->filterParameterValue("core.conf", "USER_SHARED_USERS_LIMIT", AJXP_REPO_SCOPE_ALL, "");
                 if (!empty($limit) && intval($limit) > 0) {
                     $count = count(ConfService::getConfStorageImpl()->getUserChildren($loggedUser->getId()));
                     if ($count >= $limit) {
                         $mess = ConfService::getMessages();
                         throw new Exception($mess['483']);
                     }
                 }
             }
             AuthService::createUser($userName, $pass, false, isset($httpVars["minisite"]));
             $userObject = $confDriver->createUserObject($userName);
             $userObject->personalRole->clearAcls();
             $userObject->setParent($loggedUser->id);
             $userObject->setGroupPath($loggedUser->getGroupPath());
             $userObject->setProfile("shared");
             if (isset($httpVars["minisite"])) {
                 $mess = ConfService::getMessages();
                 $userObject->setHidden(true);
                 $userObject->personalRole->setParameterValue("core.conf", "USER_DISPLAY_NAME", "[" . $mess["share_center.109"] . "] " . AJXP_Utils::sanitize($newRepo->getDisplay(), AJXP_SANITIZE_EMAILCHARS));
             }
             AJXP_Controller::applyHook("user.after_create", array($userObject));
         }
         // CREATE USER WITH NEW REPO RIGHTS
         $userObject->personalRole->setAcl($newRepoUniqueId, $uRights[$userName]);
         // FORK MASK IF THERE IS ANY
         if ($file != "/" && $loggedUser->mergedRole->hasMask($repository->getId())) {
             $parentTree = $loggedUser->mergedRole->getMask($repository->getId())->getTree();
             // Try to find a branch on the current selection
             $parts = explode("/", trim($file, "/"));
             while (($next = array_shift($parts)) !== null) {
                 if (isset($parentTree[$next])) {
                     $parentTree = $parentTree[$next];
                 } else {
                     $parentTree = null;
                     break;
                 }
             }
             if ($parentTree != null) {
                 $newMask = new AJXP_PermissionMask();
                 $newMask->updateTree($parentTree);
             }
             if (isset($newMask)) {
                 $userObject->personalRole->setMask($newRepoUniqueId, $newMask);
             }
         }
         if (isset($httpVars["minisite"])) {
             if (isset($editingRepo)) {
                 try {
                     AuthService::deleteRole("AJXP_SHARED-" . $newRepoUniqueId);
                 } catch (Exception $e) {
                 }
             }
             $newRole = new AJXP_Role("AJXP_SHARED-" . $newRepoUniqueId);
             $r = AuthService::getRole("MINISITE");
             if (is_a($r, "AJXP_Role")) {
                 if ($httpVars["disable_download"]) {
                     $f = AuthService::getRole("MINISITE_NODOWNLOAD");
                     if (is_a($f, "AJXP_Role")) {
                         $r = $f->override($r);
                     }
                 }
                 $allData = $r->getDataArray();
                 $newData = $newRole->getDataArray();
                 if (isset($allData["ACTIONS"][AJXP_REPO_SCOPE_SHARED])) {
                     $newData["ACTIONS"][$newRepoUniqueId] = $allData["ACTIONS"][AJXP_REPO_SCOPE_SHARED];
                 }
                 if (isset($allData["PARAMETERS"][AJXP_REPO_SCOPE_SHARED])) {
                     $newData["PARAMETERS"][$newRepoUniqueId] = $allData["PARAMETERS"][AJXP_REPO_SCOPE_SHARED];
                 }
                 $newRole->bunchUpdate($newData);
                 AuthService::updateRole($newRole);
                 $userObject->addRole($newRole);
             }
         }
         $userObject->save("superuser");
         if ($this->watcher !== false) {
             // Register a watch on the current folder for shared user
             if ($uWatches[$userName]) {
                 $this->watcher->setWatchOnFolder(new AJXP_Node("pydio://" . $newRepoUniqueId . "/"), $userName, MetaWatchRegister::$META_WATCH_USERS_CHANGE, array(AuthService::getLoggedUser()->getId()));
             } else {
                 $this->watcher->removeWatchFromFolder(new AJXP_Node("pydio://" . $newRepoUniqueId . "/"), $userName, true);
             }
         }
     }
     if ($this->watcher !== false) {
         // Register a watch on the new repository root for current user
         if ($httpVars["self_watch_folder"] == "true") {
             $this->watcher->setWatchOnFolder(new AJXP_Node("pydio://" . $newRepoUniqueId . "/"), AuthService::getLoggedUser()->getId(), MetaWatchRegister::$META_WATCH_BOTH);
         } else {
             $this->watcher->removeWatchFromFolder(new AJXP_Node("pydio://" . $newRepoUniqueId . "/"), AuthService::getLoggedUser()->getId());
         }
     }
     foreach ($groups as $group) {
         $r = $uRights[$group];
         /*if($group == "AJXP_GRP_/") {
               $group = "ROOT_ROLE";
           }*/
         $grRole = AuthService::getRole($group, true);
         $grRole->setAcl($newRepoUniqueId, $r);
         AuthService::updateRole($grRole);
     }
     if (array_key_exists("minisite", $httpVars) && $httpVars["minisite"] != true) {
         AJXP_Controller::applyHook(isset($editingRepo) ? "node.share.update" : "node.share.create", array('type' => 'repository', 'repository' => &$repository, 'accessDriver' => &$accessDriver, 'new_repository' => &$newRepo));
     }
     return $newRepo;
 }