Skip to content

Commit dc2066b

Browse files
authored
Merge pull request #32400 from nextcloud/feat/public-dav-v2
2 parents fdc64ea + 9e4c9b9 commit dc2066b

File tree

25 files changed

+923
-80
lines changed

25 files changed

+923
-80
lines changed

apps/dav/appinfo/info.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,4 @@
8686
<provider>OCA\DAV\CardDAV\Activity\Provider\Card</provider>
8787
</providers>
8888
</activity>
89-
90-
<public>
91-
<webdav>appinfo/v1/publicwebdav.php</webdav>
92-
</public>
9389
</info>

apps/dav/appinfo/v1/publicwebdav.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
\OC::$server->getSession()->close();
4444

4545
// Backends
46-
$authBackend = new OCA\DAV\Connector\PublicAuth(
46+
$authBackend = new OCA\DAV\Connector\LegacyPublicAuth(
4747
\OC::$server->getRequest(),
4848
\OC::$server->getShareManager(),
4949
\OC::$server->getSession(),
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<?php
2+
/**
3+
* @copyright Copyright (c) 2016, ownCloud, Inc.
4+
*
5+
* @author Bjoern Schiessle <[email protected]>
6+
* @author Björn Schießle <[email protected]>
7+
* @author Christoph Wurst <[email protected]>
8+
* @author Joas Schilling <[email protected]>
9+
* @author Julius Härtl <[email protected]>
10+
* @author Lukas Reschke <[email protected]>
11+
* @author Morris Jobke <[email protected]>
12+
* @author Robin Appelman <[email protected]>
13+
* @author Roeland Jago Douma <[email protected]>
14+
* @author Thomas Müller <[email protected]>
15+
* @author Vincent Petry <[email protected]>
16+
*
17+
* @license AGPL-3.0
18+
*
19+
* This code is free software: you can redistribute it and/or modify
20+
* it under the terms of the GNU Affero General Public License, version 3,
21+
* as published by the Free Software Foundation.
22+
*
23+
* This program is distributed in the hope that it will be useful,
24+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
25+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26+
* GNU Affero General Public License for more details.
27+
*
28+
* You should have received a copy of the GNU Affero General Public License, version 3,
29+
* along with this program. If not, see <http://www.gnu.org/licenses/>
30+
*
31+
*/
32+
33+
use OC\Files\Filesystem;
34+
use OC\Files\Storage\Wrapper\PermissionsMask;
35+
use OC\Files\View;
36+
use OCA\DAV\Storage\PublicOwnerWrapper;
37+
use OCA\FederatedFileSharing\FederatedShareProvider;
38+
use OCP\EventDispatcher\IEventDispatcher;
39+
use OCP\Files\Mount\IMountManager;
40+
use OCP\IConfig;
41+
use OCP\IDBConnection;
42+
use OCP\IPreview;
43+
use OCP\IRequest;
44+
use OCP\ISession;
45+
use OCP\ITagManager;
46+
use OCP\IUserSession;
47+
use OCP\L10N\IFactory;
48+
use OCP\Security\Bruteforce\IThrottler;
49+
use OCP\Share\IManager;
50+
use Psr\Log\LoggerInterface;
51+
use Sabre\DAV\Exception\NotAuthenticated;
52+
use Sabre\DAV\Exception\NotFound;
53+
54+
// load needed apps
55+
$RUNTIME_APPTYPES = ['filesystem', 'authentication', 'logging'];
56+
OC_App::loadApps($RUNTIME_APPTYPES);
57+
OC_Util::obEnd();
58+
59+
$session = \OCP\Server::get(ISession::class);
60+
$request = \OCP\Server::get(IRequest::class);
61+
62+
$session->close();
63+
$requestUri = $request->getRequestUri();
64+
65+
// Backends
66+
$authBackend = new OCA\DAV\Connector\Sabre\PublicAuth(
67+
$request,
68+
\OCP\Server::get(IManager::class),
69+
$session,
70+
\OCP\Server::get(IThrottler::class),
71+
\OCP\Server::get(LoggerInterface::class)
72+
);
73+
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
74+
75+
$l10nFactory = \OCP\Server::get(IFactory::class);
76+
$serverFactory = new OCA\DAV\Connector\Sabre\ServerFactory(
77+
\OCP\Server::get(IConfig::class),
78+
\OCP\Server::get(LoggerInterface::class),
79+
\OCP\Server::get(IDBConnection::class),
80+
\OCP\Server::get(IUserSession::class),
81+
\OCP\Server::get(IMountManager::class),
82+
\OCP\Server::get(ITagManager::class),
83+
$request,
84+
\OCP\Server::get(IPreview::class),
85+
\OCP\Server::get(IEventDispatcher::class),
86+
$l10nFactory->get('dav'),
87+
);
88+
89+
90+
$linkCheckPlugin = new \OCA\DAV\Files\Sharing\PublicLinkCheckPlugin();
91+
$filesDropPlugin = new \OCA\DAV\Files\Sharing\FilesDropPlugin();
92+
93+
// Define root url with /public.php/dav/files/TOKEN
94+
/** @var string $baseuri defined in public.php */
95+
preg_match('/(^files\/\w+)/i', substr($requestUri, strlen($baseuri)), $match);
96+
$baseuri = $baseuri . $match[0];
97+
98+
$server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
99+
$isAjax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
100+
$federatedShareProvider = \OCP\Server::get(FederatedShareProvider::class);
101+
if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && !$isAjax) {
102+
// this is what is thrown when trying to access a non-existing share
103+
throw new NotAuthenticated();
104+
}
105+
106+
$share = $authBackend->getShare();
107+
$owner = $share->getShareOwner();
108+
$isReadable = $share->getPermissions() & \OCP\Constants::PERMISSION_READ;
109+
$fileId = $share->getNodeId();
110+
111+
// FIXME: should not add storage wrappers outside of preSetup, need to find a better way
112+
/** @psalm-suppress InternalMethod */
113+
$previousLog = Filesystem::logWarningWhenAddingStorageWrapper(false);
114+
115+
/** @psalm-suppress MissingClosureParamType */
116+
Filesystem::addStorageWrapper('sharePermissions', function ($mountPoint, $storage) use ($share) {
117+
return new PermissionsMask(['storage' => $storage, 'mask' => $share->getPermissions() | \OCP\Constants::PERMISSION_SHARE]);
118+
});
119+
120+
/** @psalm-suppress MissingClosureParamType */
121+
Filesystem::addStorageWrapper('shareOwner', function ($mountPoint, $storage) use ($share) {
122+
return new PublicOwnerWrapper(['storage' => $storage, 'owner' => $share->getShareOwner()]);
123+
});
124+
125+
/** @psalm-suppress InternalMethod */
126+
Filesystem::logWarningWhenAddingStorageWrapper($previousLog);
127+
128+
OC_Util::tearDownFS();
129+
OC_Util::setupFS($owner);
130+
$ownerView = new View('/'. $owner . '/files');
131+
$path = $ownerView->getPath($fileId);
132+
$fileInfo = $ownerView->getFileInfo($path);
133+
134+
if ($fileInfo === false) {
135+
throw new NotFound();
136+
}
137+
138+
$linkCheckPlugin->setFileInfo($fileInfo);
139+
140+
// If not readble (files_drop) enable the filesdrop plugin
141+
if (!$isReadable) {
142+
$filesDropPlugin->enable();
143+
}
144+
145+
$view = new View($ownerView->getAbsolutePath($path));
146+
$filesDropPlugin->setView($view);
147+
148+
return $view;
149+
});
150+
151+
$server->addPlugin($linkCheckPlugin);
152+
$server->addPlugin($filesDropPlugin);
153+
154+
// And off we go!
155+
$server->exec();

apps/dav/composer/composer/autoload_classmap.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
'OCA\\DAV\\Comments\\EntityTypeCollection' => $baseDir . '/../lib/Comments/EntityTypeCollection.php',
150150
'OCA\\DAV\\Comments\\RootCollection' => $baseDir . '/../lib/Comments/RootCollection.php',
151151
'OCA\\DAV\\Connector\\LegacyDAVACL' => $baseDir . '/../lib/Connector/LegacyDAVACL.php',
152-
'OCA\\DAV\\Connector\\PublicAuth' => $baseDir . '/../lib/Connector/PublicAuth.php',
152+
'OCA\\DAV\\Connector\\LegacyPublicAuth' => $baseDir . '/../lib/Connector/LegacyPublicAuth.php',
153153
'OCA\\DAV\\Connector\\Sabre\\AnonymousOptionsPlugin' => $baseDir . '/../lib/Connector/Sabre/AnonymousOptionsPlugin.php',
154154
'OCA\\DAV\\Connector\\Sabre\\AppleQuirksPlugin' => $baseDir . '/../lib/Connector/Sabre/AppleQuirksPlugin.php',
155155
'OCA\\DAV\\Connector\\Sabre\\Auth' => $baseDir . '/../lib/Connector/Sabre/Auth.php',
@@ -183,6 +183,7 @@
183183
'OCA\\DAV\\Connector\\Sabre\\ObjectTree' => $baseDir . '/../lib/Connector/Sabre/ObjectTree.php',
184184
'OCA\\DAV\\Connector\\Sabre\\Principal' => $baseDir . '/../lib/Connector/Sabre/Principal.php',
185185
'OCA\\DAV\\Connector\\Sabre\\PropfindCompressionPlugin' => $baseDir . '/../lib/Connector/Sabre/PropfindCompressionPlugin.php',
186+
'OCA\\DAV\\Connector\\Sabre\\PublicAuth' => $baseDir . '/../lib/Connector/Sabre/PublicAuth.php',
186187
'OCA\\DAV\\Connector\\Sabre\\QuotaPlugin' => $baseDir . '/../lib/Connector/Sabre/QuotaPlugin.php',
187188
'OCA\\DAV\\Connector\\Sabre\\RequestIdHeaderPlugin' => $baseDir . '/../lib/Connector/Sabre/RequestIdHeaderPlugin.php',
188189
'OCA\\DAV\\Connector\\Sabre\\Server' => $baseDir . '/../lib/Connector/Sabre/Server.php',

apps/dav/composer/composer/autoload_static.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class ComposerStaticInitDAV
164164
'OCA\\DAV\\Comments\\EntityTypeCollection' => __DIR__ . '/..' . '/../lib/Comments/EntityTypeCollection.php',
165165
'OCA\\DAV\\Comments\\RootCollection' => __DIR__ . '/..' . '/../lib/Comments/RootCollection.php',
166166
'OCA\\DAV\\Connector\\LegacyDAVACL' => __DIR__ . '/..' . '/../lib/Connector/LegacyDAVACL.php',
167-
'OCA\\DAV\\Connector\\PublicAuth' => __DIR__ . '/..' . '/../lib/Connector/PublicAuth.php',
167+
'OCA\\DAV\\Connector\\LegacyPublicAuth' => __DIR__ . '/..' . '/../lib/Connector/LegacyPublicAuth.php',
168168
'OCA\\DAV\\Connector\\Sabre\\AnonymousOptionsPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/AnonymousOptionsPlugin.php',
169169
'OCA\\DAV\\Connector\\Sabre\\AppleQuirksPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/AppleQuirksPlugin.php',
170170
'OCA\\DAV\\Connector\\Sabre\\Auth' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Auth.php',
@@ -198,6 +198,7 @@ class ComposerStaticInitDAV
198198
'OCA\\DAV\\Connector\\Sabre\\ObjectTree' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ObjectTree.php',
199199
'OCA\\DAV\\Connector\\Sabre\\Principal' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Principal.php',
200200
'OCA\\DAV\\Connector\\Sabre\\PropfindCompressionPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/PropfindCompressionPlugin.php',
201+
'OCA\\DAV\\Connector\\Sabre\\PublicAuth' => __DIR__ . '/..' . '/../lib/Connector/Sabre/PublicAuth.php',
201202
'OCA\\DAV\\Connector\\Sabre\\QuotaPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/QuotaPlugin.php',
202203
'OCA\\DAV\\Connector\\Sabre\\RequestIdHeaderPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/RequestIdHeaderPlugin.php',
203204
'OCA\\DAV\\Connector\\Sabre\\Server' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Server.php',

apps/dav/lib/Connector/PublicAuth.php renamed to apps/dav/lib/Connector/LegacyPublicAuth.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
*/
3030
namespace OCA\DAV\Connector;
3131

32+
use OCA\DAV\Connector\Sabre\PublicAuth;
3233
use OCP\IRequest;
3334
use OCP\ISession;
3435
use OCP\Security\Bruteforce\IThrottler;
@@ -42,8 +43,9 @@
4243
*
4344
* @package OCA\DAV\Connector
4445
*/
45-
class PublicAuth extends AbstractBasic {
46-
private const BRUTEFORCE_ACTION = 'public_webdav_auth';
46+
class LegacyPublicAuth extends AbstractBasic {
47+
private const BRUTEFORCE_ACTION = 'legacy_public_webdav_auth';
48+
4749
private ?IShare $share = null;
4850
private IManager $shareManager;
4951
private ISession $session;
@@ -72,6 +74,7 @@ public function __construct(IRequest $request,
7274
*
7375
* @param string $username
7476
* @param string $password
77+
*
7578
* @return bool
7679
* @throws \Sabre\DAV\Exception\NotAuthenticated
7780
*/
@@ -96,8 +99,8 @@ protected function validateUserPass($username, $password) {
9699
|| $share->getShareType() === IShare::TYPE_CIRCLE) {
97100
if ($this->shareManager->checkPassword($share, $password)) {
98101
return true;
99-
} elseif ($this->session->exists('public_link_authenticated')
100-
&& $this->session->get('public_link_authenticated') === (string)$share->getId()) {
102+
} elseif ($this->session->exists(PublicAuth::DAV_AUTHENTICATED)
103+
&& $this->session->get(PublicAuth::DAV_AUTHENTICATED) === $share->getId()) {
101104
return true;
102105
} else {
103106
if (in_array('XMLHttpRequest', explode(',', $this->request->getHeader('X-Requested-With')))) {

0 commit comments

Comments
 (0)