diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index 9dd862abb3175..d455bd4c46613 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -53,6 +53,7 @@ use OCP\Mail\IMailer; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IAttributes; +use OCP\Share\IManager; use OCP\Share\IShare; use OCP\Share\IShareProvider; use function str_starts_with; @@ -94,15 +95,17 @@ class DefaultShareProvider implements IShareProvider { private $config; 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, + IConfig $config, + private IManager $shareManager, + ) { $this->dbConn = $connection; $this->userManager = $userManager; $this->groupManager = $groupManager; @@ -1302,6 +1305,7 @@ public function groupDeleted($gid) { * * @param string $uid * @param string $gid + * @return void */ public function userDeletedFromGroup($uid, $gid) { /* @@ -1313,7 +1317,7 @@ public function userDeletedFromGroup($uid, $gid) { ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))) ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid))); - $cursor = $qb->execute(); + $cursor = $qb->executeQuery(); $ids = []; while ($row = $cursor->fetch()) { $ids[] = (int)$row['id']; @@ -1330,7 +1334,45 @@ public function userDeletedFromGroup($uid, $gid) { ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))) ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid))) ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY))); - $qb->execute(); + $qb->executeStatement(); + } + } + + if ($this->shareManager->shareWithGroupMembersOnly()) { + $user = $this->userManager->get($uid); + if ($user === null) { + return; + } + $userGroups = $this->groupManager->getUserGroupIds($user); + + // Delete user shares received by the user from users in the group. + $userReceivedShares = $this->shareManager->getSharedWith($uid, IShare::TYPE_USER, null, -1); + foreach ($userReceivedShares as $share) { + $owner = $this->userManager->get($share->getSharedBy()); + if ($owner === null) { + continue; + } + $ownerGroups = $this->groupManager->getUserGroupIds($owner); + $mutualGroups = array_intersect($userGroups, $ownerGroups); + + if (count($mutualGroups) === 0) { + $this->shareManager->deleteShare($share); + } + } + + // Delete user shares from the user to users in the group. + $userEmittedShares = $this->shareManager->getSharesBy($uid, IShare::TYPE_USER, null, true, -1); + foreach ($userEmittedShares as $share) { + $recipient = $this->userManager->get($share->getSharedWith()); + if ($recipient === null) { + continue; + } + $recipientGroups = $this->groupManager->getUserGroupIds($recipient); + $mutualGroups = array_intersect($userGroups, $recipientGroups); + + if (count($mutualGroups) === 0) { + $this->shareManager->deleteShare($share); + } } } } diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php index 6abfb372a4d1e..f861eafda7f0f 100644 --- a/lib/private/Share20/ProviderFactory.php +++ b/lib/private/Share20/ProviderFactory.php @@ -104,7 +104,8 @@ protected function defaultShareProvider() { $this->serverContainer->query(Defaults::class), $this->serverContainer->getL10NFactory(), $this->serverContainer->getURLGenerator(), - $this->serverContainer->getConfig() + $this->serverContainer->getConfig(), + $this->serverContainer->get(IManager::class), ); } diff --git a/tests/lib/Share20/DefaultShareProviderTest.php b/tests/lib/Share20/DefaultShareProviderTest.php index 0a6f106a5dba9..75acae1ffcaee 100644 --- a/tests/lib/Share20/DefaultShareProviderTest.php +++ b/tests/lib/Share20/DefaultShareProviderTest.php @@ -39,6 +39,7 @@ use OCP\IUserManager; use OCP\L10N\IFactory; use OCP\Mail\IMailer; +use OCP\Share\IManager as IShareManager; use OCP\Share\IShare; use PHPUnit\Framework\MockObject\MockObject; @@ -82,6 +83,9 @@ class DefaultShareProviderTest extends \Test\TestCase { /** @var IConfig|MockObject */ protected $config; + /** @var IShareManager&MockObject */ + protected $shareManager; + protected function setUp(): void { $this->dbConn = \OC::$server->getDatabaseConnection(); $this->userManager = $this->createMock(IUserManager::class); @@ -93,6 +97,7 @@ protected function setUp(): void { $this->defaults = $this->getMockBuilder(Defaults::class)->disableOriginalConstructor()->getMock(); $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->config = $this->createMock(IConfig::class); + $this->shareManager = $this->createMock(IShareManager::class); $this->userManager->expects($this->any())->method('userExists')->willReturn(true); @@ -108,7 +113,8 @@ protected function setUp(): void { $this->defaults, $this->l10nFactory, $this->urlGenerator, - $this->config + $this->config, + $this->shareManager, ); } @@ -132,8 +138,8 @@ protected function tearDown(): void { * @return int */ private function addShareToDB($shareType, $sharedWith, $sharedBy, $shareOwner, - $itemType, $fileSource, $fileTarget, $permissions, $token, $expiration, - $parent = null) { + $itemType, $fileSource, $fileTarget, $permissions, $token, $expiration, + $parent = null) { $qb = $this->dbConn->getQueryBuilder(); $qb->insert('share'); @@ -469,7 +475,8 @@ public function testDeleteSingleShare() { $this->defaults, $this->l10nFactory, $this->urlGenerator, - $this->config + $this->config, + $this->shareManager, ]) ->setMethods(['getShareById']) ->getMock(); @@ -564,7 +571,8 @@ public function testDeleteGroupShareWithUserGroupShares() { $this->defaults, $this->l10nFactory, $this->urlGenerator, - $this->config + $this->config, + $this->shareManager, ]) ->setMethods(['getShareById']) ->getMock(); @@ -2524,7 +2532,8 @@ public function testGetSharesInFolder() { $this->defaults, $this->l10nFactory, $this->urlGenerator, - $this->config + $this->config, + $this->shareManager, ); $password = md5(time()); @@ -2622,7 +2631,8 @@ public function testGetAccessListNoCurrentAccessRequired() { $this->defaults, $this->l10nFactory, $this->urlGenerator, - $this->config + $this->config, + $this->shareManager, ); $u1 = $userManager->createUser('testShare1', 'test'); @@ -2718,7 +2728,8 @@ public function testGetAccessListCurrentAccessRequired() { $this->defaults, $this->l10nFactory, $this->urlGenerator, - $this->config + $this->config, + $this->shareManager, ); $u1 = $userManager->createUser('testShare1', 'test');