From f317e5f11f242e23b7089d8a9bf49e4684f85fc3 Mon Sep 17 00:00:00 2001 From: szaimen Date: Fri, 11 Mar 2022 12:23:15 +0100 Subject: [PATCH] disable web updater by default on instances with more than 100 users Signed-off-by: szaimen --- .../lib/Controller/AdminController.php | 50 ++++++++++++++++++- .../tests/Controller/AdminControllerTest.php | 12 ++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/apps/updatenotification/lib/Controller/AdminController.php b/apps/updatenotification/lib/Controller/AdminController.php index b13ba66efd573..e10011d646867 100644 --- a/apps/updatenotification/lib/Controller/AdminController.php +++ b/apps/updatenotification/lib/Controller/AdminController.php @@ -27,6 +27,8 @@ */ namespace OCA\UpdateNotification\Controller; +use OC\User\Backend; +use OCP\User\Backend\ICountUsersBackend; use OCA\UpdateNotification\ResetTokenBackgroundJob; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; @@ -38,6 +40,8 @@ use OCP\IRequest; use OCP\Security\ISecureRandom; use OCP\Util; +use OCP\IUserManager; +use Psr\Log\LoggerInterface; class AdminController extends Controller { /** @var IJobList */ @@ -50,6 +54,10 @@ class AdminController extends Controller { private $timeFactory; /** @var IL10N */ private $l10n; + /** @var IUserManager */ + private $userManager; + /** @var LoggerInterface */ + private $logger; /** * @param string $appName @@ -66,17 +74,24 @@ public function __construct($appName, ISecureRandom $secureRandom, IConfig $config, ITimeFactory $timeFactory, - IL10N $l10n) { + IL10N $l10n, + IUserManager $userManager, + LoggerInterface $logger) { parent::__construct($appName, $request); $this->jobList = $jobList; $this->secureRandom = $secureRandom; $this->config = $config; $this->timeFactory = $timeFactory; $this->l10n = $l10n; + $this->userManager = $userManager; + $this->logger = $logger; } private function isUpdaterEnabled() { - return !$this->config->getSystemValue('upgrade.disable-web', false); + if ($this->config->getSystemValue('upgrade.disable-web', false) || $this->getUserCount() > 100) { + return false; + } + return true; } /** @@ -107,4 +122,35 @@ public function createCredentials(): DataResponse { return new DataResponse($newToken); } + + // Copied from https://github.com/nextcloud/server/blob/a06001e0851abc6073af678b742da3e1aa96eec9/lib/private/Support/Subscription/Registry.php#L187-L214 + private function getUserCount(): int { + $userCount = 0; + $backends = $this->userManager->getBackends(); + foreach ($backends as $backend) { + if ($backend->implementsActions(Backend::COUNT_USERS)) { + /** @var ICountUsersBackend $backend */ + $backendUsers = $backend->countUsers(); + if ($backendUsers !== false) { + $userCount += $backendUsers; + } else { + // TODO what if the user count can't be determined? + $this->logger->warning('Can not determine user count for ' . get_class($backend), ['app' => 'updatenotification']); + } + } + } + + $disabledUsers = $this->config->getUsersForUserValue('core', 'enabled', 'false'); + $disabledUsersCount = count($disabledUsers); + $userCount = $userCount - $disabledUsersCount; + + if ($userCount < 0) { + $userCount = 0; + + // this should never happen + $this->logger->warning("Total user count was negative (users: $userCount, disabled: $disabledUsersCount)", ['app' => 'updatenotification']); + } + + return $userCount; + } } diff --git a/apps/updatenotification/tests/Controller/AdminControllerTest.php b/apps/updatenotification/tests/Controller/AdminControllerTest.php index 836dc25f4aa78..7aa0f8d38a613 100644 --- a/apps/updatenotification/tests/Controller/AdminControllerTest.php +++ b/apps/updatenotification/tests/Controller/AdminControllerTest.php @@ -37,6 +37,8 @@ use OCP\IRequest; use OCP\Security\ISecureRandom; use Test\TestCase; +use OCP\IUserManager; +use Psr\Log\LoggerInterface; class AdminControllerTest extends TestCase { /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ @@ -53,6 +55,10 @@ class AdminControllerTest extends TestCase { private $timeFactory; /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ private $l10n; + /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ + private $userManager; + /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ + private $logger; protected function setUp(): void { parent::setUp(); @@ -63,6 +69,8 @@ protected function setUp(): void { $this->config = $this->createMock(IConfig::class); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->l10n = $this->createMock(IL10N::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->adminController = new AdminController( 'updatenotification', @@ -71,7 +79,9 @@ protected function setUp(): void { $this->secureRandom, $this->config, $this->timeFactory, - $this->l10n + $this->l10n, + $this->userManager, + $this->logger ); }