Ejemplo n.º 1
0
 public static function postAvatar($args)
 {
     \OC_JSON::checkLoggedIn();
     \OC_JSON::callCheck();
     $user = \OC_User::getUser();
     if (isset($_POST['path'])) {
         $path = stripslashes($_POST['path']);
         $view = new \OC\Files\View('/' . $user . '/files');
         $fileInfo = $view->getFileInfo($path);
         if ($fileInfo['encrypted'] === true) {
             $fileName = $view->toTmpFile($path);
         } else {
             $fileName = $view->getLocalFile($path);
         }
     } elseif (!empty($_FILES)) {
         $files = $_FILES['files'];
         if ($files['error'][0] === 0 && is_uploaded_file($files['tmp_name'][0]) && !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])) {
             \OC\Cache::set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
             $view = new \OC\Files\View('/' . $user . '/cache');
             $fileName = $view->getLocalFile('avatar_upload');
             unlink($files['tmp_name'][0]);
         }
     } else {
         $l = new \OC_L10n('core');
         \OC_JSON::error(array("data" => array("message" => $l->t("No image or file provided"))));
         return;
     }
     try {
         $image = new \OC_Image();
         $image->loadFromFile($fileName);
         $image->fixOrientation();
         if ($image->valid()) {
             \OC\Cache::set('tmpavatar', $image->data(), 7200);
             \OC_JSON::error(array("data" => "notsquare"));
         } else {
             $l = new \OC_L10n('core');
             $mimeType = $image->mimeType();
             if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
                 \OC_JSON::error(array("data" => array("message" => $l->t("Unknown filetype"))));
             }
             if (!$image->valid()) {
                 \OC_JSON::error(array("data" => array("message" => $l->t("Invalid image"))));
             }
         }
     } catch (\Exception $e) {
         \OC_JSON::error(array("data" => array("message" => $e->getMessage())));
     }
 }
Ejemplo n.º 2
0
 /**
  * Save the certificate and re-generate the certificate bundle
  *
  * @param string $certificate the certificate data
  * @param string $name the filename for the certificate
  * @return \OCP\ICertificate|void|bool
  * @throws \Exception If the certificate could not get added
  */
 public function addCertificate($certificate, $name)
 {
     if (!Filesystem::isValidPath($name) or Filesystem::isFileBlacklisted($name)) {
         return false;
     }
     $dir = $this->getPathToCertificates() . 'uploads/';
     if (!file_exists($dir)) {
         //path might not exist (e.g. non-standard OC_User::getHome() value)
         //in this case create full path using 3rd (recursive=true) parameter.
         //note that we use "normal" php filesystem functions here since the certs need to be local
         mkdir($dir, 0700, true);
     }
     try {
         $file = $dir . $name;
         $certificateObject = new Certificate($certificate, $name);
         file_put_contents($file, $certificate);
         $this->createCertificateBundle();
         return $certificateObject;
     } catch (\Exception $e) {
         throw $e;
     }
 }
Ejemplo n.º 3
0
 /**
  * Recursive copying of folders
  * @param string $src source folder
  * @param string $dest target folder
  *
  */
 static function copyr($src, $dest)
 {
     if (is_dir($src)) {
         if (!is_dir($dest)) {
             mkdir($dest);
         }
         $files = scandir($src);
         foreach ($files as $file) {
             if ($file != "." && $file != "..") {
                 self::copyr("{$src}/{$file}", "{$dest}/{$file}");
             }
         }
     } elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
         copy($src, $dest);
     }
 }
Ejemplo n.º 4
0
 /**
  * scan a single file and store it in the cache
  *
  * @param string $file
  * @param int $reuseExisting
  * @param bool $parentExistsInCache
  * @return array with metadata of the scanned file
  */
 public function scanFile($file, $reuseExisting = 0, $parentExistsInCache = false)
 {
     if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) {
         $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFile', array($file, $this->storageId));
         \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
         $data = $this->getData($file);
         if ($data) {
             if ($file and !$parentExistsInCache) {
                 $parent = dirname($file);
                 if ($parent === '.' or $parent === '/') {
                     $parent = '';
                 }
                 if (!$this->cache->inCache($parent)) {
                     $this->scanFile($parent);
                 }
             }
             $newData = $data;
             $cacheData = $this->cache->get($file);
             if ($cacheData) {
                 if (isset($cacheData['fileid'])) {
                     $this->permissionsCache->remove($cacheData['fileid']);
                 }
                 if ($reuseExisting) {
                     // prevent empty etag
                     $etag = $cacheData['etag'];
                     $propagateETagChange = false;
                     if (empty($etag)) {
                         $etag = $data['etag'];
                         $propagateETagChange = true;
                     }
                     // only reuse data if the file hasn't explicitly changed
                     if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) {
                         if ($reuseExisting & self::REUSE_SIZE && $data['size'] === -1) {
                             $data['size'] = $cacheData['size'];
                         }
                         if ($reuseExisting & self::REUSE_ETAG) {
                             $data['etag'] = $etag;
                             if ($propagateETagChange) {
                                 $parent = $file;
                                 while ($parent !== '') {
                                     $parent = dirname($parent);
                                     if ($parent === '.') {
                                         $parent = '';
                                     }
                                     $parentCacheData = $this->cache->get($parent);
                                     $this->cache->update($parentCacheData['fileid'], array('etag' => $this->storage->getETag($parent)));
                                 }
                             }
                         }
                     }
                     // Only update metadata that has changed
                     $newData = array_diff_assoc($data, $cacheData);
                     if (isset($newData['etag'])) {
                         $cacheDataString = print_r($cacheData, true);
                         $dataString = print_r($data, true);
                         \OCP\Util::writeLog('OC\\Files\\Cache\\Scanner', "!!! No reuse of etag for '{$file}' !!! \ncache: {$cacheDataString} \ndata: {$dataString}", \OCP\Util::DEBUG);
                     }
                 }
             }
             if (!empty($newData)) {
                 $this->cache->put($file, $newData);
                 $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFile', array($file, $this->storageId));
                 \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId));
             }
         } else {
             $this->cache->remove($file);
         }
         return $data;
     }
     return null;
 }
Ejemplo n.º 5
0
 /**
  * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage
  *
  * @param string $operation
  * @param string $path
  * @param array $hooks (optional)
  * @param mixed $extraParam (optional)
  * @return mixed
  *
  * This method takes requests for basic filesystem functions (e.g. reading & writing
  * files), processes hooks and proxies, sanitises paths, and finally passes them on to
  * \OC\Files\Storage\Storage for delegation to a storage backend for execution
  */
 private function basicOperation($operation, $path, $hooks = array(), $extraParam = null)
 {
     $postFix = substr($path, -1, 1) === '/' ? '/' : '';
     $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
     if (Filesystem::isValidPath($path) and !Filesystem::isFileBlacklisted($path)) {
         $path = $this->getRelativePath($absolutePath);
         if ($path == null) {
             return false;
         }
         $run = $this->runHooks($hooks, $path);
         list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
         if ($run and $storage) {
             if (!is_null($extraParam)) {
                 $result = $storage->{$operation}($internalPath, $extraParam);
             } else {
                 $result = $storage->{$operation}($internalPath);
             }
             if (in_array('delete', $hooks) and $result) {
                 $this->updater->remove($path);
             }
             if (in_array('write', $hooks) and $operation !== 'fopen') {
                 $this->updater->update($path);
             }
             if (in_array('touch', $hooks)) {
                 $this->updater->update($path, $extraParam);
             }
             if ($this->shouldEmitHooks($path) && $result !== false) {
                 if ($operation != 'fopen') {
                     //no post hooks for fopen, the file stream is still open
                     $this->runHooks($hooks, $path, true);
                 }
             }
             return $result;
         }
     }
     return null;
 }
Ejemplo n.º 6
0
 /**
  * scan a single file and store it in the cache
  *
  * @param string $file
  * @param int $reuseExisting
  * @param int $parentId
  * @param array | null $cacheData existing data in the cache for the file to be scanned
  * @param bool $lock set to false to disable getting an additional read lock during scanning
  * @return array an array of metadata of the scanned file
  * @throws \OC\ServerNotAvailableException
  * @throws \OCP\Lock\LockedException
  */
 public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true)
 {
     if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) {
         if ($lock) {
             $this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
         }
         $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFile', array($file, $this->storageId));
         \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
         $data = $this->getData($file);
         if ($data) {
             $parent = dirname($file);
             if ($parent === '.' or $parent === '/') {
                 $parent = '';
             }
             if ($parentId === -1) {
                 $parentId = $this->cache->getId($parent);
             }
             // scan the parent if it's not in the cache (id -1) and the current file is not the root folder
             if ($file and $parentId === -1) {
                 $parentData = $this->scanFile($parent);
                 $parentId = $parentData['fileid'];
             }
             if ($parent) {
                 $data['parent'] = $parentId;
             }
             if (is_null($cacheData)) {
                 $cacheData = $this->cache->get($file);
             }
             if ($cacheData and $reuseExisting and isset($cacheData['fileid'])) {
                 // prevent empty etag
                 if (empty($cacheData['etag'])) {
                     $etag = $data['etag'];
                 } else {
                     $etag = $cacheData['etag'];
                 }
                 $fileId = $cacheData['fileid'];
                 $data['fileid'] = $fileId;
                 // only reuse data if the file hasn't explicitly changed
                 if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) {
                     $data['mtime'] = $cacheData['mtime'];
                     if ($reuseExisting & self::REUSE_SIZE && $data['size'] === -1) {
                         $data['size'] = $cacheData['size'];
                     }
                     if ($reuseExisting & self::REUSE_ETAG) {
                         $data['etag'] = $etag;
                     }
                 }
                 // Only update metadata that has changed
                 $newData = array_diff_assoc($data, $cacheData);
             } else {
                 $newData = $data;
                 $fileId = -1;
             }
             if (!empty($newData)) {
                 $data['fileid'] = $this->addToCache($file, $newData, $fileId);
             }
             $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFile', array($file, $this->storageId));
             \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId));
         } else {
             $this->removeFromCache($file);
         }
         if ($lock) {
             $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
         }
         return $data;
     }
     return null;
 }
Ejemplo n.º 7
0
 /**
  * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage
  *
  * @param string $operation
  * @param string $path
  * @param array $hooks (optional)
  * @param mixed $extraParam (optional)
  * @return mixed
  * @throws \Exception
  *
  * This method takes requests for basic filesystem functions (e.g. reading & writing
  * files), processes hooks and proxies, sanitises paths, and finally passes them on to
  * \OC\Files\Storage\Storage for delegation to a storage backend for execution
  */
 private function basicOperation($operation, $path, $hooks = [], $extraParam = null)
 {
     $postFix = substr($path, -1, 1) === '/' ? '/' : '';
     $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
     if (Filesystem::isValidPath($path) and !Filesystem::isFileBlacklisted($path)) {
         $path = $this->getRelativePath($absolutePath);
         if ($path == null) {
             return false;
         }
         if (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) {
             // always a shared lock during pre-hooks so the hook can read the file
             $this->lockFile($path, ILockingProvider::LOCK_SHARED);
         }
         $run = $this->runHooks($hooks, $path);
         /** @var \OC\Files\Storage\Storage $storage */
         list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
         if ($run and $storage) {
             if (in_array('write', $hooks) || in_array('delete', $hooks)) {
                 $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
             }
             try {
                 if (!is_null($extraParam)) {
                     $result = $storage->{$operation}($internalPath, $extraParam);
                 } else {
                     $result = $storage->{$operation}($internalPath);
                 }
             } catch (\Exception $e) {
                 if (in_array('write', $hooks) || in_array('delete', $hooks)) {
                     $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
                 } else {
                     if (in_array('read', $hooks)) {
                         $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
                     }
                 }
                 throw $e;
             }
             if (in_array('delete', $hooks) and $result) {
                 $this->removeUpdate($storage, $internalPath);
             }
             if (in_array('write', $hooks) and $operation !== 'fopen') {
                 $this->writeUpdate($storage, $internalPath);
             }
             if (in_array('touch', $hooks)) {
                 $this->writeUpdate($storage, $internalPath, $extraParam);
             }
             if ((in_array('write', $hooks) || in_array('delete', $hooks)) && ($operation !== 'fopen' || $result === false)) {
                 $this->changeLock($path, ILockingProvider::LOCK_SHARED);
             }
             $unlockLater = false;
             if ($this->lockingEnabled && $operation === 'fopen' && is_resource($result)) {
                 $unlockLater = true;
                 $result = CallbackWrapper::wrap($result, null, null, function () use($hooks, $path) {
                     if (in_array('write', $hooks)) {
                         $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
                     } else {
                         if (in_array('read', $hooks)) {
                             $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
                         }
                     }
                 });
             }
             if ($this->shouldEmitHooks($path) && $result !== false) {
                 if ($operation != 'fopen') {
                     //no post hooks for fopen, the file stream is still open
                     $this->runHooks($hooks, $path, true);
                 }
             }
             if (!$unlockLater && (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks))) {
                 $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
             }
             return $result;
         } else {
             $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
         }
     }
     return null;
 }
Ejemplo n.º 8
0
 /**
  * @NoAdminRequired
  *
  * @param string $path
  * @return DataResponse
  */
 public function postAvatar($path)
 {
     $userId = $this->userSession->getUser()->getUID();
     $files = $this->request->getUploadedFile('files');
     $headers = [];
     if ($this->request->isUserAgent([\OC\AppFramework\Http\Request::USER_AGENT_IE_8])) {
         // due to upload iframe workaround, need to set content-type to text/plain
         $headers['Content-Type'] = 'text/plain';
     }
     if (isset($path)) {
         $path = stripslashes($path);
         $node = $this->userFolder->get($path);
         if (!$node instanceof \OCP\Files\File) {
             return new DataResponse(['data' => ['message' => $this->l->t('Please select a file.')]], Http::STATUS_OK, $headers);
         }
         if ($node->getSize() > 20 * 1024 * 1024) {
             return new DataResponse(['data' => ['message' => $this->l->t('File is too big')]], Http::STATUS_BAD_REQUEST, $headers);
         }
         $content = $node->getContent();
     } elseif (!is_null($files)) {
         if ($files['error'][0] === 0 && is_uploaded_file($files['tmp_name'][0]) && !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])) {
             if ($files['size'][0] > 20 * 1024 * 1024) {
                 return new DataResponse(['data' => ['message' => $this->l->t('File is too big')]], Http::STATUS_BAD_REQUEST, $headers);
             }
             $this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
             $content = $this->cache->get('avatar_upload');
             unlink($files['tmp_name'][0]);
         } else {
             return new DataResponse(['data' => ['message' => $this->l->t('Invalid file provided')]], Http::STATUS_BAD_REQUEST, $headers);
         }
     } else {
         //Add imgfile
         return new DataResponse(['data' => ['message' => $this->l->t('No image or file provided')]], Http::STATUS_BAD_REQUEST, $headers);
     }
     try {
         $image = new \OC_Image();
         $image->loadFromData($content);
         $image->fixOrientation();
         if ($image->valid()) {
             $mimeType = $image->mimeType();
             if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
                 return new DataResponse(['data' => ['message' => $this->l->t('Unknown filetype')]], Http::STATUS_OK, $headers);
             }
             $this->cache->set('tmpAvatar', $image->data(), 7200);
             return new DataResponse(['data' => 'notsquare'], Http::STATUS_OK, $headers);
         } else {
             return new DataResponse(['data' => ['message' => $this->l->t('Invalid image')]], Http::STATUS_OK, $headers);
         }
     } catch (\Exception $e) {
         $this->logger->logException($e, ['app' => 'core']);
         return new DataResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_OK, $headers);
     }
 }
Ejemplo n.º 9
0
 /**
  * Modifies a string to remove all non ASCII characters and spaces.
  *
  * @param string $text
  * @return string
  */
 private function slugify($text)
 {
     $originalText = $text;
     // replace non letter or digits or dots by -
     $text = preg_replace('~[^\\pL\\d\\.]+~u', '-', $text);
     // trim
     $text = trim($text, '-');
     // transliterate
     if (function_exists('iconv')) {
         $text = iconv('utf-8', 'us-ascii//TRANSLIT//IGNORE', $text);
     }
     // lowercase
     $text = strtolower($text);
     // remove unwanted characters
     $text = preg_replace('~[^-\\w\\.]+~', '', $text);
     // trim ending dots (for security reasons and win compatibility)
     $text = preg_replace('~\\.+$~', '', $text);
     if (empty($text) || \OC\Files\Filesystem::isFileBlacklisted($text)) {
         /**
          * Item slug would be empty. Previously we used uniqid() here.
          * However this means that the behaviour is not reproducible, so
          * when uploading files into a "empty" folder, the folders name is
          * different.
          *
          * The other case is, that the slugified name would be a blacklisted
          * filename. In this case we just use the same workaround by
          * returning the secure md5 hash of the original name.
          *
          *
          * If there would be a md5() hash collision, the deduplicate check
          * will spot this and append an index later, so this should not be
          * a problem.
          */
         return md5($originalText);
     }
     return $text;
 }
Ejemplo n.º 10
0
 /**
  * @dataProvider isFileBlacklistedData
  */
 public function testIsFileBlacklisted($path, $expected)
 {
     $this->assertSame($expected, \OC\Files\Filesystem::isFileBlacklisted($path));
 }
Ejemplo n.º 11
0
 /**
  * @NoAdminRequired
  */
 public function start()
 {
     $request = $this->request;
     $response = new JSONResponse();
     $params = $this->request->urlParams;
     $app = new App($this->api->getUserId());
     $addressBook = $app->getAddressBook($params['backend'], $params['addressBookId']);
     if (!$addressBook->hasPermission(\OCP\PERMISSION_CREATE)) {
         $response->setStatus('403');
         $response->bailOut(App::$l10n->t('You do not have permissions to import into this address book.'));
         return $response;
     }
     $filename = isset($request->post['filename']) ? $request->post['filename'] : null;
     $progresskey = isset($request->post['progresskey']) ? $request->post['progresskey'] : null;
     if (is_null($filename)) {
         $response->bailOut(App::$l10n->t('File name missing from request.'));
         return $response;
     }
     if (is_null($progresskey)) {
         $response->bailOut(App::$l10n->t('Progress key missing from request.'));
         return $response;
     }
     $filename = strtr($filename, array('/' => '', "\\" => ''));
     if (\OC\Files\Filesystem::isFileBlacklisted($filename)) {
         $response->bailOut(App::$l10n->t('Attempt to access blacklisted file:') . $filename);
         return $response;
     }
     $view = \OCP\Files::getStorage('contacts');
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $file = $view->file_get_contents('/imports/' . $filename);
     \OC_FileProxy::$enabled = $proxyStatus;
     $writeProgress = function ($pct) use($progresskey) {
         \OC_Cache::set($progresskey, $pct, 300);
     };
     $cleanup = function () use($view, $filename, $progresskey) {
         if (!$view->unlink('/imports/' . $filename)) {
             $response->debug('Unable to unlink /imports/' . $filename);
         }
         \OC_Cache::remove($progresskey);
     };
     $writeProgress('20');
     $nl = "\n";
     $file = str_replace(array("\r", "\n\n"), array("\n", "\n"), $file);
     $lines = explode($nl, $file);
     $inelement = false;
     $parts = array();
     $card = array();
     foreach ($lines as $line) {
         if (strtoupper(trim($line)) == 'BEGIN:VCARD') {
             $inelement = true;
         } elseif (strtoupper(trim($line)) == 'END:VCARD') {
             $card[] = $line;
             $parts[] = implode($nl, $card);
             $card = array();
             $inelement = false;
         }
         if ($inelement === true && trim($line) != '') {
             $card[] = $line;
         }
     }
     if (count($parts) === 0) {
         $response->bailOut(App::$l10n->t('No contacts found in: ') . $filename);
         $cleanup();
         return $response;
     }
     //import the contacts
     $imported = 0;
     $failed = 0;
     $partially = 0;
     $processed = 0;
     // TODO: Add a new group: "Imported at {date}"
     foreach ($parts as $part) {
         try {
             $vcard = VObject\Reader::read($part);
         } catch (VObject\ParseException $e) {
             try {
                 $vcard = VObject\Reader::read($part, VObject\Reader::OPTION_IGNORE_INVALID_LINES);
                 $partially += 1;
                 $response->debug('Import: Retrying reading card. Error parsing VCard: ' . $e->getMessage());
             } catch (\Exception $e) {
                 $failed += 1;
                 $response->debug('Import: skipping card. Error parsing VCard: ' . $e->getMessage());
                 continue;
                 // Ditch cards that can't be parsed by Sabre.
             }
         }
         try {
             $vcard->validate(MyVCard::REPAIR | MyVCard::UPGRADE);
         } catch (\Exception $e) {
             \OCP\Util::writeLog('contacts', __METHOD__ . ' ' . 'Error validating vcard: ' . $e->getMessage(), \OCP\Util::ERROR);
             $failed += 1;
         }
         /**
          * TODO
          * - Check if a contact with identical UID exists.
          * - If so, fetch that contact and call $contact->mergeFromVCard($vcard);
          * - Increment $updated var (not present yet.)
          * - continue
          */
         try {
             if ($addressBook->addChild($vcard)) {
                 $imported += 1;
             } else {
                 $failed += 1;
             }
         } catch (\Exception $e) {
             $response->debug('Error importing vcard: ' . $e->getMessage() . $nl . $vcard->serialize());
             $failed += 1;
         }
         $processed += 1;
         $writeProgress($processed);
     }
     //done the import
     sleep(3);
     // Give client side a chance to read the progress.
     $response->setParams(array('backend' => $params['backend'], 'addressBookId' => $params['addressBookId'], 'imported' => $imported, 'partially' => $partially, 'failed' => $failed));
     return $response;
 }
 /**
  * @NoAdminRequired
  */
 public function start()
 {
     $request = $this->request;
     $response = new JSONResponse();
     $params = $this->request->urlParams;
     $app = new App(\OCP\User::getUser());
     $addressBookId = $params['addressBookId'];
     $format = $params['importType'];
     $addressBook = $app->getAddressBook($params['backend'], $addressBookId);
     if (!$addressBook->hasPermission(\OCP\PERMISSION_CREATE)) {
         $response->setStatus('403');
         $response->bailOut(App::$l10n->t('You do not have permissions to import into this address book.'));
         return $response;
     }
     $filename = isset($request->post['filename']) ? $request->post['filename'] : null;
     $progresskey = isset($request->post['progresskey']) ? $request->post['progresskey'] : null;
     if (is_null($filename)) {
         $response->bailOut(App::$l10n->t('File name missing from request.'));
         return $response;
     }
     if (is_null($progresskey)) {
         $response->bailOut(App::$l10n->t('Progress key missing from request.'));
         return $response;
     }
     $filename = strtr($filename, array('/' => '', "\\" => ''));
     if (\OC\Files\Filesystem::isFileBlacklisted($filename)) {
         $response->bailOut(App::$l10n->t('Attempt to access blacklisted file:') . $filename);
         return $response;
     }
     $view = \OCP\Files::getStorage('contacts');
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $file = $view->file_get_contents('/imports/' . $filename);
     \OC_FileProxy::$enabled = $proxyStatus;
     $importManager = new ImportManager();
     $formatList = $importManager->getTypes();
     $found = false;
     $parts = array();
     foreach ($formatList as $formatName => $formatDisplayName) {
         if ($formatName == $format) {
             $parts = $importManager->importFile($view->getLocalFile('/imports/' . $filename), $formatName);
             $found = true;
         }
     }
     if (!$found) {
         // detect file type
         $mostLikelyName = "";
         $mostLikelyValue = 0;
         $probability = $importManager->detectFileType($view->getLocalFile('/imports/' . $filename));
         foreach ($probability as $probName => $probValue) {
             if ($probValue > $mostLikelyValue) {
                 $mostLikelyName = $probName;
                 $mostLikelyValue = $probValue;
             }
         }
         if ($mostLikelyValue > 0) {
             // found one (most likely...)
             $parts = $importManager->importFile($view->getLocalFile('/imports/' . $filename), $mostLikelyName);
         }
     }
     if ($parts) {
         //import the contacts
         $imported = 0;
         $failed = 0;
         $processed = 0;
         $total = count($parts);
         foreach ($parts as $part) {
             /**
              * TODO
              * - Check if a contact with identical UID exists.
              * - If so, fetch that contact and call $contact->mergeFromVCard($part);
              * - Increment $updated var (not present yet.)
              * - continue
              */
             try {
                 $id = $addressBook->addChild($part);
                 if ($id) {
                     $imported++;
                     $favourites = $part->select('X-FAVOURITES');
                     foreach ($favourites as $favourite) {
                         if ($favourite->getValue() == 'yes') {
                             $this->tagMgr->addToFavorites($id);
                         }
                     }
                 } else {
                     $failed++;
                 }
             } catch (\Exception $e) {
                 $response->debug('Error importing vcard: ' . $e->getMessage() . $nl . $part->serialize());
                 $failed++;
             }
             $processed++;
             $this->writeProcess($processed, $total, $progresskey);
         }
     } else {
         $imported = 0;
         $failed = 0;
         $processed = 0;
         $total = 0;
     }
     $this->cleanup($view, $filename, $progresskey, $response);
     //done the import
     sleep(3);
     // Give client side a chance to read the progress.
     $response->setParams(array('backend' => $params['backend'], 'addressBookId' => $params['addressBookId'], 'importType' => $params['importType'], 'imported' => $imported, 'count' => $processed, 'total' => $total, 'failed' => $failed));
     return $response;
 }
Ejemplo n.º 13
0
 /**
  * Modifies a string to remove all non ASCII characters and spaces.
  *
  * @param string $text
  * @return string
  */
 private function slugify($text)
 {
     // replace non letter or digits or dots by -
     $text = preg_replace('~[^\\pL\\d\\.]+~u', '-', $text);
     // trim
     $text = trim($text, '-');
     // transliterate
     if (function_exists('iconv')) {
         $text = iconv('utf-8', 'us-ascii//TRANSLIT//IGNORE', $text);
     }
     // lowercase
     $text = strtolower($text);
     // remove unwanted characters
     $text = preg_replace('~[^-\\w\\.]+~', '', $text);
     // trim ending dots (for security reasons and win compatibility)
     $text = preg_replace('~\\.+$~', '', $text);
     if (empty($text) || \OC\Files\Filesystem::isFileBlacklisted($text)) {
         return uniqid();
     }
     return $text;
 }
Ejemplo n.º 14
0
 /**
  * scan a single file and store it in the cache
  *
  * @param string $file
  * @param int $reuseExisting
  * @param int $parentId
  * @param array | null $cacheData existing data in the cache for the file to be scanned
  * @param bool $lock set to false to disable getting an additional read lock during scanning
  * @return array an array of metadata of the scanned file
  * @throws \OC\ServerNotAvailableException
  * @throws \OCP\Lock\LockedException
  */
 public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true)
 {
     // only proceed if $file is not a partial file nor a blacklisted file
     if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) {
         //acquire a lock
         if ($lock) {
             if ($this->storage->instanceOfStorage('\\OCP\\Files\\Storage\\ILockingStorage')) {
                 $this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
             }
         }
         $data = $this->getData($file);
         if ($data) {
             // pre-emit only if it was a file. By that we avoid counting/treating folders as files
             if ($data['mimetype'] !== 'httpd/unix-directory') {
                 $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFile', array($file, $this->storageId));
                 \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
             }
             $parent = dirname($file);
             if ($parent === '.' or $parent === '/') {
                 $parent = '';
             }
             if ($parentId === -1) {
                 $parentId = $this->cache->getId($parent);
             }
             // scan the parent if it's not in the cache (id -1) and the current file is not the root folder
             if ($file and $parentId === -1) {
                 $parentData = $this->scanFile($parent);
                 $parentId = $parentData['fileid'];
             }
             if ($parent) {
                 $data['parent'] = $parentId;
             }
             if (is_null($cacheData)) {
                 /** @var CacheEntry $cacheData */
                 $cacheData = $this->cache->get($file);
             }
             if ($cacheData and $reuseExisting and isset($cacheData['fileid'])) {
                 // prevent empty etag
                 if (empty($cacheData['etag'])) {
                     $etag = $data['etag'];
                 } else {
                     $etag = $cacheData['etag'];
                 }
                 $fileId = $cacheData['fileid'];
                 $data['fileid'] = $fileId;
                 // only reuse data if the file hasn't explicitly changed
                 if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) {
                     $data['mtime'] = $cacheData['mtime'];
                     if ($reuseExisting & self::REUSE_SIZE && $data['size'] === -1) {
                         $data['size'] = $cacheData['size'];
                     }
                     if ($reuseExisting & self::REUSE_ETAG) {
                         $data['etag'] = $etag;
                     }
                 }
                 // Only update metadata that has changed
                 $newData = array_diff_assoc($data, $cacheData->getData());
             } else {
                 $newData = $data;
                 $fileId = -1;
             }
             if (!empty($newData)) {
                 // Reset the checksum if the data has changed
                 $newData['checksum'] = '';
                 $data['fileid'] = $this->addToCache($file, $newData, $fileId);
             }
             if (isset($cacheData['size'])) {
                 $data['oldSize'] = $cacheData['size'];
             } else {
                 $data['oldSize'] = 0;
             }
             if (isset($cacheData['encrypted'])) {
                 $data['encrypted'] = $cacheData['encrypted'];
             }
             // post-emit only if it was a file. By that we avoid counting/treating folders as files
             if ($data['mimetype'] !== 'httpd/unix-directory') {
                 $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFile', array($file, $this->storageId));
                 \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId));
             }
         } else {
             $this->removeFromCache($file);
         }
         //release the acquired lock
         if ($lock) {
             if ($this->storage->instanceOfStorage('\\OCP\\Files\\Storage\\ILockingStorage')) {
                 $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
             }
         }
         if ($data && !isset($data['encrypted'])) {
             $data['encrypted'] = false;
         }
         return $data;
     }
     return null;
 }
Ejemplo n.º 15
0
 /**
  * Save the certificate and re-generate the certificate bundle
  *
  * @param string $certificate the certificate data
  * @param string $name the filename for the certificate
  * @return \OCP\ICertificate
  * @throws \Exception If the certificate could not get added
  */
 public function addCertificate($certificate, $name)
 {
     if (!Filesystem::isValidPath($name) or Filesystem::isFileBlacklisted($name)) {
         throw new \Exception('Filename is not valid');
     }
     $dir = $this->getPathToCertificates() . 'uploads/';
     if (!$this->view->file_exists($dir)) {
         $this->view->mkdir($dir);
     }
     try {
         $file = $dir . $name;
         $certificateObject = new Certificate($certificate, $name);
         $this->view->file_put_contents($file, $certificate);
         $this->createCertificateBundle();
         return $certificateObject;
     } catch (\Exception $e) {
         throw $e;
     }
 }
Ejemplo n.º 16
0
 /**
  * scan a single file and store it in the cache
  *
  * @param string $file
  * @param int $reuseExisting
  * @return array an array of metadata of the scanned file
  */
 public function scanFile($file, $reuseExisting = 0)
 {
     if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) {
         $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFile', array($file, $this->storageId));
         \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
         $data = $this->getData($file);
         if ($data) {
             $parent = dirname($file);
             if ($parent === '.' or $parent === '/') {
                 $parent = '';
             }
             $parentId = $this->cache->getId($parent);
             // scan the parent if it's not in the cache (id -1) and the current file is not the root folder
             if ($file and $parentId === -1) {
                 $parentData = $this->scanFile($parent);
                 $parentId = $parentData['fileid'];
             }
             if ($parent) {
                 $data['parent'] = $parentId;
             }
             $cacheData = $this->cache->get($file);
             if ($cacheData and $reuseExisting) {
                 // prevent empty etag
                 if (empty($cacheData['etag'])) {
                     $etag = $data['etag'];
                 } else {
                     $etag = $cacheData['etag'];
                 }
                 // only reuse data if the file hasn't explicitly changed
                 if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) {
                     $data['mtime'] = $cacheData['mtime'];
                     if ($reuseExisting & self::REUSE_SIZE && $data['size'] === -1) {
                         $data['size'] = $cacheData['size'];
                     }
                     if ($reuseExisting & self::REUSE_ETAG) {
                         $data['etag'] = $etag;
                     }
                 }
                 // Only update metadata that has changed
                 $newData = array_diff_assoc($data, $cacheData);
                 if (isset($newData['etag'])) {
                     $cacheDataString = print_r($cacheData, true);
                     $dataString = print_r($data, true);
                     \OCP\Util::writeLog('OC\\Files\\Cache\\Scanner', "!!! No reuse of etag for '{$file}' !!! \ncache: {$cacheDataString} \ndata: {$dataString}", \OCP\Util::DEBUG);
                 }
             } else {
                 $newData = $data;
             }
             if (!empty($newData)) {
                 $data['fileid'] = $this->addToCache($file, $newData);
                 $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFile', array($file, $this->storageId));
                 \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId));
             }
         } else {
             $this->removeFromCache($file);
         }
         return $data;
     }
     return null;
 }
Ejemplo n.º 17
0
 /**
  * @NoAdminRequired
  *
  * @param string $path
  * @return DataResponse
  */
 public function postAvatar($path)
 {
     $userId = $this->userSession->getUser()->getUID();
     $files = $this->request->getUploadedFile('files');
     if (isset($path)) {
         $path = stripslashes($path);
         $view = new \OC\Files\View('/' . $userId . '/files');
         if ($view->filesize($path) > 20 * 1024 * 1024) {
             return new DataResponse(['data' => ['message' => $this->l->t('File is too big')]], Http::STATUS_BAD_REQUEST);
         }
         $fileName = $view->getLocalFile($path);
     } elseif (!is_null($files)) {
         if ($files['error'][0] === 0 && is_uploaded_file($files['tmp_name'][0]) && !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])) {
             if ($files['size'][0] > 20 * 1024 * 1024) {
                 return new DataResponse(['data' => ['message' => $this->l->t('File is too big')]], Http::STATUS_BAD_REQUEST);
             }
             $this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
             $view = new \OC\Files\View('/' . $userId . '/cache');
             $fileName = $view->getLocalFile('avatar_upload');
             unlink($files['tmp_name'][0]);
         } else {
             return new DataResponse(['data' => ['message' => $this->l->t('Invalid file provided')]], Http::STATUS_BAD_REQUEST);
         }
     } else {
         //Add imgfile
         return new DataResponse(['data' => ['message' => $this->l->t('No image or file provided')]], Http::STATUS_BAD_REQUEST);
     }
     try {
         $image = new \OC_Image();
         $image->loadFromFile($fileName);
         $image->fixOrientation();
         if ($image->valid()) {
             $mimeType = $image->mimeType();
             if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
                 return new DataResponse(['data' => ['message' => $this->l->t('Unknown filetype')]]);
             }
             $this->cache->set('tmpAvatar', $image->data(), 7200);
             return new DataResponse(['data' => 'notsquare']);
         } else {
             return new DataResponse(['data' => ['message' => $this->l->t('Invalid image')]]);
         }
     } catch (\Exception $e) {
         return new DataResponse(['data' => ['message' => $e->getMessage()]]);
     }
 }
Ejemplo n.º 18
0
	/**
	 * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage
	 *
	 * @param string $operation
	 * @param string $path
	 * @param array $hooks (optional)
	 * @param mixed $extraParam (optional)
	 * @return mixed
	 *
	 * This method takes requests for basic filesystem functions (e.g. reading & writing
	 * files), processes hooks and proxies, sanitises paths, and finally passes them on to
	 * \OC\Files\Storage\Storage for delegation to a storage backend for execution
	 */
	private function basicOperation($operation, $path, $hooks = array(), $extraParam = null) {
		$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
		$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
		if (\OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam)
			and Filesystem::isValidPath($path)
			and !Filesystem::isFileBlacklisted($path)
		) {
			$path = $this->getRelativePath($absolutePath);
			if ($path == null) {
				return false;
			}

			$run = $this->runHooks($hooks, $path);
			list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
			if ($run and $storage) {
				if (!is_null($extraParam)) {
					$result = $storage->$operation($internalPath, $extraParam);
				} else {
					$result = $storage->$operation($internalPath);
				}
				$result = \OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result);
				if ($this->shouldEmitHooks($path) && $result !== false) {
					if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open
						$this->runHooks($hooks, $path, true);
					}
				}
				return $result;
			}
		}
		return null;
	}