mirror of
https://github.com/nextcloud/server.git
synced 2026-02-03 20:41:22 -05:00
87 lines
2.9 KiB
PHP
87 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\CloudFederationAPI\Controller;
|
|
|
|
use JsonException;
|
|
use OCP\AppFramework\Controller;
|
|
use OCP\AppFramework\Http;
|
|
use OCP\AppFramework\Http\Attribute\BruteForceProtection;
|
|
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
|
use OCP\AppFramework\Http\Attribute\PublicPage;
|
|
use OCP\AppFramework\Http\JSONResponse;
|
|
use OCP\AppFramework\Http\Response;
|
|
use OCP\EventDispatcher\IEventDispatcher;
|
|
use OCP\IRequest;
|
|
use OCP\OCM\Events\OCMEndpointRequestEvent;
|
|
use OCP\OCM\Exceptions\OCMArgumentException;
|
|
use OCP\OCM\IOCMDiscoveryService;
|
|
use OCP\Security\Signature\Exceptions\IncomingRequestException;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class OCMRequestController extends Controller {
|
|
public function __construct(
|
|
string $appName,
|
|
IRequest $request,
|
|
private readonly IEventDispatcher $eventDispatcher,
|
|
private readonly IOCMDiscoveryService $ocmDiscoveryService,
|
|
private readonly LoggerInterface $logger,
|
|
) {
|
|
parent::__construct($appName, $request);
|
|
}
|
|
|
|
/**
|
|
* Method will catch any request done to /ocm/[...] and will broadcast an event.
|
|
* The first parameter of the remaining subpath (post-/ocm/) is defined as
|
|
* capability and should be used by listeners to filter incoming requests.
|
|
*
|
|
* @see OCMEndpointRequestEvent
|
|
* @see OCMEndpointRequestEvent::getArgs
|
|
*
|
|
* @param string $ocmPath
|
|
* @return Response
|
|
* @throws OCMArgumentException
|
|
*/
|
|
#[NoCSRFRequired]
|
|
#[PublicPage]
|
|
#[BruteForceProtection(action: 'receiveOcmRequest')]
|
|
public function manageOCMRequests(string $ocmPath): Response {
|
|
if (!mb_check_encoding($ocmPath, 'UTF-8')) {
|
|
throw new OCMArgumentException('path is not UTF-8');
|
|
}
|
|
|
|
try {
|
|
// if request is signed and well signed, no exceptions are thrown
|
|
// if request is not signed and host is known for not supporting signed request, no exceptions are thrown
|
|
$signedRequest = $this->ocmDiscoveryService->getIncomingSignedRequest();
|
|
} catch (IncomingRequestException $e) {
|
|
$this->logger->warning('incoming ocm request exception', ['exception' => $e]);
|
|
return new JSONResponse(['message' => $e->getMessage(), 'validationErrors' => []], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
// assuming that ocm request contains a json array
|
|
$payload = $signedRequest?->getBody() ?? file_get_contents('php://input');
|
|
try {
|
|
$payload = ($payload) ? json_decode($payload, true, 512, JSON_THROW_ON_ERROR) : null;
|
|
} catch (JsonException $e) {
|
|
$this->logger->debug('json decode error', ['exception' => $e]);
|
|
$payload = null;
|
|
}
|
|
|
|
$event = new OCMEndpointRequestEvent(
|
|
$this->request->getMethod(),
|
|
preg_replace('@/+@', '/', $ocmPath),
|
|
$payload,
|
|
$signedRequest?->getOrigin()
|
|
);
|
|
$this->eventDispatcher->dispatchTyped($event);
|
|
|
|
return $event->getResponse() ?? new Response(Http::STATUS_NOT_FOUND);
|
|
}
|
|
}
|