2828
2929namespace OC \Support \Subscription ;
3030
31+ use OC \User \Backend ;
3132use OCP \AppFramework \QueryException ;
3233use OCP \IConfig ;
34+ use OCP \IGroupManager ;
3335use OCP \IServerContainer ;
36+ use OCP \IUserManager ;
37+ use OCP \Notification \IManager ;
3438use OCP \Support \Subscription \Exception \AlreadyRegisteredException ;
3539use OCP \Support \Subscription \IRegistry ;
3640use OCP \Support \Subscription \ISubscription ;
3741use OCP \Support \Subscription \ISupportedApps ;
42+ use Psr \Log \LoggerInterface ;
3843
3944class Registry implements IRegistry {
4045
@@ -49,10 +54,27 @@ class Registry implements IRegistry {
4954
5055 /** @var IServerContainer */
5156 private $ container ;
52-
53- public function __construct (IConfig $ config , IServerContainer $ container ) {
57+ /** @var IUserManager */
58+ private $ userManager ;
59+ /** @var IGroupManager */
60+ private $ groupManager ;
61+ /** @var LoggerInterface */
62+ private $ logger ;
63+ /** @var IManager */
64+ private $ notificationManager ;
65+
66+ public function __construct (IConfig $ config ,
67+ IServerContainer $ container ,
68+ IUserManager $ userManager ,
69+ IGroupManager $ groupManager ,
70+ LoggerInterface $ logger ,
71+ IManager $ notificationManager ) {
5472 $ this ->config = $ config ;
5573 $ this ->container = $ container ;
74+ $ this ->userManager = $ userManager ;
75+ $ this ->groupManager = $ groupManager ;
76+ $ this ->logger = $ logger ;
77+ $ this ->notificationManager = $ notificationManager ;
5678 }
5779
5880 private function getSubscription (): ?ISubscription {
@@ -127,9 +149,87 @@ public function delegateHasValidSubscription(): bool {
127149 * @since 17.0.0
128150 */
129151 public function delegateHasExtendedSupport (): bool {
130- if ($ this ->getSubscription () instanceof ISubscription && method_exists ( $ this -> subscription , ' hasExtendedSupport ' ) ) {
152+ if ($ this ->getSubscription () instanceof ISubscription) {
131153 return $ this ->getSubscription ()->hasExtendedSupport ();
132154 }
133155 return false ;
134156 }
157+
158+
159+ /**
160+ * Indicates if a hard user limit is reached and no new users should be created
161+ *
162+ * @since 21.0.0
163+ */
164+ public function delegateIsHardUserLimitReached (): bool {
165+ $ subscription = $ this ->getSubscription ();
166+ if ($ subscription instanceof ISubscription &&
167+ $ subscription ->hasValidSubscription ()) {
168+ $ userLimitReached = $ subscription ->isHardUserLimitReached ();
169+ if ($ userLimitReached ) {
170+ $ this ->notifyAboutReachedUserLimit ();
171+ }
172+ return $ userLimitReached ;
173+ }
174+
175+ $ isOneClickInstance = $ this ->config ->getSystemValueBool ('one-click-instance ' , false );
176+
177+ if (!$ isOneClickInstance ) {
178+ return false ;
179+ }
180+
181+ $ userCount = $ this ->getUserCount ();
182+ $ hardUserLimit = $ this ->config ->getSystemValue ('one-click-instance.user-limit ' , 50 );
183+
184+ $ userLimitReached = $ userCount >= $ hardUserLimit ;
185+ if ($ userLimitReached ) {
186+ $ this ->notifyAboutReachedUserLimit ();
187+ }
188+ return $ userLimitReached ;
189+ }
190+
191+ private function getUserCount (): int {
192+ $ userCount = 0 ;
193+ $ backends = $ this ->userManager ->getBackends ();
194+ foreach ($ backends as $ backend ) {
195+ if ($ backend ->implementsActions (Backend::COUNT_USERS )) {
196+ $ backendUsers = $ backend ->countUsers ();
197+ if ($ backendUsers !== false ) {
198+ $ userCount += $ backendUsers ;
199+ } else {
200+ // TODO what if the user count can't be determined?
201+ $ this ->logger ->warning ('Can not determine user count for ' . get_class ($ backend ), ['app ' => 'lib ' ]);
202+ }
203+ }
204+ }
205+
206+ $ disabledUsers = $ this ->config ->getUsersForUserValue ('core ' , 'enabled ' , 'false ' );
207+ $ disabledUsersCount = count ($ disabledUsers );
208+ $ userCount = $ userCount - $ disabledUsersCount ;
209+
210+ if ($ userCount < 0 ) {
211+ $ userCount = 0 ;
212+
213+ // this should never happen
214+ $ this ->logger ->warning ("Total user count was negative (users: $ userCount, disabled: $ disabledUsersCount) " , ['app ' => 'lib ' ]);
215+ }
216+
217+ return $ userCount ;
218+ }
219+
220+ private function notifyAboutReachedUserLimit () {
221+ $ admins = $ this ->groupManager ->get ('admin ' )->getUsers ();
222+ foreach ($ admins as $ admin ) {
223+ $ notification = $ this ->notificationManager ->createNotification ();
224+
225+ $ notification ->setApp ('core ' )
226+ ->setUser ($ admin ->getUID ())
227+ ->setDateTime (new \DateTime ())
228+ ->setObject ('user_limit_reached ' , '1 ' )
229+ ->setSubject ('user_limit_reached ' );
230+ $ this ->notificationManager ->notify ($ notification );
231+ }
232+
233+ $ this ->logger ->warning ('The user limit was reached and the new user was not created ' , ['app ' => 'lib ' ]);
234+ }
135235}
0 commit comments