FakeLockerPlugin.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Lukas Reschke <lukas@statuscode.ch>
  6. * @author Thomas Müller <thomas.mueller@tmit.eu>
  7. *
  8. * @license AGPL-3.0
  9. *
  10. * This code is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License, version 3,
  12. * as published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License, version 3,
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>
  21. *
  22. */
  23. namespace OCA\DAV\Connector\Sabre;
  24. use Sabre\DAV\Locks\LockInfo;
  25. use Sabre\DAV\ServerPlugin;
  26. use Sabre\DAV\Xml\Property\LockDiscovery;
  27. use Sabre\DAV\Xml\Property\SupportedLock;
  28. use Sabre\HTTP\RequestInterface;
  29. use Sabre\HTTP\ResponseInterface;
  30. use Sabre\DAV\PropFind;
  31. use Sabre\DAV\INode;
  32. /**
  33. * Class FakeLockerPlugin is a plugin only used when connections come in from
  34. * OS X via Finder. The fake locking plugin does emulate Class 2 WebDAV support
  35. * (locking of files) which allows Finder to access the storage in write mode as
  36. * well.
  37. *
  38. * No real locking is performed, instead the plugin just returns always positive
  39. * responses.
  40. *
  41. * @see https://github.com/owncloud/core/issues/17732
  42. * @package OCA\DAV\Connector\Sabre
  43. */
  44. class FakeLockerPlugin extends ServerPlugin {
  45. /** @var \Sabre\DAV\Server */
  46. private $server;
  47. /** {@inheritDoc} */
  48. public function initialize(\Sabre\DAV\Server $server) {
  49. $this->server = $server;
  50. $this->server->on('method:LOCK', [$this, 'fakeLockProvider'], 1);
  51. $this->server->on('method:UNLOCK', [$this, 'fakeUnlockProvider'], 1);
  52. $server->on('propFind', [$this, 'propFind']);
  53. $server->on('validateTokens', [$this, 'validateTokens']);
  54. }
  55. /**
  56. * Indicate that we support LOCK and UNLOCK
  57. *
  58. * @param string $path
  59. * @return string[]
  60. */
  61. public function getHTTPMethods($path) {
  62. return [
  63. 'LOCK',
  64. 'UNLOCK',
  65. ];
  66. }
  67. /**
  68. * Indicate that we support locking
  69. *
  70. * @return integer[]
  71. */
  72. function getFeatures() {
  73. return [2];
  74. }
  75. /**
  76. * Return some dummy response for PROPFIND requests with regard to locking
  77. *
  78. * @param PropFind $propFind
  79. * @param INode $node
  80. * @return void
  81. */
  82. function propFind(PropFind $propFind, INode $node) {
  83. $propFind->handle('{DAV:}supportedlock', function() {
  84. return new SupportedLock(true);
  85. });
  86. $propFind->handle('{DAV:}lockdiscovery', function() use ($propFind) {
  87. return new LockDiscovery([]);
  88. });
  89. }
  90. /**
  91. * Mark a locking token always as valid
  92. *
  93. * @param RequestInterface $request
  94. * @param array $conditions
  95. */
  96. public function validateTokens(RequestInterface $request, &$conditions) {
  97. foreach($conditions as &$fileCondition) {
  98. if(isset($fileCondition['tokens'])) {
  99. foreach($fileCondition['tokens'] as &$token) {
  100. if(isset($token['token'])) {
  101. if(substr($token['token'], 0, 16) === 'opaquelocktoken:') {
  102. $token['validToken'] = true;
  103. }
  104. }
  105. }
  106. }
  107. }
  108. }
  109. /**
  110. * Fakes a successful LOCK
  111. *
  112. * @param RequestInterface $request
  113. * @param ResponseInterface $response
  114. * @return bool
  115. */
  116. public function fakeLockProvider(RequestInterface $request,
  117. ResponseInterface $response) {
  118. $lockInfo = new LockInfo();
  119. $lockInfo->token = md5($request->getPath());
  120. $lockInfo->uri = $request->getPath();
  121. $lockInfo->depth = \Sabre\DAV\Server::DEPTH_INFINITY;
  122. $lockInfo->timeout = 1800;
  123. $body = $this->server->xml->write('{DAV:}prop', [
  124. '{DAV:}lockdiscovery' =>
  125. new LockDiscovery([$lockInfo])
  126. ]);
  127. $response->setBody($body);
  128. return false;
  129. }
  130. /**
  131. * Fakes a successful LOCK
  132. *
  133. * @param RequestInterface $request
  134. * @param ResponseInterface $response
  135. * @return bool
  136. */
  137. public function fakeUnlockProvider(RequestInterface $request,
  138. ResponseInterface $response) {
  139. $response->setStatus(204);
  140. $response->setHeader('Content-Length', '0');
  141. return false;
  142. }
  143. }