LockPlugin.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\DAV\Connector\Sabre;
  8. use OCA\DAV\Connector\Sabre\Exception\FileLocked;
  9. use OCP\Lock\ILockingProvider;
  10. use OCP\Lock\LockedException;
  11. use Sabre\DAV\Exception\NotFound;
  12. use Sabre\DAV\ServerPlugin;
  13. use Sabre\HTTP\RequestInterface;
  14. class LockPlugin extends ServerPlugin {
  15. /**
  16. * Reference to main server object
  17. *
  18. * @var \Sabre\DAV\Server
  19. */
  20. private $server;
  21. /**
  22. * State of the lock
  23. *
  24. * @var bool
  25. */
  26. private $isLocked;
  27. /**
  28. * {@inheritdoc}
  29. */
  30. public function initialize(\Sabre\DAV\Server $server) {
  31. $this->server = $server;
  32. $this->server->on('beforeMethod:*', [$this, 'getLock'], 50);
  33. $this->server->on('afterMethod:*', [$this, 'releaseLock'], 50);
  34. $this->isLocked = false;
  35. }
  36. public function getLock(RequestInterface $request) {
  37. // we can't listen on 'beforeMethod:PUT' due to order of operations with setting up the tree
  38. // so instead we limit ourselves to the PUT method manually
  39. if ($request->getMethod() !== 'PUT') {
  40. return;
  41. }
  42. try {
  43. $node = $this->server->tree->getNodeForPath($request->getPath());
  44. } catch (NotFound $e) {
  45. return;
  46. }
  47. if ($node instanceof Node) {
  48. try {
  49. $node->acquireLock(ILockingProvider::LOCK_SHARED);
  50. } catch (LockedException $e) {
  51. throw new FileLocked($e->getMessage(), $e->getCode(), $e);
  52. }
  53. $this->isLocked = true;
  54. }
  55. }
  56. public function releaseLock(RequestInterface $request) {
  57. // don't try to release the lock if we never locked one
  58. if ($this->isLocked === false) {
  59. return;
  60. }
  61. if ($request->getMethod() !== 'PUT') {
  62. return;
  63. }
  64. try {
  65. $node = $this->server->tree->getNodeForPath($request->getPath());
  66. } catch (NotFound $e) {
  67. return;
  68. }
  69. if ($node instanceof Node) {
  70. $node->releaseLock(ILockingProvider::LOCK_SHARED);
  71. $this->isLocked = false;
  72. }
  73. }
  74. }