Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions lib/Service/ParticipantService.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

namespace OCA\Talk\Service;

use OC\User\LazyUser;
use OCA\Circles\CirclesManager;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Member;
use OCA\Files_Sharing\Event\UserShareAccessUpdatedEvent;
use OCA\Talk\CachePrefix;
use OCA\Talk\Chat\ChatManager;
use OCA\Talk\Config;
Expand Down Expand Up @@ -676,6 +678,13 @@ public function addUsers(Room $room, array $participants, ?IUser $addedBy = null
try {
$this->attendeeMapper->insert($attendee);

// Clear share access cache
if ($attendee->getActorType() === Attendee::ACTOR_USERS) {
$user = new LazyUser($attendee->getActorId(), $this->userManager);
$event = new UserShareAccessUpdatedEvent($user);
$this->dispatcher->dispatchTyped($event);
}

if ($attendee->getActorType() === Attendee::ACTOR_FEDERATED_USERS) {
$response = $this->backendNotifier->sendRemoteShare((string)$attendee->getId(), $attendee->getAccessToken(), $attendee->getActorId(), $addedBy, 'user', $room, $this->getHighestPermissionAttendee($room));
if (!$response) {
Expand Down Expand Up @@ -1103,6 +1112,13 @@ public function removeAttendee(Room $room, Participant $participant, string $rea
$this->sessionMapper->deleteByAttendeeId($participant->getAttendee()->getId());
$this->attendeeMapper->delete($participant->getAttendee());

if ($participant->getAttendee()->getActorType() === Attendee::ACTOR_USERS) {
// Clear share access cache
$user = new LazyUser($participant->getAttendee()->getActorId(), $this->userManager);
$event = new UserShareAccessUpdatedEvent($user);
$this->dispatcher->dispatchTyped($event);
}

$event = new AttendeeRemovedEvent($room, $participant->getAttendee(), $reason, $sessions);
$this->dispatcher->dispatchTyped($event);

Expand Down Expand Up @@ -1251,6 +1267,10 @@ public function removeUser(Room $room, IUser $user, string $reason): void {

$this->attendeeMapper->delete($attendee);

// Clear share access cache
$event = new UserShareAccessUpdatedEvent($user);
$this->dispatcher->dispatchTyped($event);

$attendeeEvent = new AttendeeRemovedEvent($room, $attendee, $reason, $sessions);
$this->dispatcher->dispatchTyped($attendeeEvent);

Expand Down
14 changes: 14 additions & 0 deletions lib/Service/RoomService.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
namespace OCA\Talk\Service;

use InvalidArgumentException;
use OC\User\LazyUser;
use OCA\Files_Sharing\Event\UserShareAccessUpdatedEvent;
use OCA\Talk\Config;
use OCA\Talk\Events\AParticipantModifiedEvent;
use OCA\Talk\Events\ARoomModifiedEvent;
Expand Down Expand Up @@ -63,6 +65,7 @@
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Log\Audit\CriticalActionPerformedEvent;
use OCP\Security\Events\ValidatePasswordPolicyEvent;
use OCP\Security\IHasher;
Expand All @@ -89,6 +92,7 @@ public function __construct(
protected LoggerInterface $logger,
protected IL10N $l10n,
protected IManager $calendarManager,
protected IUserManager $userManager,
) {
}

Expand Down Expand Up @@ -1440,12 +1444,22 @@ public function deleteRoom(Room $room): void {
$delete->executeStatement();
}

// Get user ids for clearing the share access cache after deleting
$userIds = $this->participantService->getParticipantUserIds($room);

// Delete attendees
$delete = $this->db->getQueryBuilder();
$delete->delete('talk_attendees')
->where($delete->expr()->eq('room_id', $delete->createNamedParameter($room->getId(), IQueryBuilder::PARAM_INT)));
$delete->executeStatement();

// Clear share access cache
foreach ($userIds as $userId) {
$user = new LazyUser($userId, $this->userManager);
$event = new UserShareAccessUpdatedEvent($user);
$this->dispatcher->dispatchTyped($event);
}

// Delete room
$delete = $this->db->getQueryBuilder();
$delete->delete('talk_rooms')
Expand Down
34 changes: 33 additions & 1 deletion lib/Share/RoomShareProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace OCA\Talk\Share;

use OC\Files\Cache\Cache;
use OC\User\LazyUser;
use OCA\Talk\Events\BeforeDuplicateShareSentEvent;
use OCA\Talk\Exceptions\ParticipantNotFoundException;
use OCA\Talk\Exceptions\RoomNotFoundException;
Expand All @@ -27,13 +28,16 @@
use OCP\Files\Node;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Security\ISecureRandom;
use OCP\Share\Exceptions\GenericShareException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager as IShareManager;
use OCP\Share\IPartialShareProvider;
use OCP\Share\IShare;
use OCP\Share\IShareProvider;
use OCP\Share\IShareProviderGetUsers;

/**
* Share provider for room shares.
Expand All @@ -45,7 +49,7 @@
* Like in group shares, a recipient can move or delete a share without
* modifying the share for the other users in the room.
*/
class RoomShareProvider implements IShareProvider, IPartialShareProvider {
class RoomShareProvider implements IShareProvider, IPartialShareProvider, IShareProviderGetUsers {
use TTransactional;
// Special share type for user modified room shares
public const SHARE_TYPE_USERROOM = 11;
Expand All @@ -66,6 +70,7 @@ public function __construct(
protected ITimeFactory $timeFactory,
private IL10N $l,
private IMimeTypeLoader $mimeTypeLoader,
private IUserManager $userManager,
) {
$this->sharesByIdCache = new CappedMemoryCache();
}
Expand Down Expand Up @@ -1230,4 +1235,31 @@ public function getAllShares(): iterable {
}
$cursor->closeCursor();
}

#[\Override]
public function getUsersForShare(IShare $share): iterable {
if ($share->getShareType() === self::SHARE_TYPE_USERROOM) {
// User record for a share, user is the shared_with
return [new LazyUser($share->getSharedWith(), $this->userManager)];
}

if ($share->getShareType() !== IShare::TYPE_ROOM) {
return [];
}

// Room share entry, shared_with is the conversation token
try {
$room = $this->manager->getRoomByToken($share->getSharedWith());
} catch (RoomNotFoundException) {
return [];
}

if ($room->getType() === Room::TYPE_ONE_TO_ONE) {
return array_map(fn (string $userId): IUser => new LazyUser($userId, $this->userManager), json_decode($room->getName(), true));
}

// Get all user ids for the room
$userIds = $this->participantService->getParticipantUserIds($room);
return array_map(fn (string $userId): IUser => new LazyUser($userId, $this->userManager), $userIds);
}
}
2 changes: 2 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@
<file name="tests/stubs/oc_hooks_emitter.php" />
<file name="tests/stubs/oc_http_client_response.php" />
<file name="tests/stubs/oc_memcache.php" />
<file name="tests/stubs/oc_user_lazyuser.php" />
<file name="tests/stubs/oca_circles.php" />
<file name="tests/stubs/oca_federation_trustedservers.php" />
<file name="tests/stubs/oca_dav_caldav_timezoneservice.php" />
<file name="tests/stubs/oca_files_events.php" />
<file name="tests/stubs/oca_files_sharing_events.php" />
<file name="tests/stubs/GuzzleHttp_Exception_ClientException.php" />
<file name="tests/stubs/GuzzleHttp_Exception_ConnectException.php" />
<file name="tests/stubs/GuzzleHttp_Exception_ServerException.php" />
Expand Down
5 changes: 4 additions & 1 deletion tests/integration/features/conversation-2/files.feature
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ Feature: conversation/files
And add user "participant2" to team "team1"
And user "participant1" shares "welcome.txt" with team "team1" with OCS 100
When user "participant1" gets the room for path "welcome.txt" with 200 (v1)
And user "participant2" gets the room for path "welcome (2).txt" with 200 (v1)
And user "participant2" gets the DAV properties for "/"
# Temporary disabled because it breaks as circles / Teams does not implement
# OCP\Share\IShareProviderGetUsers yet.
# And user "participant2" gets the room for path "welcome (2).txt" with 200 (v1)
Then user "participant1" is not participant of room "file welcome (2).txt room" (v4)
And user "participant2" is not participant of room "file welcome (2).txt room" (v4)

Expand Down
5 changes: 5 additions & 0 deletions tests/php/Service/RoomServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Security\IHasher;
use OCP\Server;
use OCP\Share\IManager as IShareManager;
Expand All @@ -52,6 +53,7 @@ class RoomServiceTest extends TestCase {
protected LoggerInterface&MockObject $logger;
protected IL10N&MockObject $l10n;
protected IManager $calendarManager;
protected IUserManager&MockObject $userManager;
protected EmojiService $emojiService;
protected ?RoomService $service = null;

Expand All @@ -70,6 +72,7 @@ public function setUp(): void {
$this->l10n = $this->createMock(IL10N::class);
$this->emojiService = Server::get(EmojiService::class);
$this->calendarManager = $this->createMock(IManager::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->service = new RoomService(
$this->manager,
$this->participantService,
Expand All @@ -84,6 +87,7 @@ public function setUp(): void {
$this->logger,
$this->l10n,
$this->calendarManager,
$this->userManager,
);
}

Expand Down Expand Up @@ -340,6 +344,7 @@ public function testVerifyPassword(): void {
$this->logger,
$this->l10n,
$this->calendarManager,
$this->userManager,
);

$room = new Room(
Expand Down
17 changes: 17 additions & 0 deletions tests/stubs/oc_user_lazyuser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\User;

use OCP\IUser;
use OCP\IUserManager;
use OCP\UserInterface;

class LazyUser implements IUser {

public function __construct(string $uid, IUserManager $userManager, ?string $displayName = null, ?UserInterface $backend = null) {
}
}
16 changes: 16 additions & 0 deletions tests/stubs/oca_files_sharing_events.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Files_Sharing\Event {

use OCP\EventDispatcher\Event;
use OCP\IUser;

class UserShareAccessUpdatedEvent extends Event {
public function __construct(IUser $user) {
}
}
}
Loading