/** * 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; }
/** * 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; }
/** * 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'); } }