Example #1
0
 private function doTestRestore()
 {
     $filePath = self::TEST_VERSIONS_USER . '/files/sub/test.txt';
     $this->rootView->file_put_contents($filePath, 'test file');
     $t0 = $this->rootView->filemtime($filePath);
     // not exactly the same timestamp as the file
     $t1 = time() - 60;
     // second version is two weeks older
     $t2 = $t1 - 60 * 60 * 24 * 14;
     // create some versions
     $v1 = self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t1;
     $v2 = self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t2;
     $this->rootView->mkdir(self::USERS_VERSIONS_ROOT . '/sub');
     $this->rootView->file_put_contents($v1, 'version1');
     $this->rootView->file_put_contents($v2, 'version2');
     $oldVersions = \OCA\Files_Versions\Storage::getVersions(self::TEST_VERSIONS_USER, '/sub/test.txt');
     $this->assertCount(2, $oldVersions);
     $this->assertEquals('test file', $this->rootView->file_get_contents($filePath));
     $info1 = $this->rootView->getFileInfo($filePath);
     \OCA\Files_Versions\Storage::rollback('sub/test.txt', $t2);
     $this->assertEquals('version2', $this->rootView->file_get_contents($filePath));
     $info2 = $this->rootView->getFileInfo($filePath);
     $this->assertNotEquals($info2['etag'], $info1['etag'], 'Etag must change after rolling back version');
     $this->assertEquals($info2['fileid'], $info1['fileid'], 'File id must not change after rolling back version');
     $this->assertEquals($info2['mtime'], $t2, 'Restored file has mtime from version');
     $newVersions = \OCA\Files_Versions\Storage::getVersions(self::TEST_VERSIONS_USER, '/sub/test.txt');
     $this->assertTrue($this->rootView->file_exists(self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t0), 'A version file was created for the file before restoration');
     $this->assertTrue($this->rootView->file_exists($v1), 'Untouched version file is still there');
     $this->assertFalse($this->rootView->file_exists($v2), 'Restored version file gone from files_version folder');
     $this->assertCount(2, $newVersions, 'Additional version created');
     $this->assertTrue(isset($newVersions[$t0 . '#' . 'test.txt']), 'A version was created for the file before restoration');
     $this->assertTrue(isset($newVersions[$t1 . '#' . 'test.txt']), 'Untouched version is still there');
     $this->assertFalse(isset($newVersions[$t2 . '#' . 'test.txt']), 'Restored version is not in the list any more');
 }
 /**
  * save text file
  *
  * @NoAdminRequired
  *
  * @param string $path
  * @param string $filecontents
  * @param integer $mtime
  * @return DataResponse
  */
 public function save($path, $filecontents, $mtime)
 {
     try {
         if ($path !== '' && (is_integer($mtime) && $mtime > 0)) {
             // Get file mtime
             $filemtime = $this->view->filemtime($path);
             if ($mtime !== $filemtime) {
                 // Then the file has changed since opening
                 $this->logger->error('File: ' . $path . ' modified since opening.', ['app' => 'files_texteditor']);
                 return new DataResponse(['message' => $this->l->t('Cannot save file as it has been modified since opening')], Http::STATUS_BAD_REQUEST);
             } else {
                 // File same as when opened, save file
                 if ($this->view->isUpdatable($path)) {
                     $filecontents = iconv(mb_detect_encoding($filecontents), "UTF-8", $filecontents);
                     try {
                         $this->view->file_put_contents($path, $filecontents);
                     } catch (LockedException $e) {
                         $message = (string) $this->l->t('The file is locked.');
                         return new DataResponse(['message' => $message], Http::STATUS_BAD_REQUEST);
                     } catch (ForbiddenException $e) {
                         return new DataResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
                     }
                     // Clear statcache
                     clearstatcache();
                     // Get new mtime
                     $newmtime = $this->view->filemtime($path);
                     $newsize = $this->view->filesize($path);
                     return new DataResponse(['mtime' => $newmtime, 'size' => $newsize], Http::STATUS_OK);
                 } else {
                     // Not writeable!
                     $this->logger->error('User does not have permission to write to file: ' . $path, ['app' => 'files_texteditor']);
                     return new DataResponse(['message' => $this->l->t('Insufficient permissions')], Http::STATUS_BAD_REQUEST);
                 }
             }
         } else {
             if ($path === '') {
                 $this->logger->error('No file path supplied');
                 return new DataResponse(['message' => $this->l->t('File path not supplied')], Http::STATUS_BAD_REQUEST);
             } else {
                 $this->logger->error('No file mtime supplied', ['app' => 'files_texteditor']);
                 return new DataResponse(['message' => $this->l->t('File mtime not supplied')], Http::STATUS_BAD_REQUEST);
             }
         }
     } catch (HintException $e) {
         $message = (string) $e->getHint();
         return new DataResponse(['message' => $message], Http::STATUS_BAD_REQUEST);
     } catch (\Exception $e) {
         $message = (string) $this->l->t('An internal server error occurred.');
         return new DataResponse(['message' => $message], Http::STATUS_BAD_REQUEST);
     }
 }
 /**
  * Check if we need to re-bundle the certificates because one of the sources has updated
  *
  * @param string $uid (optional) user to get the certificate path for, use `null` to get the system path
  * @return bool
  */
 private function needsRebundling($uid = '')
 {
     if ($uid === '') {
         $uid = $this->uid;
     }
     $sourceMTimes = [filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt')];
     $targetBundle = $this->getCertificateBundle($uid);
     if (!$this->view->file_exists($targetBundle)) {
         return true;
     }
     if (!is_null($uid)) {
         // also depend on the system bundle
         $sourceBundles[] = $this->view->filemtime($this->getCertificateBundle(null));
     }
     $sourceMTime = array_reduce($sourceMTimes, function ($max, $mtime) {
         return max($max, $mtime);
     }, 0);
     return $sourceMTime > $this->view->filemtime($targetBundle);
 }
Example #4
0
 public function show()
 {
     if ($this->useOriginal) {
         $fp = @$this->view->fopen($this->path, 'rb');
         $mtime = $this->view->filemtime($this->path);
         $size = $this->view->filesize($this->path);
         $mime = $this->view->getMimetype($this->path);
     } else {
         $fp = @fopen($this->path, 'rb');
         $mtime = filemtime($this->path);
         $size = filesize($this->path);
         $mime = \OC_Helper::getMimetype($this->path);
     }
     if ($fp) {
         \OCP\Response::enableCaching();
         \OCP\Response::setLastModifiedHeader($mtime);
         header('Content-Length: ' . $size);
         header('Content-Type: ' . $mime);
         fpassthru($fp);
     } else {
         \OC_Response::setStatus(\OC_Response::STATUS_NOT_FOUND);
     }
 }
Example #5
0
 /**
  * @return int
  */
 public function getMTime()
 {
     return $this->view->filemtime($this->path);
 }
Example #6
0
 /**
  * recursive copy to copy a whole directory
  *
  * @param string $source source path, relative to the users files directory
  * @param string $destination destination path relative to the users root directoy
  * @param \OC\Files\View $view file view for the users root directory
  */
 private static function copy_recursive($source, $destination, $view)
 {
     $size = 0;
     if ($view->is_dir($source)) {
         $view->mkdir($destination);
         $view->touch($destination, $view->filemtime($source));
         foreach ($view->getDirectoryContent($source) as $i) {
             $pathDir = $source . '/' . $i['name'];
             if ($view->is_dir($pathDir)) {
                 $size += self::copy_recursive($pathDir, $destination . '/' . $i['name'], $view);
             } else {
                 $size += $view->filesize($pathDir);
                 $result = $view->copy($pathDir, $destination . '/' . $i['name']);
                 if (!$result) {
                     throw new \OCA\Files_Trashbin\Exceptions\CopyRecursiveException();
                 }
                 $view->touch($destination . '/' . $i['name'], $view->filemtime($pathDir));
             }
         }
     } else {
         $size += $view->filesize($source);
         $result = $view->copy($source, $destination);
         if (!$result) {
             throw new \OCA\Files_Trashbin\Exceptions\CopyRecursiveException();
         }
         $view->touch($destination, $view->filemtime($source));
     }
     return $size;
 }
Example #7
0
 /**
  * Rollback to an old version of a file.
  *
  * @param string $file file name
  * @param int $revision revision timestamp
  */
 public static function rollback($file, $revision)
 {
     if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') {
         // add expected leading slash
         $file = '/' . ltrim($file, '/');
         list($uid, $filename) = self::getUidAndFilename($file);
         $users_view = new View('/' . $uid);
         $files_view = new View('/' . User::getUser() . '/files');
         $versionCreated = false;
         //first create a new version
         $version = 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename);
         if (!$users_view->file_exists($version)) {
             $users_view->copy('files' . $filename, 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename));
             $versionCreated = true;
         }
         $fileToRestore = 'files_versions' . $filename . '.v' . $revision;
         // Restore encrypted version of the old file for the newly restored file
         // This has to happen manually here since the file is manually copied below
         $oldVersion = $users_view->getFileInfo($fileToRestore)->getEncryptedVersion();
         $newFileInfo = $files_view->getFileInfo($filename);
         $cache = $newFileInfo->getStorage()->getCache();
         $cache->update($newFileInfo->getId(), ['encrypted' => $oldVersion, 'encryptedVersion' => $oldVersion]);
         // rollback
         if (self::copyFileContents($users_view, $fileToRestore, 'files' . $filename)) {
             $files_view->touch($file, $revision);
             Storage::scheduleExpire($uid, $file);
             \OC_Hook::emit('\\OCP\\Versions', 'rollback', array('path' => $filename, 'revision' => $revision));
             return true;
         } else {
             if ($versionCreated) {
                 self::deleteVersion($users_view, $version);
             }
         }
     }
     return false;
 }
Example #8
0
 public static function filemtime($path)
 {
     return self::$defaultInstance->filemtime($path);
 }