Jail.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Morris Jobke <hey@morrisjobke.de>
  6. * @author Robin Appelman <robin@icewind.nl>
  7. * @author Roeland Jago Douma <roeland@famdouma.nl>
  8. *
  9. * @license AGPL-3.0
  10. *
  11. * This code is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License, version 3,
  13. * as published by the Free Software Foundation.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License, version 3,
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>
  22. *
  23. */
  24. namespace OC\Files\Storage\Wrapper;
  25. use OC\Files\Cache\Wrapper\CacheJail;
  26. use OCP\Lock\ILockingProvider;
  27. /**
  28. * Jail to a subdirectory of the wrapped storage
  29. *
  30. * This restricts access to a subfolder of the wrapped storage with the subfolder becoming the root folder new storage
  31. */
  32. class Jail extends Wrapper {
  33. /**
  34. * @var string
  35. */
  36. protected $rootPath;
  37. /**
  38. * @param array $arguments ['storage' => $storage, 'mask' => $root]
  39. *
  40. * $storage: The storage that will be wrapper
  41. * $root: The folder in the wrapped storage that will become the root folder of the wrapped storage
  42. */
  43. public function __construct($arguments) {
  44. parent::__construct($arguments);
  45. $this->rootPath = $arguments['root'];
  46. }
  47. public function getSourcePath($path) {
  48. if ($path === '') {
  49. return $this->rootPath;
  50. } else {
  51. return $this->rootPath . '/' . $path;
  52. }
  53. }
  54. public function getId() {
  55. return parent::getId();
  56. }
  57. /**
  58. * see http://php.net/manual/en/function.mkdir.php
  59. *
  60. * @param string $path
  61. * @return bool
  62. */
  63. public function mkdir($path) {
  64. return $this->getWrapperStorage()->mkdir($this->getSourcePath($path));
  65. }
  66. /**
  67. * see http://php.net/manual/en/function.rmdir.php
  68. *
  69. * @param string $path
  70. * @return bool
  71. */
  72. public function rmdir($path) {
  73. return $this->getWrapperStorage()->rmdir($this->getSourcePath($path));
  74. }
  75. /**
  76. * see http://php.net/manual/en/function.opendir.php
  77. *
  78. * @param string $path
  79. * @return resource
  80. */
  81. public function opendir($path) {
  82. return $this->getWrapperStorage()->opendir($this->getSourcePath($path));
  83. }
  84. /**
  85. * see http://php.net/manual/en/function.is_dir.php
  86. *
  87. * @param string $path
  88. * @return bool
  89. */
  90. public function is_dir($path) {
  91. return $this->getWrapperStorage()->is_dir($this->getSourcePath($path));
  92. }
  93. /**
  94. * see http://php.net/manual/en/function.is_file.php
  95. *
  96. * @param string $path
  97. * @return bool
  98. */
  99. public function is_file($path) {
  100. return $this->getWrapperStorage()->is_file($this->getSourcePath($path));
  101. }
  102. /**
  103. * see http://php.net/manual/en/function.stat.php
  104. * only the following keys are required in the result: size and mtime
  105. *
  106. * @param string $path
  107. * @return array
  108. */
  109. public function stat($path) {
  110. return $this->getWrapperStorage()->stat($this->getSourcePath($path));
  111. }
  112. /**
  113. * see http://php.net/manual/en/function.filetype.php
  114. *
  115. * @param string $path
  116. * @return bool
  117. */
  118. public function filetype($path) {
  119. return $this->getWrapperStorage()->filetype($this->getSourcePath($path));
  120. }
  121. /**
  122. * see http://php.net/manual/en/function.filesize.php
  123. * The result for filesize when called on a folder is required to be 0
  124. *
  125. * @param string $path
  126. * @return int
  127. */
  128. public function filesize($path) {
  129. return $this->getWrapperStorage()->filesize($this->getSourcePath($path));
  130. }
  131. /**
  132. * check if a file can be created in $path
  133. *
  134. * @param string $path
  135. * @return bool
  136. */
  137. public function isCreatable($path) {
  138. return $this->getWrapperStorage()->isCreatable($this->getSourcePath($path));
  139. }
  140. /**
  141. * check if a file can be read
  142. *
  143. * @param string $path
  144. * @return bool
  145. */
  146. public function isReadable($path) {
  147. return $this->getWrapperStorage()->isReadable($this->getSourcePath($path));
  148. }
  149. /**
  150. * check if a file can be written to
  151. *
  152. * @param string $path
  153. * @return bool
  154. */
  155. public function isUpdatable($path) {
  156. return $this->getWrapperStorage()->isUpdatable($this->getSourcePath($path));
  157. }
  158. /**
  159. * check if a file can be deleted
  160. *
  161. * @param string $path
  162. * @return bool
  163. */
  164. public function isDeletable($path) {
  165. return $this->getWrapperStorage()->isDeletable($this->getSourcePath($path));
  166. }
  167. /**
  168. * check if a file can be shared
  169. *
  170. * @param string $path
  171. * @return bool
  172. */
  173. public function isSharable($path) {
  174. return $this->getWrapperStorage()->isSharable($this->getSourcePath($path));
  175. }
  176. /**
  177. * get the full permissions of a path.
  178. * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
  179. *
  180. * @param string $path
  181. * @return int
  182. */
  183. public function getPermissions($path) {
  184. return $this->getWrapperStorage()->getPermissions($this->getSourcePath($path));
  185. }
  186. /**
  187. * see http://php.net/manual/en/function.file_exists.php
  188. *
  189. * @param string $path
  190. * @return bool
  191. */
  192. public function file_exists($path) {
  193. return $this->getWrapperStorage()->file_exists($this->getSourcePath($path));
  194. }
  195. /**
  196. * see http://php.net/manual/en/function.filemtime.php
  197. *
  198. * @param string $path
  199. * @return int
  200. */
  201. public function filemtime($path) {
  202. return $this->getWrapperStorage()->filemtime($this->getSourcePath($path));
  203. }
  204. /**
  205. * see http://php.net/manual/en/function.file_get_contents.php
  206. *
  207. * @param string $path
  208. * @return string
  209. */
  210. public function file_get_contents($path) {
  211. return $this->getWrapperStorage()->file_get_contents($this->getSourcePath($path));
  212. }
  213. /**
  214. * see http://php.net/manual/en/function.file_put_contents.php
  215. *
  216. * @param string $path
  217. * @param string $data
  218. * @return bool
  219. */
  220. public function file_put_contents($path, $data) {
  221. return $this->getWrapperStorage()->file_put_contents($this->getSourcePath($path), $data);
  222. }
  223. /**
  224. * see http://php.net/manual/en/function.unlink.php
  225. *
  226. * @param string $path
  227. * @return bool
  228. */
  229. public function unlink($path) {
  230. return $this->getWrapperStorage()->unlink($this->getSourcePath($path));
  231. }
  232. /**
  233. * see http://php.net/manual/en/function.rename.php
  234. *
  235. * @param string $path1
  236. * @param string $path2
  237. * @return bool
  238. */
  239. public function rename($path1, $path2) {
  240. return $this->getWrapperStorage()->rename($this->getSourcePath($path1), $this->getSourcePath($path2));
  241. }
  242. /**
  243. * see http://php.net/manual/en/function.copy.php
  244. *
  245. * @param string $path1
  246. * @param string $path2
  247. * @return bool
  248. */
  249. public function copy($path1, $path2) {
  250. return $this->getWrapperStorage()->copy($this->getSourcePath($path1), $this->getSourcePath($path2));
  251. }
  252. /**
  253. * see http://php.net/manual/en/function.fopen.php
  254. *
  255. * @param string $path
  256. * @param string $mode
  257. * @return resource
  258. */
  259. public function fopen($path, $mode) {
  260. return $this->getWrapperStorage()->fopen($this->getSourcePath($path), $mode);
  261. }
  262. /**
  263. * get the mimetype for a file or folder
  264. * The mimetype for a folder is required to be "httpd/unix-directory"
  265. *
  266. * @param string $path
  267. * @return string
  268. */
  269. public function getMimeType($path) {
  270. return $this->getWrapperStorage()->getMimeType($this->getSourcePath($path));
  271. }
  272. /**
  273. * see http://php.net/manual/en/function.hash.php
  274. *
  275. * @param string $type
  276. * @param string $path
  277. * @param bool $raw
  278. * @return string
  279. */
  280. public function hash($type, $path, $raw = false) {
  281. return $this->getWrapperStorage()->hash($type, $this->getSourcePath($path), $raw);
  282. }
  283. /**
  284. * see http://php.net/manual/en/function.free_space.php
  285. *
  286. * @param string $path
  287. * @return int
  288. */
  289. public function free_space($path) {
  290. return $this->getWrapperStorage()->free_space($this->getSourcePath($path));
  291. }
  292. /**
  293. * search for occurrences of $query in file names
  294. *
  295. * @param string $query
  296. * @return array
  297. */
  298. public function search($query) {
  299. return $this->getWrapperStorage()->search($query);
  300. }
  301. /**
  302. * see http://php.net/manual/en/function.touch.php
  303. * If the backend does not support the operation, false should be returned
  304. *
  305. * @param string $path
  306. * @param int $mtime
  307. * @return bool
  308. */
  309. public function touch($path, $mtime = null) {
  310. return $this->getWrapperStorage()->touch($this->getSourcePath($path), $mtime);
  311. }
  312. /**
  313. * get the path to a local version of the file.
  314. * The local version of the file can be temporary and doesn't have to be persistent across requests
  315. *
  316. * @param string $path
  317. * @return string
  318. */
  319. public function getLocalFile($path) {
  320. return $this->getWrapperStorage()->getLocalFile($this->getSourcePath($path));
  321. }
  322. /**
  323. * check if a file or folder has been updated since $time
  324. *
  325. * @param string $path
  326. * @param int $time
  327. * @return bool
  328. *
  329. * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
  330. * returning true for other changes in the folder is optional
  331. */
  332. public function hasUpdated($path, $time) {
  333. return $this->getWrapperStorage()->hasUpdated($this->getSourcePath($path), $time);
  334. }
  335. /**
  336. * get a cache instance for the storage
  337. *
  338. * @param string $path
  339. * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
  340. * @return \OC\Files\Cache\Cache
  341. */
  342. public function getCache($path = '', $storage = null) {
  343. if (!$storage) {
  344. $storage = $this->getWrapperStorage();
  345. }
  346. $sourceCache = $this->getWrapperStorage()->getCache($this->getSourcePath($path), $storage);
  347. return new CacheJail($sourceCache, $this->rootPath);
  348. }
  349. /**
  350. * get the user id of the owner of a file or folder
  351. *
  352. * @param string $path
  353. * @return string
  354. */
  355. public function getOwner($path) {
  356. return $this->getWrapperStorage()->getOwner($this->getSourcePath($path));
  357. }
  358. /**
  359. * get a watcher instance for the cache
  360. *
  361. * @param string $path
  362. * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
  363. * @return \OC\Files\Cache\Watcher
  364. */
  365. public function getWatcher($path = '', $storage = null) {
  366. if (!$storage) {
  367. $storage = $this;
  368. }
  369. return $this->getWrapperStorage()->getWatcher($this->getSourcePath($path), $storage);
  370. }
  371. /**
  372. * get the ETag for a file or folder
  373. *
  374. * @param string $path
  375. * @return string
  376. */
  377. public function getETag($path) {
  378. return $this->getWrapperStorage()->getETag($this->getSourcePath($path));
  379. }
  380. /**
  381. * @param string $path
  382. * @return array
  383. */
  384. public function getMetaData($path) {
  385. return $this->getWrapperStorage()->getMetaData($this->getSourcePath($path));
  386. }
  387. /**
  388. * @param string $path
  389. * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
  390. * @param \OCP\Lock\ILockingProvider $provider
  391. * @throws \OCP\Lock\LockedException
  392. */
  393. public function acquireLock($path, $type, ILockingProvider $provider) {
  394. $this->getWrapperStorage()->acquireLock($this->getSourcePath($path), $type, $provider);
  395. }
  396. /**
  397. * @param string $path
  398. * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
  399. * @param \OCP\Lock\ILockingProvider $provider
  400. */
  401. public function releaseLock($path, $type, ILockingProvider $provider) {
  402. $this->getWrapperStorage()->releaseLock($this->getSourcePath($path), $type, $provider);
  403. }
  404. /**
  405. * @param string $path
  406. * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
  407. * @param \OCP\Lock\ILockingProvider $provider
  408. */
  409. public function changeLock($path, $type, ILockingProvider $provider) {
  410. $this->getWrapperStorage()->changeLock($this->getSourcePath($path), $type, $provider);
  411. }
  412. /**
  413. * Resolve the path for the source of the share
  414. *
  415. * @param string $path
  416. * @return array
  417. */
  418. public function resolvePath($path) {
  419. return [$this->getWrapperStorage(), $this->getSourcePath($path)];
  420. }
  421. /**
  422. * @param \OCP\Files\Storage $sourceStorage
  423. * @param string $sourceInternalPath
  424. * @param string $targetInternalPath
  425. * @return bool
  426. */
  427. public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
  428. if ($sourceStorage === $this) {
  429. return $this->copy($sourceInternalPath, $targetInternalPath);
  430. }
  431. return $this->getWrapperStorage()->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath));
  432. }
  433. /**
  434. * @param \OCP\Files\Storage $sourceStorage
  435. * @param string $sourceInternalPath
  436. * @param string $targetInternalPath
  437. * @return bool
  438. */
  439. public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
  440. if ($sourceStorage === $this) {
  441. return $this->rename($sourceInternalPath, $targetInternalPath);
  442. }
  443. return $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath));
  444. }
  445. }