/** * Get the cache mount for a user * * @param IUser $user * @param IStorageFactory $loader * @return \OCP\Files\Mount\IMountPoint[] */ public function getHomeMountForUser(IUser $user, IStorageFactory $loader) { $arguments = ['user' => $user]; if (\OC\Files\Cache\Storage::exists('local::' . $user->getHome() . '/')) { $arguments['legacy'] = true; } return new MountPoint('\\OC\\Files\\Storage\\Home', '/' . $user->getUID(), $arguments, $loader); }
/** * Returns the storage id based on the numeric id * * @param int $numericId numeric id of the storage * @return string storage id or null if not found */ private function getStorageId($storageId) { $numericId = \OC\Files\Cache\Storage::getNumericStorageId($storageId); if (!is_null($numericId)) { return (int) $numericId; } return null; }
public static function getFileInfo($numericId, $path, $pharPath = null) { $storage = Storage::getStorageId($numericId); $config = \OC::$server->getConfig(); $home = $config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/'); $user = explode("::", $storage)[1]; $urn = $home . '/' . $user . '/' . $path; if ($pharPath != null) { $urn = TarParser::PHAR_PROTOCOLE . $urn . $pharPath; } return array('urn' => $urn, 'user' => $user); }
/** * Convert an IShare to an array for OCS output * * @param IShare $share * @return array */ protected function formatShare($share) { $result = ['id' => $share->getId(), 'share_type' => $share->getShareType(), 'uid_owner' => $share->getSharedBy()->getUID(), 'displayname_owner' => $share->getSharedBy()->getDisplayName(), 'permissions' => $share->getPermissions(), 'stime' => $share->getShareTime(), 'parent' => $share->getParent(), 'expiration' => null, 'token' => null]; $path = $share->getPath(); $result['path'] = $this->userFolder->getRelativePath($path->getPath()); if ($path instanceof \OCP\Files\Folder) { $result['item_type'] = 'folder'; } else { $result['item_type'] = 'file'; } $result['storage_id'] = $path->getStorage()->getId(); $result['storage'] = \OC\Files\Cache\Storage::getNumericStorageId($path->getStorage()->getId()); $result['item_source'] = $path->getId(); $result['file_source'] = $path->getId(); $result['file_parent'] = $path->getParent()->getId(); $result['file_target'] = $share->getTarget(); if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { $sharedWith = $share->getSharedWith(); $result['share_with'] = $sharedWith->getUID(); $result['share_with_displayname'] = $sharedWith->getDisplayName(); } else { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { $sharedWith = $share->getSharedWith(); $result['share_with'] = $sharedWith->getGID(); $result['share_with_displayname'] = $sharedWith->getGID(); } else { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { $result['share_with'] = $share->getPassword(); $result['share_with_displayname'] = $share->getPassword(); $result['token'] = $share->getToken(); $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]); $expiration = $share->getExpirationDate(); if ($expiration !== null) { $result['expiration'] = $expiration->format('Y-m-d 00:00:00'); } } else { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) { $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $share->getSharedWith(); $result['token'] = $share->getToken(); } } } } $result['mail_send'] = $share->getMailSend() ? 1 : 0; return $result; }
/** * get the storage id of the storage for a file and the internal path of the file * unlike getPathById this does not limit the search to files on this storage and * instead does a global search in the cache table * * @param int $id * @deprecated use getPathById() instead * @return array first element holding the storage id, second the path */ public static function getById($id) { $connection = \OC::$server->getDatabaseConnection(); $sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?'; $result = $connection->executeQuery($sql, array($id)); if ($row = $result->fetch()) { $numericId = $row['storage']; $path = $row['path']; } else { return null; } if ($id = Storage::getStorageId($numericId)) { return array($id, $path); } else { return null; } }
/** * Delete the user * * @return bool */ public function delete() { if ($this->emitter) { $this->emitter->emit('\\OC\\User', 'preDelete', array($this)); } $result = $this->backend->deleteUser($this->uid); if ($result) { // FIXME: Feels like an hack - suggestions? // We have to delete the user from all groups foreach (\OC_Group::getUserGroups($this->uid) as $i) { \OC_Group::removeFromGroup($this->uid, $i); } // Delete the user's keys in preferences \OC::$server->getConfig()->deleteAllUserValues($this->uid); // Delete user files in /data/ \OC_Helper::rmdirr(\OC_User::getHome($this->uid)); // Delete the users entry in the storage table \OC\Files\Cache\Storage::remove('home::' . $this->uid); \OC::$server->getCommentsManager()->deleteReferencesOfActor('users', $this->uid); \OC::$server->getCommentsManager()->deleteReadMarksFromUser($this); } if ($this->emitter) { $this->emitter->emit('\\OC\\User', 'postDelete', array($this)); } return !($result === false); }
/** * Initialize system and personal mount points for a user * * @param string $user * @throws \OC\User\NoUserException if the user is not available */ public static function initMountPoints($user = '') { if ($user == '') { $user = \OC_User::getUser(); } if ($user === null || $user === false || $user === '') { throw new \OC\User\NoUserException('Attempted to initialize mount points for null user and no user in session'); } if (isset(self::$usersSetup[$user])) { return; } $root = \OC_User::getHome($user); $userManager = \OC::$server->getUserManager(); $userObject = $userManager->get($user); if (is_null($userObject)) { \OCP\Util::writeLog('files', ' Backends provided no user object for ' . $user, \OCP\Util::ERROR); throw new \OC\User\NoUserException('Backends provided no user object for ' . $user); } self::$usersSetup[$user] = true; $homeStorage = \OC::$server->getConfig()->getSystemValue('objectstore'); if (!empty($homeStorage)) { // sanity checks if (empty($homeStorage['class'])) { \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR); } if (!isset($homeStorage['arguments'])) { $homeStorage['arguments'] = array(); } // instantiate object store implementation $homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']); // mount with home object store implementation $homeStorage['class'] = '\\OC\\Files\\ObjectStore\\HomeObjectStoreStorage'; } else { $homeStorage = array('class' => '\\OC\\Files\\Storage\\Home', 'arguments' => array()); } $homeStorage['arguments']['user'] = $userObject; // check for legacy home id (<= 5.0.12) if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { $homeStorage['arguments']['legacy'] = true; } $mount = new MountPoint($homeStorage['class'], '/' . $user, $homeStorage['arguments'], self::getLoader()); self::getMountManager()->addMount($mount); $home = \OC\Files\Filesystem::getStorage($user); // Chance to mount for other storages /** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */ $mountConfigManager = \OC::$server->getMountProviderCollection(); if ($userObject) { $mounts = $mountConfigManager->getMountsForUser($userObject); array_walk($mounts, array(self::$mounts, 'addMount')); $mounts[] = $mount; $mountConfigManager->registerMounts($userObject, $mounts); } self::listenForNewMountProviders($mountConfigManager, $userManager); \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); }
/** * Initialize system and personal mount points for a user * * @param string $user */ public static function initMountPoints($user = '') { if ($user == '') { $user = \OC_User::getUser(); } $parser = new \OC\ArrayParser(); $root = \OC_User::getHome($user); $userObject = \OC_User::getManager()->get($user); if (is_null($userObject)) { \OCP\Util::writeLog('files', ' Backends provided no user object for ' . $user, \OCP\Util::ERROR); throw new \OC\User\NoUserException('Backends provided no user object for ' . $user); } $homeStorage = \OC_Config::getValue('objectstore'); if (!empty($homeStorage)) { // sanity checks if (empty($homeStorage['class'])) { \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR); } if (!isset($homeStorage['arguments'])) { $homeStorage['arguments'] = array(); } // instantiate object store implementation $homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']); // mount with home object store implementation $homeStorage['class'] = '\\OC\\Files\\ObjectStore\\HomeObjectStoreStorage'; } else { $homeStorage = array('class' => '\\OC\\Files\\Storage\\Home', 'arguments' => array()); } $homeStorage['arguments']['user'] = $userObject; // check for legacy home id (<= 5.0.12) if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { $homeStorage['arguments']['legacy'] = true; } self::mount($homeStorage['class'], $homeStorage['arguments'], $user); $home = \OC\Files\Filesystem::getStorage($user); self::mountCacheDir($user); // Chance to mount for other storages \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); }
/** * Updates old storage ids (v0.2.1 and older) that are based on key and secret to new ones based on the bucket name. * TODO Do this in an update.php. requires iterating over all users and loading the mount.json from their home * * @param array $params */ public function updateLegacyId(array $params) { $oldId = 'amazon::' . $params['key'] . md5($params['secret']); // find by old id or bucket $stmt = \OC::$server->getDatabaseConnection()->prepare('SELECT `numeric_id`, `id` FROM `*PREFIX*storages` WHERE `id` IN (?, ?)'); $stmt->execute(array($oldId, $this->id)); while ($row = $stmt->fetch()) { $storages[$row['id']] = $row['numeric_id']; } if (isset($storages[$this->id]) && isset($storages[$oldId])) { // if both ids exist, delete the old storage and corresponding filecache entries \OC\Files\Cache\Storage::remove($oldId); } else { if (isset($storages[$oldId])) { // if only the old id exists do an update $stmt = \OC::$server->getDatabaseConnection()->prepare('UPDATE `*PREFIX*storages` SET `id` = ? WHERE `id` = ?'); $stmt->execute(array($this->id, $oldId)); } } // only the bucket based id may exist, do nothing }
/** * @brief delete a user * @param string $uid The username of the user to delete * @return bool * * Deletes a user */ public static function deleteUser($uid) { $user = self::getManager()->get($uid); if ($user) { $result = $user->delete(); // if delete was successful we clean-up the rest if ($result) { // We have to delete the user from all groups foreach (OC_Group::getUserGroups($uid) as $i) { OC_Group::removeFromGroup($uid, $i); } // Delete the user's keys in preferences OC_Preferences::deleteUser($uid); // Delete user files in /data/ $home = \OC_User::getHome($uid); OC_Helper::rmdirr($home); // Delete the users entry in the storage table \OC\Files\Cache\Storage::remove('home::' . $uid); \OC\Files\Cache\Storage::remove('local::' . $home . '/'); // Remove it from the Cache self::getManager()->delete($uid); } return true; } else { return false; } }
/** * get the storage id of the storage for a file and the internal path of the file * unlike getPathById this does not limit the search to files on this storage and * instead does a global search in the cache table * * @param int $id * @deprecated use getPathById() instead * @return array first element holding the storage id, second the path */ public static function getById($id) { $sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?'; $result = \OC_DB::executeAudited($sql, array($id)); if ($row = $result->fetchRow()) { $numericId = $row['storage']; $path = $row['path']; } else { return null; } if ($id = Storage::getStorageId($numericId)) { return array($id, $path); } else { return null; } }
/** * Find mounts by numeric storage id * * @param int $id * @return MountPoint[] */ public function findByNumericId($id) { $storageId = \OC\Files\Cache\Storage::getStorageId($id); return $this->findByStorageId($storageId); }
/** * Initialize system and personal mount points for a user * * @param string $user */ public static function initMountPoints($user = '') { if ($user == '') { $user = \OC_User::getUser(); } $parser = new \OC\ArrayParser(); $root = \OC_User::getHome($user); $userObject = \OC_User::getManager()->get($user); if (!is_null($userObject)) { // check for legacy home id (<= 5.0.12) if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { self::mount('\\OC\\Files\\Storage\\Home', array('user' => $userObject, 'legacy' => true), $user); } else { self::mount('\\OC\\Files\\Storage\\Home', array('user' => $userObject), $user); } } else { self::mount('\\OC\\Files\\Storage\\Local', array('datadir' => $root), $user); } // Chance to mount for other storages \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); }
/** * Initialize system and personal mount points for a user * * @param string $user */ public static function initMountPoints($user = '') { if ($user == '') { $user = \OC_User::getUser(); } $parser = new \OC\ArrayParser(); $root = \OC_User::getHome($user); $userObject = \OC_User::getManager()->get($user); if (!is_null($userObject)) { // check for legacy home id (<= 5.0.12) if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { self::mount('\\OC\\Files\\Storage\\Home', array('user' => $userObject, 'legacy' => true), $user); } else { self::mount('\\OC\\Files\\Storage\\Home', array('user' => $userObject), $user); } } else { self::mount('\\OC\\Files\\Storage\\Local', array('datadir' => $root), $user); } $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); //move config file to it's new position if (is_file(\OC::$SERVERROOT . '/config/mount.json')) { rename(\OC::$SERVERROOT . '/config/mount.json', $datadir . '/mount.json'); } // Load system mount points if (is_file(\OC::$SERVERROOT . '/config/mount.php') or is_file($datadir . '/mount.json')) { if (is_file($datadir . '/mount.json')) { $mountConfig = json_decode(file_get_contents($datadir . '/mount.json'), true); } elseif (is_file(\OC::$SERVERROOT . '/config/mount.php')) { $mountConfig = $parser->parsePHP(file_get_contents(\OC::$SERVERROOT . '/config/mount.php')); } if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); } } if (isset($mountConfig['group'])) { foreach ($mountConfig['group'] as $group => $mounts) { if (\OC_Group::inGroup($user, $group)) { foreach ($mounts as $mountPoint => $options) { $mountPoint = self::setUserVars($user, $mountPoint); foreach ($options as &$option) { $option = self::setUserVars($user, $option); } self::mount($options['class'], $options['options'], $mountPoint); } } } } if (isset($mountConfig['user'])) { foreach ($mountConfig['user'] as $mountUser => $mounts) { if ($mountUser === 'all' or strtolower($mountUser) === strtolower($user)) { foreach ($mounts as $mountPoint => $options) { $mountPoint = self::setUserVars($user, $mountPoint); foreach ($options as &$option) { $option = self::setUserVars($user, $option); } self::mount($options['class'], $options['options'], $mountPoint); } } } } } // Load personal mount points if (is_file($root . '/mount.php') or is_file($root . '/mount.json')) { if (is_file($root . '/mount.json')) { $mountConfig = json_decode(file_get_contents($root . '/mount.json'), true); } elseif (is_file($root . '/mount.php')) { $mountConfig = $parser->parsePHP(file_get_contents($root . '/mount.php')); } if (isset($mountConfig['user'][$user])) { foreach ($mountConfig['user'][$user] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); } } } // Chance to mount for other storages \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); }
/** * Converts legacy home storage ids in the format * "local::/data/dir/path/userid/" to the new format "home::userid" */ public function run(IOutput $out) { // only run once if ($this->config->getAppValue('core', 'repairlegacystoragesdone') === 'yes') { return; } $dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/'); $dataDir = rtrim($dataDir, '/') . '/'; $dataDirId = 'local::' . $dataDir; $count = 0; $hasWarnings = false; $this->connection->beginTransaction(); // note: not doing a direct UPDATE with the REPLACE function // because regexp search/extract is needed and it is not guaranteed // to work on all database types $sql = 'SELECT `id`, `numeric_id` FROM `*PREFIX*storages`' . ' WHERE `id` LIKE ?' . ' ORDER BY `id`'; $result = $this->connection->executeQuery($sql, array($dataDirId . '%')); while ($row = $result->fetch()) { $currentId = $row['id']; // one entry is the datadir itself if ($currentId === $dataDirId) { continue; } try { if ($this->fixLegacyStorage($currentId, (int) $row['numeric_id'])) { $count++; } } catch (RepairException $e) { $hasWarnings = true; $out->warning('Could not repair legacy storage ' . $currentId . ' automatically.'); } } // check for md5 ids, not in the format "prefix::" $sql = 'SELECT COUNT(*) AS "c" FROM `*PREFIX*storages`' . ' WHERE `id` NOT LIKE \'%::%\''; $result = $this->connection->executeQuery($sql); $row = $result->fetch(); // find at least one to make sure it's worth // querying the user list if ((int) $row['c'] > 0) { $userManager = \OC::$server->getUserManager(); // use chunks to avoid caching too many users in memory $limit = 30; $offset = 0; do { // query the next page of users $results = $userManager->search('', $limit, $offset); $storageIds = array(); foreach ($results as $uid => $userObject) { $storageId = $dataDirId . $uid . '/'; if (strlen($storageId) <= 64) { // skip short storage ids as they were handled in the previous section continue; } $storageIds[$uid] = $storageId; } if (count($storageIds) > 0) { // update the storages of these users foreach ($storageIds as $uid => $storageId) { $numericId = Storage::getNumericStorageId($storageId); try { if (!is_null($numericId) && $this->fixLegacyStorage($storageId, (int) $numericId)) { $count++; } } catch (RepairException $e) { $hasWarnings = true; $out->warning('Could not repair legacy storage ' . $storageId . ' automatically.'); } } } $offset += $limit; } while (count($results) >= $limit); } $out->info('Updated ' . $count . ' legacy home storage ids'); $this->connection->commit(); if ($hasWarnings) { $out->warning('Some legacy storages could not be repaired. Please manually fix them then re-run ./occ maintenance:repair'); } else { // if all were done, no need to redo the repair during next upgrade $this->config->setAppValue('core', 'repairlegacystoragesdone', 'yes'); } }
/** * Delete the storage with the given id. * * @param int $id storage id * * @throws NotFoundException if no storage was found with the given id */ public function removeStorage($id) { $existingMount = $this->dbConfig->getMountById($id); if (!is_array($existingMount)) { throw new NotFoundException('Storage with id "' . $id . '" not found'); } $this->dbConfig->removeMount($id); $deletedStorage = $this->getStorageConfigFromDBMount($existingMount); $this->triggerHooks($deletedStorage, Filesystem::signal_delete_mount); // delete oc_storages entries and oc_filecache try { $rustyStorageId = $this->getRustyStorageIdFromConfig($deletedStorage); \OC\Files\Cache\Storage::remove($rustyStorageId); } catch (\Exception $e) { // can happen either for invalid configs where the storage could not // be instantiated or whenever $user vars where used, in which case // the storage id could not be computed \OCP\Util::writeLog('files_external', 'Exception: "' . $e->getMessage() . '"', \OCP\Util::ERROR); } }
/** * Initialize system and personal mount points for a user * * @param string $user */ public static function initMountPoints($user = '') { if ($user == '') { $user = \OC_User::getUser(); } if (isset(self::$usersSetup[$user])) { return; } self::$usersSetup[$user] = true; $root = \OC_User::getHome($user); $userObject = \OC_User::getManager()->get($user); if (!is_null($userObject)) { $homeStorage = \OC_Config::getValue('objectstore'); if (!empty($homeStorage)) { // sanity checks if (empty($homeStorage['class'])) { \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR); } if (!isset($homeStorage['arguments'])) { $homeStorage['arguments'] = array(); } // instantiate object store implementation $homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']); // mount with home object store implementation $homeStorage['class'] = '\\OC\\Files\\ObjectStore\\HomeObjectStoreStorage'; } else { $homeStorage = array('class' => '\\OC\\Files\\Storage\\Home', 'arguments' => array()); } $homeStorage['arguments']['user'] = $userObject; // check for legacy home id (<= 5.0.12) if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { $homeStorage['arguments']['legacy'] = true; } self::mount($homeStorage['class'], $homeStorage['arguments'], $user); $home = \OC\Files\Filesystem::getStorage($user); } else { self::mount('\\OC\\Files\\Storage\\Local', array('datadir' => $root), $user); } self::mountCacheDir($user); // Chance to mount for other storages if ($userObject) { $mountConfigManager = \OC::$server->getMountProviderCollection(); $mounts = $mountConfigManager->getMountsForUser($userObject); array_walk($mounts, array(self::$mounts, 'addMount')); } \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); }