Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/config.sample.php6
-rw-r--r--lib/private/App/AppStore/Fetcher/AppFetcher.php26
-rw-r--r--tests/lib/App/AppStore/Fetcher/AppFetcherTest.php79
3 files changed, 108 insertions, 3 deletions
diff --git a/config/config.sample.php b/config/config.sample.php
index 845db00ac12..be79b22063d 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -973,6 +973,12 @@ $CONFIG = [
'appstoreurl' => 'https://apps.nextcloud.com/api/v1',
/**
+ * Filters allowed installable apps from the appstore.
+ * Empty array will prevent all apps from the store to be found.
+ */
+'appsallowlist' => [],
+
+/**
* Use the ``apps_paths`` parameter to set the location of the Apps directory,
* which should be scanned for available apps, and where user-specific apps
* should be installed from the Apps store. The ``path`` defines the absolute
diff --git a/lib/private/App/AppStore/Fetcher/AppFetcher.php b/lib/private/App/AppStore/Fetcher/AppFetcher.php
index 1605e5bd230..2216999e12f 100644
--- a/lib/private/App/AppStore/Fetcher/AppFetcher.php
+++ b/lib/private/App/AppStore/Fetcher/AppFetcher.php
@@ -35,6 +35,7 @@ use OC\Files\AppData\Factory;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
+use OCP\Support\Subscription\IRegistry;
use Psr\Log\LoggerInterface;
class AppFetcher extends Fetcher {
@@ -42,6 +43,9 @@ class AppFetcher extends Fetcher {
/** @var CompareVersion */
private $compareVersion;
+ /** @var IRegistry */
+ private $registry;
+
/** @var bool */
private $ignoreMaxVersion;
@@ -50,7 +54,8 @@ class AppFetcher extends Fetcher {
ITimeFactory $timeFactory,
IConfig $config,
CompareVersion $compareVersion,
- LoggerInterface $logger) {
+ LoggerInterface $logger,
+ IRegistry $registry) {
parent::__construct(
$appDataFactory,
$clientService,
@@ -59,9 +64,11 @@ class AppFetcher extends Fetcher {
$logger
);
+ $this->compareVersion = $compareVersion;
+ $this->registry = $registry;
+
$this->fileName = 'apps.json';
$this->endpointName = 'apps.json';
- $this->compareVersion = $compareVersion;
$this->ignoreMaxVersion = true;
}
@@ -172,4 +179,19 @@ class AppFetcher extends Fetcher {
$this->fileName = $fileName;
$this->ignoreMaxVersion = $ignoreMaxVersion;
}
+
+
+ public function get($allowUnstable = false) {
+ $apps = parent::get($allowUnstable);
+ $whitelist = $this->config->getSystemValue('appsallowlist');
+
+ // If the admin specified a whitelist, filter apps from the appstore
+ if (is_array($whitelist) && $this->registry->delegateHasValidSubscription()) {
+ return array_filter($apps, function ($app) use ($whitelist) {
+ return in_array($app['id'], $whitelist);
+ });
+ }
+
+ return $apps;
+ }
}
diff --git a/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php b/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php
index 840d47ed802..44869d353a4 100644
--- a/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php
+++ b/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php
@@ -34,6 +34,7 @@ use OCP\Http\Client\IClient;
use OCP\Http\Client\IClientService;
use OCP\Http\Client\IResponse;
use OCP\IConfig;
+use OCP\Support\Subscription\IRegistry;
use Psr\Log\LoggerInterface;
use Test\TestCase;
@@ -50,6 +51,8 @@ class AppFetcherTest extends TestCase {
protected $compareVersion;
/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
protected $logger;
+ /** @var IRegistry */
+ protected $registry;
/** @var AppFetcher */
protected $fetcher;
/** @var string */
@@ -1849,6 +1852,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg==
$this->config = $this->createMock(IConfig::class);
$this->compareVersion = new CompareVersion();
$this->logger = $this->createMock(LoggerInterface::class);
+ $this->registry = $this->createMock(IRegistry::class);
$this->fetcher = new AppFetcher(
$factory,
@@ -1856,7 +1860,8 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg==
$this->timeFactory,
$this->config,
$this->compareVersion,
- $this->logger
+ $this->logger,
+ $this->registry
);
}
@@ -2061,4 +2066,76 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg==
$this->fetcher->setVersion('11.0.0.2', 'future-apps.json', false);
$this->assertEquals(self::$expectedResponse['data'], $this->fetcher->get());
}
+
+ public function testGetWhitelist() {
+ $this->config->method('getSystemValue')
+ ->willReturnCallback(function ($key, $default) {
+ if ($key === 'appstoreenabled') {
+ return true;
+ } elseif ($key === 'version') {
+ return '11.0.0.2';
+ } elseif ($key === 'appstoreurl' && $default === 'https://apps.nextcloud.com/api/v1') {
+ return 'https://custom.appsstore.endpoint/api/v1';
+ } elseif ($key === 'appsallowlist') {
+ return ['contacts'];
+ } else {
+ return $default;
+ }
+ });
+
+ $file = $this->createMock(ISimpleFile::class);
+ $folder = $this->createMock(ISimpleFolder::class);
+ $folder
+ ->expects($this->at(0))
+ ->method('getFile')
+ ->with('apps.json')
+ ->willThrowException(new NotFoundException());
+ $folder
+ ->expects($this->at(1))
+ ->method('newFile')
+ ->with('apps.json')
+ ->willReturn($file);
+ $this->appData
+ ->expects($this->once())
+ ->method('getFolder')
+ ->with('/')
+ ->willReturn($folder);
+ $client = $this->createMock(IClient::class);
+ $this->clientService
+ ->expects($this->once())
+ ->method('newClient')
+ ->willReturn($client);
+ $response = $this->createMock(IResponse::class);
+ $client
+ ->method('get')
+ ->with('https://custom.appsstore.endpoint/api/v1/apps.json')
+ ->willReturn($response);
+ $response
+ ->expects($this->once())
+ ->method('getBody')
+ ->willReturn(self::$responseJson);
+ $response->method('getHeader')
+ ->with($this->equalTo('ETag'))
+ ->willReturn('"myETag"');
+ $this->timeFactory
+ ->expects($this->once())
+ ->method('getTime')
+ ->willReturn(1234);
+
+ $this->registry
+ ->expects($this->once())
+ ->method('delegateHasValidSubscription')
+ ->willReturn(true);
+
+ $file
+ ->expects($this->once())
+ ->method('putContent');
+ $file
+ ->method('getContent')
+ ->willReturn(json_encode(self::$expectedResponse));
+
+ $apps = array_values($this->fetcher->get());
+ $this->assertEquals(count($apps), 1);
+ $this->assertEquals($apps[0]['id'], 'contacts');
+ }
}