You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
5.0 KiB

3 years ago
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Bjoern Schiessle <bjoern@schiessle.org>
  6. * @author Björn Schießle <bjoern@schiessle.org>
  7. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  8. * @author Roeland Jago Douma <roeland@famdouma.nl>
  9. * @author Thomas Müller <thomas.mueller@tmit.eu>
  10. *
  11. * @license AGPL-3.0
  12. *
  13. * This code is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License, version 3,
  15. * as published by the Free Software Foundation.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Affero General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Affero General Public License, version 3,
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>
  24. *
  25. */
  26. namespace OC\Encryption;
  27. use OC\Files\Filesystem;
  28. use OC\Files\Mount;
  29. use OC\Files\View;
  30. /**
  31. * update encrypted files, e.g. because a file was shared
  32. */
  33. class Update {
  34. /** @var \OC\Files\View */
  35. protected $view;
  36. /** @var \OC\Encryption\Util */
  37. protected $util;
  38. /** @var \OC\Files\Mount\Manager */
  39. protected $mountManager;
  40. /** @var \OC\Encryption\Manager */
  41. protected $encryptionManager;
  42. /** @var string */
  43. protected $uid;
  44. /** @var \OC\Encryption\File */
  45. protected $file;
  46. /**
  47. *
  48. * @param \OC\Files\View $view
  49. * @param \OC\Encryption\Util $util
  50. * @param \OC\Files\Mount\Manager $mountManager
  51. * @param \OC\Encryption\Manager $encryptionManager
  52. * @param \OC\Encryption\File $file
  53. * @param string $uid
  54. */
  55. public function __construct(
  56. View $view,
  57. Util $util,
  58. Mount\Manager $mountManager,
  59. Manager $encryptionManager,
  60. File $file,
  61. $uid
  62. ) {
  63. $this->view = $view;
  64. $this->util = $util;
  65. $this->mountManager = $mountManager;
  66. $this->encryptionManager = $encryptionManager;
  67. $this->file = $file;
  68. $this->uid = $uid;
  69. }
  70. /**
  71. * hook after file was shared
  72. *
  73. * @param array $params
  74. */
  75. public function postShared($params) {
  76. if ($this->encryptionManager->isEnabled()) {
  77. if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
  78. $path = Filesystem::getPath($params['fileSource']);
  79. list($owner, $ownerPath) = $this->getOwnerPath($path);
  80. $absPath = '/' . $owner . '/files/' . $ownerPath;
  81. $this->update($absPath);
  82. }
  83. }
  84. }
  85. /**
  86. * hook after file was unshared
  87. *
  88. * @param array $params
  89. */
  90. public function postUnshared($params) {
  91. if ($this->encryptionManager->isEnabled()) {
  92. if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
  93. $path = Filesystem::getPath($params['fileSource']);
  94. list($owner, $ownerPath) = $this->getOwnerPath($path);
  95. $absPath = '/' . $owner . '/files/' . $ownerPath;
  96. $this->update($absPath);
  97. }
  98. }
  99. }
  100. /**
  101. * inform encryption module that a file was restored from the trash bin,
  102. * e.g. to update the encryption keys
  103. *
  104. * @param array $params
  105. */
  106. public function postRestore($params) {
  107. if ($this->encryptionManager->isEnabled()) {
  108. $path = Filesystem::normalizePath('/' . $this->uid . '/files/' . $params['filePath']);
  109. $this->update($path);
  110. }
  111. }
  112. /**
  113. * inform encryption module that a file was renamed,
  114. * e.g. to update the encryption keys
  115. *
  116. * @param array $params
  117. */
  118. public function postRename($params) {
  119. $source = $params['oldpath'];
  120. $target = $params['newpath'];
  121. if (
  122. $this->encryptionManager->isEnabled() &&
  123. dirname($source) !== dirname($target)
  124. ) {
  125. list($owner, $ownerPath) = $this->getOwnerPath($target);
  126. $absPath = '/' . $owner . '/files/' . $ownerPath;
  127. $this->update($absPath);
  128. }
  129. }
  130. /**
  131. * get owner and path relative to data/<owner>/files
  132. *
  133. * @param string $path path to file for current user
  134. * @return array ['owner' => $owner, 'path' => $path]
  135. * @throw \InvalidArgumentException
  136. */
  137. protected function getOwnerPath($path) {
  138. $info = Filesystem::getFileInfo($path);
  139. $owner = Filesystem::getOwner($path);
  140. $view = new View('/' . $owner . '/files');
  141. $path = $view->getPath($info->getId());
  142. if ($path === null) {
  143. throw new \InvalidArgumentException('No file found for ' . $info->getId());
  144. }
  145. return [$owner, $path];
  146. }
  147. /**
  148. * notify encryption module about added/removed users from a file/folder
  149. *
  150. * @param string $path relative to data/
  151. * @throws Exceptions\ModuleDoesNotExistsException
  152. */
  153. public function update($path) {
  154. $encryptionModule = $this->encryptionManager->getEncryptionModule();
  155. // if the encryption module doesn't encrypt the files on a per-user basis
  156. // we have nothing to do here.
  157. if ($encryptionModule->needDetailedAccessList() === false) {
  158. return;
  159. }
  160. // if a folder was shared, get a list of all (sub-)folders
  161. if ($this->view->is_dir($path)) {
  162. $allFiles = $this->util->getAllFiles($path);
  163. } else {
  164. $allFiles = [$path];
  165. }
  166. foreach ($allFiles as $file) {
  167. $usersSharing = $this->file->getAccessList($file);
  168. $encryptionModule->update($file, $this->uid, $usersSharing);
  169. }
  170. }
  171. }