Skip to content

Commit

Permalink
Merge pull request #47927 from nextcloud/fix/migrate-away-from-oc_app
Browse files Browse the repository at this point in the history
Migrate away from OC_App to IAppManager
  • Loading branch information
come-nc authored Sep 13, 2024
2 parents 032f17c + 7a16d01 commit bcb4e78
Show file tree
Hide file tree
Showing 26 changed files with 186 additions and 156 deletions.
7 changes: 4 additions & 3 deletions apps/provisioning_api/lib/Controller/AppConfigController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use OC\AppConfig;
use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException;
use OCP\App\IAppManager;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
Expand All @@ -35,6 +36,7 @@ public function __construct(
private IL10N $l10n,
private IGroupManager $groupManager,
private IManager $settingManager,
private IAppManager $appManager,
) {
parent::__construct($appName, $request);
}
Expand Down Expand Up @@ -171,11 +173,10 @@ public function deleteKey(string $app, string $key): DataResponse {
}

/**
* @param string $app
* @throws \InvalidArgumentException
*/
protected function verifyAppId(string $app) {
if (\OC_App::cleanAppId($app) !== $app) {
protected function verifyAppId(string $app): void {
if ($this->appManager->cleanAppId($app) !== $app) {
throw new \InvalidArgumentException('Invalid app id given');
}
}
Expand Down
27 changes: 14 additions & 13 deletions apps/provisioning_api/tests/Controller/AppConfigControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

use OC\AppConfig;
use OCA\Provisioning_API\Controller\AppConfigController;
use OCP\App\IAppManager;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\Exceptions\AppConfigUnknownKeyException;
Expand All @@ -17,6 +18,7 @@
use OCP\IUser;
use OCP\IUserSession;
use OCP\Settings\IManager;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
use function json_decode;
use function json_encode;
Expand All @@ -28,25 +30,22 @@
*/
class AppConfigControllerTest extends TestCase {

/** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
private $appConfig;
/** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
private $userSession;
/** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
private $l10n;
/** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
private $settingManager;
/** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
private $groupManager;
private IAppConfig&MockObject $appConfig;
private IUserSession&MockObject $userSession;
private IL10N&MockObject $l10n;
private IManager&MockObject $settingManager;
private IGroupManager&MockObject $groupManager;
private IAppManager $appManager;

protected function setUp(): void {
parent::setUp();

$this->appConfig = $this->createMock(AppConfig::class);
$this->userSession = $this->createMock(IUserSession::class);
$this->l10n = $this->createMock(IL10N::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->settingManager = $this->createMock(IManager::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->appManager = \OCP\Server::get(IAppManager::class);
}

/**
Expand All @@ -64,7 +63,8 @@ protected function getInstance(array $methods = []) {
$this->userSession,
$this->l10n,
$this->groupManager,
$this->settingManager
$this->settingManager,
$this->appManager,
);
} else {
return $this->getMockBuilder(AppConfigController::class)
Expand All @@ -75,7 +75,8 @@ protected function getInstance(array $methods = []) {
$this->userSession,
$this->l10n,
$this->groupManager,
$this->settingManager
$this->settingManager,
$this->appManager,
])
->setMethods($methods)
->getMock();
Expand Down
11 changes: 5 additions & 6 deletions apps/settings/lib/Controller/AppSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use OC\App\DependencyAnalyzer;
use OC\App\Platform;
use OC\Installer;
use OC_App;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AppFramework\Controller;
Expand Down Expand Up @@ -479,7 +478,7 @@ public function enableApps(array $appIds, array $groups = []): JSONResponse {
$updateRequired = false;

foreach ($appIds as $appId) {
$appId = OC_App::cleanAppId($appId);
$appId = $this->appManager->cleanAppId($appId);

// Check if app is already downloaded
/** @var Installer $installer */
Expand Down Expand Up @@ -537,7 +536,7 @@ public function disableApp(string $appId): JSONResponse {
public function disableApps(array $appIds): JSONResponse {
try {
foreach ($appIds as $appId) {
$appId = OC_App::cleanAppId($appId);
$appId = $this->appManager->cleanAppId($appId);
$this->appManager->disableApp($appId);
}
return new JSONResponse([]);
Expand All @@ -553,7 +552,7 @@ public function disableApps(array $appIds): JSONResponse {
*/
#[PasswordConfirmationRequired]
public function uninstallApp(string $appId): JSONResponse {
$appId = OC_App::cleanAppId($appId);
$appId = $this->appManager->cleanAppId($appId);
$result = $this->installer->removeApp($appId);
if ($result !== false) {
$this->appManager->clearAppsCache();
Expand All @@ -567,7 +566,7 @@ public function uninstallApp(string $appId): JSONResponse {
* @return JSONResponse
*/
public function updateApp(string $appId): JSONResponse {
$appId = OC_App::cleanAppId($appId);
$appId = $this->appManager->cleanAppId($appId);

$this->config->setSystemValue('maintenance', true);
try {
Expand All @@ -594,7 +593,7 @@ private function sortApps($a, $b) {
}

public function force(string $appId): JSONResponse {
$appId = OC_App::cleanAppId($appId);
$appId = $this->appManager->cleanAppId($appId);
$this->appManager->ignoreNextcloudRequirementForApp($appId);
return new JSONResponse();
}
Expand Down
31 changes: 8 additions & 23 deletions apps/theming/tests/UtilTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,17 @@

class UtilTest extends TestCase {

/** @var Util */
protected $util;
/** @var IConfig|MockObject */
protected $config;
/** @var IAppData|MockObject */
protected $appData;
/** @var IAppManager|MockObject */
protected $appManager;
/** @var ImageManager|MockObject */
protected $imageManager;
protected Util $util;
protected IConfig&MockObject $config;
protected IAppData&MockObject $appData;
protected IAppManager $appManager;
protected ImageManager&MockObject $imageManager;

protected function setUp(): void {
parent::setUp();
$this->config = $this->createMock(IConfig::class);
$this->appData = $this->createMock(IAppData::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->appManager = \OCP\Server::get(IAppManager::class);
$this->imageManager = $this->createMock(ImageManager::class);
$this->util = new Util($this->config, $this->appManager, $this->appData, $this->imageManager);
}
Expand Down Expand Up @@ -152,19 +147,15 @@ public function testGetAppIcon($app, $expected) {
->method('getFolder')
->with('global/images')
->willThrowException(new NotFoundException());
$this->appManager->expects($this->once())
->method('getAppPath')
->with($app)
->willReturn(\OC_App::getAppPath($app));
$icon = $this->util->getAppIcon($app);
$this->assertEquals($expected, $icon);
}

public function dataGetAppIcon() {
return [
['user_ldap', \OC_App::getAppPath('user_ldap') . '/img/app.svg'],
['user_ldap', \OCP\Server::get(IAppManager::class)->getAppPath('user_ldap') . '/img/app.svg'],
['noapplikethis', \OC::$SERVERROOT . '/core/img/logo/logo.svg'],
['comments', \OC_App::getAppPath('comments') . '/img/comments.svg'],
['comments', \OCP\Server::get(IAppManager::class)->getAppPath('comments') . '/img/comments.svg'],
];
}

Expand All @@ -187,12 +178,6 @@ public function testGetAppIconThemed() {
* @dataProvider dataGetAppImage
*/
public function testGetAppImage($app, $image, $expected) {
if ($app !== 'core') {
$this->appManager->expects($this->once())
->method('getAppPath')
->with($app)
->willReturn(\OC_App::getAppPath($app));
}
$this->assertEquals($expected, $this->util->getAppImage($app, $image));
}

Expand Down
2 changes: 1 addition & 1 deletion core/Command/App/Enable.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public function completeOptionValues($optionName, CompletionContext $context): a
*/
public function completeArgumentValues($argumentName, CompletionContext $context): array {
if ($argumentName === 'app-id') {
$allApps = \OC_App::getAllApps();
$allApps = $this->appManager->getAllAppsInAppsFolders();
return array_diff($allApps, \OC_App::getEnabledApps(true, true));
}
return [];
Expand Down
2 changes: 1 addition & 1 deletion core/Command/App/GetPath.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
*/
public function completeArgumentValues($argumentName, CompletionContext $context): array {
if ($argumentName === 'app') {
return \OC_App::getAllApps();
return $this->appManager->getAllAppsInAppsFolders();
}
return [];
}
Expand Down
2 changes: 1 addition & 1 deletion core/Command/App/Update.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return 1;
}
} elseif ($input->getOption('all') || $input->getOption('showonly')) {
$apps = \OC_App::getAllApps();
$apps = $this->manager->getAllAppsInAppsFolders();
} else {
$output->writeln('<error>Please specify an app to update or "--all" to update all updatable apps"</error>');
return 1;
Expand Down
13 changes: 5 additions & 8 deletions core/Command/Db/Migrations/GenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,10 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array
}
';

protected Connection $connection;
protected IAppManager $appManager;

public function __construct(Connection $connection, IAppManager $appManager) {
$this->connection = $connection;
$this->appManager = $appManager;

public function __construct(
protected Connection $connection,
protected IAppManager $appManager,
) {
parent::__construct();
}

Expand Down Expand Up @@ -155,7 +152,7 @@ public function completeOptionValues($optionName, CompletionContext $context) {
*/
public function completeArgumentValues($argumentName, CompletionContext $context) {
if ($argumentName === 'app') {
$allApps = \OC_App::getAllApps();
$allApps = $this->appManager->getAllAppsInAppsFolders();
return array_diff($allApps, \OC_App::getEnabledApps(true, true));
}

Expand Down
2 changes: 1 addition & 1 deletion core/Command/Db/Migrations/GenerateMetadataCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private function extractMigrationMetadataFromCore(): array {
* @throws \Exception
*/
private function extractMigrationMetadataFromApps(): array {
$allApps = \OC_App::getAllApps();
$allApps = $this->appManager->getAllAppsInAppsFolders();
$metadata = [];
foreach ($allApps as $appId) {
// We need to load app before being able to extract Migrations
Expand Down
9 changes: 7 additions & 2 deletions core/Command/L10n/CreateJs.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use DirectoryIterator;

use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
Expand Down Expand Up @@ -147,10 +148,14 @@ public function completeOptionValues($optionName, CompletionContext $context) {
*/
public function completeArgumentValues($argumentName, CompletionContext $context) {
if ($argumentName === 'app') {
return \OC_App::getAllApps();
return $this->appManager->getAllAppsInAppsFolders();
} elseif ($argumentName === 'lang') {
$appName = $context->getWordAtIndex($context->getWordIndex() - 1);
return $this->getAllLanguages(\OC_App::getAppPath($appName));
try {
return $this->getAllLanguages($this->appManager->getAppPath($appName));
} catch(AppPathNotFoundException) {
return [];
}
}
return [];
}
Expand Down
40 changes: 37 additions & 3 deletions lib/private/App/AppManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,37 @@ public function getInstalledApps() {
return array_keys($this->getInstalledAppsValues());
}

/**
* Get a list of all apps in the apps folder
*
* @return list<string> an array of app names (string IDs)
*/
public function getAllAppsInAppsFolders(): array {
$apps = [];

foreach (\OC::$APPSROOTS as $apps_dir) {
if (!is_readable($apps_dir['path'])) {
$this->logger->warning('unable to read app folder : ' . $apps_dir['path'], ['app' => 'core']);
continue;
}
$dh = opendir($apps_dir['path']);

if (is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
if (
$file[0] != '.' &&
is_dir($apps_dir['path'] . '/' . $file) &&
is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')
) {
$apps[] = $file;
}
}
}
}

return array_values(array_unique($apps));
}

/**
* List all apps enabled for a user
*
Expand Down Expand Up @@ -647,11 +678,9 @@ public function disableApp($appId, $automaticDisabled = false) {
/**
* Get the directory for the given app.
*
* @param string $appId
* @return string
* @throws AppPathNotFoundException if app folder can't be found
*/
public function getAppPath($appId) {
public function getAppPath(string $appId): string {
$appPath = \OC_App::getAppPath($appId);
if ($appPath === false) {
throw new AppPathNotFoundException('Could not find path for ' . $appId);
Expand Down Expand Up @@ -877,4 +906,9 @@ public function isBackendRequired(string $backend): bool {

return false;
}

public function cleanAppId(string $app): string {
// FIXME should list allowed characters instead
return str_replace(['<', '>', '"', "'", '\0', '/', '\\', '..'], '', $app);
}
}
Loading

0 comments on commit bcb4e78

Please sign in to comment.