diff options
Diffstat (limited to 'apps/dav/lib/connector/sabre/fakelockerplugin.php')
-rw-r--r-- | apps/dav/lib/connector/sabre/fakelockerplugin.php | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/apps/dav/lib/connector/sabre/fakelockerplugin.php b/apps/dav/lib/connector/sabre/fakelockerplugin.php new file mode 100644 index 00000000000..493d3b0ade4 --- /dev/null +++ b/apps/dav/lib/connector/sabre/fakelockerplugin.php @@ -0,0 +1,159 @@ +<?php +/** + * @author Lukas Reschke <lukas@owncloud.com> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @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\Connector\Sabre; + +use Sabre\DAV\Locks\LockInfo; +use Sabre\DAV\Property\LockDiscovery; +use Sabre\DAV\Property\SupportedLock; +use Sabre\DAV\ServerPlugin; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; +use Sabre\DAV\PropFind; +use Sabre\DAV\INode; + +/** + * Class FakeLockerPlugin is a plugin only used when connections come in from + * OS X via Finder. The fake locking plugin does emulate Class 2 WebDAV support + * (locking of files) which allows Finder to access the storage in write mode as + * well. + * + * No real locking is performed, instead the plugin just returns always positive + * responses. + * + * @see https://github.com/owncloud/core/issues/17732 + * @package OCA\DAV\Connector\Sabre + */ +class FakeLockerPlugin extends ServerPlugin { + /** @var \Sabre\DAV\Server */ + private $server; + + /** {@inheritDoc} */ + public function initialize(\Sabre\DAV\Server $server) { + $this->server = $server; + $this->server->on('method:LOCK', [$this, 'fakeLockProvider'], 1); + $this->server->on('method:UNLOCK', [$this, 'fakeUnlockProvider'], 1); + $server->on('propFind', [$this, 'propFind']); + $server->on('validateTokens', [$this, 'validateTokens']); + } + + /** + * Indicate that we support LOCK and UNLOCK + * + * @param string $path + * @return array + */ + public function getHTTPMethods($path) { + return [ + 'LOCK', + 'UNLOCK', + ]; + } + + /** + * Indicate that we support locking + * + * @return array + */ + function getFeatures() { + return [2]; + } + + /** + * Return some dummy response for PROPFIND requests with regard to locking + * + * @param PropFind $propFind + * @param INode $node + * @return void + */ + function propFind(PropFind $propFind, INode $node) { + $propFind->handle('{DAV:}supportedlock', function() { + return new SupportedLock(true); + }); + $propFind->handle('{DAV:}lockdiscovery', function() use ($propFind) { + return new LockDiscovery([]); + }); + } + + /** + * Mark a locking token always as valid + * + * @param RequestInterface $request + * @param array $conditions + */ + public function validateTokens(RequestInterface $request, &$conditions) { + foreach($conditions as &$fileCondition) { + if(isset($fileCondition['tokens'])) { + foreach($fileCondition['tokens'] as &$token) { + if(isset($token['token'])) { + if(substr($token['token'], 0, 16) === 'opaquelocktoken:') { + $token['validToken'] = true; + } + } + } + } + } + } + + /** + * Fakes a successful LOCK + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + public function fakeLockProvider(RequestInterface $request, + ResponseInterface $response) { + $dom = new \DOMDocument('1.0', 'utf-8'); + $prop = $dom->createElementNS('DAV:', 'd:prop'); + $dom->appendChild($prop); + + $lockDiscovery = $dom->createElementNS('DAV:', 'd:lockdiscovery'); + $prop->appendChild($lockDiscovery); + + $lockInfo = new LockInfo(); + $lockInfo->token = md5($request->getPath()); + $lockInfo->uri = $request->getPath(); + $lockInfo->depth = \Sabre\DAV\Server::DEPTH_INFINITY; + $lockInfo->timeout = 1800; + + $lockObj = new LockDiscovery([$lockInfo]); + $lockObj->serialize($this->server, $lockDiscovery); + + $response->setBody($dom->saveXML()); + + return false; + } + + /** + * Fakes a successful LOCK + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + public function fakeUnlockProvider(RequestInterface $request, + ResponseInterface $response) { + $response->setStatus(204); + $response->setHeader('Content-Length', '0'); + return false; + } +} |