aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Installer.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Installer.php')
-rw-r--r--lib/private/Installer.php48
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 {