From 3c20b50db2820fc0c6cfce70e4f9a08d526ad68d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 21 Feb 2024 17:53:22 +0100 Subject: [PATCH] fix(federation): Abstract away the OCS data access Signed-off-by: Joas Schilling --- .../TalkV1/Controller/ChatController.php | 61 ++++++------------- .../TalkV1/Controller/RoomController.php | 32 +--------- lib/Federation/Proxy/TalkV1/ProxyRequest.php | 23 +++++++ 3 files changed, 44 insertions(+), 72 deletions(-) diff --git a/lib/Federation/Proxy/TalkV1/Controller/ChatController.php b/lib/Federation/Proxy/TalkV1/Controller/ChatController.php index 2110f17c3efa..d405b024e2de 100644 --- a/lib/Federation/Proxy/TalkV1/Controller/ChatController.php +++ b/lib/Federation/Proxy/TalkV1/Controller/ChatController.php @@ -74,46 +74,37 @@ public function sendMessage(Room $room, Participant $participant, string $messag ], ); - try { - $content = $proxy->getBody(); - $responseData = json_decode($content, true, flags: JSON_THROW_ON_ERROR); - if (!is_array($responseData)) { - throw new \RuntimeException('JSON response is not an array'); - } - } catch (\Throwable $e) { - throw new CannotReachRemoteException('Error parsing JSON response', $e->getCode(), $e); - } - /** @var Http::STATUS_CREATED|Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND|Http::STATUS_REQUEST_ENTITY_TOO_LARGE|Http::STATUS_TOO_MANY_REQUESTS $statusCode */ - $statusCode = match ($proxy->getStatusCode()) { - Http::STATUS_CREATED, - Http::STATUS_BAD_REQUEST, - Http::STATUS_NOT_FOUND, - Http::STATUS_REQUEST_ENTITY_TOO_LARGE, - Http::STATUS_TOO_MANY_REQUESTS => $proxy->getStatusCode(), - default => $this->proxy->logUnexpectedStatusCode(__METHOD__, $proxy->getStatusCode()), - }; + $statusCode = $proxy->getStatusCode(); if ($statusCode !== Http::STATUS_CREATED) { + if (in_array($statusCode, [ + Http::STATUS_BAD_REQUEST, + Http::STATUS_NOT_FOUND, + Http::STATUS_REQUEST_ENTITY_TOO_LARGE, + Http::STATUS_TOO_MANY_REQUESTS, + ], true)) { + $statusCode = $this->proxy->logUnexpectedStatusCode(__METHOD__, $statusCode); + } return new DataResponse([], $statusCode); } + /** @var ?TalkChatMessageWithParent $data */ + $data = $this->proxy->getOCSData($proxy, [Http::STATUS_CREATED]); + if (!empty($data)) { + $data = $this->userConverter->convertAttendee($room, $data, 'actorType', 'actorId', 'actorDisplayName'); + } else { + $data = null; + } + $headers = []; if ($proxy->getHeader('X-Chat-Last-Common-Read')) { $headers['X-Chat-Last-Common-Read'] = (string) (int) $proxy->getHeader('X-Chat-Last-Common-Read'); } - /** @var ?TalkChatMessageWithParent $data */ - $data = $responseData['ocs']['data'] ?? null; - - if ($data !== null) { - /** @var ?TalkChatMessageWithParent $data */ - $data = $this->userConverter->convertAttendee($room, $data, 'actorType', 'actorId', 'actorDisplayName'); - } - return new DataResponse( $data, - $statusCode, + Http::STATUS_CREATED, $headers ); } @@ -139,22 +130,8 @@ public function mentions(Room $room, Participant $participant, string $search, i ], ); - if ($proxy->getStatusCode() !== Http::STATUS_OK) { - $this->proxy->logUnexpectedStatusCode(__METHOD__, $proxy->getStatusCode()); - } - - try { - $content = $proxy->getBody(); - $responseData = json_decode($content, true, flags: JSON_THROW_ON_ERROR); - if (!is_array($responseData)) { - throw new \RuntimeException('JSON response is not an array'); - } - } catch (\Throwable $e) { - throw new CannotReachRemoteException('Error parsing JSON response', $e->getCode(), $e); - } - /** @var TalkChatMentionSuggestion[] $data */ - $data = $responseData['ocs']['data'] ?? []; + $data = $this->proxy->getOCSData($proxy); $data = $this->userConverter->convertAttendees($room, $data, 'source', 'id', 'label'); // FIXME post-load status information diff --git a/lib/Federation/Proxy/TalkV1/Controller/RoomController.php b/lib/Federation/Proxy/TalkV1/Controller/RoomController.php index 8a5fa9fb7bc9..d5b8c4fe8959 100644 --- a/lib/Federation/Proxy/TalkV1/Controller/RoomController.php +++ b/lib/Federation/Proxy/TalkV1/Controller/RoomController.php @@ -68,22 +68,8 @@ public function getParticipants(Room $room, Participant $participant, bool $incl ], ); - if ($proxy->getStatusCode() !== Http::STATUS_OK) { - $this->proxy->logUnexpectedStatusCode(__METHOD__, $proxy->getStatusCode()); - } - - try { - $content = $proxy->getBody(); - $responseData = json_decode($content, true, flags: JSON_THROW_ON_ERROR); - if (!is_array($responseData)) { - throw new \RuntimeException('JSON response is not an array'); - } - } catch (\Throwable $e) { - throw new CannotReachRemoteException('Error parsing JSON response', $e->getCode(), $e); - } - /** @var TalkParticipant[] $data */ - $data = $responseData['ocs']['data'] ?? []; + $data = $this->proxy->getOCSData($proxy); // FIXME post-load status information /** @var TalkParticipant[] $data */ @@ -112,22 +98,8 @@ public function getCapabilities(Room $room, Participant $participant): DataRespo $room->getRemoteServer() . '/ocs/v2.php/apps/spreed/api/v4/room/' . $room->getRemoteToken() . '/capabilities', ); - if ($proxy->getStatusCode() !== Http::STATUS_OK) { - $this->proxy->logUnexpectedStatusCode(__METHOD__, $proxy->getStatusCode()); - } - - try { - $content = $proxy->getBody(); - $responseData = json_decode($content, true, flags: JSON_THROW_ON_ERROR); - if (!is_array($responseData)) { - throw new \RuntimeException('JSON response is not an array'); - } - } catch (\Throwable $e) { - throw new CannotReachRemoteException('Error parsing JSON response', $e->getCode(), $e); - } - /** @var TalkCapabilities|array $data */ - $data = $responseData['ocs']['data'] ?? []; + $data = $this->proxy->getOCSData($proxy); $headers = ['X-Nextcloud-Talk-Hash' => $proxy->getHeader('X-Nextcloud-Talk-Hash')]; diff --git a/lib/Federation/Proxy/TalkV1/ProxyRequest.php b/lib/Federation/Proxy/TalkV1/ProxyRequest.php index 3178b6081d8f..ed0a964e2dbc 100644 --- a/lib/Federation/Proxy/TalkV1/ProxyRequest.php +++ b/lib/Federation/Proxy/TalkV1/ProxyRequest.php @@ -158,4 +158,27 @@ public function post( throw $serverException; } } + + /** + * @param list $allowedStatusCodes + * @throws CannotReachRemoteException + */ + public function getOCSData(IResponse $response, array $allowedStatusCodes = [Http::STATUS_OK]): array { + if (!in_array($response->getStatusCode(), $allowedStatusCodes, true)) { + $this->logUnexpectedStatusCode(__METHOD__, $response->getStatusCode()); + } + + try { + $content = $response->getBody(); + $responseData = json_decode($content, true, flags: JSON_THROW_ON_ERROR); + if (!is_array($responseData)) { + throw new \RuntimeException('JSON response is not an array'); + } + } catch (\Throwable $e) { + $this->logger->error('Error parsing JSON response', ['exception' => $e]); + throw new CannotReachRemoteException('Error parsing JSON response', $e->getCode(), $e); + } + + return $responseData['ocs']['data'] ?? []; + } }