Skip to content

Commit 977beac

Browse files
enriquepablomickenordin
authored andcommitted
feat(dav): accept bearer access tokens on webdav endpoints
Signed-off-by: Micke Nordin <kano@sunet.se> Signed-off-by: Enrique Pérez Arnaud <enrique@cazalla.net>
1 parent 72e8aab commit 977beac

5 files changed

Lines changed: 67 additions & 6 deletions

File tree

apps/dav/appinfo/v1/caldav.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use OCA\DAV\CalDAV\Validation\CalDavValidatePlugin;
1919
use OCA\DAV\Connector\LegacyDAVACL;
2020
use OCA\DAV\Connector\Sabre\Auth;
21+
use OCA\DAV\Connector\Sabre\BearerAuth;
2122
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
2223
use OCA\DAV\Connector\Sabre\MaintenancePlugin;
2324
use OCA\DAV\Connector\Sabre\Principal;
@@ -47,6 +48,12 @@
4748
Server::get(IThrottler::class),
4849
'principals/'
4950
);
51+
$bearerAuthBackend = new BearerAuth(
52+
Server::get(IUserSession::class),
53+
Server::get(ISession::class),
54+
Server::get(IRequest::class),
55+
Server::get(IConfig::class),
56+
);
5057
$principalBackend = new Principal(
5158
Server::get(IUserManager::class),
5259
Server::get(IGroupManager::class),
@@ -108,7 +115,9 @@
108115

109116
// Add plugins
110117
$server->addPlugin(new MaintenancePlugin(Server::get(IConfig::class), $davL10n));
111-
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
118+
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
119+
$authPlugin->addBackend($bearerAuthBackend);
120+
$server->addPlugin($authPlugin);
112121
$server->addPlugin(new \Sabre\CalDAV\Plugin());
113122

114123
$server->addPlugin(new LegacyDAVACL());

apps/dav/appinfo/v1/carddav.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use OCA\DAV\CardDAV\Validation\CardDavValidatePlugin;
1818
use OCA\DAV\Connector\LegacyDAVACL;
1919
use OCA\DAV\Connector\Sabre\Auth;
20+
use OCA\DAV\Connector\Sabre\BearerAuth;
2021
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
2122
use OCA\DAV\Connector\Sabre\MaintenancePlugin;
2223
use OCA\DAV\Connector\Sabre\Principal;
@@ -44,6 +45,12 @@
4445
Server::get(IThrottler::class),
4546
'principals/'
4647
);
48+
$bearerAuthBackend = new BearerAuth(
49+
Server::get(IUserSession::class),
50+
Server::get(ISession::class),
51+
Server::get(IRequest::class),
52+
Server::get(IConfig::class),
53+
);
4754
$principalBackend = new Principal(
4855
Server::get(IUserManager::class),
4956
Server::get(IGroupManager::class),
@@ -90,7 +97,9 @@
9097
$server->setBaseUri($baseuri);
9198
// Add plugins
9299
$server->addPlugin(new MaintenancePlugin(Server::get(IConfig::class), Server::get(IL10nFactory::class)->get('dav')));
93-
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
100+
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
101+
$authPlugin->addBackend($bearerAuthBackend);
102+
$server->addPlugin($authPlugin);
94103
$server->addPlugin(new Plugin());
95104

96105
$server->addPlugin(new LegacyDAVACL());

apps/dav/appinfo/v1/publicwebdav.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use OC\Files\Storage\Wrapper\DirPermissionsMask;
1010
use OC\Files\View;
1111
use OCA\DAV\Connector\LegacyPublicAuth;
12+
use OCA\DAV\Connector\Sabre\BearerAuth;
1213
use OCA\DAV\Connector\Sabre\ServerFactory;
1314
use OCA\DAV\Files\Sharing\FilesDropPlugin;
1415
use OCA\DAV\Files\Sharing\PublicLinkCheckPlugin;
@@ -49,7 +50,14 @@
4950
Server::get(ISession::class),
5051
Server::get(IThrottler::class)
5152
);
53+
$bearerAuthBackend = new BearerAuth(
54+
Server::get(IUserSession::class),
55+
Server::get(ISession::class),
56+
Server::get(IRequest::class),
57+
Server::get(IConfig::class),
58+
);
5259
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
60+
$authPlugin->addBackend($bearerAuthBackend);
5361

5462
/** @var IEventDispatcher $eventDispatcher */
5563
$eventDispatcher = Server::get(IEventDispatcher::class);
@@ -80,6 +88,7 @@
8088
$authPlugin,
8189
function (\Sabre\DAV\Server $server) use (
8290
$authBackend,
91+
$bearerAuthBackend,
8392
$linkCheckPlugin,
8493
$filesDropPlugin
8594
) {
@@ -90,8 +99,11 @@ function (\Sabre\DAV\Server $server) use (
9099
// this is what is thrown when trying to access a non-existing share
91100
throw new \Sabre\DAV\Exception\NotAuthenticated();
92101
}
93-
94-
$share = $authBackend->getShare();
102+
try {
103+
$share = $authBackend->getShare();
104+
} catch (AssertionError $e) {
105+
$share = $bearerAuthBackend->getShare();
106+
}
95107
$isReadable = $share->getPermissions() & Constants::PERMISSION_READ;
96108
$fileId = $share->getNodeId();
97109

apps/dav/appinfo/v2/publicremote.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use OC\Files\Filesystem;
99
use OC\Files\Storage\Wrapper\DirPermissionsMask;
1010
use OC\Files\View;
11+
use OCA\DAV\Connector\Sabre\BearerAuth;
1112
use OCA\DAV\Connector\Sabre\PublicAuth;
1213
use OCA\DAV\Connector\Sabre\ServerFactory;
1314
use OCA\DAV\Files\Sharing\FilesDropPlugin;
@@ -65,7 +66,14 @@
6566
Server::get(LoggerInterface::class),
6667
Server::get(IURLGenerator::class),
6768
);
69+
$bearerAuthBackend = new BearerAuth(
70+
Server::get(IUserSession::class),
71+
$session,
72+
$request,
73+
Server::get(IConfig::class),
74+
);
6875
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
76+
$authPlugin->addBackend($bearerAuthBackend);
6977

7078
$l10nFactory = Server::get(IFactory::class);
7179
$serverFactory = new ServerFactory(
@@ -86,7 +94,7 @@
8694
$filesDropPlugin = new FilesDropPlugin();
8795

8896
/** @var string $baseuri defined in public.php */
89-
$server = $serverFactory->createServer(true, $baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($baseuri, $requestUri, $authBackend, $linkCheckPlugin, $filesDropPlugin) {
97+
$server = $serverFactory->createServer(true, $baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($baseuri, $requestUri, $authBackend, $bearerAuthBackend, $linkCheckPlugin, $filesDropPlugin) {
9098
// GET must be allowed for e.g. showing images and allowing Zip downloads
9199
if ($server->httpRequest->getMethod() !== 'GET') {
92100
// If this is *not* a GET request we only allow access to public DAV from AJAX or when Server2Server is allowed
@@ -98,7 +106,11 @@
98106
}
99107
}
100108

101-
$share = $authBackend->getShare();
109+
try {
110+
$share = $authBackend->getShare();
111+
} catch (NotFound $e) {
112+
$share = $bearerAuthBackend->getShare();
113+
}
102114
$isReadable = $share->getPermissions() & Constants::PERMISSION_READ;
103115
$fileId = $share->getNodeId();
104116

apps/dav/lib/Connector/Sabre/BearerAuth.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
use OCP\IRequest;
1313
use OCP\ISession;
1414
use OCP\IUserSession;
15+
use OCP\Server;
16+
use OCP\Share\IManager;
17+
use OCP\Share\IShare;
1518
use Sabre\DAV\Auth\Backend\AbstractBearer;
1619
use Sabre\HTTP\RequestInterface;
1720
use Sabre\HTTP\ResponseInterface;
@@ -23,6 +26,7 @@ public function __construct(
2326
private IRequest $request,
2427
private IConfig $config,
2528
private string $principalPrefix = 'principals/users/',
29+
private string $token = '',
2630
) {
2731
// setup realm
2832
$defaults = new Defaults();
@@ -41,6 +45,15 @@ private function setupUserFs($userId) {
4145
#[\Override]
4246
public function validateBearerToken($bearerToken) {
4347
\OC_Util::setupFS();
48+
$this->token = $bearerToken;
49+
50+
// public.php sets incognito mode for anonymous share access, which makes
51+
// Session::getUser() return null and consequently Session::isLoggedIn()
52+
// return false even after a successful token login. Disable it here so
53+
// the logged-in user is visible for the rest of the request. If the
54+
// bearer token is invalid and Sabre falls back to one of the public
55+
// auth backends, that backend will re-enable incognito mode itself.
56+
\OC_User::setIncognitoMode(false);
4457

4558
if (!$this->userSession->isLoggedIn()) {
4659
$this->userSession->tryTokenLogin($this->request);
@@ -52,6 +65,12 @@ public function validateBearerToken($bearerToken) {
5265
return false;
5366
}
5467

68+
public function getShare(): IShare {
69+
$shareManager = Server::get(IManager::class);
70+
$share = $shareManager->getShareByToken($this->token);
71+
return $share;
72+
}
73+
5574
/**
5675
* \Sabre\DAV\Auth\Backend\AbstractBearer::challenge sets an WWW-Authenticate
5776
* header which some DAV clients can't handle. Thus we override this function

0 commit comments

Comments
 (0)