Browse Source

Allow to whitelist apps from the apsptore

Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
tags/v23.0.0beta1
John Molakvoæ 2 years ago
parent
commit
1a6bac5874
No account linked to committer's email address

+ 6
- 0
config/config.sample.php View File

@@ -972,6 +972,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

+ 24
- 2
lib/private/App/AppStore/Fetcher/AppFetcher.php View File

@@ -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;
}
}

+ 78
- 1
tests/lib/App/AppStore/Fetcher/AppFetcherTest.php View File

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

Loading…
Cancel
Save