Skip to content

Commit 8852fda

Browse files
committed
Merge pull request #22789 from owncloud/dav-sharesproperty
Add webdav property for share info in PROPFIND response
2 parents e983bd7 + 6e6e002 commit 8852fda

File tree

13 files changed

+818
-61
lines changed

13 files changed

+818
-61
lines changed

apps/dav/lib/connector/sabre/serverfactory.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ public function createServer($baseUri,
137137

138138
if($this->userSession->isLoggedIn()) {
139139
$server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
140+
$server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin(
141+
$objectTree,
142+
$this->userSession,
143+
$userFolder,
144+
\OC::$server->getShareManager()
145+
));
140146
$server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(\OC::$server->getCommentsManager(), $this->userSession));
141147
$server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin(
142148
$objectTree,
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?php
2+
/**
3+
* @author Vincent Petry <pvince81@owncloud.com>
4+
*
5+
* @copyright Copyright (c) 2016, ownCloud, Inc.
6+
* @license AGPL-3.0
7+
*
8+
* This code is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License, version 3,
10+
* as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Affero General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License, version 3,
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>
19+
*
20+
*/
21+
namespace OCA\DAV\Connector\Sabre;
22+
23+
use \Sabre\DAV\PropFind;
24+
use \Sabre\DAV\PropPatch;
25+
use OCP\IUserSession;
26+
use OCP\Share\IShare;
27+
use OCA\DAV\Connector\Sabre\ShareTypeList;
28+
29+
/**
30+
* Sabre Plugin to provide share-related properties
31+
*/
32+
class SharesPlugin extends \Sabre\DAV\ServerPlugin {
33+
34+
const NS_OWNCLOUD = 'http://owncloud.org/ns';
35+
const SHARETYPES_PROPERTYNAME = '{http://owncloud.org/ns}share-types';
36+
37+
/**
38+
* Reference to main server object
39+
*
40+
* @var \Sabre\DAV\Server
41+
*/
42+
private $server;
43+
44+
/**
45+
* @var \OCP\Share\IManager
46+
*/
47+
private $shareManager;
48+
49+
/**
50+
* @var \Sabre\DAV\Tree
51+
*/
52+
private $tree;
53+
54+
/**
55+
* @var string
56+
*/
57+
private $userId;
58+
59+
/**
60+
* @var \OCP\Files\Folder
61+
*/
62+
private $userFolder;
63+
64+
/**
65+
* @var IShare[]
66+
*/
67+
private $cachedShareTypes;
68+
69+
/**
70+
* @param \Sabre\DAV\Tree $tree tree
71+
* @param IUserSession $userSession user session
72+
* @param \OCP\Files\Folder $userFolder user home folder
73+
* @param \OCP\Share\IManager $shareManager share manager
74+
*/
75+
public function __construct(
76+
\Sabre\DAV\Tree $tree,
77+
IUserSession $userSession,
78+
\OCP\Files\Folder $userFolder,
79+
\OCP\Share\IManager $shareManager
80+
) {
81+
$this->tree = $tree;
82+
$this->shareManager = $shareManager;
83+
$this->userFolder = $userFolder;
84+
$this->userId = $userSession->getUser()->getUID();
85+
$this->cachedShareTypes = [];
86+
}
87+
88+
/**
89+
* This initializes the plugin.
90+
*
91+
* This function is called by \Sabre\DAV\Server, after
92+
* addPlugin is called.
93+
*
94+
* This method should set up the required event subscriptions.
95+
*
96+
* @param \Sabre\DAV\Server $server
97+
*/
98+
public function initialize(\Sabre\DAV\Server $server) {
99+
$server->xml->namespacesMap[self::NS_OWNCLOUD] = 'oc';
100+
$server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = 'OCA\\DAV\\Connector\\Sabre\\ShareTypeList';
101+
$server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME;
102+
103+
$this->server = $server;
104+
$this->server->on('propFind', array($this, 'handleGetProperties'));
105+
}
106+
107+
/**
108+
* Return a list of share types for outgoing shares
109+
*
110+
* @param \OCP\Files\Node $node file node
111+
*
112+
* @return int[] array of share types
113+
*/
114+
private function getShareTypes(\OCP\Files\Node $node) {
115+
$shareTypes = [];
116+
$requestedShareTypes = [
117+
\OCP\Share::SHARE_TYPE_USER,
118+
\OCP\Share::SHARE_TYPE_GROUP,
119+
\OCP\Share::SHARE_TYPE_LINK
120+
];
121+
foreach ($requestedShareTypes as $requestedShareType) {
122+
// one of each type is enough to find out about the types
123+
$shares = $this->shareManager->getSharesBy(
124+
$this->userId,
125+
$requestedShareType,
126+
$node,
127+
false,
128+
1
129+
);
130+
if (!empty($shares)) {
131+
$shareTypes[] = $requestedShareType;
132+
}
133+
}
134+
return $shareTypes;
135+
}
136+
137+
/**
138+
* Adds shares to propfind response
139+
*
140+
* @param PropFind $propFind propfind object
141+
* @param \Sabre\DAV\INode $sabreNode sabre node
142+
*/
143+
public function handleGetProperties(
144+
PropFind $propFind,
145+
\Sabre\DAV\INode $sabreNode
146+
) {
147+
if (!($sabreNode instanceof \OCA\DAV\Connector\Sabre\Node)) {
148+
return;
149+
}
150+
151+
// need prefetch ?
152+
if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory
153+
&& $propFind->getDepth() !== 0
154+
&& !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME))
155+
) {
156+
$folderNode = $this->userFolder->get($propFind->getPath());
157+
$children = $folderNode->getDirectoryListing();
158+
159+
$this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode);
160+
foreach ($children as $childNode) {
161+
$this->cachedShareTypes[$childNode->getId()] = $this->getShareTypes($childNode);
162+
}
163+
}
164+
165+
$propFind->handle(self::SHARETYPES_PROPERTYNAME, function() use ($sabreNode) {
166+
if (isset($this->cachedShareTypes[$sabreNode->getId()])) {
167+
$shareTypes = $this->cachedShareTypes[$sabreNode->getId()];
168+
} else {
169+
$node = $this->userFolder->get($sabreNode->getPath());
170+
$shareTypes = $this->getShareTypes($node);
171+
}
172+
173+
return new ShareTypeList($shareTypes);
174+
});
175+
}
176+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
/**
3+
* @author Vincent Petry <pvince81@owncloud.com>
4+
*
5+
* @copyright Copyright (c) 2016, ownCloud, Inc.
6+
* @license AGPL-3.0
7+
*
8+
* This code is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License, version 3,
10+
* as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Affero General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License, version 3,
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>
19+
*
20+
*/
21+
22+
namespace OCA\DAV\Connector\Sabre;
23+
24+
use Sabre\Xml\Element;
25+
use Sabre\Xml\Reader;
26+
use Sabre\Xml\Writer;
27+
28+
/**
29+
* ShareTypeList property
30+
*
31+
* This property contains multiple "share-type" elements, each containing a share type.
32+
*/
33+
class ShareTypeList implements Element {
34+
const NS_OWNCLOUD = 'http://owncloud.org/ns';
35+
36+
/**
37+
* Share types
38+
*
39+
* @var int[]
40+
*/
41+
private $shareTypes;
42+
43+
/**
44+
* @param int[] $shareTypes
45+
*/
46+
public function __construct($shareTypes) {
47+
$this->shareTypes = $shareTypes;
48+
}
49+
50+
/**
51+
* Returns the share types
52+
*
53+
* @return int[]
54+
*/
55+
public function getShareTypes() {
56+
return $this->shareTypes;
57+
}
58+
59+
/**
60+
* The deserialize method is called during xml parsing.
61+
*
62+
* @param Reader $reader
63+
* @return mixed
64+
*/
65+
static function xmlDeserialize(Reader $reader) {
66+
$shareTypes = [];
67+
68+
foreach ($reader->parseInnerTree() as $elem) {
69+
if ($elem['name'] === '{' . self::NS_OWNCLOUD . '}share-type') {
70+
$shareTypes[] = (int)$elem['value'];
71+
}
72+
}
73+
return new self($shareTypes);
74+
}
75+
76+
/**
77+
* The xmlSerialize metod is called during xml writing.
78+
*
79+
* @param Writer $writer
80+
* @return void
81+
*/
82+
function xmlSerialize(Writer $writer) {
83+
foreach ($this->shareTypes as $shareType) {
84+
$writer->writeElement('{' . self::NS_OWNCLOUD . '}share-type', $shareType);
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)