Skip to content

Commit 2309e25

Browse files
committed
Offload acceslist creation to providers
* This allows for effective queries. * Introduce currentAccess parameter to speciy if the users needs to have currently acces (deleted incomming group share). (For notifications) Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
1 parent 2d2e5f8 commit 2309e25

9 files changed

Lines changed: 372 additions & 82 deletions

File tree

apps/federatedfilesharing/lib/FederatedShareProvider.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
namespace OCA\FederatedFileSharing;
2828

2929
use OC\Share20\Share;
30+
use OCP\DB\QueryBuilder\IQueryBuilder;
3031
use OCP\Files\Folder;
3132
use OCP\Files\IRootFolder;
3233
use OCP\IConfig;
@@ -953,4 +954,28 @@ public function isLookupServerQueriesEnabled() {
953954
$result = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
954955
return ($result === 'yes') ? true : false;
955956
}
957+
958+
public function getAccessList($nodes, $currentAccess) {
959+
$ids = [];
960+
foreach ($nodes as $node) {
961+
$ids[] = $node->getId();
962+
}
963+
964+
$qb = $this->dbConnection->getQueryBuilder();
965+
$qb->select('share_with')
966+
->from('share')
967+
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
968+
->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
969+
->andWhere($qb->expr()->orX(
970+
$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
971+
$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
972+
))
973+
->setMaxResults(1);
974+
$cursor = $qb->execute();
975+
976+
$remote = $cursor->fetch() !== false;
977+
$cursor->closeCursor();
978+
979+
return ['users' => [], 'remote' => $remote, 'public' => false];
980+
}
956981
}

apps/sharebymail/lib/ShareByMailProvider.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,4 +767,8 @@ public function getSharesInFolder($userId, Folder $node, $reshares) {
767767
return $shares;
768768
}
769769

770+
public function getAccessList($nodes, $currentAccess) {
771+
return ['users' => [], 'remote' => false, 'public' => false];
772+
}
773+
770774
}

lib/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,7 @@
769769
'OC\\Share20\\Manager' => $baseDir . '/lib/private/Share20/Manager.php',
770770
'OC\\Share20\\ProviderFactory' => $baseDir . '/lib/private/Share20/ProviderFactory.php',
771771
'OC\\Share20\\Share' => $baseDir . '/lib/private/Share20/Share.php',
772+
'OC\\Share20\\ShareHelper' => $baseDir . '/lib/private/Share20/ShareHelper.php',
772773
'OC\\Share\\Constants' => $baseDir . '/lib/private/Share/Constants.php',
773774
'OC\\Share\\Helper' => $baseDir . '/lib/private/Share/Helper.php',
774775
'OC\\Share\\MailNotifications' => $baseDir . '/lib/private/Share/MailNotifications.php',

lib/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
799799
'OC\\Share20\\Manager' => __DIR__ . '/../../..' . '/lib/private/Share20/Manager.php',
800800
'OC\\Share20\\ProviderFactory' => __DIR__ . '/../../..' . '/lib/private/Share20/ProviderFactory.php',
801801
'OC\\Share20\\Share' => __DIR__ . '/../../..' . '/lib/private/Share20/Share.php',
802+
'OC\\Share20\\ShareHelper' => __DIR__ . '/../../..' . '/lib/private/Share20/ShareHelper.php',
802803
'OC\\Share\\Constants' => __DIR__ . '/../../..' . '/lib/private/Share/Constants.php',
803804
'OC\\Share\\Helper' => __DIR__ . '/../../..' . '/lib/private/Share/Helper.php',
804805
'OC\\Share\\MailNotifications' => __DIR__ . '/../../..' . '/lib/private/Share/MailNotifications.php',

lib/private/Share20/DefaultShareProvider.php

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
355355
if ($data === false) {
356356
$qb = $this->dbConn->getQueryBuilder();
357357

358-
$type = $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder';
358+
$type = $share->getNodeType();
359359

360360
//Insert new share
361361
$qb->insert('share')
@@ -366,8 +366,8 @@ public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
366366
'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
367367
'parent' => $qb->createNamedParameter($share->getId()),
368368
'item_type' => $qb->createNamedParameter($type),
369-
'item_source' => $qb->createNamedParameter($share->getNode()->getId()),
370-
'file_source' => $qb->createNamedParameter($share->getNode()->getId()),
369+
'item_source' => $qb->createNamedParameter($share->getNodeId()),
370+
'file_source' => $qb->createNamedParameter($share->getNodeId()),
371371
'file_target' => $qb->createNamedParameter($share->getTarget()),
372372
'permissions' => $qb->createNamedParameter(0),
373373
'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
@@ -1062,4 +1062,74 @@ public function userDeletedFromGroup($uid, $gid) {
10621062
}
10631063
}
10641064
}
1065+
1066+
/**
1067+
* @inheritdoc
1068+
*/
1069+
public function getAccessList($nodes, $currentAccess) {
1070+
$ids = [];
1071+
foreach ($nodes as $node) {
1072+
$ids[] = $node->getId();
1073+
}
1074+
1075+
$qb = $this->dbConn->getQueryBuilder();
1076+
1077+
$or = $qb->expr()->orX(
1078+
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
1079+
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1080+
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
1081+
);
1082+
1083+
if ($currentAccess) {
1084+
$or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)));
1085+
}
1086+
1087+
$qb->select('share_type', 'share_with')
1088+
->from('share')
1089+
->where(
1090+
$or
1091+
)
1092+
->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1093+
->andWhere($qb->expr()->orX(
1094+
$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1095+
$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1096+
));
1097+
$cursor = $qb->execute();
1098+
1099+
$users = [];
1100+
$link = false;
1101+
while($row = $cursor->fetch()) {
1102+
$type = (int)$row['share_type'];
1103+
if ($type === \OCP\Share::SHARE_TYPE_USER) {
1104+
$uid = $row['share_with'];
1105+
$users[$uid] = isset($users[$uid]) ? $users[$uid] + 1 : 1;
1106+
} else if ($type === \OCP\Share::SHARE_TYPE_GROUP) {
1107+
$gid = $row['share_with'];
1108+
$group = $this->groupManager->get($gid);
1109+
1110+
if ($gid === null) {
1111+
continue;
1112+
}
1113+
1114+
$userList = $group->getUsers();
1115+
foreach ($userList as $user) {
1116+
$users[$user->getUID()] = isset($users[$user->getUID()]) ? $users[$user->getUID()] + 1 : 1;
1117+
}
1118+
} else if ($type === \OCP\Share::SHARE_TYPE_LINK) {
1119+
$link = true;
1120+
} else if ($type === self::SHARE_TYPE_USERGROUP) {
1121+
if ($currentAccess === true) {
1122+
$uid = $row['share_with'];
1123+
$users[$uid] = isset($users[$uid]) ? $users[$uid] - 1 : -1;
1124+
}
1125+
}
1126+
}
1127+
$cursor->closeCursor();
1128+
1129+
$users = array_filter($users, function($count) {
1130+
return $count > 0;
1131+
});
1132+
1133+
return ['users' => array_keys($users), 'public' => $link, 'remote' => false];
1134+
}
10651135
}

lib/private/Share20/Manager.php

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,69 +1194,50 @@ public function userDeletedFromGroup($uid, $gid) {
11941194
*
11951195
* @param \OCP\Files\Node $path
11961196
* @param bool $recursive Should we check all parent folders as well
1197+
* @param bool $currentAccess Should the user have currently access to the file
11971198
* @return array
11981199
*/
1199-
public function getAccessList(\OCP\Files\Node $path, $recursive = true) {
1200+
public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
12001201
$owner = $path->getOwner()->getUID();
12011202

1203+
$al = ['users' => [], 'public' => false, 'remote' => false];
1204+
if (!$this->userManager->userExists($owner)) {
1205+
return $al;
1206+
}
1207+
12021208
//Get node for the owner
12031209
$userFolder = $this->rootFolder->getUserFolder($owner);
1204-
12051210
if (!$userFolder->isSubNode($path)) {
12061211
$path = $userFolder->getById($path->getId())[0];
12071212
}
12081213

12091214
$providers = $this->factory->getAllProviders();
12101215

1211-
/** @var IShare[] $shares */
1212-
$shares = [];
1216+
/** @var Node[] $nodes */
1217+
$nodes = [];
1218+
1219+
$al['users'][] = $owner;
12131220

12141221
// Collect all the shares
12151222
while ($path->getPath() !== $userFolder->getPath()) {
1216-
foreach ($providers as $provider) {
1217-
$shares = array_merge($shares, $provider->getSharesByPath($path));
1218-
}
1223+
$nodes[] = $path;
12191224
if (!$recursive) {
12201225
break;
12211226
}
12221227
$path = $path->getParent();
12231228
}
12241229

1225-
$users = [$owner => 'null'];
1226-
$public = false;
1227-
$remote = false;
1228-
foreach ($shares as $share) {
1229-
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
1230-
$uid = $share->getSharedWith();
1231-
1232-
// Skip if user does not exist
1233-
if (!$this->userManager->userExists($uid)) {
1234-
continue;
1235-
}
1236-
1237-
$users[$uid] = null;
1238-
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
1239-
$group = $this->groupManager->get($share->getSharedWith());
1230+
foreach ($providers as $provider) {
1231+
$tmp = $provider->getAccessList($nodes, $currentAccess);
12401232

1241-
// If group does not exist skip
1242-
if ($group === null) {
1243-
continue;
1244-
}
1245-
1246-
$groupUsers = $group->getUsers();
1247-
foreach ($groupUsers as $groupUser) {
1248-
$users[$groupUser->getUID()] = null;
1249-
}
1250-
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
1251-
$public = true;
1252-
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
1253-
$remote = true;
1254-
}
1233+
$al['users'] = array_merge($al['users'], $tmp['users']);
1234+
$al['public'] = $al['public'] || $tmp['public'];
1235+
$al['remote'] = $al['remote'] || $tmp['remote'];
12551236
}
12561237

1257-
$users = array_keys($users);
1238+
$al['users'] = array_unique($al['users']);
12581239

1259-
return ['users' => $users, 'public' => $public, 'remote' => $remote];
1240+
return $al;
12601241
}
12611242

12621243
/**

lib/public/Share/IShareProvider.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,21 @@ public function groupDeleted($gid);
190190
* @since 9.1.0
191191
*/
192192
public function userDeletedFromGroup($uid, $gid);
193+
194+
/**
195+
* Get the access list to the array of provided nodes.
196+
* Return will look like:
197+
*
198+
* [
199+
* users => ['user1', 'user2', 'user4'],
200+
* public => bool
201+
* remote => bool
202+
* ]
203+
*
204+
* @param Node[] $nodes The list of nodes to get access for
205+
* @param bool $currentAccess If current access is required (like for removed shares that might get revived later)
206+
* @return string[]
207+
* @since 12
208+
*/
209+
public function getAccessList($nodes, $currentAccess);
193210
}

0 commit comments

Comments
 (0)