FilesDropPlugin.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OCA\DAV\Files\Sharing;
  7. use OC\Files\View;
  8. use OCP\Share\IShare;
  9. use Sabre\DAV\Exception\MethodNotAllowed;
  10. use Sabre\DAV\ServerPlugin;
  11. use Sabre\HTTP\RequestInterface;
  12. use Sabre\HTTP\ResponseInterface;
  13. /**
  14. * Make sure that the destination is writable
  15. */
  16. class FilesDropPlugin extends ServerPlugin {
  17. private ?View $view = null;
  18. private ?IShare $share = null;
  19. private bool $enabled = false;
  20. public function setView(View $view): void {
  21. $this->view = $view;
  22. }
  23. public function setShare(IShare $share): void {
  24. $this->share = $share;
  25. }
  26. public function enable(): void {
  27. $this->enabled = true;
  28. }
  29. /**
  30. * This initializes the plugin.
  31. *
  32. * @param \Sabre\DAV\Server $server Sabre server
  33. *
  34. * @return void
  35. * @throws MethodNotAllowed
  36. */
  37. public function initialize(\Sabre\DAV\Server $server): void {
  38. $server->on('beforeMethod:*', [$this, 'beforeMethod'], 999);
  39. $this->enabled = false;
  40. }
  41. public function beforeMethod(RequestInterface $request, ResponseInterface $response): void {
  42. if (!$this->enabled || $this->share === null || $this->view === null) {
  43. return;
  44. }
  45. // Only allow file drop
  46. if ($request->getMethod() !== 'PUT') {
  47. throw new MethodNotAllowed('Only PUT is allowed on files drop');
  48. }
  49. // Always upload at the root level
  50. $path = explode('/', $request->getPath());
  51. $path = array_pop($path);
  52. // Extract the attributes for the file request
  53. $isFileRequest = false;
  54. $attributes = $this->share->getAttributes();
  55. $nickName = $request->hasHeader('X-NC-Nickname') ? urldecode($request->getHeader('X-NC-Nickname')) : null;
  56. if ($attributes !== null) {
  57. $isFileRequest = $attributes->getAttribute('fileRequest', 'enabled') === true;
  58. }
  59. // We need a valid nickname for file requests
  60. if ($isFileRequest && ($nickName == null || trim($nickName) === '')) {
  61. throw new MethodNotAllowed('Nickname is required for file requests');
  62. }
  63. // If this is a file request we need to create a folder for the user
  64. if ($isFileRequest) {
  65. // Check if the folder already exists
  66. if (!($this->view->file_exists($nickName) === true)) {
  67. $this->view->mkdir($nickName);
  68. }
  69. // Put all files in the subfolder
  70. $path = $nickName . '/' . $path;
  71. }
  72. $newName = \OC_Helper::buildNotExistingFileNameForView('/', $path, $this->view);
  73. $url = $request->getBaseUrl() . $newName;
  74. $request->setUrl($url);
  75. }
  76. }