summaryrefslogtreecommitdiffstats
path: root/apps/dav
diff options
context:
space:
mode:
authorLukas Reschke <lukas@statuscode.ch>2017-05-18 23:30:44 +0200
committerGitHub <noreply@github.com>2017-05-18 23:30:44 +0200
commit0eb4970ec8981d112a412a4858833459533b158a (patch)
tree4604252f8c26906dd2af1804d531465e0cb2d7f1 /apps/dav
parentc60547295025eec862ee1ea9a3f5009f901f8bc2 (diff)
parentf4189699e7348615eeb0e528bc5395d818d301ea (diff)
downloadnextcloud-server-0eb4970ec8981d112a412a4858833459533b158a.tar.gz
nextcloud-server-0eb4970ec8981d112a412a4858833459533b158a.zip
Merge pull request #4704 from nextcloud/add-oauth-code-flow-support
Add oauth code flow support
Diffstat (limited to 'apps/dav')
-rw-r--r--apps/dav/appinfo/v1/publicwebdav.php3
-rw-r--r--apps/dav/appinfo/v1/webdav.php10
-rw-r--r--apps/dav/lib/Connector/Sabre/Auth.php1
-rw-r--r--apps/dav/lib/Connector/Sabre/BearerAuth.php80
-rw-r--r--apps/dav/lib/Connector/Sabre/ServerFactory.php7
-rw-r--r--apps/dav/lib/Server.php8
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/BearerAuthTest.php88
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php3
8 files changed, 194 insertions, 6 deletions
diff --git a/apps/dav/appinfo/v1/publicwebdav.php b/apps/dav/appinfo/v1/publicwebdav.php
index 95fb71032d5..3ef1c2e62a5 100644
--- a/apps/dav/appinfo/v1/publicwebdav.php
+++ b/apps/dav/appinfo/v1/publicwebdav.php
@@ -42,6 +42,7 @@ $authBackend = new OCA\DAV\Connector\PublicAuth(
\OC::$server->getShareManager(),
\OC::$server->getSession()
);
+$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
$serverFactory = new OCA\DAV\Connector\Sabre\ServerFactory(
\OC::$server->getConfig(),
@@ -59,7 +60,7 @@ $requestUri = \OC::$server->getRequest()->getRequestUri();
$linkCheckPlugin = new \OCA\DAV\Files\Sharing\PublicLinkCheckPlugin();
$filesDropPlugin = new \OCA\DAV\Files\Sharing\FilesDropPlugin();
-$server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
+$server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
$isAjax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
$federatedSharingApp = new \OCA\FederatedFileSharing\AppInfo\Application();
$federatedShareProvider = $federatedSharingApp->getFederatedShareProvider();
diff --git a/apps/dav/appinfo/v1/webdav.php b/apps/dav/appinfo/v1/webdav.php
index 32f93b27760..a1ad4ab489d 100644
--- a/apps/dav/appinfo/v1/webdav.php
+++ b/apps/dav/appinfo/v1/webdav.php
@@ -52,9 +52,17 @@ $authBackend = new \OCA\DAV\Connector\Sabre\Auth(
\OC::$server->getBruteForceThrottler(),
'principals/'
);
+$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
+$bearerAuthPlugin = new \OCA\DAV\Connector\Sabre\BearerAuth(
+ \OC::$server->getUserSession(),
+ \OC::$server->getSession(),
+ \OC::$server->getRequest()
+);
+$authPlugin->addBackend($bearerAuthPlugin);
+
$requestUri = \OC::$server->getRequest()->getRequestUri();
-$server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, function() {
+$server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function() {
// use the view for the logged in user
return \OC\Files\Filesystem::getView();
});
diff --git a/apps/dav/lib/Connector/Sabre/Auth.php b/apps/dav/lib/Connector/Sabre/Auth.php
index bdaf73d46e7..9147e79594c 100644
--- a/apps/dav/lib/Connector/Sabre/Auth.php
+++ b/apps/dav/lib/Connector/Sabre/Auth.php
@@ -210,6 +210,7 @@ class Auth extends AbstractBasic {
*/
private function auth(RequestInterface $request, ResponseInterface $response) {
$forcedLogout = false;
+
if(!$this->request->passesCSRFCheck() &&
$this->requiresCSRFCheck()) {
// In case of a fail with POST we need to recheck the credentials
diff --git a/apps/dav/lib/Connector/Sabre/BearerAuth.php b/apps/dav/lib/Connector/Sabre/BearerAuth.php
new file mode 100644
index 00000000000..f0e0f389c33
--- /dev/null
+++ b/apps/dav/lib/Connector/Sabre/BearerAuth.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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 OCA\DAV\Connector\Sabre;
+
+use OCP\IRequest;
+use OCP\ISession;
+use OCP\IUserSession;
+use Sabre\DAV\Auth\Backend\AbstractBearer;
+
+class BearerAuth extends AbstractBearer {
+ /** @var IUserSession */
+ private $userSession;
+ /** @var ISession */
+ private $session;
+ /** @var IRequest */
+ private $request;
+ /** @var string */
+ private $principalPrefix;
+
+ /**
+ * @param IUserSession $userSession
+ * @param ISession $session
+ * @param string $principalPrefix
+ * @param IRequest $request
+ */
+ public function __construct(IUserSession $userSession,
+ ISession $session,
+ IRequest $request,
+ $principalPrefix = 'principals/users/') {
+ $this->userSession = $userSession;
+ $this->session = $session;
+ $this->request = $request;
+ $this->principalPrefix = $principalPrefix;
+
+ // setup realm
+ $defaults = new \OCP\Defaults();
+ $this->realm = $defaults->getName();
+ }
+
+ private function setupUserFs($userId) {
+ \OC_Util::setupFS($userId);
+ $this->session->close();
+ return $this->principalPrefix . $userId;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateBearerToken($bearerToken) {
+ \OC_Util::setupFS();
+
+ if(!$this->userSession->isLoggedIn()) {
+ $this->userSession->tryTokenLogin($this->request);
+ }
+ if($this->userSession->isLoggedIn()) {
+ return $this->setupUserFs($this->userSession->getUser()->getUID());
+ }
+
+ return false;
+ }
+}
diff --git a/apps/dav/lib/Connector/Sabre/ServerFactory.php b/apps/dav/lib/Connector/Sabre/ServerFactory.php
index f04362dfc08..329aa335ea4 100644
--- a/apps/dav/lib/Connector/Sabre/ServerFactory.php
+++ b/apps/dav/lib/Connector/Sabre/ServerFactory.php
@@ -40,6 +40,7 @@ use OCP\IRequest;
use OCP\ITagManager;
use OCP\IUserSession;
use Sabre\DAV\Auth\Backend\BackendInterface;
+use Sabre\DAV\Auth\Plugin;
class ServerFactory {
/** @var IConfig */
@@ -92,13 +93,13 @@ class ServerFactory {
/**
* @param string $baseUri
* @param string $requestUri
- * @param BackendInterface $authBackend
+ * @param Plugin $authPlugin
* @param callable $viewCallBack callback that should return the view for the dav endpoint
* @return Server
*/
public function createServer($baseUri,
$requestUri,
- BackendInterface $authBackend,
+ Plugin $authPlugin,
callable $viewCallBack) {
// Fire up server
$objectTree = new \OCA\DAV\Connector\Sabre\ObjectTree();
@@ -110,7 +111,7 @@ class ServerFactory {
// Load plugins
$server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config));
$server->addPlugin(new \OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin($this->config));
- $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
+ $server->addPlugin($authPlugin);
// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
$server->addPlugin(new \OCA\DAV\Connector\Sabre\DummyGetResponsePlugin());
$server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger));
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index df5b0ea05b6..994ac04033a 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -33,6 +33,7 @@ use OCA\DAV\CardDAV\ImageExportPlugin;
use OCA\DAV\CardDAV\PhotoCache;
use OCA\DAV\Comments\CommentsPlugin;
use OCA\DAV\Connector\Sabre\Auth;
+use OCA\DAV\Connector\Sabre\BearerAuth;
use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin;
use OCA\DAV\Connector\Sabre\CommentPropertiesPlugin;
use OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin;
@@ -52,6 +53,7 @@ use OCP\SabrePluginEvent;
use Sabre\CardDAV\VCFExportPlugin;
use Sabre\DAV\Auth\Plugin;
use OCA\DAV\Connector\Sabre\TagsPlugin;
+use Sabre\HTTP\Auth\Bearer;
use SearchDAV\DAV\SearchPlugin;
class Server {
@@ -100,6 +102,12 @@ class Server {
$event = new SabrePluginEvent($this->server);
$dispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
+ $bearerAuthBackend = new BearerAuth(
+ \OC::$server->getUserSession(),
+ \OC::$server->getSession(),
+ \OC::$server->getRequest()
+ );
+ $authPlugin->addBackend($bearerAuthBackend);
// because we are throwing exceptions this plugin has to be the last one
$authPlugin->addBackend($authBackend);
diff --git a/apps/dav/tests/unit/Connector/Sabre/BearerAuthTest.php b/apps/dav/tests/unit/Connector/Sabre/BearerAuthTest.php
new file mode 100644
index 00000000000..5eae75eb8e9
--- /dev/null
+++ b/apps/dav/tests/unit/Connector/Sabre/BearerAuthTest.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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 OCA\DAV\Tests\unit\Connector\Sabre;
+
+use OC\Authentication\TwoFactorAuth\Manager;
+use OC\Security\Bruteforce\Throttler;
+use OC\User\Session;
+use OCA\DAV\Connector\Sabre\BearerAuth;
+use OCP\IRequest;
+use OCP\ISession;
+use OCP\IUser;
+use OCP\IUserSession;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class BearerAuthTest extends TestCase {
+ /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
+ private $userSession;
+ /** @var ISession|\PHPUnit_Framework_MockObject_MockObject */
+ private $session;
+ /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
+ private $request;
+ /** @var BearerAuth */
+ private $bearerAuth;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->userSession = $this->createMock(\OC\User\Session::class);
+ $this->session = $this->createMock(ISession::class);
+ $this->request = $this->createMock(IRequest::class);
+
+ $this->bearerAuth = new BearerAuth(
+ $this->userSession,
+ $this->session,
+ $this->request
+ );
+ }
+
+ public function testValidateBearerTokenNotLoggedIn() {
+ $this->assertFalse($this->bearerAuth->validateBearerToken('Token'));
+ }
+
+ public function testValidateBearerToken() {
+ $this->userSession
+ ->expects($this->at(0))
+ ->method('isLoggedIn')
+ ->willReturn(false);
+ $this->userSession
+ ->expects($this->at(2))
+ ->method('isLoggedIn')
+ ->willReturn(true);
+ $user = $this->createMock(IUser::class);
+ $user
+ ->expects($this->once())
+ ->method('getUID')
+ ->willReturn('admin');
+ $this->userSession
+ ->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user);
+
+ $this->assertSame('principals/users/admin', $this->bearerAuth->validateBearerToken('Token'));
+ }
+}
diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php
index 50e228b7e84..58a729e18ec 100644
--- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php
+++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php
@@ -138,8 +138,9 @@ abstract class RequestTestCase extends TestCase {
*/
protected function getSabreServer(View $view, $user, $password, ExceptionPlugin $exceptionPlugin) {
$authBackend = new Auth($user, $password);
+ $authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
- $server = $this->serverFactory->createServer('/', 'dummy', $authBackend, function () use ($view) {
+ $server = $this->serverFactory->createServer('/', 'dummy', $authPlugin, function () use ($view) {
return $view;
});
$server->addPlugin($exceptionPlugin);