From 987840592e6d15c8031f06691d28576757dd2fb1 Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Thu, 5 Sep 2024 16:17:32 +0200 Subject: fix(dav): Always respond custom error page on exceptions Signed-off-by: Louis Chemineau --- apps/dav/composer/composer/autoload_classmap.php | 2 +- apps/dav/composer/composer/autoload_static.php | 2 +- apps/dav/lib/Connector/Sabre/ServerFactory.php | 6 +- apps/dav/lib/Files/BrowserErrorPagePlugin.php | 118 -------------------- apps/dav/lib/Files/ErrorPagePlugin.php | 124 +++++++++++++++++++++ apps/dav/lib/Server.php | 6 +- .../travis/caldavtest/tests/CalDAV/sync-report.xml | 2 +- .../tests/unit/DAV/BrowserErrorPagePluginTest.php | 60 ---------- apps/dav/tests/unit/DAV/ErrorPagePluginTest.php | 60 ++++++++++ build/integration/dav_features/caldav.feature | 18 +-- build/integration/dav_features/carddav.feature | 15 +-- core/templates/xml_exception.php | 47 ++++++++ 12 files changed, 249 insertions(+), 211 deletions(-) delete mode 100644 apps/dav/lib/Files/BrowserErrorPagePlugin.php create mode 100644 apps/dav/lib/Files/ErrorPagePlugin.php delete mode 100644 apps/dav/tests/unit/DAV/BrowserErrorPagePluginTest.php create mode 100644 apps/dav/tests/unit/DAV/ErrorPagePluginTest.php create mode 100644 core/templates/xml_exception.php diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php index 3e4dfbcabd1..ff6ac0a0928 100644 --- a/apps/dav/composer/composer/autoload_classmap.php +++ b/apps/dav/composer/composer/autoload_classmap.php @@ -265,7 +265,7 @@ return array( 'OCA\\DAV\\Events\\SubscriptionUpdatedEvent' => $baseDir . '/../lib/Events/SubscriptionUpdatedEvent.php', 'OCA\\DAV\\Exception\\ServerMaintenanceMode' => $baseDir . '/../lib/Exception/ServerMaintenanceMode.php', 'OCA\\DAV\\Exception\\UnsupportedLimitOnInitialSyncException' => $baseDir . '/../lib/Exception/UnsupportedLimitOnInitialSyncException.php', - 'OCA\\DAV\\Files\\BrowserErrorPagePlugin' => $baseDir . '/../lib/Files/BrowserErrorPagePlugin.php', + 'OCA\\DAV\\Files\\ErrorPagePlugin' => $baseDir . '/../lib/Files/ErrorPagePlugin.php', 'OCA\\DAV\\Files\\FileSearchBackend' => $baseDir . '/../lib/Files/FileSearchBackend.php', 'OCA\\DAV\\Files\\FilesHome' => $baseDir . '/../lib/Files/FilesHome.php', 'OCA\\DAV\\Files\\LazySearchBackend' => $baseDir . '/../lib/Files/LazySearchBackend.php', diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php index 23feaf5227a..00d90a532fb 100644 --- a/apps/dav/composer/composer/autoload_static.php +++ b/apps/dav/composer/composer/autoload_static.php @@ -280,7 +280,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\Events\\SubscriptionUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/SubscriptionUpdatedEvent.php', 'OCA\\DAV\\Exception\\ServerMaintenanceMode' => __DIR__ . '/..' . '/../lib/Exception/ServerMaintenanceMode.php', 'OCA\\DAV\\Exception\\UnsupportedLimitOnInitialSyncException' => __DIR__ . '/..' . '/../lib/Exception/UnsupportedLimitOnInitialSyncException.php', - 'OCA\\DAV\\Files\\BrowserErrorPagePlugin' => __DIR__ . '/..' . '/../lib/Files/BrowserErrorPagePlugin.php', + 'OCA\\DAV\\Files\\ErrorPagePlugin' => __DIR__ . '/..' . '/../lib/Files/ErrorPagePlugin.php', 'OCA\\DAV\\Files\\FileSearchBackend' => __DIR__ . '/..' . '/../lib/Files/FileSearchBackend.php', 'OCA\\DAV\\Files\\FilesHome' => __DIR__ . '/..' . '/../lib/Files/FilesHome.php', 'OCA\\DAV\\Files\\LazySearchBackend' => __DIR__ . '/..' . '/../lib/Files/LazySearchBackend.php', diff --git a/apps/dav/lib/Connector/Sabre/ServerFactory.php b/apps/dav/lib/Connector/Sabre/ServerFactory.php index 3b3c10e58cd..c415b49b58d 100644 --- a/apps/dav/lib/Connector/Sabre/ServerFactory.php +++ b/apps/dav/lib/Connector/Sabre/ServerFactory.php @@ -34,7 +34,7 @@ namespace OCA\DAV\Connector\Sabre; use OCA\DAV\AppInfo\PluginManager; use OCA\DAV\CalDAV\DefaultCalendarValidator; use OCA\DAV\DAV\ViewOnlyPlugin; -use OCA\DAV\Files\BrowserErrorPagePlugin; +use OCA\DAV\Files\ErrorPagePlugin; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Folder; use OCP\Files\Mount\IMountManager; @@ -121,9 +121,7 @@ class ServerFactory { $server->addPlugin(new \OCA\DAV\Connector\Sabre\FakeLockerPlugin()); } - if (BrowserErrorPagePlugin::isBrowserRequest($this->request)) { - $server->addPlugin(new BrowserErrorPagePlugin()); - } + $server->addPlugin(new ErrorPagePlugin($this->request, $this->config)); // wait with registering these until auth is handled and the filesystem is setup $server->on('beforeMethod:*', function () use ($server, $objectTree, $viewCallBack) { diff --git a/apps/dav/lib/Files/BrowserErrorPagePlugin.php b/apps/dav/lib/Files/BrowserErrorPagePlugin.php deleted file mode 100644 index eccae8afdd5..00000000000 --- a/apps/dav/lib/Files/BrowserErrorPagePlugin.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @author Christoph Wurst - * @author Lukas Reschke - * @author Thomas Müller - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ -namespace OCA\DAV\Files; - -use OC\AppFramework\Http\Request; -use OC_Template; -use OCP\AppFramework\Http\ContentSecurityPolicy; -use OCP\IRequest; -use Sabre\DAV\Exception; -use Sabre\DAV\Server; -use Sabre\DAV\ServerPlugin; - -class BrowserErrorPagePlugin extends ServerPlugin { - /** @var Server */ - private $server; - - /** - * This initializes the plugin. - * - * This function is called by Sabre\DAV\Server, after - * addPlugin is called. - * - * This method should set up the required event subscriptions. - * - * @param Server $server - * @return void - */ - public function initialize(Server $server) { - $this->server = $server; - $server->on('exception', [$this, 'logException'], 1000); - } - - /** - * @param IRequest $request - * @return bool - */ - public static function isBrowserRequest(IRequest $request) { - if ($request->getMethod() !== 'GET') { - return false; - } - return $request->isUserAgent([ - Request::USER_AGENT_IE, - Request::USER_AGENT_MS_EDGE, - Request::USER_AGENT_CHROME, - Request::USER_AGENT_FIREFOX, - Request::USER_AGENT_SAFARI, - ]); - } - - /** - * @param \Throwable $ex - */ - public function logException(\Throwable $ex): void { - if ($ex instanceof Exception) { - $httpCode = $ex->getHTTPCode(); - $headers = $ex->getHTTPHeaders($this->server); - } else { - $httpCode = 500; - $headers = []; - } - $this->server->httpResponse->addHeaders($headers); - $this->server->httpResponse->setStatus($httpCode); - $body = $this->generateBody($httpCode); - $this->server->httpResponse->setBody($body); - $csp = new ContentSecurityPolicy(); - $this->server->httpResponse->addHeader('Content-Security-Policy', $csp->buildPolicy()); - $this->sendResponse(); - } - - /** - * @codeCoverageIgnore - * @return bool|string - */ - public function generateBody(int $httpCode) { - $request = \OC::$server->getRequest(); - - $templateName = 'exception'; - if ($httpCode === 403 || $httpCode === 404) { - $templateName = (string)$httpCode; - } - - $content = new OC_Template('core', $templateName, 'guest'); - $content->assign('title', $this->server->httpResponse->getStatusText()); - $content->assign('remoteAddr', $request->getRemoteAddress()); - $content->assign('requestID', $request->getId()); - return $content->fetchPage(); - } - - /** - * @codeCoverageIgnore - */ - public function sendResponse() { - $this->server->sapi->sendResponse($this->server->httpResponse); - exit(); - } -} diff --git a/apps/dav/lib/Files/ErrorPagePlugin.php b/apps/dav/lib/Files/ErrorPagePlugin.php new file mode 100644 index 00000000000..d918da4fab3 --- /dev/null +++ b/apps/dav/lib/Files/ErrorPagePlugin.php @@ -0,0 +1,124 @@ + + * @author Christoph Wurst + * @author Lukas Reschke + * @author Thomas Müller + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\DAV\Files; + +use OC_Template; +use OCP\AppFramework\Http\ContentSecurityPolicy; +use OCP\IConfig; +use OCP\IRequest; +use Sabre\DAV\Exception; +use Sabre\DAV\Server; +use Sabre\DAV\ServerPlugin; + +class ErrorPagePlugin extends ServerPlugin { + private ?Server $server = null; + + public function __construct( + private IRequest $request, + private IConfig $config, + ) { + } + + /** + * This initializes the plugin. + * + * This function is called by Sabre\DAV\Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + */ + public function initialize(Server $server): void { + $this->server = $server; + $server->on('exception', [$this, 'logException'], 1000); + } + + public function logException(\Throwable $ex): void { + if ($ex instanceof Exception) { + $httpCode = $ex->getHTTPCode(); + $headers = $ex->getHTTPHeaders($this->server); + } else { + $httpCode = 500; + $headers = []; + } + $this->server->httpResponse->addHeaders($headers); + $this->server->httpResponse->setStatus($httpCode); + $body = $this->generateBody($ex, $httpCode); + $this->server->httpResponse->setBody($body); + $csp = new ContentSecurityPolicy(); + $this->server->httpResponse->addHeader('Content-Security-Policy', $csp->buildPolicy()); + $this->sendResponse(); + } + + /** + * @codeCoverageIgnore + * @return bool|string + */ + public function generateBody(\Throwable $ex, int $httpCode): mixed { + if ($this->acceptHtml()) { + $templateName = 'exception'; + $renderAs = 'guest'; + if ($httpCode === 403 || $httpCode === 404) { + $templateName = (string)$httpCode; + } + } else { + $templateName = 'xml_exception'; + $renderAs = null; + $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); + } + + $debug = $this->config->getSystemValueBool('debug', false); + + $content = new OC_Template('core', $templateName, $renderAs); + $content->assign('title', $this->server->httpResponse->getStatusText()); + $content->assign('remoteAddr', $this->request->getRemoteAddress()); + $content->assign('requestID', $this->request->getId()); + $content->assign('debugMode', $debug); + $content->assign('errorClass', get_class($ex)); + $content->assign('errorMsg', $ex->getMessage()); + $content->assign('errorCode', $ex->getCode()); + $content->assign('file', $ex->getFile()); + $content->assign('line', $ex->getLine()); + $content->assign('exception', $ex); + return $content->fetchPage(); + } + + /** + * @codeCoverageIgnore + */ + public function sendResponse() { + $this->server->sapi->sendResponse($this->server->httpResponse); + exit(); + } + + private function acceptHtml(): bool { + foreach (explode(',', $this->request->getHeader('Accept')) as $part) { + $subparts = explode(';', $part); + if (str_ends_with($subparts[0], '/html')) { + return true; + } + } + return false; + } +} diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index 11fa61015e8..8c5d3eef4c6 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -72,7 +72,7 @@ use OCA\DAV\DAV\PublicAuth; use OCA\DAV\DAV\ViewOnlyPlugin; use OCA\DAV\Events\SabrePluginAddEvent; use OCA\DAV\Events\SabrePluginAuthInitEvent; -use OCA\DAV\Files\BrowserErrorPagePlugin; +use OCA\DAV\Files\ErrorPagePlugin; use OCA\DAV\Files\LazySearchBackend; use OCA\DAV\Profiler\ProfilerPlugin; use OCA\DAV\Provisioning\Apple\AppleProvisioningPlugin; @@ -249,9 +249,7 @@ class Server { $this->server->addPlugin(new FakeLockerPlugin()); } - if (BrowserErrorPagePlugin::isBrowserRequest($request)) { - $this->server->addPlugin(new BrowserErrorPagePlugin()); - } + $this->server->addPlugin(new ErrorPagePlugin($this->request, \OC::$server->getConfig())); $lazySearchBackend = new LazySearchBackend(); $this->server->addPlugin(new SearchPlugin($lazySearchBackend)); diff --git a/apps/dav/tests/travis/caldavtest/tests/CalDAV/sync-report.xml b/apps/dav/tests/travis/caldavtest/tests/CalDAV/sync-report.xml index cf4fcde251f..388d9df8413 100644 --- a/apps/dav/tests/travis/caldavtest/tests/CalDAV/sync-report.xml +++ b/apps/dav/tests/travis/caldavtest/tests/CalDAV/sync-report.xml @@ -2712,7 +2712,7 @@ prepostcondition error - {DAV:}valid-sync-token + {http://sabredav.org/ns}exception ignoreextras diff --git a/apps/dav/tests/unit/DAV/BrowserErrorPagePluginTest.php b/apps/dav/tests/unit/DAV/BrowserErrorPagePluginTest.php deleted file mode 100644 index b6ec05afd78..00000000000 --- a/apps/dav/tests/unit/DAV/BrowserErrorPagePluginTest.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @author Morris Jobke - * @author Thomas Müller - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ -namespace OCA\DAV\Tests\unit\DAV; - -use OCA\DAV\Files\BrowserErrorPagePlugin; -use Sabre\DAV\Exception\NotFound; -use Sabre\HTTP\Response; - -class BrowserErrorPagePluginTest extends \Test\TestCase { - - /** - * @dataProvider providesExceptions - * @param $expectedCode - * @param $exception - */ - public function test($expectedCode, $exception): void { - /** @var BrowserErrorPagePlugin | \PHPUnit\Framework\MockObject\MockObject $plugin */ - $plugin = $this->getMockBuilder(BrowserErrorPagePlugin::class)->setMethods(['sendResponse', 'generateBody'])->getMock(); - $plugin->expects($this->once())->method('generateBody')->willReturn(':boom:'); - $plugin->expects($this->once())->method('sendResponse'); - /** @var \Sabre\DAV\Server | \PHPUnit\Framework\MockObject\MockObject $server */ - $server = $this->getMockBuilder('Sabre\DAV\Server')->disableOriginalConstructor()->getMock(); - $server->expects($this->once())->method('on'); - $httpResponse = $this->getMockBuilder(Response::class)->disableOriginalConstructor()->getMock(); - $httpResponse->expects($this->once())->method('addHeaders'); - $httpResponse->expects($this->once())->method('setStatus')->with($expectedCode); - $httpResponse->expects($this->once())->method('setBody')->with(':boom:'); - $server->httpResponse = $httpResponse; - $plugin->initialize($server); - $plugin->logException($exception); - } - - public function providesExceptions() { - return [ - [ 404, new NotFound()], - [ 500, new \RuntimeException()], - ]; - } -} diff --git a/apps/dav/tests/unit/DAV/ErrorPagePluginTest.php b/apps/dav/tests/unit/DAV/ErrorPagePluginTest.php new file mode 100644 index 00000000000..3c87574e8d2 --- /dev/null +++ b/apps/dav/tests/unit/DAV/ErrorPagePluginTest.php @@ -0,0 +1,60 @@ + + * @author Morris Jobke + * @author Thomas Müller + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\DAV\Tests\unit\DAV; + +use OCA\DAV\Files\ErrorPagePlugin; +use Sabre\DAV\Exception\NotFound; +use Sabre\HTTP\Response; + +class ErrorPagePluginTest extends \Test\TestCase { + + /** + * @dataProvider providesExceptions + * @param $expectedCode + * @param $exception + */ + public function test($expectedCode, $exception): void { + /** @var ErrorPagePlugin | \PHPUnit\Framework\MockObject\MockObject $plugin */ + $plugin = $this->getMockBuilder(ErrorPagePlugin::class)->disableOriginalConstructor()->setMethods(['sendResponse', 'generateBody'])->getMock(); + $plugin->expects($this->once())->method('generateBody')->willReturn(':boom:'); + $plugin->expects($this->once())->method('sendResponse'); + /** @var \Sabre\DAV\Server | \PHPUnit\Framework\MockObject\MockObject $server */ + $server = $this->getMockBuilder('Sabre\DAV\Server')->disableOriginalConstructor()->getMock(); + $server->expects($this->once())->method('on'); + $httpResponse = $this->getMockBuilder(Response::class)->disableOriginalConstructor()->getMock(); + $httpResponse->expects($this->once())->method('addHeaders'); + $httpResponse->expects($this->once())->method('setStatus')->with($expectedCode); + $httpResponse->expects($this->once())->method('setBody')->with(':boom:'); + $server->httpResponse = $httpResponse; + $plugin->initialize($server); + $plugin->logException($exception); + } + + public function providesExceptions() { + return [ + [ 404, new NotFound()], + [ 500, new \RuntimeException()], + ]; + } +} diff --git a/build/integration/dav_features/caldav.feature b/build/integration/dav_features/caldav.feature index f7baf76d4bc..b3068590863 100644 --- a/build/integration/dav_features/caldav.feature +++ b/build/integration/dav_features/caldav.feature @@ -3,8 +3,7 @@ Feature: caldav Given user "user0" exists When "admin" requests calendar "user0/MyCalendar" on the endpoint "/remote.php/dav/calendars/" Then The CalDAV HTTP status code should be "404" - And The exception is "Sabre\DAV\Exception\NotFound" - And The error message is "Node with name 'MyCalendar' could not be found" + And The exception is "Internal Server Error" Scenario: Accessing a not shared calendar of another user Given user "user0" exists @@ -12,8 +11,7 @@ Feature: caldav Given The CalDAV HTTP status code should be "201" When "user0" requests calendar "admin/MyCalendar" on the endpoint "/remote.php/dav/calendars/" Then The CalDAV HTTP status code should be "404" - And The exception is "Sabre\DAV\Exception\NotFound" - And The error message is "Calendar with name 'MyCalendar' could not be found" + And The exception is "Internal Server Error" Scenario: Accessing a not shared calendar of another user via the legacy endpoint Given user "user0" exists @@ -28,8 +26,7 @@ Feature: caldav Given user "user0" exists When "user0" requests calendar "admin/MyCalendar" on the endpoint "/remote.php/dav/calendars/" Then The CalDAV HTTP status code should be "404" - And The exception is "Sabre\DAV\Exception\NotFound" - And The error message is "Node with name 'MyCalendar' could not be found" + And The exception is "Internal Server Error" Scenario: Accessing a not existing calendar of another user via the legacy endpoint Given user "user0" exists @@ -42,8 +39,7 @@ Feature: caldav Given user "user0" exists When "user0" requests calendar "admin/MyCalendar" on the endpoint "/remote.php/dav/calendars/" Then The CalDAV HTTP status code should be "404" - And The exception is "Sabre\DAV\Exception\NotFound" - And The error message is "Node with name 'MyCalendar' could not be found" + And The exception is "Internal Server Error" Scenario: Creating a new calendar When "admin" creates a calendar named "MyCalendar" @@ -64,8 +60,7 @@ Feature: caldav Given user "user0" exists When "user0" sends a create calendar request to "admin/MyCalendar2" on the endpoint "/remote.php/dav/calendars/" Then The CalDAV HTTP status code should be "404" - And The exception is "Sabre\DAV\Exception\NotFound" - And The error message is "Node with name 'admin' could not be found" + And The exception is "Internal Server Error" Scenario: Create calendar request for existing calendar of another user Given user "user0" exists @@ -73,8 +68,7 @@ Feature: caldav Then The CalDAV HTTP status code should be "201" When "user0" sends a create calendar request to "admin/MyCalendar2" on the endpoint "/remote.php/dav/calendars/" Then The CalDAV HTTP status code should be "404" - And The exception is "Sabre\DAV\Exception\NotFound" - And The error message is "Node with name 'admin' could not be found" + And The exception is "Internal Server Error" Scenario: Update a principal's schedule-default-calendar-URL Given user "user0" exists diff --git a/build/integration/dav_features/carddav.feature b/build/integration/dav_features/carddav.feature index 9c9df6ddd94..15f1e95e737 100644 --- a/build/integration/dav_features/carddav.feature +++ b/build/integration/dav_features/carddav.feature @@ -2,15 +2,13 @@ Feature: carddav Scenario: Accessing a not existing addressbook of another user Given user "user0" exists When "admin" requests addressbook "user0/MyAddressbook" with statuscode "404" on the endpoint "/remote.php/dav/addressbooks/users/" - And The CardDAV exception is "Sabre\DAV\Exception\NotFound" - And The CardDAV error message is "Addressbook with name 'MyAddressbook' could not be found" + And The CardDAV exception is "Internal Server Error" Scenario: Accessing a not shared addressbook of another user Given user "user0" exists Given "admin" creates an addressbook named "MyAddressbook" with statuscode "201" When "user0" requests addressbook "admin/MyAddressbook" with statuscode "404" on the endpoint "/remote.php/dav/addressbooks/users/" - And The CardDAV exception is "Sabre\DAV\Exception\NotFound" - And The CardDAV error message is "Addressbook with name 'MyAddressbook' could not be found" + And The CardDAV exception is "Internal Server Error" Scenario: Accessing a not existing addressbook of another user via legacy endpoint Given user "user0" exists @@ -28,8 +26,7 @@ Feature: carddav Scenario: Accessing a not existing addressbook of myself Given user "user0" exists When "user0" requests addressbook "admin/MyAddressbook" with statuscode "404" on the endpoint "/remote.php/dav/addressbooks/users/" - And The CardDAV exception is "Sabre\DAV\Exception\NotFound" - And The CardDAV error message is "Addressbook with name 'MyAddressbook' could not be found" + And The CardDAV exception is "Internal Server Error" Scenario: Creating a new addressbook When "admin" creates an addressbook named "MyAddressbook" with statuscode "201" @@ -67,13 +64,11 @@ Feature: carddav Given user "user0" exists When "user0" sends a create addressbook request to "admin/MyAddressbook2" on the endpoint "/remote.php/dav/addressbooks/" Then The CardDAV HTTP status code should be "404" - And The CardDAV exception is "Sabre\DAV\Exception\NotFound" - And The CardDAV error message is "File not found: admin in 'addressbooks'" + And The CardDAV exception is "Internal Server Error" Scenario: Create addressbook request for existing addressbook of another user Given user "user0" exists When "admin" creates an addressbook named "MyAddressbook2" with statuscode "201" When "user0" sends a create addressbook request to "admin/MyAddressbook2" on the endpoint "/remote.php/dav/addressbooks/" Then The CardDAV HTTP status code should be "404" - And The CardDAV exception is "Sabre\DAV\Exception\NotFound" - And The CardDAV error message is "File not found: admin in 'addressbooks'" + And The CardDAV exception is "Internal Server Error" diff --git a/core/templates/xml_exception.php b/core/templates/xml_exception.php new file mode 100644 index 00000000000..d7fb276a730 --- /dev/null +++ b/core/templates/xml_exception.php @@ -0,0 +1,47 @@ +getTraceAsString()); + + if ($e->getPrevious() !== null) { + print_unescaped(''); + print_exception($e->getPrevious(), $l); + print_unescaped(''); + } +} + +?> + + + t('Internal Server Error')) ?> + + t('The server was unable to complete your request.')) ?> + t('If this happens again, please send the technical details below to the server administrator.')) ?> + t('More details can be found in the server log.')) ?> + + t('For more details see the documentation ↗.'))?>: + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3