Skip to content
Open
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
21 changes: 20 additions & 1 deletion lib/Federation/Proxy/TalkV1/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
use OCA\Talk\Exceptions\CannotReachRemoteException;
use OCA\Talk\Federation\Proxy\TalkV1\ProxyRequest;
use OCA\Talk\Federation\Proxy\TalkV1\UserConverter;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Model\Session;
use OCA\Talk\Participant;
use OCA\Talk\ResponseDefinitions;
use OCA\Talk\Room;
use OCA\Talk\Service\ParticipantService;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;

Expand All @@ -27,6 +29,7 @@ class RoomController {
public function __construct(
protected ProxyRequest $proxy,
protected UserConverter $userConverter,
protected ParticipantService $participantService,
) {
}

Expand Down Expand Up @@ -91,9 +94,25 @@ public function joinFederatedRoom(Room $room, Participant $participant): DataRes

$headers = ['X-Nextcloud-Talk-Proxy-Hash' => $this->proxy->overwrittenRemoteTalkHash($proxy->getHeader('X-Nextcloud-Talk-Hash'))];

/** @var TalkRoom[] $data */
/** @var TalkRoom $data */
$data = $this->proxy->getOCSData($proxy);

// Heal permissions: The host server is the source of truth for permissions.
// If the host returns different permissions than what we have locally,
// update the local copy. This handles version mismatches where migrations
// on either side may have added/changed permission bits (e.g., REACT permission).
if ($statusCode === Http::STATUS_OK
&& isset($data['permissions'])
&& is_int($data['permissions'])
&& $data['permissions'] !== $participant->getAttendee()->getPermissions()) {
$this->participantService->updatePermissions(
$room,
$participant,
Attendee::PERMISSIONS_MODIFY_SET,
$data['permissions']
);
}

$data = $this->userConverter->convertAttendee($room, $data, 'actorType', 'actorId', 'displayName');

return new DataResponse($data, $statusCode, $headers);
Expand Down
11 changes: 11 additions & 0 deletions lib/Middleware/InjectionMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,17 @@ protected function checkPermission(AEnvironmentAwareOCSController $controller, s
throw new PermissionsException();
}

$room = $controller->getRoom();

// For federated conversations, skip local permission checks.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds a bit risky, while it might be true at the moment, it could be possible that in the future there would be local handling returning data.
I assume it's currently required for 34 servers that require reaction permissions when the federation host is 33 without it.
If that is the case we could simply add that to the react case for now:

if ($permission === RequirePermission::REACT && !($participant->getPermissions() & Attendee::PERMISSIONS_REACT)) {
		// Allow reacting with chat permission for now, in case the host server does not have split permissions yet.
		if (($participant->getPermissions() & Attendee::PERMISSIONS_CHAT) && $room instanceof Room && $room->isFederatedConversation()) {
			return;
		}

// The request will be proxied to the host server which will validate
// permissions authoritatively. This handles version mismatches where
// the local instance may have different permission bits than the host
// (e.g., after a migration that adds new permission types like REACT).
if ($room instanceof Room && $room->isFederatedConversation()) {
return;
}

if ($permission === RequirePermission::CHAT && !($participant->getPermissions() & Attendee::PERMISSIONS_CHAT)) {
throw new PermissionsException();
}
Expand Down
Loading