diff options
Diffstat (limited to 'lib/private/Installer.php')
-rw-r--r-- | lib/private/Installer.php | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/lib/private/Installer.php b/lib/private/Installer.php index f32b0e5919a..91d20a129ae 100644 --- a/lib/private/Installer.php +++ b/lib/private/Installer.php @@ -10,6 +10,7 @@ declare(strict_types=1); namespace OC; use Doctrine\DBAL\Exception\TableExistsException; +use OC\App\AppStore\AppNotFoundException; use OC\App\AppStore\Bundles\Bundle; use OC\App\AppStore\Fetcher\AppFetcher; use OC\AppFramework\Bootstrap\Coordinator; @@ -169,16 +170,44 @@ class Installer { } /** + * Get the path where to install apps + * + * @throws \RuntimeException if an app folder is marked as writable but is missing permissions + */ + public function getInstallPath(): ?string { + foreach (\OC::$APPSROOTS as $dir) { + if (isset($dir['writable']) && $dir['writable'] === true) { + // Check if there is a writable install folder. + if (!is_writable($dir['path']) + || !is_readable($dir['path']) + ) { + throw new \RuntimeException( + 'Cannot write into "apps" directory. This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file.' + ); + } + return $dir['path']; + } + } + return null; + } + + /** * Downloads an app and puts it into the app directory * * @param string $appId * @param bool [$allowUnstable] * + * @throws AppNotFoundException If the app is not found on the appstore * @throws \Exception If the installation was not successful */ public function downloadApp(string $appId, bool $allowUnstable = false): void { $appId = strtolower($appId); + $installPath = $this->getInstallPath(); + if ($installPath === null) { + throw new \Exception('No application directories are marked as writable.'); + } + $apps = $this->appFetcher->get($allowUnstable); foreach ($apps as $app) { if ($app['id'] === $appId) { @@ -331,7 +360,7 @@ class Installer { ); } - $baseDir = OC_App::getInstallPath() . '/' . $appId; + $baseDir = $installPath . '/' . $appId; // Remove old app with the ID if existent Files::rmdirr($baseDir); // Move to app folder @@ -341,6 +370,9 @@ class Installer { // otherwise we just copy the outer directory $this->copyRecursive($extractDir, $baseDir); Files::rmdirr($extractDir); + if (function_exists('opcache_reset')) { + opcache_reset(); + } return; } // Signature does not match @@ -353,9 +385,9 @@ class Installer { } } - throw new \Exception( + throw new AppNotFoundException( sprintf( - 'Could not download app %s', + 'Could not download app %s, it was not found on the appstore', $appId ) ); @@ -370,7 +402,7 @@ class Installer { */ public function isUpdateAvailable($appId, $allowUnstable = false): string|false { if ($this->isInstanceReadyForUpdates === null) { - $installPath = OC_App::getInstallPath(); + $installPath = $this->getInstallPath(); if ($installPath === null) { $this->isInstanceReadyForUpdates = false; } else { @@ -458,7 +490,13 @@ class Installer { if (\OCP\Server::get(IAppManager::class)->isShipped($appId)) { return false; } - $appDir = OC_App::getInstallPath() . '/' . $appId; + + $installPath = $this->getInstallPath(); + if ($installPath === null) { + $this->logger->error('No application directories are marked as writable.', ['app' => 'core']); + return false; + } + $appDir = $installPath . '/' . $appId; Files::rmdirr($appDir); return true; } else { |