Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/updatenotification/lib/Controller/APIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function getAppList(string $newVersion): DataResponse {
]);
}

$this->appFetcher->setVersion($newVersion, 'future-apps.json');
$this->appFetcher->setVersion($newVersion, 'future-apps.json', false);

// Apps available on the app store for that version
$availableApps = array_map(function(array $app) {
Expand Down
4 changes: 0 additions & 4 deletions apps/updatenotification/lib/Settings/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ class Admin implements ISettings {
private $groupManager;
/** @var IDateTimeFormatter */
private $dateTimeFormatter;
/** @var IUserSession */
private $session;
/** @var IFactory */
private $l10nFactory;

Expand All @@ -55,14 +53,12 @@ public function __construct(
UpdateChecker $updateChecker,
IGroupManager $groupManager,
IDateTimeFormatter $dateTimeFormatter,
IUserSession $session,
IFactory $l10nFactory
) {
$this->config = $config;
$this->updateChecker = $updateChecker;
$this->groupManager = $groupManager;
$this->dateTimeFormatter = $dateTimeFormatter;
$this->session = $session;
$this->l10nFactory = $l10nFactory;
}

Expand Down
5 changes: 1 addition & 4 deletions apps/updatenotification/tests/Settings/AdminTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
use Test\TestCase;

class AdminTest extends TestCase {
/** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
protected $userSession;
/** @var IFactory|\PHPUnit_Framework_MockObject_MockObject */
protected $l10nFactory;
/** @var Admin */
Expand All @@ -61,11 +59,10 @@ public function setUp() {
$this->updateChecker = $this->createMock(UpdateChecker::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->dateTimeFormatter = $this->createMock(IDateTimeFormatter::class);
$this->userSession = $this->createMock(IUserSession::class);
$this->l10nFactory = $this->createMock(IFactory::class);

$this->admin = new Admin(
$this->config, $this->updateChecker, $this->groupManager, $this->dateTimeFormatter, $this->userSession, $this->l10nFactory
$this->config, $this->updateChecker, $this->groupManager, $this->dateTimeFormatter, $this->l10nFactory
);
}

Expand Down
28 changes: 14 additions & 14 deletions lib/private/App/AppStore/Fetcher/AppFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class AppFetcher extends Fetcher {
/** @var CompareVersion */
private $compareVersion;

/** @var bool */
private $ignoreMaxVersion;

/**
* @param Factory $appDataFactory
* @param IClientService $clientService
Expand All @@ -65,6 +68,7 @@ public function __construct(Factory $appDataFactory,
$this->fileName = 'apps.json';
$this->setEndpoint();
$this->compareVersion = $compareVersion;
$this->ignoreMaxVersion = true;
}

/**
Expand Down Expand Up @@ -97,7 +101,7 @@ protected function fetch($ETag, $content) {
$minFulfilled = $this->compareVersion->isCompatible($ncVersion, $min, '>=');
$maxFulfilled = $max !== '' &&
$this->compareVersion->isCompatible($ncVersion, $max, '<=');
if ($minFulfilled && $maxFulfilled) {
if ($minFulfilled && ($this->ignoreMaxVersion || $maxFulfilled)) {
$releases[] = $release;
}
} catch (\InvalidArgumentException $e) {
Expand All @@ -106,50 +110,46 @@ protected function fetch($ETag, $content) {
}
}

if (empty($releases)) {
// Remove apps that don't have a matching release
continue;
}

// Get the highest version
$versions = [];
foreach($releases as $release) {
$versions[] = $release['version'];
}
usort($versions, 'version_compare');
$versions = array_reverse($versions);
$compatible = false;
if(isset($versions[0])) {
$highestVersion = $versions[0];
foreach ($releases as $release) {
if ((string)$release['version'] === (string)$highestVersion) {
$compatible = true;
$response['data'][$dataKey]['releases'] = [$release];
break;
}
}
}
if(!$compatible) {
unset($response['data'][$dataKey]);
}
}

$response['data'] = array_values($response['data']);
return $response;
}

private function setEndpoint() {
$versionArray = explode('.', $this->getVersion());
$this->endpointUrl = sprintf(
'https://apps.nextcloud.com/api/v1/platform/%d.%d.%d/apps.json',
$versionArray[0],
$versionArray[1],
$versionArray[2]
);
$this->endpointUrl = 'https://apps.nextcloud.com/api/v1/apps.json';
}

/**
* @param string $version
* @param string $fileName
* @param bool $ignoreMaxVersion
*/
public function setVersion(string $version, string $fileName = 'apps.json') {
public function setVersion(string $version, string $fileName = 'apps.json', bool $ignoreMaxVersion = true) {
parent::setVersion($version);
$this->fileName = $fileName;
$this->ignoreMaxVersion = $ignoreMaxVersion;
$this->setEndpoint();
}
}
46 changes: 34 additions & 12 deletions lib/private/App/DependencyAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

namespace OC\App;

use OCP\IConfig;
use OCP\IL10N;

class DependencyAnalyzer {
Expand All @@ -53,7 +54,7 @@ public function __construct(Platform $platform, IL10N $l) {
* @param array $app
* @returns array of missing dependencies
*/
public function analyze(array $app) {
public function analyze(array $app, bool $ignoreMax = false) {
$this->appInfo = $app;
if (isset($app['dependencies'])) {
$dependencies = $app['dependencies'];
Expand All @@ -67,10 +68,24 @@ public function analyze(array $app) {
$this->analyzeCommands($dependencies),
$this->analyzeLibraries($dependencies),
$this->analyzeOS($dependencies),
$this->analyzeOC($dependencies, $app)
$this->analyzeOC($dependencies, $app, $ignoreMax)
);
}

public function isMarkedCompatible(array $app): bool {
if (isset($app['dependencies'])) {
$dependencies = $app['dependencies'];
} else {
$dependencies = [];
}

$maxVersion = $this->getMaxVersion($dependencies, $app);
if ($maxVersion === null) {
return true;
}
return !$this->compareBigger($this->platform->getOcVersion(), $maxVersion);
}

/**
* Truncates both versions to the lowest common version, e.g.
* 5.1.2.3 and 5.1 will be turned into 5.1 and 5.1,
Expand Down Expand Up @@ -293,7 +308,7 @@ private function analyzeOS(array $dependencies) {
* @param array $appInfo
* @return array
*/
private function analyzeOC(array $dependencies, array $appInfo) {
private function analyzeOC(array $dependencies, array $appInfo, bool $ignoreMax) {
$missing = [];
$minVersion = null;
if (isset($dependencies['nextcloud']['@attributes']['min-version'])) {
Expand All @@ -305,28 +320,35 @@ private function analyzeOC(array $dependencies, array $appInfo) {
} elseif (isset($appInfo['require'])) {
$minVersion = $appInfo['require'];
}
$maxVersion = null;
if (isset($dependencies['nextcloud']['@attributes']['max-version'])) {
$maxVersion = $dependencies['nextcloud']['@attributes']['max-version'];
} elseif (isset($dependencies['owncloud']['@attributes']['max-version'])) {
$maxVersion = $dependencies['owncloud']['@attributes']['max-version'];
} elseif (isset($appInfo['requiremax'])) {
$maxVersion = $appInfo['requiremax'];
}
$maxVersion = $this->getMaxVersion($dependencies, $appInfo);

if (!is_null($minVersion)) {
if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
$missing[] = (string)$this->l->t('Server version %s or higher is required.', [$this->toVisibleVersion($minVersion)]);
}
}
if (!is_null($maxVersion)) {
if (!$ignoreMax && !is_null($maxVersion)) {
if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
$missing[] = (string)$this->l->t('Server version %s or lower is required.', [$this->toVisibleVersion($maxVersion)]);
}
}
return $missing;
}

private function getMaxVersion(array $dependencies, array $appInfo): ?string {
if (isset($dependencies['nextcloud']['@attributes']['max-version'])) {
return $dependencies['nextcloud']['@attributes']['max-version'];
}
if (isset($dependencies['owncloud']['@attributes']['max-version'])) {
return $dependencies['owncloud']['@attributes']['max-version'];
}
if (isset($appInfo['requiremax'])) {
return $appInfo['requiremax'];
}

return null;
}

/**
* Map the internal version number to the Nextcloud version
*
Expand Down
7 changes: 5 additions & 2 deletions lib/private/Installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,11 @@ public function installApp($appId) {
);
}

$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
$ignoreMax = in_array($appId, $ignoreMaxApps);

$version = implode('.', \OCP\Util::getVersion());
if (!\OC_App::isAppCompatible($version, $info)) {
if (!\OC_App::isAppCompatible($version, $info, $ignoreMax)) {
throw new \Exception(
// TODO $l
$l->t('App "%s" cannot be installed because it is not compatible with this version of the server.',
Expand All @@ -123,7 +126,7 @@ public function installApp($appId) {
}

// check for required dependencies
\OC_App::checkAppDependencies($this->config, $l, $info);
\OC_App::checkAppDependencies($this->config, $l, $info, $ignoreMax);
\OC_App::registerAutoloading($appId, $basedir);

//install the database
Expand Down
8 changes: 4 additions & 4 deletions lib/private/legacy/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ private static function adjustVersionParts(string $version1, string $version2):
*
* @return boolean true if compatible, otherwise false
*/
public static function isAppCompatible(string $ocVersion, array $appInfo): bool {
public static function isAppCompatible(string $ocVersion, array $appInfo, bool $ignoreMax = false): bool {
$requireMin = '';
$requireMax = '';
if (isset($appInfo['dependencies']['nextcloud']['@attributes']['min-version'])) {
Expand Down Expand Up @@ -854,7 +854,7 @@ public static function isAppCompatible(string $ocVersion, array $appInfo): bool
return false;
}

if (!empty($requireMax)
if (!$ignoreMax && !empty($requireMax)
&& version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>')
) {
return false;
Expand Down Expand Up @@ -1090,9 +1090,9 @@ public static function parseAppInfo(array $data, $lang = null): array {
* @param array $info
* @throws \Exception
*/
public static function checkAppDependencies(\OCP\IConfig $config, \OCP\IL10N $l, array $info) {
public static function checkAppDependencies(\OCP\IConfig $config, \OCP\IL10N $l, array $info, bool $ignoreMax) {
$dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l);
$missing = $dependencyAnalyzer->analyze($info);
$missing = $dependencyAnalyzer->analyze($info, $ignoreMax);
if (!empty($missing)) {
$missingMsg = implode(PHP_EOL, $missing);
throw new \Exception(
Expand Down
21 changes: 20 additions & 1 deletion settings/Controller/AppSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,17 @@ public function listApps(): JSONResponse {
$appData['licence'] = $appData['license'];
}

$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
$ignoreMax = in_array($appData['id'], $ignoreMaxApps);

// analyse dependencies
$missing = $dependencyAnalyzer->analyze($appData);
$missing = $dependencyAnalyzer->analyze($appData, $ignoreMax);
$appData['canInstall'] = empty($missing);
$appData['missingDependencies'] = $missing;

$appData['missingMinOwnCloudVersion'] = !isset($appData['dependencies']['nextcloud']['@attributes']['min-version']);
$appData['missingMaxOwnCloudVersion'] = !isset($appData['dependencies']['nextcloud']['@attributes']['max-version']);
$appData['isCompatible'] = $dependencyAnalyzer->isMarkedCompatible($appData);

return $appData;
}, $apps);
Expand Down Expand Up @@ -315,6 +319,9 @@ private function getAppsForCategory($requestedCategory = ''): array {
}
}

if (!isset($app['releases'][0]['rawPlatformVersionSpec'])) {
continue;
}
$nextCloudVersion = $versionParser->getVersion($app['releases'][0]['rawPlatformVersionSpec']);
$nextCloudVersionDependencies = [];
if($nextCloudVersion->getMinimumVersion() !== '') {
Expand Down Expand Up @@ -544,4 +551,16 @@ private function sortApps($a, $b) {
return ($a < $b) ? -1 : 1;
}

public function force(string $appId): JSONResponse {
$appId = OC_App::cleanAppId($appId);

$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
if (!in_array($appId, $ignoreMaxApps, true)) {
$ignoreMaxApps[] = $appId;
$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
}

return new JSONResponse();
}

}
2 changes: 1 addition & 1 deletion settings/js/vue-0.js

Large diffs are not rendered by default.

Loading