WellKnownUrls.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2024 Côme Chilliet <come.chilliet@nextcloud.com>
  5. *
  6. * @author Côme Chilliet <come.chilliet@nextcloud.com>
  7. * @author Ferdinand Thiessen <opensource@fthiessen.de>
  8. *
  9. * @license AGPL-3.0-or-later
  10. *
  11. * This program is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License as
  13. * published by the Free Software Foundation, either version 3 of the
  14. * License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. *
  24. */
  25. namespace OCA\Settings\SetupChecks;
  26. use OCP\Http\Client\IClientService;
  27. use OCP\IConfig;
  28. use OCP\IL10N;
  29. use OCP\IURLGenerator;
  30. use OCP\SetupCheck\ISetupCheck;
  31. use OCP\SetupCheck\SetupResult;
  32. use Psr\Log\LoggerInterface;
  33. class WellKnownUrls implements ISetupCheck {
  34. use CheckServerResponseTrait;
  35. public function __construct(
  36. protected IL10N $l10n,
  37. protected IConfig $config,
  38. protected IURLGenerator $urlGenerator,
  39. protected IClientService $clientService,
  40. protected LoggerInterface $logger,
  41. ) {
  42. }
  43. public function getCategory(): string {
  44. return 'network';
  45. }
  46. public function getName(): string {
  47. return $this->l10n->t('.well-known URLs');
  48. }
  49. public function run(): SetupResult {
  50. if (!$this->config->getSystemValueBool('check_for_working_wellknown_setup', true)) {
  51. return SetupResult::info($this->l10n->t('`check_for_working_wellknown_setup` is set to false in your configuration, so this check was skipped.'));
  52. }
  53. $urls = [
  54. ['get', '/.well-known/webfinger', [200, 404], true],
  55. ['get', '/.well-known/nodeinfo', [200, 404], true],
  56. ['propfind', '/.well-known/caldav', [207], false],
  57. ['propfind', '/.well-known/carddav', [207], false],
  58. ];
  59. foreach ($urls as [$verb,$url,$validStatuses,$checkCustomHeader]) {
  60. $works = null;
  61. foreach ($this->runRequest($verb, $url, ['httpErrors' => false, 'options' => ['allow_redirects' => ['track_redirects' => true]]]) as $response) {
  62. // Check that the response status matches
  63. $works = in_array($response->getStatusCode(), $validStatuses);
  64. // and (if needed) the custom Nextcloud header is set
  65. if ($checkCustomHeader) {
  66. $works = $works && !empty($response->getHeader('X-NEXTCLOUD-WELL-KNOWN'));
  67. } else {
  68. // For default DAV endpoints we lack authorization, but we still can check that the redirect works as expected
  69. if (!$works && $response->getStatusCode() === 401) {
  70. $redirectHops = explode(',', $response->getHeader('X-Guzzle-Redirect-History'));
  71. $effectiveUri = end($redirectHops);
  72. $works = str_ends_with($effectiveUri, '/remote.php/dav/');
  73. }
  74. }
  75. // Skip the other requests if one works
  76. if ($works === true) {
  77. break;
  78. }
  79. }
  80. // If 'works' is null then we could not connect to the server
  81. if ($works === null) {
  82. return SetupResult::info(
  83. $this->l10n->t('Could not check that your web server serves `.well-known` correctly. Please check manually.') . "\n" . $this->serverConfigHelp(),
  84. $this->urlGenerator->linkToDocs('admin-setup-well-known-URL'),
  85. );
  86. }
  87. // Otherwise if we fail we can abort here
  88. if ($works === false) {
  89. return SetupResult::warning(
  90. $this->l10n->t("Your web server is not properly set up to resolve `.well-known` URLs, failed on:\n`%s`", [$url]),
  91. $this->urlGenerator->linkToDocs('admin-setup-well-known-URL'),
  92. );
  93. }
  94. }
  95. return SetupResult::success(
  96. $this->l10n->t('Your server is correctly configured to serve `.well-known` URLs.')
  97. );
  98. }
  99. }