diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/Controller/WellKnownController.php | 67 | ||||
-rw-r--r-- | core/js/setupchecks.js | 7 | ||||
-rw-r--r-- | core/js/tests/specs/setupchecksSpec.js | 8 | ||||
-rw-r--r-- | core/routes.php | 3 |
4 files changed, 78 insertions, 7 deletions
diff --git a/core/Controller/WellKnownController.php b/core/Controller/WellKnownController.php new file mode 100644 index 00000000000..1d45e87569b --- /dev/null +++ b/core/Controller/WellKnownController.php @@ -0,0 +1,67 @@ +<?php + +declare(strict_types=1); + +/* + * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace OC\Core\Controller; + +use OC\Http\WellKnown\RequestManager; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\Response; +use OCP\IRequest; + +class WellKnownController extends Controller { + + /** @var RequestManager */ + private $requestManager; + + public function __construct(IRequest $request, + RequestManager $wellKnownManager) { + parent::__construct('core', $request); + $this->requestManager = $wellKnownManager; + } + + /** + * @PublicPage + * @NoCSRFRequired + * + * @return Response + */ + public function handle(string $service): Response { + $response = $this->requestManager->process( + $service, + $this->request + ); + + if ($response === null) { + $httpResponse = new JSONResponse(["message" => "$service not supported"], Http::STATUS_NOT_FOUND); + } else { + $httpResponse = $response->toHttpResponse(); + } + + // We add a custom header so that setup checks can detect if their requests are answered by this controller + return $httpResponse->addHeader('X-NEXTCLOUD-WELL-KNOWN', '1'); + } +} diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js index 22c8589f73b..fb01a91b30e 100644 --- a/core/js/setupchecks.js +++ b/core/js/setupchecks.js @@ -56,7 +56,7 @@ * @param {int|int[]} expectedStatus the expected HTTP status to be returned by the URL, 207 by default * @return $.Deferred object resolved with an array of error messages */ - checkWellKnownUrl: function(url, placeholderUrl, runCheck, expectedStatus) { + checkWellKnownUrl: function(verb, url, placeholderUrl, runCheck, expectedStatus, checkCustomHeader) { if (expectedStatus === undefined) { expectedStatus = [207]; } @@ -73,7 +73,8 @@ } var afterCall = function(xhr) { var messages = []; - if (expectedStatus.indexOf(xhr.status) === -1) { + var customWellKnown = xhr.getResponseHeader('X-NEXTCLOUD-WELL-KNOWN') + if (expectedStatus.indexOf(xhr.status) === -1 || (checkCustomHeader && !customWellKnown)) { var docUrl = placeholderUrl.replace('PLACEHOLDER', 'admin-setup-well-known-URL'); messages.push({ msg: t('core', 'Your web server is not properly set up to resolve "{url}". Further information can be found in the <a target="_blank" rel="noreferrer noopener" href="{docLink}">documentation</a>.', { docLink: docUrl, url: url }), @@ -84,7 +85,7 @@ }; $.ajax({ - type: 'PROPFIND', + type: verb, url: url, complete: afterCall, allowAuthErrors: true diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js index c3cddb88a9d..3f02302ee80 100644 --- a/core/js/tests/specs/setupchecksSpec.js +++ b/core/js/tests/specs/setupchecksSpec.js @@ -62,7 +62,7 @@ describe('OC.SetupChecks tests', function() { describe('checkWellKnownUrl', function() { it('should fail with another response status code than the expected one', function(done) { - var async = OC.SetupChecks.checkWellKnownUrl('/.well-known/caldav', 'http://example.org/PLACEHOLDER', true, 207); + var async = OC.SetupChecks.checkWellKnownUrl('PROPFIND', '/.well-known/caldav', 'http://example.org/PLACEHOLDER', true, 207); suite.server.requests[0].respond(200); @@ -76,7 +76,7 @@ describe('OC.SetupChecks tests', function() { }); it('should return no error with the expected response status code', function(done) { - var async = OC.SetupChecks.checkWellKnownUrl('/.well-known/caldav', 'http://example.org/PLACEHOLDER', true, 207); + var async = OC.SetupChecks.checkWellKnownUrl('PROPFIND', '/.well-known/caldav', 'http://example.org/PLACEHOLDER', true, 207); suite.server.requests[0].respond(207); @@ -87,7 +87,7 @@ describe('OC.SetupChecks tests', function() { }); it('should return no error with the default expected response status code', function(done) { - var async = OC.SetupChecks.checkWellKnownUrl('/.well-known/caldav', 'http://example.org/PLACEHOLDER', true); + var async = OC.SetupChecks.checkWellKnownUrl('PROPFIND', '/.well-known/caldav', 'http://example.org/PLACEHOLDER', true); suite.server.requests[0].respond(207); @@ -98,7 +98,7 @@ describe('OC.SetupChecks tests', function() { }); it('should return no error when no check should be run', function(done) { - var async = OC.SetupChecks.checkWellKnownUrl('/.well-known/caldav', 'http://example.org/PLACEHOLDER', false); + var async = OC.SetupChecks.checkWellKnownUrl('PROPFIND', '/.well-known/caldav', 'http://example.org/PLACEHOLDER', false); async.done(function( data, s, x ){ expect(data).toEqual([]); diff --git a/core/routes.php b/core/routes.php index 9fa378dc1d8..5bc4075315a 100644 --- a/core/routes.php +++ b/core/routes.php @@ -89,6 +89,9 @@ $application->registerRoutes($this, [ // Logins for passwordless auth ['name' => 'WebAuthn#startAuthentication', 'url' => 'login/webauthn/start', 'verb' => 'POST'], ['name' => 'WebAuthn#finishAuthentication', 'url' => 'login/webauthn/finish', 'verb' => 'POST'], + + // Well known requests https://tools.ietf.org/html/rfc5785 + ['name' => 'WellKnown#handle', 'url' => '.well-known/{service}'], ], 'ocs' => [ ['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'], |