diff --git a/apps/dav/lib/DAV/PublicAuth.php b/apps/dav/lib/DAV/PublicAuth.php
index c637e7929b01..ea1160fa4ab3 100644
--- a/apps/dav/lib/DAV/PublicAuth.php
+++ b/apps/dav/lib/DAV/PublicAuth.php
@@ -29,9 +29,6 @@ class PublicAuth implements BackendInterface {
/** @var string[] */
private $publicURLs;
- /**
- * @param string[] $publicURLs
- */
public function __construct() {
$this->publicURLs = [
'public-calendars',
diff --git a/apps/dav/lib/Files/PublicFiles/PublicSharingAuth.php b/apps/dav/lib/Files/PublicFiles/PublicSharingAuth.php
new file mode 100644
index 000000000000..e449d174473b
--- /dev/null
+++ b/apps/dav/lib/Files/PublicFiles/PublicSharingAuth.php
@@ -0,0 +1,116 @@
+
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+namespace OCA\DAV\Files\PublicFiles;
+
+use OCP\Share\IManager;
+use OCP\Share\IShare;
+use Sabre\DAV\Auth\Backend\AbstractBasic;
+use Sabre\DAV\Server;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
+
+class PublicSharingAuth extends AbstractBasic {
+
+ /** @var Server */
+ private $server;
+ /** @var IShare */
+ private $share;
+ /** @var IManager */
+ private $shareManager;
+
+ /**
+ * PublicSharingAuth constructor.
+ *
+ * @param Server $server
+ */
+ public function __construct(Server $server, IManager $manager) {
+ $this->server = $server;
+ $this->shareManager = $manager;
+ $this->principalPrefix = 'principals/system/';
+ $this->setRealm('owncloud/share');
+ }
+
+ /**
+ * When this method is called, the backend must check if authentication was
+ * successful.
+ *
+ * The returned value must be one of the following
+ *
+ * [true, "principals/username"]
+ * [false, "reason for failure"]
+ *
+ * If authentication was successful, it's expected that the authentication
+ * backend returns a so-called principal url.
+ *
+ * Examples of a principal url:
+ *
+ * principals/admin
+ * principals/user1
+ * principals/users/joe
+ * principals/uid/123457
+ *
+ * If you don't use WebDAV ACL (RFC3744) we recommend that you simply
+ * return a string such as:
+ *
+ * principals/users/[username]
+ *
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @return array
+ */
+ function check(RequestInterface $request, ResponseInterface $response) {
+
+ $node = $this->server->tree->getNodeForPath($request->getPath());
+ if (!$node instanceof ShareNode && !$node instanceof SharedFile && !$node instanceof SharedFolder) {
+ return [true, "principals/system/public"];
+ }
+ $this->share = $node->getShare();
+ $password = $this->share->getPassword();
+ if ($password === null) {
+ return [true, "principals/system/public"];
+ }
+
+ return parent::check($request, $response);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ function challenge(RequestInterface $request, ResponseInterface $response) {
+ }
+
+ /**
+ * Validates a username and password
+ *
+ * This method should return true or false depending on if login
+ * succeeded.
+ *
+ * @param string $username
+ * @param string $password
+ * @return bool
+ */
+ protected function validateUserPass($username, $password) {
+ if ($username !== 'public') {
+ return false;
+ }
+ return $this->shareManager->checkPassword($this->share, $password);
+ }
+}
diff --git a/apps/dav/lib/Files/PublicFiles/RootCollection.php b/apps/dav/lib/Files/PublicFiles/RootCollection.php
new file mode 100644
index 000000000000..fb361b3cf6f2
--- /dev/null
+++ b/apps/dav/lib/Files/PublicFiles/RootCollection.php
@@ -0,0 +1,87 @@
+
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\DAV\Files\PublicFiles;
+
+use OC\Share\Constants;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IManager;
+use OCP\Share\IShare;
+use Sabre\DAV\Collection;
+use Sabre\DAV\Exception\MethodNotAllowed;
+use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\SimpleCollection;
+use Sabre\DAV\SimpleFile;
+
+class RootCollection extends Collection {
+
+ /** @var IManager */
+ private $shareManager;
+ /** @var \OCP\IL10N */
+ protected $l10n;
+
+ /**
+ * If this value is set to true, it effectively disables listing of users
+ * it still allows user to find other users if they have an exact url.
+ *
+ * @var bool
+ */
+ public $disableListing = false;
+
+ function __construct() {
+ $this->l10n = \OC::$server->getL10N('dav');
+ $this->shareManager = \OC::$server->getShareManager();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ function getName() {
+ return 'public-files';
+ }
+
+ /**
+ * @inheritdoc
+ */
+ function getChild($name) {
+ try {
+ $share = $this->shareManager->getShareByToken($name);
+ $password = $share->getPassword();
+ return new ShareNode($share);
+ } catch (ShareNotFound $ex) {
+ throw new NotFound();
+ }
+ }
+
+ /**
+ * @inheritdoc
+ */
+ function getChildren() {
+ if ($this->disableListing) {
+ throw new MethodNotAllowed('Listing members of this collection is disabled');
+ }
+
+ $shares = $this->shareManager->getAllSharedWith(null, [Constants::SHARE_TYPE_LINK]);
+ return array_map(function(IShare $share) {
+ return new ShareNode($share);
+ }, $shares);
+ }
+}
diff --git a/apps/dav/lib/Files/PublicFiles/ShareNode.php b/apps/dav/lib/Files/PublicFiles/ShareNode.php
new file mode 100644
index 000000000000..76b13a42404b
--- /dev/null
+++ b/apps/dav/lib/Files/PublicFiles/ShareNode.php
@@ -0,0 +1,59 @@
+share = $share;
+ }
+ /**
+ * Returns an array with all the child nodes
+ *
+ * @return INode[]
+ */
+ function getChildren() {
+ if ($this->share->getNodeType() === 'folder') {
+ $nodes = $this->share->getNode()->getDirectoryListing();
+ } else {
+ $nodes = [$this->share->getNode()];
+ }
+ return array_map(function(Node $node) {
+ if ($node->getType() === FileInfo::TYPE_FOLDER) {
+ return new SharedFolder($node, $this->share);
+ }
+ return new SharedFile($node, $this->share);
+ }, $nodes);
+ }
+
+ /**
+ * Returns the name of the node.
+ *
+ * This is used to generate the url.
+ *
+ * @return string
+ */
+ function getName() {
+ return $this->share->getToken();
+ }
+
+ function getShare() {
+ return $this->share;
+ }
+}
\ No newline at end of file
diff --git a/apps/dav/lib/Files/PublicFiles/SharedFile.php b/apps/dav/lib/Files/PublicFiles/SharedFile.php
new file mode 100644
index 000000000000..e67087287d66
--- /dev/null
+++ b/apps/dav/lib/Files/PublicFiles/SharedFile.php
@@ -0,0 +1,109 @@
+
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+
+namespace OCA\DAV\Files\PublicFiles;
+
+
+use OCP\Share\IShare;
+use Sabre\DAV\File;
+use Sabre\DAVACL\ACLTrait;
+use Sabre\DAVACL\IACL;
+
+/**
+ * Class MetaFile
+ * This is a Sabre based implementation of a file living in the /meta resource.
+ *
+ * @package OCA\DAV\Meta
+ */
+class SharedFile extends File implements IACL {
+
+ use ACLTrait;
+
+ /** @var \OCP\Files\File */
+ private $file;
+
+ /**
+ * MetaFolder constructor.
+ *
+ * @param \OCP\Files\File $file
+ * @param IShare $share
+ */
+ public function __construct(\OCP\Files\File $file, IShare $share) {
+ $this->file = $file;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ function getName() {
+ return $this->file->getName();
+ }
+
+ public function getSize() {
+ return $this->file->getSize();
+ }
+
+ public function getContentType() {
+ return $this->file->getMimeType();
+ }
+
+ public function getETag() {
+ return $this->file->getETag();
+ }
+
+ function getLastModified() {
+ return $this->file->getMTime();
+ }
+
+ function delete() {
+ // TODO: check permissions - via ACL?
+ $this->file->delete();
+ }
+
+// function setName($name) {
+// $this->file->setName($name);
+// }
+
+ function getOwner() {
+ return '';
+ }
+
+ function getACL() {
+ return [
+ [
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
+ 'protected' => true,
+ ],
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/system/public',
+ 'protected' => true,
+ ]
+ ];
+ }
+
+ function getShare() {
+ return $this->share;
+ }
+
+}
diff --git a/apps/dav/lib/Files/PublicFiles/SharedFolder.php b/apps/dav/lib/Files/PublicFiles/SharedFolder.php
new file mode 100644
index 000000000000..8136be752e61
--- /dev/null
+++ b/apps/dav/lib/Files/PublicFiles/SharedFolder.php
@@ -0,0 +1,132 @@
+
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+
+namespace OCA\DAV\Files\PublicFiles;
+
+
+use OCP\Constants;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\Node;
+use OCP\Share\IShare;
+use Sabre\DAV\Collection;
+use Sabre\DAVACL\ACLTrait;
+use Sabre\DAVACL\IACL;
+
+/**
+ * Class MetaFolder
+ * This is a Sabre based implementation of a folder living in the /meta resource.
+ *
+ * @package OCA\DAV\Meta
+ */
+class SharedFolder extends Collection implements IACL {
+ use ACLTrait;
+
+ /** @var Folder */
+ private $folder;
+ /** @var IShare */
+ private $share;
+
+ /**
+ * MetaFolder constructor.
+ *
+ * @param Folder $folder
+ */
+ public function __construct(Folder $folder, IShare $share) {
+ $this->folder = $folder;
+ $this->share = $share;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ function getChildren() {
+ $nodes = $this->folder->getDirectoryListing();
+ return array_map(function($node) {
+ return $this->nodeFactory($node);
+ }, $nodes);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ function getName() {
+ return $this->folder->getName();
+ }
+
+ function getLastModified() {
+ return $this->folder->getMTime();
+ }
+
+ function createDirectory($name) {
+ $this->folder->newFolder($name);
+ }
+
+ function createFile($name, $data = null) {
+ $file = $this->folder->newFile($name);
+ $file->putContent($data);
+
+ }
+
+ private function nodeFactory(Node $node) {
+ if ($node instanceof Folder) {
+ return new SharedFolder($node, $this->share);
+ }
+ if ($node instanceof File) {
+ return new SharedFile($node, $this->share);
+ }
+ throw new \InvalidArgumentException();
+ }
+
+ function getACL() {
+ $acl = [
+ [
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
+ 'protected' => true,
+ ],
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/system/public',
+ 'protected' => true,
+ ]
+ ];
+
+ // TODO: add more acl to convert the logic
+ if ($this->share->getPermissions() & Constants::PERMISSION_DELETE === Constants::PERMISSION_DELETE) {
+ $acl[]= [
+ [
+ 'privilege' => '{DAV:}unbind',
+ 'principal' => 'principals/system/public',
+ 'protected' => true,
+ ]
+ ];
+ }
+
+ return $acl;
+ }
+
+ function getShare() {
+ return $this->share;
+ }
+
+}
diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php
index 3f5ab59d2c8f..29e5031f8314 100644
--- a/apps/dav/lib/RootCollection.php
+++ b/apps/dav/lib/RootCollection.php
@@ -64,6 +64,8 @@ public function __construct() {
$calendarRoot->disableListing = $disableListing;
$publicCalendarRoot = new PublicCalendarRoot($caldavBackend);
$publicCalendarRoot->disableListing = $disableListing;
+ $publicFilesRoot = new Files\PublicFiles\RootCollection();
+ $publicFilesRoot->disableListing = $disableListing;
$systemTagCollection = new SystemTag\SystemTagsByIdCollection(
\OC::$server->getSystemTagManager(),
@@ -107,7 +109,8 @@ public function __construct() {
$systemTagRelationsCollection,
$uploadCollection,
$avatarCollection,
- new \OCA\DAV\Meta\RootCollection(\OC::$server->getRootFolder())
+ new \OCA\DAV\Meta\RootCollection(\OC::$server->getRootFolder()),
+ $publicFilesRoot
];
parent::__construct('root', $children);
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index f0ccc621b8e7..53c2032bebd9 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -51,6 +51,7 @@
use OCA\DAV\Files\BrowserErrorPagePlugin;
use OCA\DAV\Files\PreviewPlugin;
use OCA\DAV\Files\ZsyncPlugin;
+use OCA\DAV\Files\PublicFiles\PublicSharingAuth;
use OCA\DAV\SystemTag\SystemTagPlugin;
use OCA\DAV\Upload\ChunkingPlugin;
use OCA\DAV\Upload\ChunkingPluginZsync;
@@ -103,6 +104,7 @@ public function __construct(IRequest $request, $baseUri) {
$this->server->addPlugin(new BlockLegacyClientPlugin($config));
$this->server->addPlugin(new CorsPlugin(\OC::$server->getUserSession()));
$authPlugin = new Plugin();
+ $authPlugin->addBackend(new PublicSharingAuth($this->server, \OC::$server->getShareManager()));
$authPlugin->addBackend(new PublicAuth());
$this->server->addPlugin($authPlugin);
diff --git a/lib/private/Files/Node/Node.php b/lib/private/Files/Node/Node.php
index a4af937fe7c8..f90dfaabfd25 100644
--- a/lib/private/Files/Node/Node.php
+++ b/lib/private/Files/Node/Node.php
@@ -425,4 +425,7 @@ public function move($targetPath) {
}
}
+ public function getView() {
+ return $this->view;
+ }
}