limiter = $limiter; $this->userManager = $userManager; $this->calDavBackend = $calDavBackend; $this->config = $config; $this->logger = $logger; $this->userId = $userId; } public function initialize(DAV\Server $server): void { $server->on('beforeBind', [$this, 'beforeBind'], 1); } public function beforeBind(string $path): void { if ($this->userId === null) { // We only care about authenticated users here return; } $user = $this->userManager->get($this->userId); if ($user === null) { // We only care about authenticated users here return; } $pathParts = explode('/', $path); if (count($pathParts) === 3 && $pathParts[0] === 'calendars') { // Path looks like calendars/username/calendarname so a new calendar or subscription is created try { $this->limiter->registerUserRequest( 'caldav-create-calendar', $this->config->getValueInt('dav', 'rateLimitCalendarCreation', 10), $this->config->getValueInt('dav', 'rateLimitPeriodCalendarCreation', 3600), $user ); } catch (RateLimitExceededException $e) { throw new TooManyRequests('Too many calendars created', 0, $e); } $calendarLimit = $this->config->getValueInt('dav', 'maximumCalendarsSubscriptions', 30); if ($calendarLimit === -1) { return; } $numCalendars = $this->calDavBackend->getCalendarsForUserCount('principals/users/' . $user->getUID()); $numSubscriptions = $this->calDavBackend->getSubscriptionsForUserCount('principals/users/' . $user->getUID()); if (($numCalendars + $numSubscriptions) >= $calendarLimit) { $this->logger->warning('Maximum number of calendars/subscriptions reached', [ 'calendars' => $numCalendars, 'subscription' => $numSubscriptions, 'limit' => $calendarLimit, ]); throw new Forbidden('Calendar limit reached', 0); } } } }