/**
  * @param array $share
  * @param string $internalPath
  * @param \OC\Files\Cache\ChangePropagator $propagator
  */
 private function propagateForOwner($share, $internalPath, ChangePropagator $propagator)
 {
     // note that we have already set up the filesystem for the owner when mounting the share
     $view = new View('/' . $share['uid_owner'] . '/files');
     $shareRootPath = $view->getPath($share['item_source']);
     if (!is_null($shareRootPath)) {
         $path = $shareRootPath . '/' . $internalPath;
         $path = Filesystem::normalizePath($path);
         $propagator->addChange($path);
         $propagator->propagateChanges();
     }
 }
Example #2
0
 /**
  * @param string $dir
  * @throws \OC\ForbiddenException
  */
 public function scan($dir = '')
 {
     if (!Filesystem::isValidPath($dir)) {
         throw new \InvalidArgumentException('Invalid path to scan');
     }
     $mounts = $this->getMounts($dir);
     foreach ($mounts as $mount) {
         if (is_null($mount->getStorage())) {
             continue;
         }
         $storage = $mount->getStorage();
         // if the home storage isn't writable then the scanner is run as the wrong user
         if ($storage->instanceOfStorage('\\OC\\Files\\Storage\\Home') and (!$storage->isCreatable('') or !$storage->isCreatable('files'))) {
             throw new ForbiddenException();
         }
         $relativePath = $mount->getInternalPath($dir);
         $scanner = $storage->getScanner();
         $scanner->setUseTransactions(false);
         $this->attachListener($mount);
         $isDbLocking = \OC::$server->getLockingProvider() instanceof DBLockingProvider;
         if (!$isDbLocking) {
             $this->db->beginTransaction();
         }
         $scanner->scan($relativePath, \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
         if (!$isDbLocking) {
             $this->db->commit();
         }
     }
     $this->propagator->propagateChanges(time());
 }
Example #3
0
 public function testPropagateCrossStorage()
 {
     $storage = new Temporary();
     $this->view->mkdir('/foo');
     Filesystem::mount($storage, [], $this->view->getAbsolutePath('/foo/submount'));
     $this->view->mkdir('/foo/submount/bar');
     $this->view->file_put_contents('/foo/submount/bar/sad.txt', 'qwerty');
     $oldInfo1 = $this->view->getFileInfo('/');
     $oldInfo2 = $this->view->getFileInfo('/foo');
     $oldInfo3 = $this->view->getFileInfo('/foo/submount');
     $oldInfo4 = $this->view->getFileInfo('/foo/submount/bar');
     $time = time() + 50;
     $this->propagator->addChange('/foo/submount/bar/sad.txt');
     $this->propagator->propagateChanges($time);
     $newInfo1 = $this->view->getFileInfo('/');
     $newInfo2 = $this->view->getFileInfo('/foo');
     $newInfo3 = $this->view->getFileInfo('/foo/submount');
     $newInfo4 = $this->view->getFileInfo('/foo/submount/bar');
     $this->assertEquals($newInfo1->getMTime(), $time);
     $this->assertEquals($newInfo2->getMTime(), $time);
     $this->assertEquals($newInfo3->getMTime(), $time);
     $this->assertEquals($newInfo4->getMTime(), $time);
     $this->assertNotSame($oldInfo1->getEtag(), $newInfo1->getEtag());
     $this->assertNotSame($oldInfo2->getEtag(), $newInfo2->getEtag());
     $this->assertNotSame($oldInfo3->getEtag(), $newInfo3->getEtag());
     $this->assertNotSame($oldInfo4->getEtag(), $newInfo3->getEtag());
 }
Example #4
0
 public function testSinglePropagate()
 {
     $this->view->mkdir('/foo');
     $this->view->mkdir('/foo/bar');
     $this->view->file_put_contents('/foo/bar/sad.txt', 'qwerty');
     $oldInfo1 = $this->view->getFileInfo('/');
     $oldInfo2 = $this->view->getFileInfo('/foo');
     $oldInfo3 = $this->view->getFileInfo('/foo/bar');
     $time = time() + 50;
     $this->propagator->addChange('/foo/bar/sad.txt');
     $this->propagator->propagateChanges($time);
     $newInfo1 = $this->view->getFileInfo('/');
     $newInfo2 = $this->view->getFileInfo('/foo');
     $newInfo3 = $this->view->getFileInfo('/foo/bar');
     $this->assertEquals($newInfo1->getMTime(), $time);
     $this->assertEquals($newInfo2->getMTime(), $time);
     $this->assertEquals($newInfo3->getMTime(), $time);
     $this->assertNotSame($oldInfo1->getEtag(), $newInfo1->getEtag());
     $this->assertNotSame($oldInfo2->getEtag(), $newInfo2->getEtag());
     $this->assertNotSame($oldInfo3->getEtag(), $newInfo3->getEtag());
 }
Example #5
0
 public function scan($dir)
 {
     $mounts = $this->getMounts($dir);
     foreach ($mounts as $mount) {
         if (is_null($mount->getStorage())) {
             continue;
         }
         $scanner = $mount->getStorage()->getScanner();
         $this->attachListener($mount);
         $scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
     }
     $this->propagator->propagateChanges(time());
 }
Example #6
0
 /**
  * Update etags for mount points for known user
  * For global or group mount points, updating the etag for every user is not feasible
  * instead we mark the mount point as dirty and update the etag when the filesystem is loaded for the user
  * For personal mount points, the change is propagated directly
  *
  * @param array $params hook parameters
  * @param int $time update time to use when marking a mount point as dirty
  */
 public function updateHook($params, $time = null)
 {
     if ($time === null) {
         $time = time();
     }
     $users = $params[Filesystem::signal_param_users];
     $type = $params[Filesystem::signal_param_mount_type];
     $mountPoint = $params[Filesystem::signal_param_path];
     $mountPoint = Filesystem::normalizePath($mountPoint);
     if ($type === \OC_Mount_Config::MOUNT_TYPE_GROUP or $users === 'all') {
         $this->markDirty($mountPoint, $time);
     } else {
         $this->changePropagator->addChange($mountPoint);
         $this->changePropagator->propagateChanges($time);
     }
 }
Example #7
0
	public function testDontLowerMtime() {
		$time = time();
		$this->view->mkdir('/foo');
		$this->view->mkdir('/foo/bar');

		$cache = $this->storage->getCache();
		$cache->put('', ['mtime' => $time - 50]);
		$cache->put('foo', ['mtime' => $time - 150]);
		$cache->put('foo/bar', ['mtime' => $time - 250]);

		$this->propagator->addChange('/foo/bar/foo');
		$this->propagator->propagateChanges($time - 100);

		$this->assertEquals(50, $time - $cache->get('')['mtime']);
		$this->assertEquals(100, $time - $cache->get('foo')['mtime']);
		$this->assertEquals(100, $time - $cache->get('foo/bar')['mtime']);
	}
Example #8
0
 /**
  * @param string $dir
  * @throws \OC\ForbiddenException
  */
 public function scan($dir)
 {
     $mounts = $this->getMounts($dir);
     foreach ($mounts as $mount) {
         if (is_null($mount->getStorage())) {
             continue;
         }
         $storage = $mount->getStorage();
         // if the home storage isn't writable then the scanner is run as the wrong user
         if ($storage->instanceOfStorage('\\OC\\Files\\Storage\\Home') and (!$storage->isCreatable('') or !$storage->isCreatable('files'))) {
             throw new ForbiddenException();
         }
         $scanner = $storage->getScanner();
         $this->attachListener($mount);
         $scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
     }
     $this->propagator->propagateChanges(time());
 }
Example #9
0
	/**
	 * @param string $dir
	 * @throws \OC\ForbiddenException
	 */
	public function scan($dir = '') {
		$mounts = $this->getMounts($dir);
		foreach ($mounts as $mount) {
			if (is_null($mount->getStorage())) {
				continue;
			}
			$storage = $mount->getStorage();
			// if the home storage isn't writable then the scanner is run as the wrong user
			if ($storage->instanceOfStorage('\OC\Files\Storage\Home') and
				(!$storage->isCreatable('') or !$storage->isCreatable('files'))
			) {
				throw new ForbiddenException();
			}
			$relativePath = $mount->getInternalPath($dir);
			$scanner = $storage->getScanner();
			$scanner->setUseTransactions(false);
			$this->attachListener($mount);
			$this->db->beginTransaction();
			$scanner->scan($relativePath, \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
			$this->db->commit();
		}
		$this->propagator->propagateChanges(time());
	}
Example #10
0
 /**
  * Listen on the propagator for updates made to shares owned by a user
  *
  * @param \OC\Files\Cache\ChangePropagator $propagator
  * @param string $owner
  */
 public function attachToPropagator(ChangePropagator $propagator, $owner)
 {
     $propagator->listen('\\OC\\Files', 'propagate', function ($path, $entry) use($owner) {
         $this->propagateById($entry['fileid']);
     });
 }
Example #11
0
 public function __destruct()
 {
     // propagate any leftover changes
     $this->propagator->propagateChanges();
 }
 /**
  * Listen on the propagator for updates made to shares owned by a user
  *
  * @param \OC\Files\Cache\ChangePropagator $propagator
  * @param string $owner
  */
 public function attachToPropagator(ChangePropagator $propagator, $owner)
 {
     $propagator->listen('\\OC\\Files', 'propagate', function ($path, $entry) use($owner) {
         $shares = Share::getAllSharesForFileId($entry['fileid']);
         foreach ($shares as $share) {
             // propagate down the share tree
             $this->markDirty($share, microtime(true));
             // propagate up the share tree
             $user = $share['uid_owner'];
             $view = new View('/' . $user . '/files');
             $path = $view->getPath($share['file_source']);
             $watcher = new ChangeWatcher($view);
             $watcher->writeHook(['path' => $path]);
         }
     });
 }