-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add public-files to DAV #29369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add public-files to DAV #29369
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| <?php | ||
| /** | ||
| * @author Thomas Müller <[email protected]> | ||
| * | ||
| * @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 <http://www.gnu.org/licenses/> | ||
| * | ||
| */ | ||
|
|
||
| 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(); | ||
| // TODO: check password | ||
| 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); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| <?php | ||
| /** | ||
| * Created by PhpStorm. | ||
| * User: deepdiver | ||
| * Date: 26.10.17 | ||
| * Time: 14:40 | ||
| */ | ||
|
|
||
| namespace OCA\DAV\Files\PublicFiles; | ||
|
|
||
|
|
||
| use OCP\Files\FileInfo; | ||
| use OCP\Files\Node; | ||
| use OCP\Share\IShare; | ||
| use Sabre\DAV\Collection; | ||
| use Sabre\DAV\INode; | ||
|
|
||
| class ShareNode extends Collection { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PHPDoc, what is this node about ? |
||
|
|
||
| /** @var IShare */ | ||
| private $share; | ||
|
|
||
| public function __construct(IShare $share) { | ||
| $this->share = $share; | ||
| } | ||
| /** | ||
| * Returns an array with all the child nodes | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest clarifying and saying we are returning both SharedFolder and SharedFile nodes depending on child types |
||
| * | ||
| * @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(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| <?php | ||
| /** | ||
| * @author Thomas Müller <[email protected]> | ||
| * | ||
| * @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 <http://www.gnu.org/licenses/> | ||
| * | ||
| */ | ||
|
|
||
|
|
||
| namespace OCA\DAV\Files\PublicFiles; | ||
|
|
||
|
|
||
| use OCP\Share\IShare; | ||
| use Sabre\DAV\File; | ||
| use Sabre\DAVACL\ACLTrait; | ||
| use Sabre\DAVACL\IACL; | ||
|
|
||
| /** | ||
| * Class MetaFile | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please adjust, smells like copy-pasted from another PR 😉 |
||
| * 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); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can forbid renaming share file here. This is because the name itself isn't visible anyway but someone might attempt to hack the API to try it out. For local shares the file name is a received mount point. But here for link shares this is no mount point. Throw |
||
| // } | ||
|
|
||
| function getOwner() { | ||
| return ''; | ||
| } | ||
|
|
||
| function getACL() { | ||
| return [ | ||
| [ | ||
| 'privilege' => '{DAV:}all', | ||
| 'principal' => '{DAV:}owner', | ||
| 'protected' => true, | ||
| ], | ||
| [ | ||
| 'privilege' => '{DAV:}read', | ||
| 'principal' => 'principals/system/public', | ||
| 'protected' => true, | ||
| ] | ||
| ]; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| <?php | ||
| /** | ||
| * @author Thomas Müller <[email protected]> | ||
| * | ||
| * @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 <http://www.gnu.org/licenses/> | ||
| * | ||
| */ | ||
|
|
||
|
|
||
| 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. phpdoc |
||
| * 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() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add getEtag() maybe. We'll likely do a PROPFIND on this folder so it's good to get the etag to know if there were changes inside the folder. Also add this to SharedFile. Sounds like we might need a custom INode interface which has the getEtag method ? Or does Sabre retrieve the Etag differently ? (I forgot) |
||
| 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; | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use DI ?