diff options
author | Côme Chilliet <come.chilliet@nextcloud.com> | 2024-09-03 14:56:26 +0200 |
---|---|---|
committer | Côme Chilliet <91878298+come-nc@users.noreply.github.com> | 2024-09-09 10:46:29 +0200 |
commit | e184784f86f6f3c176a29a2aeec2588d357ebf08 (patch) | |
tree | 146828420b82f9903dcbd87585f5ed1fbf16e7d1 | |
parent | 4c9104ef08e54a83754f3add425b71df4f43cbec (diff) | |
download | nextcloud-server-e184784f86f6f3c176a29a2aeec2588d357ebf08.tar.gz nextcloud-server-e184784f86f6f3c176a29a2aeec2588d357ebf08.zip |
fix: Remove duplicated code in \OC\OCS\ApiHelper, use Response classes instead
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
-rw-r--r-- | lib/private/OCS/ApiHelper.php | 108 | ||||
-rw-r--r-- | ocs/v1.php | 38 |
2 files changed, 35 insertions, 111 deletions
diff --git a/lib/private/OCS/ApiHelper.php b/lib/private/OCS/ApiHelper.php index 845b3954719..04d6983db98 100644 --- a/lib/private/OCS/ApiHelper.php +++ b/lib/private/OCS/ApiHelper.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,24 +10,29 @@ namespace OC\OCS; -use OCP\AppFramework\Http; +use OC\AppFramework\OCS\V1Response; +use OC\AppFramework\OCS\V2Response; +use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; use OCP\IRequest; use OCP\Server; -use XMLWriter; class ApiHelper { /** - * respond to a call - * @param \OC\OCS\Result $result - * @param string $format the format xml|json + * Respond to a call * @psalm-taint-escape html */ - public static function respond(Result $result, string $format = 'xml'): void { + public static function respond(int $statusCode, string $statusMessage, array $headers = []): void { $request = Server::get(IRequest::class); + $format = $request->getParam('format', 'xml'); + if (self::isV2($request)) { + $response = new V2Response(new DataResponse([], $statusCode, $headers), $format, $statusMessage); + } else { + $response = new V1Response(new DataResponse([], $statusCode, $headers), $format, $statusMessage); + } // Send 401 headers if unauthorised - if ($result->getStatusCode() === OCSController::RESPOND_UNAUTHORISED) { + if ($response->getOCSStatus() === OCSController::RESPOND_UNAUTHORISED) { // If request comes from JS return dummy auth request if ($request->getHeader('X-Requested-With') === 'XMLHttpRequest') { header('WWW-Authenticate: DummyBasic realm="Authorisation Required"'); @@ -35,55 +42,22 @@ class ApiHelper { http_response_code(401); } - foreach ($result->getHeaders() as $name => $value) { + foreach ($response->getHeaders() as $name => $value) { header($name . ': ' . $value); } - $meta = $result->getMeta(); - $data = $result->getData(); - if (self::isV2($request)) { - $statusCode = self::mapStatusCodes($result->getStatusCode()); - if (!is_null($statusCode)) { - $meta['statuscode'] = $statusCode; - http_response_code($statusCode); - } - } + http_response_code($response->getStatus()); self::setContentType($format); - $body = self::renderResult($format, $meta, $data); + $body = $response->render(); echo $body; } - private static function toXML(iterable $array, XMLWriter $writer): void { - foreach ($array as $k => $v) { - if ($k[0] === '@') { - $writer->writeAttribute(substr($k, 1), $v); - continue; - } elseif (is_numeric($k)) { - $k = 'element'; - } - if (is_array($v)) { - $writer->startElement($k); - self::toXML($v, $writer); - $writer->endElement(); - } else { - $writer->writeElement($k, $v); - } - } - } - - public static function requestedFormat(): string { - $formats = ['json', 'xml']; - - $format = (isset($_GET['format']) && is_string($_GET['format']) && in_array($_GET['format'], $formats)) ? $_GET['format'] : 'xml'; - return $format; - } - /** * Based on the requested format the response content type is set */ public static function setContentType(?string $format = null): void { - $format = is_null($format) ? self::requestedFormat() : $format; + $format ??= Server::get(IRequest::class)->getParam('format', 'xml'); if ($format === 'xml') { header('Content-type: text/xml; charset=UTF-8'); return; @@ -102,50 +76,4 @@ class ApiHelper { return str_ends_with($script, '/ocs/v2.php'); } - - public static function mapStatusCodes(int $sc): ?int { - switch ($sc) { - case OCSController::RESPOND_NOT_FOUND: - return Http::STATUS_NOT_FOUND; - case OCSController::RESPOND_SERVER_ERROR: - return Http::STATUS_INTERNAL_SERVER_ERROR; - case OCSController::RESPOND_UNKNOWN_ERROR: - return Http::STATUS_INTERNAL_SERVER_ERROR; - case OCSController::RESPOND_UNAUTHORISED: - // already handled for v1 - return null; - case 100: - return Http::STATUS_OK; - } - // any 2xx, 4xx and 5xx will be used as is - if ($sc >= 200 && $sc < 600) { - return $sc; - } - - return Http::STATUS_BAD_REQUEST; - } - - /** - * @param string $format - * @return string - */ - public static function renderResult(string $format, $meta, $data): string { - $response = [ - 'ocs' => [ - 'meta' => $meta, - 'data' => $data, - ], - ]; - if ($format == 'json') { - return json_encode($response, JSON_HEX_TAG); - } - - $writer = new XMLWriter(); - $writer->openMemory(); - $writer->setIndent(true); - $writer->startDocument(); - self::toXML($response, $writer); - $writer->endDocument(); - return $writer->outputMemory(true); - } } diff --git a/ocs/v1.php b/ocs/v1.php index 40a64f823fa..7aad1526d22 100644 --- a/ocs/v1.php +++ b/ocs/v1.php @@ -1,29 +1,33 @@ <?php + +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ + require_once __DIR__ . '/../lib/versioncheck.php'; require_once __DIR__ . '/../lib/base.php'; use OC\OCS\ApiHelper; +use OCP\AppFramework\Http; +use OCP\AppFramework\OCSController; +use OCP\Security\Bruteforce\MaxDelayReached; +use OCP\Util; +use Psr\Log\LoggerInterface; +use Symfony\Component\Routing\Exception\MethodNotAllowedException; +use Symfony\Component\Routing\Exception\ResourceNotFoundException; -if (\OCP\Util::needUpgrade() +if (Util::needUpgrade() || \OC::$server->getConfig()->getSystemValueBool('maintenance')) { // since the behavior of apps or remotes are unpredictable during // an upgrade, return a 503 directly - http_response_code(503); - header('X-Nextcloud-Maintenance-Mode: 1'); - $response = new \OC\OCS\Result(null, 503, 'Service unavailable'); - ApiHelper::respond($response, ApiHelper::requestedFormat()); + ApiHelper::respond(503, 'Service unavailable', ['X-Nextcloud-Maintenance-Mode' => '1']); exit; } -use OCP\Security\Bruteforce\MaxDelayReached; -use Psr\Log\LoggerInterface; -use Symfony\Component\Routing\Exception\MethodNotAllowedException; -use Symfony\Component\Routing\Exception\ResourceNotFoundException; /* * Try the appframework routes @@ -44,27 +48,19 @@ try { OC::$server->get(\OC\Route\Router::class)->match('/ocsapp'.\OC::$server->getRequest()->getRawPathInfo()); } catch (MaxDelayReached $ex) { - $format = \OC::$server->getRequest()->getParam('format', 'xml'); - ApiHelper::respond(new \OC\OCS\Result(null, OCP\AppFramework\Http::STATUS_TOO_MANY_REQUESTS, $ex->getMessage()), $format); + ApiHelper::respond(Http::STATUS_TOO_MANY_REQUESTS, $ex->getMessage()); } catch (ResourceNotFoundException $e) { - ApiHelper::setContentType(); - - $format = \OC::$server->getRequest()->getParam('format', 'xml'); $txt = 'Invalid query, please check the syntax. API specifications are here:' .' http://www.freedesktop.org/wiki/Specifications/open-collaboration-services.'."\n"; - ApiHelper::respond(new \OC\OCS\Result(null, \OCP\AppFramework\OCSController::RESPOND_NOT_FOUND, $txt), $format); + ApiHelper::respond(OCSController::RESPOND_NOT_FOUND, $txt); } catch (MethodNotAllowedException $e) { ApiHelper::setContentType(); http_response_code(405); -} catch (\OC\OCS\Exception $ex) { - ApiHelper::respond($ex->getResult(), ApiHelper::requestedFormat()); } catch (\OC\User\LoginException $e) { - ApiHelper::respond(new \OC\OCS\Result(null, \OCP\AppFramework\OCSController::RESPOND_UNAUTHORISED, 'Unauthorised')); + ApiHelper::respond(OCSController::RESPOND_UNAUTHORISED, 'Unauthorised'); } catch (\Exception $e) { \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]); - ApiHelper::setContentType(); - $format = \OC::$server->getRequest()->getParam('format', 'xml'); $txt = 'Internal Server Error'."\n"; try { if (\OC::$server->getSystemConfig()->getValue('debug', false)) { @@ -73,5 +69,5 @@ try { } catch (\Throwable $e) { // Just to be save } - ApiHelper::respond(new \OC\OCS\Result(null, \OCP\AppFramework\OCSController::RESPOND_SERVER_ERROR, $txt), $format); + ApiHelper::respond(OCSController::RESPOND_SERVER_ERROR, $txt); } |