Skip to content
This repository was archived by the owner on Nov 25, 2020. It is now read-only.

Commit 9d28b1c

Browse files
committed
Rework Share options for folders / files vs. public links / internal sharing - Fix #1143
Better invalid share detection and remove it from meta. Fix many error messages.
1 parent 6b2525a commit 9d28b1c

File tree

9 files changed

+134
-40
lines changed

9 files changed

+134
-40
lines changed

core/src/plugins/action.share/class.CompositeShare.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ public function getVisibilityScope(){
9494
}
9595
}
9696

97+
/**
98+
* @return bool
99+
*/
100+
public function isInvalid(){
101+
return $this->getRepository() == null;
102+
}
103+
97104
/**
98105
* @param MetaWatchRegister|false $watcher
99106
* @param ShareRightsManager $rightsManager

core/src/plugins/action.share/class.ShareCenter.php

Lines changed: 67 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ protected function parseSpecificContributions(&$contribNode)
117117
$xpathesToRemove[] = 'action[contains(@name, "share-")]';
118118
}else{
119119
$folderSharingAllowed = $this->getAuthorization("folder", "any");
120-
$fileSharingAllowed = $this->getAuthorization("file");
120+
$fileSharingAllowed = $this->getAuthorization("file", "any");
121121
if($fileSharingAllowed === false){
122122
// Share file button
123123
$xpathesToRemove[] = 'action[@name="share-file-minisite"]';
@@ -143,10 +143,23 @@ protected function parseSpecificContributions(&$contribNode)
143143
/**
144144
* Compute right to create shares based on plugin options
145145
* @param string $nodeType "file"|"folder"
146-
* @param string $shareType
146+
* @param string $shareType "any"|"minisite"|"workspace"
147147
* @return bool
148148
*/
149149
protected function getAuthorization($nodeType, $shareType = "any"){
150+
$filesMini = $this->getFilteredOption("ENABLE_FILE_PUBLIC_LINK");
151+
$filesInternal = $this->getFilteredOption("ENABLE_FILE_INTERNAL_SHARING");
152+
$foldersMini = $this->getFilteredOption("ENABLE_FOLDER_PUBLIC_LINK");
153+
$foldersInternal = $this->getFilteredOption("ENABLE_FOLDER_INTERNAL_SHARING");
154+
if($shareType == "any"){
155+
return ($nodeType == "file" ? $filesInternal || $filesMini : $foldersInternal || $foldersMini);
156+
}else if($shareType == "minisite"){
157+
return ($nodeType == "file" ? $filesMini : $foldersMini);
158+
}else if($shareType == "workspace"){
159+
return ($nodeType == "file" ? $filesInternal : $foldersInternal);
160+
}
161+
return false;
162+
/*
150163
if($nodeType == "file"){
151164
return $this->getFilteredOption("ENABLE_FILE_PUBLIC_LINK") !== false;
152165
}else{
@@ -159,6 +172,7 @@ protected function getAuthorization($nodeType, $shareType = "any"){
159172
return ($opt !== "disable");
160173
}
161174
}
175+
*/
162176
}
163177

164178
/**
@@ -431,7 +445,8 @@ public function switchAction($action, $httpVars, $fileVars)
431445

432446
$auth = $this->getAuthorization("folder", "workspace");
433447
if(!$auth){
434-
throw new Exception(103);
448+
$mess = ConfService::getMessages();
449+
throw new Exception($mess["351"]);
435450
}
436451

437452
$users = array(); $groups = array();
@@ -496,8 +511,9 @@ public function switchAction($action, $httpVars, $fileVars)
496511

497512
$httpVars["return_json"] = true;
498513
if(isSet($httpVars["hash"]) && !empty($httpVars["hash"])) $httpHash = $httpVars["hash"];
514+
$ajxpNode->loadNodeInfo();
499515

500-
$results = $this->shareNode($httpVars, $isUpdate);
516+
$results = $this->shareNode($ajxpNode, $httpVars, $isUpdate);
501517
if(is_array($results) && $ajxpNode->hasMetaStore() && !$ajxpNode->isRoot()){
502518
foreach($results as $shareObject){
503519
if($shareObject instanceof \Pydio\OCS\Model\TargettedLink){
@@ -641,11 +657,17 @@ public function switchAction($action, $httpVars, $fileVars)
641657
$file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
642658
$node = new AJXP_Node($this->urlBase.$file);
643659
if(!file_exists($node->getUrl())){
644-
throw new Exception("Cannot find file ".$file.": share may be lost.");
660+
$mess = ConfService::getMessages();
661+
throw new Exception(str_replace('%s', "Cannot find file ".$file, $mess["share_center.219"]));
662+
}
663+
if(isSet($httpVars["tmp_repository_id"]) && AuthService::getLoggedUser()->isAdmin()){
664+
$compositeShare = $this->getShareStore()->getMetaManager()->getCompositeShareForNode($node, true);
665+
}else{
666+
$compositeShare = $this->getShareStore()->getMetaManager()->getCompositeShareForNode($node);
645667
}
646-
$compositeShare = $this->getShareStore()->getMetaManager()->getCompositeShareForNode($node);
647668
if(empty($compositeShare)){
648-
throw new Exception("Cannot find share for node ".$file);
669+
$mess = ConfService::getMessages();
670+
throw new Exception(str_replace('%s', "Cannot find share for node ".$file, $mess["share_center.219"]));
649671
}
650672
header("Content-type:application/json");
651673
$json = $this->compositeShareToJson($compositeShare);
@@ -850,7 +872,7 @@ public function nodeSharedMetadata(&$ajxpNode)
850872
$this->getShareStore()->getMetaManager()->getSharesFromMeta($ajxpNode, $shares, false);
851873
if(!empty($shares)){
852874
$compositeShare = $this->getShareStore()->getMetaManager()->getCompositeShareForNode($ajxpNode);
853-
if(empty($compositeShare)){
875+
if(empty($compositeShare) || $compositeShare->isInvalid()){
854876
$this->getShareStore()->getMetaManager()->clearNodeMeta($ajxpNode);
855877
return;
856878
}
@@ -1219,6 +1241,23 @@ public function filterHttpVarsForLeafPath(&$httpVars, $userSelection){
12191241

12201242
}
12211243

1244+
/**
1245+
* @param array $httpVars
1246+
* @param AJXP_Node $ajxpNode
1247+
*/
1248+
public function filterHttpVarsFromUniqueNode(&$httpVars, $ajxpNode){
1249+
$httpVars["minisite"] = true;
1250+
$httpVars["selection"] = true;
1251+
if($ajxpNode->isLeaf()){
1252+
$httpVars["filter_nodes"] = [$ajxpNode];
1253+
$httpVars["file"] = "/";
1254+
$httpVars["nodes"] = array("/");
1255+
}
1256+
if(!isSet($httpVars["repo_label"])){
1257+
$httpVars["repo_label"] = SystemTextEncoding::toUTF8($ajxpNode->getLabel());
1258+
}
1259+
}
1260+
12221261
/**
12231262
* @param array $httpVars
12241263
* @param bool $update
@@ -1228,7 +1267,8 @@ public function filterHttpVarsForLeafPath(&$httpVars, $userSelection){
12281267
protected function createOrLoadSharedRepository($httpVars, &$update){
12291268

12301269
if (!isSet($httpVars["repo_label"]) || $httpVars["repo_label"] == "") {
1231-
throw new Exception(100);
1270+
$mess = ConfService::getMessages();
1271+
throw new Exception($mess["349"]);
12321272
}
12331273

12341274
if (isSet($httpVars["repository_id"])) {
@@ -1241,7 +1281,8 @@ protected function createOrLoadSharedRepository($httpVars, &$update){
12411281
$description = AJXP_Utils::sanitize(AJXP_Utils::securePath($httpVars["repo_description"]), AJXP_SANITIZE_HTML);
12421282
$exists = $this->checkRepoWithSameLabel($label, isSet($editingRepo)?$editingRepo:null);
12431283
if($exists){
1244-
throw new Exception(101);
1284+
$mess = ConfService::getMessages();
1285+
throw new Exception($mess["share_center.352"]);
12451286
}
12461287

12471288
$loggedUser = AuthService::getLoggedUser();
@@ -1263,7 +1304,8 @@ protected function createOrLoadSharedRepository($httpVars, &$update){
12631304
$oldScope = $editingRepo->getOption("SHARE_ACCESS");
12641305
$currentOwner = $editingRepo->getOwner();
12651306
if($newScope != $oldScope && $currentOwner != AuthService::getLoggedUser()->getId()){
1266-
throw new Exception("You are not allowed to handle this share. Please ask the owner of the share.");
1307+
$mess = ConfService::getMessages();
1308+
throw new Exception($mess["share_center.224"]);
12671309
}
12681310
if($newScope !== $oldScope){
12691311
$editingRepo->addOption("SHARE_ACCESS", $newScope);
@@ -1272,7 +1314,8 @@ protected function createOrLoadSharedRepository($httpVars, &$update){
12721314
if(isSet($httpVars["transfer_owner"])){
12731315
$newOwner = $httpVars["transfer_owner"];
12741316
if($newOwner != $currentOwner && $currentOwner != AuthService::getLoggedUser()->getId()){
1275-
throw new Exception("You are not allowed to handle this share. Please ask the owner");
1317+
$mess = ConfService::getMessages();
1318+
throw new Exception($mess["share_center.224"]);
12761319
}
12771320
$editingRepo->setOwnerData($editingRepo->getParentId(), $newOwner, $editingRepo->getUniqueUser());
12781321
$replace = true;
@@ -1390,7 +1433,8 @@ public function createSharedRepository($httpVars, &$update, $users=array(), $gro
13901433
$loggedUser = AuthService::getLoggedUser();
13911434
$actRights = $loggedUser->mergedRole->listActionsStatesFor($this->repository);
13921435
if (isSet($actRights["share"]) && $actRights["share"] === false) {
1393-
throw new Exception(103);
1436+
$mess = ConfService::getMessages();
1437+
throw new Exception($mess["351"]);
13941438
}
13951439

13961440
$newRepo = $this->createOrLoadSharedRepository($httpVars, $update);
@@ -1455,18 +1499,20 @@ protected function shareObjectFromParameters($linkData, &$hiddenUserEntries, &$s
14551499
}
14561500

14571501
/**
1502+
* @param AJXP_Node $ajxpNode
14581503
* @param array $httpVars
14591504
* @param bool $update
14601505
* @return Repository[]|ShareLink[]
14611506
* @throws Exception
14621507
*/
1463-
public function shareNode($httpVars, &$update){
1508+
public function shareNode($ajxpNode, $httpVars, &$update){
14641509

14651510
$hiddenUserEntries = array();
14661511
$originalHttpVars = $httpVars;
14671512
$ocsStore = new Pydio\OCS\Model\SQLStore();
14681513
$ocsClient = new Pydio\OCS\Client\OCSClient();
14691514
$userSelection = new UserSelection($this->repository, $httpVars);
1515+
$mess = ConfService::getMessages();
14701516

14711517
/**
14721518
* @var ShareLink[] $shareObjects
@@ -1475,6 +1521,9 @@ public function shareNode($httpVars, &$update){
14751521

14761522
// PUBLIC LINK
14771523
if(isSet($httpVars["enable_public_link"])){
1524+
if(!$this->getAuthorization($ajxpNode->isLeaf() ? "file":"folder", "minisite")){
1525+
throw new Exception($mess["share_center." . ($ajxpNode->isLeaf() ? "225" : "226")]);
1526+
}
14781527
$this->shareObjectFromParameters($httpVars, $hiddenUserEntries, $shareObjects, "public");
14791528
}else if(isSet($httpVars["disable_public_link"])){
14801529
$this->getShareStore()->deleteShare("minisite", $httpVars["disable_public_link"], true);
@@ -1498,10 +1547,13 @@ public function shareNode($httpVars, &$update){
14981547
}
14991548
}
15001549

1501-
$this->filterHttpVarsForLeafPath($httpVars, $userSelection);
1550+
$this->filterHttpVarsFromUniqueNode($httpVars, $ajxpNode);
15021551

15031552
$users = array(); $groups = array();
15041553
$this->getRightsManager()->createUsersFromParameters($httpVars, $users, $groups);
1554+
if((count($users) || count($groups)) && !$this->getAuthorization($ajxpNode->isLeaf()?"file":"folder", "workspace")){
1555+
$users = $groups = array();
1556+
}
15051557
foreach($hiddenUserEntries as $entry){
15061558
$users[$entry["ID"]] = $entry;
15071559
}

core/src/plugins/action.share/class.ShareLink.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ public function getRepository(){
125125
if(isSet($this->internal["REPOSITORY"])){
126126
return ConfService::getRepositoryById($this->internal["REPOSITORY"]);
127127
}else{
128-
throw new Exception("No repository attached!");
128+
$mess = ConfService::getMessages();
129+
throw new Exception(str_replace('%s', 'No repository attached to link', $mess["share_center.219"]));
129130
}
130131
}
131132

@@ -163,7 +164,8 @@ public function parseHttpVars($httpVars){
163164
$value = AJXP_Utils::sanitize($httpVars["custom_handle"], AJXP_SANITIZE_ALPHANUM);
164165
$value = strtolower($value);
165166
if(strlen($value) < $this->store->hashMinLength){
166-
throw new Exception("Custom link is too short, please use at least ".$this->store->hashMinLength." characters");
167+
$mess = ConfService::getMessages();
168+
throw new Exception(str_replace("%s", $this->store->hashMinLength, $mess["share_center.223"]));
167169
}
168170
$test = $this->store->loadShare($value);
169171
$mess = ConfService::getMessages();

core/src/plugins/action.share/class.ShareMetaManager.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ public function collectSharesIncludingChildren($node){
134134
*/
135135
protected function compositeShareFromMetaWithScope($node, $scope = "private"){
136136

137-
$meta = $node->retrieveMetadata(AJXP_SHARED_META_NAMESPACE, ($scope == "private"), AJXP_METADATA_SCOPE_REPOSITORY, true);
137+
if($scope !== AJXP_METADATA_ALLUSERS){
138+
$scope = ($scope == "private");
139+
}
140+
$meta = $node->retrieveMetadata(AJXP_SHARED_META_NAMESPACE, $scope, AJXP_METADATA_SCOPE_REPOSITORY, true);
138141
$shares = array();
139142
$composites = array();
140143
if(!isSet($meta["shares"])){
@@ -175,9 +178,17 @@ protected function compositeShareFromMetaWithScope($node, $scope = "private"){
175178

176179
/**
177180
* @param AJXP_Node $node
181+
* @param bool $allUsersScope
178182
* @return CompositeShare|null
179183
*/
180-
public function getCompositeShareForNode($node){
184+
public function getCompositeShareForNode($node, $allUsersScope = false){
185+
if($allUsersScope){
186+
$global = $this->compositeShareFromMetaWithScope($node, AJXP_METADATA_ALLUSERS);
187+
if(count($global)) {
188+
return $global[0];
189+
}
190+
return null;
191+
}
181192
$private = $this->compositeShareFromMetaWithScope($node, "private");
182193
if(count($private)) {
183194
return $private[0];

core/src/plugins/action.share/class.ShareRightsManager.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ public function prepareSharedUserEntry($httpVars, &$shareObject, $update, $guest
114114

115115
$hiddenUserEntry = $this->createHiddenUserEntry($httpVars, $uniqueUser, $userPass, $update);
116116
if(empty($hiddenUserEntry["RIGHT"])){
117-
throw new Exception("share_center.58");
117+
$mess = ConfService::getMessages();
118+
throw new Exception($mess["share_center.58"]);
118119
}
119120
$hiddenUserEntry["DISABLE_DOWNLOAD"] = $shareObject->disableDownload();
120121
if($shareObject instanceof \Pydio\OCS\Model\TargettedLink){
@@ -166,6 +167,7 @@ public function createUsersFromParameters($httpVars, &$users = array(), &$groups
166167
$allowSharedUsersCreation = ConfService::getCoreConf("USER_CREATE_USERS", "conf");
167168
$loggedUser = AuthService::getLoggedUser();
168169
$confDriver = ConfService::getConfStorageImpl();
170+
$mess = ConfService::getMessages();
169171

170172
while (isSet($httpVars[PARAM_USER_LOGIN_PREFIX.$index])) {
171173

@@ -188,16 +190,16 @@ public function createUsersFromParameters($httpVars, &$users = array(), &$groups
188190
$index++;
189191
continue;
190192
} else if (AuthService::userExists($u, "w") && isSet($httpVars[PARAM_USER_PASS_PREFIX.$index])) {
191-
throw new Exception("User $u already exists, please choose another name.");
193+
throw new Exception( str_replace("%s", $u, $mess["share_center.222"]));
192194
}
193195
if($userExistsRead){
194196
$userObject = $confDriver->createUserObject($u);
195197
if ( $allowCrossUserSharing != true && ( !$userObject->hasParent() || $userObject->getParent() != $loggedUser->getId() ) ) {
196-
throw new Exception("You are not allowed to share with other users, except your internal users.");
198+
throw new Exception($mess["share_center.221"]);
197199
}
198200
}else{
199201
if(!$allowSharedUsersCreation || AuthService::isReservedUserId($u)){
200-
throw new Exception("You are not allowed to create users.");
202+
throw new Exception($mess["share_center.220"]);
201203
}
202204
if(!empty($this->options["SHARED_USERS_TMP_PREFIX"]) && strpos($u, $this->options["SHARED_USERS_TMP_PREFIX"])!==0 ){
203205
$u = $this->options["SHARED_USERS_TMP_PREFIX"] . $u;

0 commit comments

Comments
 (0)