diff options
author | Morris Jobke <hey@morrisjobke.de> | 2020-10-08 11:41:16 +0200 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2020-12-02 15:20:03 +0100 |
commit | d87705a8941511a4e3bf8f6c97d6e0f36a42799e (patch) | |
tree | 5c6d2ba0aed6a6c9b3bc0563ca800de65680bfea /lib | |
parent | e25a62c69dc83ba5655577181f4ea41a47c742b5 (diff) | |
download | nextcloud-server-d87705a8941511a4e3bf8f6c97d6e0f36a42799e.tar.gz nextcloud-server-d87705a8941511a4e3bf8f6c97d6e0f36a42799e.zip |
Allow subscription to indicate that a userlimit is reached
Signed-off-by: Morris Jobke <hey@morrisjobke.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Support/Subscription/Registry.php | 85 | ||||
-rw-r--r-- | lib/private/User/Manager.php | 8 | ||||
-rw-r--r-- | lib/public/Support/Subscription/IRegistry.php | 7 | ||||
-rw-r--r-- | lib/public/Support/Subscription/ISubscription.php | 7 |
4 files changed, 104 insertions, 3 deletions
diff --git a/lib/private/Support/Subscription/Registry.php b/lib/private/Support/Subscription/Registry.php index 3d6a9b09d84..ba9c4099b9b 100644 --- a/lib/private/Support/Subscription/Registry.php +++ b/lib/private/Support/Subscription/Registry.php @@ -28,13 +28,16 @@ declare(strict_types=1); namespace OC\Support\Subscription; +use OC\User\Backend; use OCP\AppFramework\QueryException; use OCP\IConfig; use OCP\IServerContainer; +use OCP\IUserManager; use OCP\Support\Subscription\Exception\AlreadyRegisteredException; use OCP\Support\Subscription\IRegistry; use OCP\Support\Subscription\ISubscription; use OCP\Support\Subscription\ISupportedApps; +use Psr\Log\LoggerInterface; class Registry implements IRegistry { @@ -49,10 +52,19 @@ class Registry implements IRegistry { /** @var IServerContainer */ private $container; - - public function __construct(IConfig $config, IServerContainer $container) { + /** @var IUserManager */ + private $userManager; + /** @var LoggerInterface */ + private $logger; + + public function __construct(IConfig $config, + IServerContainer $container, + IUserManager $userManager, + LoggerInterface $logger) { $this->config = $config; $this->container = $container; + $this->userManager = $userManager; + $this->logger = $logger; } private function getSubscription(): ?ISubscription { @@ -127,9 +139,76 @@ class Registry implements IRegistry { * @since 17.0.0 */ public function delegateHasExtendedSupport(): bool { - if ($this->getSubscription() instanceof ISubscription && method_exists($this->subscription, 'hasExtendedSupport')) { + if ($this->getSubscription() instanceof ISubscription) { return $this->getSubscription()->hasExtendedSupport(); } return false; } + + + /** + * Indicates if a hard user limit is reached and no new users should be created + * + * @since 21.0.0 + */ + public function delegateIsHardUserLimitReached(): bool { + $subscription = $this->getSubscription(); + if ($subscription instanceof ISubscription && + $subscription->hasValidSubscription()) { + $userLimitReached = $subscription->isHardUserLimitReached(); + if ($userLimitReached) { + $this->notifyAboutReachedUserLimit(); + } + return $userLimitReached; + } + + $isOneClickInstance = $this->config->getSystemValueBool('one-click-instance', false); + + if (!$isOneClickInstance) { + return false; + } + + $userCount = $this->getUserCount(); + $hardUserLimit = $this->config->getSystemValue('one-click-instance.user-limit', 50); + + $userLimitReached = $userCount >= $hardUserLimit; + if ($userLimitReached) { + $this->notifyAboutReachedUserLimit(); + } + return $userLimitReached; + } + + private function getUserCount(): int { + $userCount = 0; + $backends = $this->userManager->getBackends(); + foreach ($backends as $backend) { + if ($backend->implementsActions(Backend::COUNT_USERS)) { + $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' => 'lib']); + } + } + } + + $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' => 'lib']); + } + + return $userCount; + } + + private function notifyAboutReachedUserLimit() { + // TODO notify admin about reached user limit + $this->logger->warning('The user limit was reached and the new user was not created', ['app' => 'lib']); + } } diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 1201a456ce2..1d58c68268c 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -34,6 +34,7 @@ namespace OC\User; +use OC\HintException; use OC\Hooks\PublicEmitter; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\EventDispatcher\IEventDispatcher; @@ -42,6 +43,7 @@ use OCP\IGroup; use OCP\IUser; use OCP\IUserBackend; use OCP\IUserManager; +use OCP\Support\Subscription\IRegistry; use OCP\User\Backend\IGetRealUIDBackend; use OCP\User\Events\BeforeUserCreatedEvent; use OCP\User\Events\UserCreatedEvent; @@ -297,6 +299,12 @@ class Manager extends PublicEmitter implements IUserManager { * @return bool|IUser the created user or false */ public function createUser($uid, $password) { + // DI injection is not used here as IRegistry needs the user manager itself for user count and thus it would create a cyclic dependency + if (\OC::$server->get(IRegistry::class)->delegateIsHardUserLimitReached()) { + $l = \OC::$server->getL10N('lib'); + throw new HintException($l->t('The user limit has been reached and the user was not created.')); + } + $localBackends = []; foreach ($this->backends as $backend) { if ($backend instanceof Database) { diff --git a/lib/public/Support/Subscription/IRegistry.php b/lib/public/Support/Subscription/IRegistry.php index f3d6cf2f92c..ab1d00fa823 100644 --- a/lib/public/Support/Subscription/IRegistry.php +++ b/lib/public/Support/Subscription/IRegistry.php @@ -78,4 +78,11 @@ interface IRegistry { * @since 17.0.0 */ public function delegateHasExtendedSupport(): bool; + + /** + * Indicates if a hard user limit is reached and no new users should be created + * + * @since 21.0.0 + */ + public function delegateIsHardUserLimitReached(): bool; } diff --git a/lib/public/Support/Subscription/ISubscription.php b/lib/public/Support/Subscription/ISubscription.php index 83b7509b9fe..9614c0ed77b 100644 --- a/lib/public/Support/Subscription/ISubscription.php +++ b/lib/public/Support/Subscription/ISubscription.php @@ -45,4 +45,11 @@ interface ISubscription { * @since 17.0.0 */ public function hasExtendedSupport(): bool; + + /** + * Indicates if a hard user limit is reached and no new users should be created + * + * @since 21.0.0 + */ + public function isHardUserLimitReached(): bool; } |