Skip to content

Commit

Permalink
fix(federation): Abstract away the OCS data access
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <coding@schilljs.com>
  • Loading branch information
nickvergessen committed Feb 22, 2024
1 parent acf0c0b commit 3c20b50
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 72 deletions.
61 changes: 19 additions & 42 deletions lib/Federation/Proxy/TalkV1/Controller/ChatController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
}
Expand All @@ -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
Expand Down
32 changes: 2 additions & 30 deletions lib/Federation/Proxy/TalkV1/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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<empty> $data */
$data = $responseData['ocs']['data'] ?? [];
$data = $this->proxy->getOCSData($proxy);

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

Expand Down
23 changes: 23 additions & 0 deletions lib/Federation/Proxy/TalkV1/ProxyRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,27 @@ public function post(
throw $serverException;
}
}

/**
* @param list<int> $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'] ?? [];
}
}

0 comments on commit 3c20b50

Please sign in to comment.