aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Share20
diff options
context:
space:
mode:
authorJohn Molakvoæ <skjnldsv@users.noreply.github.com>2024-03-15 13:03:34 +0100
committerGitHub <noreply@github.com>2024-03-15 13:03:34 +0100
commit9338ef36ded767f2c35b7ec575b351859420ed09 (patch)
tree65c53c6a36f300859dc22b2d423275bcf2911367 /lib/private/Share20
parent6b09a79227a5dc98aa4620c6e5e15b610a06c806 (diff)
parentdf1cd1ba7e6e1f6e66a2b3229b5c082f1b81162e (diff)
downloadnextcloud-server-9338ef36ded767f2c35b7ec575b351859420ed09.tar.gz
nextcloud-server-9338ef36ded767f2c35b7ec575b351859420ed09.zip
Merge branch 'master' into refactor/OC-Server-getShareManager
Signed-off-by: John Molakvoæ <skjnldsv@users.noreply.github.com>
Diffstat (limited to 'lib/private/Share20')
-rw-r--r--lib/private/Share20/DefaultShareProvider.php75
-rw-r--r--lib/private/Share20/Manager.php123
-rw-r--r--lib/private/Share20/ProviderFactory.php5
-rw-r--r--lib/private/Share20/PublicShareTemplateFactory.php2
-rw-r--r--lib/private/Share20/Share.php16
-rw-r--r--lib/private/Share20/ShareDisableChecker.php65
6 files changed, 172 insertions, 114 deletions
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index 5201cf074b1..50196402b42 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -38,12 +38,12 @@ use OC\Files\Cache\Cache;
use OC\Share20\Exception\BackendError;
use OC\Share20\Exception\InvalidShare;
use OC\Share20\Exception\ProviderException;
+use OCP\AppFramework\Utility\ITimeFactory;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Defaults;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
-use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\IURLGenerator;
@@ -55,6 +55,7 @@ use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IAttributes;
use OCP\Share\IShare;
use OCP\Share\IShareProvider;
+use Psr\Log\LoggerInterface;
use function str_starts_with;
/**
@@ -90,19 +91,19 @@ class DefaultShareProvider implements IShareProvider {
/** @var IURLGenerator */
private $urlGenerator;
- /** @var IConfig */
- private $config;
+ private ITimeFactory $timeFactory;
public function __construct(
- IDBConnection $connection,
- IUserManager $userManager,
- IGroupManager $groupManager,
- IRootFolder $rootFolder,
- IMailer $mailer,
- Defaults $defaults,
- IFactory $l10nFactory,
- IURLGenerator $urlGenerator,
- IConfig $config) {
+ IDBConnection $connection,
+ IUserManager $userManager,
+ IGroupManager $groupManager,
+ IRootFolder $rootFolder,
+ IMailer $mailer,
+ Defaults $defaults,
+ IFactory $l10nFactory,
+ IURLGenerator $urlGenerator,
+ ITimeFactory $timeFactory,
+ ) {
$this->dbConn = $connection;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
@@ -111,7 +112,7 @@ class DefaultShareProvider implements IShareProvider {
$this->defaults = $defaults;
$this->l10nFactory = $l10nFactory;
$this->urlGenerator = $urlGenerator;
- $this->config = $config;
+ $this->timeFactory = $timeFactory;
}
/**
@@ -216,32 +217,22 @@ class DefaultShareProvider implements IShareProvider {
}
// Set the time this share was created
- $qb->setValue('stime', $qb->createNamedParameter(time()));
+ $shareTime = $this->timeFactory->now();
+ $qb->setValue('stime', $qb->createNamedParameter($shareTime->getTimestamp()));
// insert the data and fetch the id of the share
- $this->dbConn->beginTransaction();
- $qb->execute();
- $id = $this->dbConn->lastInsertId('*PREFIX*share');
+ $qb->executeStatement();
- // Now fetch the inserted share and create a complete share object
- $qb = $this->dbConn->getQueryBuilder();
- $qb->select('*')
- ->from('share')
- ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
-
- $cursor = $qb->execute();
- $data = $cursor->fetch();
- $this->dbConn->commit();
- $cursor->closeCursor();
+ // Update mandatory data
+ $id = $qb->getLastInsertId();
+ $share->setId((string)$id);
+ $share->setProviderId($this->identifier());
- if ($data === false) {
- throw new ShareNotFound('Newly created share could not be found');
- }
+ $share->setShareTime(\DateTime::createFromImmutable($shareTime));
$mailSendValue = $share->getMailSend();
- $data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
+ $share->setMailSend(($mailSendValue === null) ? true : $mailSendValue);
- $share = $this->createShare($data);
return $share;
}
@@ -701,17 +692,24 @@ class DefaultShareProvider implements IShareProvider {
}, $childMountNodes);
$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
+ $storageFilter = $qb->expr()->eq('f.storage', $qb->createNamedParameter($node->getMountPoint()->getNumericStorageId(), IQueryBuilder::PARAM_INT));
if ($shallow) {
$qb->andWhere(
$qb->expr()->orX(
- $qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())),
+ $qb->expr()->andX(
+ $storageFilter,
+ $qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())),
+ ),
$qb->expr()->in('f.fileid', $qb->createParameter('chunk'))
)
);
} else {
$qb->andWhere(
$qb->expr()->orX(
- $qb->expr()->like('f.path', $qb->createNamedParameter($this->dbConn->escapeLikeParameter($node->getInternalPath()) . '/%')),
+ $qb->expr()->andX(
+ $storageFilter,
+ $qb->expr()->like('f.path', $qb->createNamedParameter($this->dbConn->escapeLikeParameter($node->getInternalPath()) . '/%')),
+ ),
$qb->expr()->in('f.fileid', $qb->createParameter('chunk'))
)
);
@@ -1247,7 +1245,8 @@ class DefaultShareProvider implements IShareProvider {
)
);
} else {
- \OC::$server->getLogger()->logException(new \InvalidArgumentException('Default share provider tried to delete all shares for type: ' . $shareType));
+ $e = new \InvalidArgumentException('Default share provider tried to delete all shares for type: ' . $shareType);
+ \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]);
return;
}
@@ -1374,7 +1373,7 @@ class DefaultShareProvider implements IShareProvider {
$type = (int)$row['share_type'];
if ($type === IShare::TYPE_USER) {
$uid = $row['share_with'];
- $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
+ $users[$uid] = $users[$uid] ?? [];
$users[$uid][$row['id']] = $row;
} elseif ($type === IShare::TYPE_GROUP) {
$gid = $row['share_with'];
@@ -1387,14 +1386,14 @@ class DefaultShareProvider implements IShareProvider {
$userList = $group->getUsers();
foreach ($userList as $user) {
$uid = $user->getUID();
- $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
+ $users[$uid] = $users[$uid] ?? [];
$users[$uid][$row['id']] = $row;
}
} elseif ($type === IShare::TYPE_LINK) {
$link = true;
} elseif ($type === IShare::TYPE_USERGROUP && $currentAccess === true) {
$uid = $row['share_with'];
- $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
+ $users[$uid] = $users[$uid] ?? [];
$users[$uid][$row['id']] = $row;
}
}
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index b03608f9872..9b54592dd1e 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -41,7 +41,6 @@
*/
namespace OC\Share20;
-use OCP\Cache\CappedMemoryCache;
use OC\Files\Mount\MoveableMount;
use OC\KnownUser\KnownUserService;
use OC\Share20\Exception\ProviderException;
@@ -55,6 +54,7 @@ use OCP\Files\Mount\IMountManager;
use OCP\Files\Node;
use OCP\HintException;
use OCP\IConfig;
+use OCP\IDateTimeZone;
use OCP\IGroupManager;
use OCP\IL10N;
use OCP\IURLGenerator;
@@ -106,8 +106,6 @@ class Manager implements IManager {
private $userManager;
/** @var IRootFolder */
private $rootFolder;
- /** @var CappedMemoryCache */
- private $sharingDisabledForUsersCache;
/** @var LegacyHooks */
private $legacyHooks;
/** @var IMailer */
@@ -122,6 +120,8 @@ class Manager implements IManager {
private $userSession;
/** @var KnownUserService */
private $knownUserService;
+ private ShareDisableChecker $shareDisableChecker;
+ private IDateTimeZone $dateTimeZone;
public function __construct(
LoggerInterface $logger,
@@ -130,7 +130,6 @@ class Manager implements IManager {
IHasher $hasher,
IMountManager $mountManager,
IGroupManager $groupManager,
- IL10N $l,
IFactory $l10nFactory,
IProviderFactory $factory,
IUserManager $userManager,
@@ -140,7 +139,9 @@ class Manager implements IManager {
\OC_Defaults $defaults,
IEventDispatcher $dispatcher,
IUserSession $userSession,
- KnownUserService $knownUserService
+ KnownUserService $knownUserService,
+ ShareDisableChecker $shareDisableChecker,
+ IDateTimeZone $dateTimeZone,
) {
$this->logger = $logger;
$this->config = $config;
@@ -148,12 +149,11 @@ class Manager implements IManager {
$this->hasher = $hasher;
$this->mountManager = $mountManager;
$this->groupManager = $groupManager;
- $this->l = $l;
+ $this->l = $l10nFactory->get('lib');
$this->l10nFactory = $l10nFactory;
$this->factory = $factory;
$this->userManager = $userManager;
$this->rootFolder = $rootFolder;
- $this->sharingDisabledForUsersCache = new CappedMemoryCache();
// The constructor of LegacyHooks registers the listeners of share events
// do not remove if those are not properly migrated
$this->legacyHooks = new LegacyHooks($dispatcher);
@@ -163,6 +163,8 @@ class Manager implements IManager {
$this->dispatcher = $dispatcher;
$this->userSession = $userSession;
$this->knownUserService = $knownUserService;
+ $this->shareDisableChecker = $shareDisableChecker;
+ $this->dateTimeZone = $dateTimeZone;
}
/**
@@ -308,8 +310,7 @@ class Manager implements IManager {
$mount = $userMount->getMountPoint();
// When it's a reshare use the parent share permissions as maximum
$userMountPointId = $mount->getStorageRootId();
- $userMountPoints = $userFolder->getById($userMountPointId);
- $userMountPoint = array_shift($userMountPoints);
+ $userMountPoint = $userFolder->getFirstNodeById($userMountPointId);
if ($userMountPoint === null) {
throw new GenericShareException('Could not get proper user mount for ' . $userMountPointId . '. Failing since else the next calls are called with null');
@@ -383,10 +384,10 @@ class Manager implements IManager {
$expirationDate = $share->getExpirationDate();
if ($expirationDate !== null) {
- //Make sure the expiration date is a date
+ $expirationDate->setTimezone($this->dateTimeZone->getTimeZone());
$expirationDate->setTime(0, 0, 0);
- $date = new \DateTime();
+ $date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
$date->setTime(0, 0, 0);
if ($date >= $expirationDate) {
$message = $this->l->t('Expiration date is in the past');
@@ -414,9 +415,8 @@ class Manager implements IManager {
$isEnforced = $this->shareApiInternalDefaultExpireDateEnforced();
}
if ($fullId === null && $expirationDate === null && $defaultExpireDate) {
- $expirationDate = new \DateTime();
+ $expirationDate = new \DateTime('now', $this->dateTimeZone->getTimeZone());
$expirationDate->setTime(0, 0, 0);
-
$days = (int)$this->config->getAppValue('core', $configProp, (string)$defaultExpireDays);
if ($days > $defaultExpireDays) {
$days = $defaultExpireDays;
@@ -430,7 +430,7 @@ class Manager implements IManager {
throw new \InvalidArgumentException('Expiration date is enforced');
}
- $date = new \DateTime();
+ $date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
$date->setTime(0, 0, 0);
$date->add(new \DateInterval('P' . $defaultExpireDays . 'D'));
if ($date < $expirationDate) {
@@ -470,10 +470,10 @@ class Manager implements IManager {
$expirationDate = $share->getExpirationDate();
if ($expirationDate !== null) {
- //Make sure the expiration date is a date
+ $expirationDate->setTimezone($this->dateTimeZone->getTimeZone());
$expirationDate->setTime(0, 0, 0);
- $date = new \DateTime();
+ $date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
$date->setTime(0, 0, 0);
if ($date >= $expirationDate) {
$message = $this->l->t('Expiration date is in the past');
@@ -490,7 +490,7 @@ class Manager implements IManager {
}
if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
- $expirationDate = new \DateTime();
+ $expirationDate = new \DateTime('now', $this->dateTimeZone->getTimeZone());
$expirationDate->setTime(0, 0, 0);
$days = (int)$this->config->getAppValue('core', 'link_defaultExpDays', (string)$this->shareApiLinkDefaultExpireDays());
@@ -506,7 +506,7 @@ class Manager implements IManager {
throw new \InvalidArgumentException('Expiration date is enforced');
}
- $date = new \DateTime();
+ $date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
$date->setTime(0, 0, 0);
$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
if ($date < $expirationDate) {
@@ -528,6 +528,9 @@ class Manager implements IManager {
throw new \Exception($message);
}
+ if ($expirationDate instanceof \DateTime) {
+ $expirationDate->setTimezone(new \DateTimeZone(date_default_timezone_get()));
+ }
$share->setExpirationDate($expirationDate);
return $share;
@@ -549,6 +552,11 @@ class Manager implements IManager {
$this->groupManager->getUserGroupIds($sharedBy),
$this->groupManager->getUserGroupIds($sharedWith)
);
+
+ // optional excluded groups
+ $excludedGroups = $this->shareWithGroupMembersOnlyExcludeGroupsList();
+ $groups = array_diff($groups, $excludedGroups);
+
if (empty($groups)) {
$message_t = $this->l->t('Sharing is only allowed with group members');
throw new \Exception($message_t);
@@ -574,7 +582,7 @@ class Manager implements IManager {
// Identical share already exists
if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
- $message = $this->l->t('Sharing %s failed, because this item is already shared with user %s', [$share->getNode()->getName(), $share->getSharedWithDisplayName()]);
+ $message = $this->l->t('Sharing %s failed, because this item is already shared with the account %s', [$share->getNode()->getName(), $share->getSharedWithDisplayName()]);
throw new AlreadySharedException($message, $existingShare);
}
@@ -585,7 +593,7 @@ class Manager implements IManager {
$user = $this->userManager->get($share->getSharedWith());
if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
- $message = $this->l->t('Sharing %s failed, because this item is already shared with user %s', [$share->getNode()->getName(), $share->getSharedWithDisplayName()]);
+ $message = $this->l->t('Sharing %s failed, because this item is already shared with the account %s', [$share->getNode()->getName(), $share->getSharedWithDisplayName()]);
throw new AlreadySharedException($message, $existingShare);
}
}
@@ -609,7 +617,10 @@ class Manager implements IManager {
if ($this->shareWithGroupMembersOnly()) {
$sharedBy = $this->userManager->get($share->getSharedBy());
$sharedWith = $this->groupManager->get($share->getSharedWith());
- if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
+
+ // optional excluded groups
+ $excludedGroups = $this->shareWithGroupMembersOnlyExcludeGroupsList();
+ if (is_null($sharedWith) || in_array($share->getSharedWith(), $excludedGroups) || !$sharedWith->inGroup($sharedBy)) {
throw new \Exception('Sharing is only allowed within your own groups');
}
}
@@ -881,12 +892,12 @@ class Manager implements IManager {
* @param \DateTime|null $expiration
*/
protected function sendMailNotification(IL10N $l,
- $filename,
- $link,
- $initiator,
- $shareWith,
- \DateTime $expiration = null,
- $note = '') {
+ $filename,
+ $link,
+ $initiator,
+ $shareWith,
+ \DateTime $expiration = null,
+ $note = '') {
$initiatorUser = $this->userManager->get($initiator);
$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
@@ -1574,14 +1585,8 @@ class Manager implements IManager {
* @return bool
*/
public function checkPassword(IShare $share, $password) {
- $passwordProtected = $share->getShareType() !== IShare::TYPE_LINK
- || $share->getShareType() !== IShare::TYPE_EMAIL
- || $share->getShareType() !== IShare::TYPE_CIRCLE;
- if (!$passwordProtected) {
- //TODO maybe exception?
- return false;
- }
+ // if there is no password on the share object / passsword is null, there is nothing to check
if ($password === null || $share->getPassword() === null) {
return false;
}
@@ -1716,8 +1721,7 @@ class Manager implements IManager {
//Get node for the owner and correct the owner in case of external storage
$userFolder = $this->rootFolder->getUserFolder($owner);
if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
- $nodes = $userFolder->getById($path->getId());
- $path = array_shift($nodes);
+ $path = $userFolder->getFirstNodeById($path->getId());
if ($path === null || $path->getOwner() === null) {
return [];
}
@@ -1946,6 +1950,21 @@ class Manager implements IManager {
}
/**
+ * If shareWithGroupMembersOnly is enabled, return an optional
+ * list of groups that must be excluded from the principle of
+ * belonging to the same group.
+ *
+ * @return array
+ */
+ public function shareWithGroupMembersOnlyExcludeGroupsList() {
+ if (!$this->shareWithGroupMembersOnly()) {
+ return [];
+ }
+ $excludeGroups = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members_exclude_group_list', '');
+ return json_decode($excludeGroups, true) ?? [];
+ }
+
+ /**
* Check if users can share with groups
*
* @return bool
@@ -2025,37 +2044,7 @@ class Manager implements IManager {
* @return bool
*/
public function sharingDisabledForUser($userId) {
- if ($userId === null) {
- return false;
- }
-
- if (isset($this->sharingDisabledForUsersCache[$userId])) {
- return $this->sharingDisabledForUsersCache[$userId];
- }
-
- if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
- $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
- $excludedGroups = json_decode($groupsList);
- if (is_null($excludedGroups)) {
- $excludedGroups = explode(',', $groupsList);
- $newValue = json_encode($excludedGroups);
- $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
- }
- $user = $this->userManager->get($userId);
- $usersGroups = $this->groupManager->getUserGroupIds($user);
- if (!empty($usersGroups)) {
- $remainingGroups = array_diff($usersGroups, $excludedGroups);
- // if the user is only in groups which are disabled for sharing then
- // sharing is also disabled for the user
- if (empty($remainingGroups)) {
- $this->sharingDisabledForUsersCache[$userId] = true;
- return true;
- }
- }
- }
-
- $this->sharingDisabledForUsersCache[$userId] = false;
- return false;
+ return $this->shareDisableChecker->sharingDisabledForUser($userId);
}
/**
diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php
index 8c01d660915..dbf1b21dabe 100644
--- a/lib/private/Share20/ProviderFactory.php
+++ b/lib/private/Share20/ProviderFactory.php
@@ -41,6 +41,7 @@ use OCA\FederatedFileSharing\TokenHandler;
use OCA\ShareByMail\Settings\SettingsManager;
use OCA\ShareByMail\ShareByMailProvider;
use OCA\Talk\Share\RoomShareProvider;
+use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Defaults;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IServerContainer;
@@ -104,7 +105,7 @@ class ProviderFactory implements IProviderFactory {
$this->serverContainer->query(Defaults::class),
$this->serverContainer->getL10NFactory(),
$this->serverContainer->getURLGenerator(),
- $this->serverContainer->getConfig()
+ $this->serverContainer->query(ITimeFactory::class),
);
}
@@ -192,7 +193,7 @@ class ProviderFactory implements IProviderFactory {
$this->serverContainer->getUserManager(),
$this->serverContainer->getLazyRootFolder(),
$this->serverContainer->getL10N('sharebymail'),
- $this->serverContainer->getLogger(),
+ $this->serverContainer->get(LoggerInterface::class),
$this->serverContainer->getMailer(),
$this->serverContainer->getURLGenerator(),
$this->serverContainer->getActivityManager(),
diff --git a/lib/private/Share20/PublicShareTemplateFactory.php b/lib/private/Share20/PublicShareTemplateFactory.php
index 222f327496a..0e9642c306e 100644
--- a/lib/private/Share20/PublicShareTemplateFactory.php
+++ b/lib/private/Share20/PublicShareTemplateFactory.php
@@ -27,9 +27,9 @@ use Exception;
use OC\AppFramework\Bootstrap\Coordinator;
use OCA\Files_Sharing\DefaultPublicShareTemplateProvider;
use OCP\Server;
-use OCP\Share\IShare;
use OCP\Share\IPublicShareTemplateFactory;
use OCP\Share\IPublicShareTemplateProvider;
+use OCP\Share\IShare;
class PublicShareTemplateFactory implements IPublicShareTemplateFactory {
public function __construct(
diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php
index 0a50fa0ccfb..19b36cb60e8 100644
--- a/lib/private/Share20/Share.php
+++ b/lib/private/Share20/Share.php
@@ -29,8 +29,8 @@
*/
namespace OC\Share20;
-use OCP\Files\File;
use OCP\Files\Cache\ICacheEntry;
+use OCP\Files\File;
use OCP\Files\FileInfo;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
@@ -188,12 +188,12 @@ class Share implements IShare {
$userFolder = $this->rootFolder->getUserFolder($this->sharedBy);
}
- $nodes = $userFolder->getById($this->fileId);
- if (empty($nodes)) {
+ $node = $userFolder->getFirstNodeById($this->fileId);
+ if (!$node) {
throw new NotFoundException('Node for share not found, fileid: ' . $this->fileId);
}
- $this->node = $nodes[0];
+ $this->node = $node;
}
return $this->node;
@@ -211,12 +211,16 @@ class Share implements IShare {
/**
* @inheritdoc
*/
- public function getNodeId() {
+ public function getNodeId(): int {
if ($this->fileId === null) {
$this->fileId = $this->getNode()->getId();
}
- return $this->fileId;
+ if ($this->fileId === null) {
+ throw new NotFoundException("Share source not found");
+ } else {
+ return $this->fileId;
+ }
}
/**
diff --git a/lib/private/Share20/ShareDisableChecker.php b/lib/private/Share20/ShareDisableChecker.php
new file mode 100644
index 00000000000..9d0c2b8c2b4
--- /dev/null
+++ b/lib/private/Share20/ShareDisableChecker.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace OC\Share20;
+
+use OCP\Cache\CappedMemoryCache;
+use OCP\IConfig;
+use OCP\IGroupManager;
+use OCP\IUserManager;
+
+/**
+ * split of from the share manager to allow using it with minimal DI
+ */
+class ShareDisableChecker {
+ private CappedMemoryCache $sharingDisabledForUsersCache;
+
+ public function __construct(
+ private IConfig $config,
+ private IUserManager $userManager,
+ private IGroupManager $groupManager,
+ ) {
+ $this->sharingDisabledForUsersCache = new CappedMemoryCache();
+ }
+
+
+ /**
+ * @param ?string $userId
+ * @return bool
+ */
+ public function sharingDisabledForUser(?string $userId) {
+ if ($userId === null) {
+ return false;
+ }
+
+ if (isset($this->sharingDisabledForUsersCache[$userId])) {
+ return $this->sharingDisabledForUsersCache[$userId];
+ }
+
+ if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
+ $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
+ $excludedGroups = json_decode($groupsList);
+ if (is_null($excludedGroups)) {
+ $excludedGroups = explode(',', $groupsList);
+ $newValue = json_encode($excludedGroups);
+ $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
+ }
+ $user = $this->userManager->get($userId);
+ if (!$user) {
+ return false;
+ }
+ $usersGroups = $this->groupManager->getUserGroupIds($user);
+ if (!empty($usersGroups)) {
+ $remainingGroups = array_diff($usersGroups, $excludedGroups);
+ // if the user is only in groups which are disabled for sharing then
+ // sharing is also disabled for the user
+ if (empty($remainingGroups)) {
+ $this->sharingDisabledForUsersCache[$userId] = true;
+ return true;
+ }
+ }
+ }
+
+ $this->sharingDisabledForUsersCache[$userId] = false;
+ return false;
+ }
+}