* @author Bernhard Posselt * @author Christoph Wurst * @author Joas Schilling * @author Julius Härtl * @author Morris Jobke * @author Robin Appelman * @author Roeland Jago Douma * @author Vincent Petry * * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see * */ namespace OC\Files\Node; use OC\Files\Filesystem; use OC\Files\Mount\MoveableMount; use OC\Files\Utils\PathHelper; use OCP\Files\FileInfo; use OCP\Files\InvalidPathException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Lock\LockedException; use Symfony\Component\EventDispatcher\GenericEvent; // FIXME: this class really should be abstract class Node implements \OCP\Files\Node { /** * @var \OC\Files\View $view */ protected $view; /** * @var \OC\Files\Node\Root $root */ protected $root; /** * @var string $path */ protected $path; /** * @var \OCP\Files\FileInfo */ protected $fileInfo; /** * @var Node|null */ protected $parent; /** * @param \OC\Files\View $view * @param \OCP\Files\IRootFolder $root * @param string $path * @param FileInfo $fileInfo */ public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null) { $this->view = $view; $this->root = $root; $this->path = $path; $this->fileInfo = $fileInfo; $this->parent = $parent; } /** * Creates a Node of the same type that represents a non-existing path * * @param string $path path * @return string non-existing node class * @throws \Exception */ protected function createNonExistingNode($path) { throw new \Exception('Must be implemented by subclasses'); } /** * Returns the matching file info * * @return FileInfo * @throws InvalidPathException * @throws NotFoundException */ public function getFileInfo() { if (!Filesystem::isValidPath($this->path)) { throw new InvalidPathException(); } if (!$this->fileInfo) { $fileInfo = $this->view->getFileInfo($this->path); if ($fileInfo instanceof FileInfo) { $this->fileInfo = $fileInfo; } else { throw new NotFoundException(); } } return $this->fileInfo; } /** * @param string[] $hooks */ protected function sendHooks($hooks, array $args = null) { $args = !empty($args) ? $args : [$this]; $dispatcher = \OC::$server->getEventDispatcher(); foreach ($hooks as $hook) { $this->root->emit('\OC\Files', $hook, $args); $dispatcher->dispatch('\OCP\Files::' . $hook, new GenericEvent($args)); } } /** * @param int $permissions * @return bool * @throws InvalidPathException * @throws NotFoundException */ protected function checkPermissions($permissions) { return ($this->getPermissions() & $permissions) === $permissions; } public function delete() { } /** * @param int $mtime * @throws InvalidPathException * @throws NotFoundException * @throws NotPermittedException */ public function touch($mtime = null) { if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) { $this->sendHooks(['preTouch']); $this->view->touch($this->path, $mtime); $this->sendHooks(['postTouch']); if ($this->fileInfo) { if (is_null($mtime)) { $mtime = time(); } $this->fileInfo['mtime'] = $mtime; } } else { throw new NotPermittedException(); } } public function getStorage() { $storage = $this->getMountPoint()->getStorage(); if (!$storage) { throw new \Exception("No storage for node"); } return $storage; } /** * @return string */ public function getPath() { return $this->path; } /** * @return string */ public function getInternalPath() { return $this->getFileInfo()->getInternalPath(); } /** * @return int * @throws InvalidPathException * @throws NotFoundException */ public function getId() { return $this->getFileInfo()->getId(); } /** * @return array */ public function stat() { return $this->view->stat($this->path); } /** * @return int * @throws InvalidPathException * @throws NotFoundException */ public function getMTime() { return $this->getFileInfo()->getMTime(); } /** * @param bool $includeMounts * @return int * @throws InvalidPathException * @throws NotFoundException */ public function getSize($includeMounts = true) { return $this->getFileInfo()->getSize($includeMounts); } /** * @return string * @throws InvalidPathException * @throws NotFoundException */ public function getEtag() { return $this->getFileInfo()->getEtag(); } /** * @return int * @throws InvalidPathException * @throws NotFoundException */ public function getPermissions() { return $this->getFileInfo()->getPermissions(); } /** * @return bool * @throws InvalidPathException * @throws NotFoundException */ public function isReadable() { return $this->getFileInfo()->isReadable(); } /** * @return bool * @throws InvalidPathException * @throws NotFoundException */ public function isUpdateable() { return $this->getFileInfo()->isUpdateable(); } /** * @return bool * @throws InvalidPathException * @throws NotFoundException */ public function isDeletable() { return $this->getFileInfo()->isDeletable(); } /** * @return bool * @throws InvalidPathException * @throws NotFoundException */ public function isShareable() { return $this->getFileInfo()->isShareable(); } /** * @return bool * @throws InvalidPathException * @throws NotFoundException */ public function isCreatable() { return $this->getFileInfo()->isCreatable(); } /** * @return Node */ public function getParent() { if ($this->parent === null) { $newPath = dirname($this->path); if ($newPath === '' || $newPath === '.' || $newPath === '/') { return $this->root; } $this->parent = $this->root->get($newPath); } return $this->parent; } /** * @return string */ public function getName() { return basename($this->path); } /** * @param string $path * @return string */ protected function normalizePath($path) { return PathHelper::normalizePath($path); } /** * check if the requested path is valid * * @param string $path * @return bool */ public function isValidPath($path) { if (!$path || $path[0] !== '/') { $path = '/' . $path; } if (strstr($path, '/../') || strrchr($path, '/') === '/..') { return false; } return true; } public function isMounted() { return $this->getFileInfo()->isMounted(); } public function isShared() { return $this->getFileInfo()->isShared(); } public function getMimeType() { return $this->getFileInfo()->getMimetype(); } public function getMimePart() { return $this->getFileInfo()->getMimePart(); } public function getType() { return $this->getFileInfo()->getType(); } public function isEncrypted() { return $this->getFileInfo()->isEncrypted(); } public function getMountPoint() { return $this->getFileInfo()->getMountPoint(); } public function getOwner() { return $this->getFileInfo()->getOwner(); } public function getChecksum() { } public function getExtension(): string { return $this->getFileInfo()->getExtension(); } /** * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE * @throws LockedException */ public function lock($type) { $this->view->lockFile($this->path, $type); } /** * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE * @throws LockedException */ public function changeLock($type) { $this->view->changeLock($this->path, $type); } /** * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE * @throws LockedException */ public function unlock($type) { $this->view->unlockFile($this->path, $type); } /** * @param string $targetPath * @return \OC\Files\Node\Node * @throws InvalidPathException * @throws NotFoundException * @throws NotPermittedException if copy not allowed or failed */ public function copy($targetPath) { $targetPath = $this->normalizePath($targetPath); $parent = $this->root->get(dirname($targetPath)); if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) { $nonExisting = $this->createNonExistingNode($targetPath); $this->sendHooks(['preCopy'], [$this, $nonExisting]); $this->sendHooks(['preWrite'], [$nonExisting]); if (!$this->view->copy($this->path, $targetPath)) { throw new NotPermittedException('Could not copy ' . $this->path . ' to ' . $targetPath); } $targetNode = $this->root->get($targetPath); $this->sendHooks(['postCopy'], [$this, $targetNode]); $this->sendHooks(['postWrite'], [$targetNode]); return $targetNode; } else { throw new NotPermittedException('No permission to copy to path ' . $targetPath); } } /** * @param string $targetPath * @return \OC\Files\Node\Node * @throws InvalidPathException * @throws NotFoundException * @throws NotPermittedException if move not allowed or failed * @throws LockedException */ public function move($targetPath) { $targetPath = $this->normalizePath($targetPath); $parent = $this->root->get(dirname($targetPath)); if ( $parent instanceof Folder and $this->isValidPath($targetPath) and ( $parent->isCreatable() || ($parent->getInternalPath() === '' && $parent->getMountPoint() instanceof MoveableMount) ) ) { $nonExisting = $this->createNonExistingNode($targetPath); $this->sendHooks(['preRename'], [$this, $nonExisting]); $this->sendHooks(['preWrite'], [$nonExisting]); if (!$this->view->rename($this->path, $targetPath)) { throw new NotPermittedException('Could not move ' . $this->path . ' to ' . $targetPath); } $mountPoint = $this->getMountPoint(); if ($mountPoint) { // update the cached fileinfo with the new (internal) path /** @var \OC\Files\FileInfo $oldFileInfo */ $oldFileInfo = $this->getFileInfo(); $this->fileInfo = new \OC\Files\FileInfo($targetPath, $oldFileInfo->getStorage(), $mountPoint->getInternalPath($targetPath), $oldFileInfo->getData(), $mountPoint, $oldFileInfo->getOwner()); } $targetNode = $this->root->get($targetPath); $this->sendHooks(['postRename'], [$this, $targetNode]); $this->sendHooks(['postWrite'], [$targetNode]); $this->path = $targetPath; return $targetNode; } else { throw new NotPermittedException('No permission to move to path ' . $targetPath); } } public function getCreationTime(): int { return $this->getFileInfo()->getCreationTime(); } public function getUploadTime(): int { return $this->getFileInfo()->getUploadTime(); } } -npm-audit'>automated/noid/main-fix-npm-audit Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
aboutsummaryrefslogtreecommitdiffstats
blob: 8749ad0bff598ef55ebcd13adc83897f757574d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?php
/**
 * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
 *
 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
 * @author Morris Jobke <hey@morrisjobke.de>
 * @author Robin Appelman <robin@icewind.nl>
 * @author Roeland Jago Douma <roeland@famdouma.nl>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
namespace OC\Command;

use OCP\Command\ICommand;
use Laravel\SerializableClosure\SerializableClosure;

class CronBus extends AsyncBus {
	/**
	 * @var \OCP\BackgroundJob\IJobList
	 */
	private $jobList;


	/**
	 * @param \OCP\BackgroundJob\IJobList $jobList
	 */
	public function __construct($jobList) {
		$this->jobList = $jobList;
	}

	protected function queueCommand($command) {
		$this->jobList->add($this->getJobClass($command), $this->serializeCommand($command));
	}

	/**
	 * @param \OCP\Command\ICommand | callable $command
	 * @return string
	 */
	private function getJobClass($command) {
		if ($command instanceof \Closure) {
			return ClosureJob::class;
		} elseif (is_callable($command)) {
			return CallableJob::class;
		} elseif ($command instanceof ICommand) {
			return CommandJob::class;
		} else {
			throw new \InvalidArgumentException('Invalid command');
		}
	}

	/**
	 * @param \OCP\Command\ICommand | callable $command
	 * @return string
	 */
	private function serializeCommand($command) {
		if ($command instanceof \Closure) {
			return serialize(new SerializableClosure($command));
		} elseif (is_callable($command) or $command instanceof ICommand) {
			return serialize($command);
		} else {
			throw new \InvalidArgumentException('Invalid command');
		}
	}
}