From 6aff0e1b1b895aeb539e630c990047edecd0b6b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 16 Jul 2024 14:12:54 +0200 Subject: wip: Update call flags by federated participants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- appinfo/routes/routesCallController.php | 2 + lib/Controller/CallController.php | 67 ++++++++++++++++++++++ .../Proxy/TalkV1/Controller/CallController.php | 34 +++++++++++ 3 files changed, 103 insertions(+) diff --git a/appinfo/routes/routesCallController.php b/appinfo/routes/routesCallController.php index 286e40f28..fb260175f 100644 --- a/appinfo/routes/routesCallController.php +++ b/appinfo/routes/routesCallController.php @@ -25,6 +25,8 @@ return [ ['name' => 'Call#sipDialOut', 'url' => '/api/{apiVersion}/call/{token}/dialout/{attendeeId}', 'verb' => 'POST', 'requirements' => $requirements], /** @see \OCA\Talk\Controller\CallController::updateCallFlags() */ ['name' => 'Call#updateCallFlags', 'url' => '/api/{apiVersion}/call/{token}', 'verb' => 'PUT', 'requirements' => $requirements], + /** @see \OCA\Talk\Controller\CallController::updateFederatedCallFlags() */ + ['name' => 'Call#updateFederatedCallFlags', 'url' => '/api/{apiVersion}/call/{token}/federation', 'verb' => 'PUT', 'requirements' => $requirements], /** @see \OCA\Talk\Controller\CallController::leaveCall() */ ['name' => 'Call#leaveCall', 'url' => '/api/{apiVersion}/call/{token}', 'verb' => 'DELETE', 'requirements' => $requirements], /** @see \OCA\Talk\Controller\CallController::leaveFederatedCall() */ diff --git a/lib/Controller/CallController.php b/lib/Controller/CallController.php index 1abdd50df..6a6e0117f 100644 --- a/lib/Controller/CallController.php +++ b/lib/Controller/CallController.php @@ -307,6 +307,7 @@ class CallController extends AEnvironmentAwareController { * 400: Updating in-call flags is not possible * 404: Call session not found */ + #[FederationSupported] #[PublicPage] #[RequireParticipant] public function updateCallFlags(int $flags): DataResponse { @@ -315,6 +316,17 @@ class CallController extends AEnvironmentAwareController { return new DataResponse([], Http::STATUS_NOT_FOUND); } + if ($this->room->isFederatedConversation()) { + /** @var \OCA\Talk\Federation\Proxy\TalkV1\Controller\CallController $proxy */ + $proxy = \OCP\Server::get(\OCA\Talk\Federation\Proxy\TalkV1\Controller\CallController::class); + $response = $proxy->updateCallFlags($this->room, $this->participant, $flags); + + if ($response->getStatus() === Http::STATUS_BAD_REQUEST + || $response->getStatus() === Http::STATUS_NOT_FOUND) { + return new DataResponse([], $response->getStatus()); + } + } + try { $this->participantService->updateCallFlags($this->room, $this->participant, $flags); } catch (\Exception $exception) { @@ -324,6 +336,61 @@ class CallController extends AEnvironmentAwareController { return new DataResponse(); } + // TODO RequireParticipant? + #[PublicPage] + #[BruteForceProtection(action: 'talkFederationAccess')] + #[BruteForceProtection(action: 'talkRoomToken')] + public function updateFederatedCallFlags(string $sessionId, int $flags): DataResponse { + $token = $this->request->getParam('token'); + + if (!$this->federationAuthenticator->isFederationRequest()) { + $response = new DataResponse(null, Http::STATUS_NOT_FOUND); + $response->throttle(['token' => $token, 'action' => 'talkRoomToken']); + return $response; + } + + try { + try { + $room = $this->federationAuthenticator->getRoom(); + } catch (RoomNotFoundException) { + $room = $this->manager->getRoomByRemoteAccess( + $token, + Attendee::ACTOR_FEDERATED_USERS, + $this->federationAuthenticator->getCloudId(), + $this->federationAuthenticator->getAccessToken(), + ); + } + + try { + $participant = $this->federationAuthenticator->getParticipant(); + } catch (ParticipantNotFoundException) { + $participant = $this->participantService->getParticipantBySession( + $room, + $sessionId, + ); + $this->federationAuthenticator->authenticated($room, $participant); + } + } catch (RoomNotFoundException|ParticipantNotFoundException $e) { + $response = new DataResponse(null, Http::STATUS_NOT_FOUND); + $response->throttle(['token' => $token, 'action' => 'talkFederationAccess']); + return $response; + } + + // TODO needed? + $session = $participant->getSession(); + if (!$session instanceof Session) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + try { + $this->participantService->updateCallFlags($room, $participant, $flags); + } catch (\Exception $exception) { + return new DataResponse([], Http::STATUS_BAD_REQUEST); + } + + return new DataResponse(); + } + /** * Leave a call * diff --git a/lib/Federation/Proxy/TalkV1/Controller/CallController.php b/lib/Federation/Proxy/TalkV1/Controller/CallController.php index 8ca0c5681..04d146b77 100644 --- a/lib/Federation/Proxy/TalkV1/Controller/CallController.php +++ b/lib/Federation/Proxy/TalkV1/Controller/CallController.php @@ -65,6 +65,40 @@ class CallController { return new DataResponse([], $statusCode); } + /** + * @see \OCA\Talk\Controller\RoomController::updateFederatedCallFlags() + * + * @return DataResponse, array{}> + * @throws CannotReachRemoteException + * + * 200: In-call flags updated successfully for federated user + * 400: Updating in-call flags is not possible + * 404: Room not found + */ + public function updateFederatedCallFlags(Room $room, Participant $participant, int $flags): DataResponse { + $options = [ + 'flags' => $flags, + ]; + if ($participant->getSession() instanceof Session) { + $options['sessionId'] = $participant->getSession()->getSessionId(); + } + + $proxy = $this->proxy->put( + $participant->getAttendee()->getInvitedCloudId(), + $participant->getAttendee()->getAccessToken(), + $room->getRemoteServer() . '/ocs/v2.php/apps/spreed/api/v4/call/' . $room->getRemoteToken() . '/federation', + $options, + ); + + $statusCode = $proxy->getStatusCode(); + if (!in_array($statusCode, [Http::STATUS_OK, Http::STATUS_BAD_REQUEST, Http::STATUS_NOT_FOUND], true)) { + $this->proxy->logUnexpectedStatusCode(__METHOD__, $proxy->getStatusCode()); + throw new CannotReachRemoteException(); + } + + return new DataResponse([], $statusCode); + } + public function leaveFederatedCall(Room $room, Participant $participant): DataResponse { $options = []; if ($participant->getSession() instanceof Session) { -- cgit v1.2.3