diff --git a/composer.lock b/composer.lock index 4fa73ed96..69ead9e02 100644 --- a/composer.lock +++ b/composer.lock @@ -163,12 +163,12 @@ "source": { "type": "git", "url": "https://github.com/ChristophWurst/nextcloud_composer.git", - "reference": "b8a6f713939cf124a3798de106c1798486d5d781" + "reference": "6abf5b57c32e6cb6093487723a37315451fa74bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ChristophWurst/nextcloud_composer/zipball/b8a6f713939cf124a3798de106c1798486d5d781", - "reference": "b8a6f713939cf124a3798de106c1798486d5d781", + "url": "https://api.github.com/repos/ChristophWurst/nextcloud_composer/zipball/6abf5b57c32e6cb6093487723a37315451fa74bd", + "reference": "6abf5b57c32e6cb6093487723a37315451fa74bd", "shasum": "" }, "require": { @@ -177,10 +177,11 @@ "psr/event-dispatcher": "^1.0", "psr/log": "^1.1" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-master": "22.0.0-dev" + "dev-master": "23.0.0-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -194,7 +195,11 @@ } ], "description": "Composer package containing Nextcloud's public API (classes, interfaces)", - "time": "2021-03-26T23:34:29+00:00" + "support": { + "issues": "https://github.com/ChristophWurst/nextcloud_composer/issues", + "source": "https://github.com/ChristophWurst/nextcloud_composer/tree/master" + }, + "time": "2021-10-24T01:09:47+00:00" }, { "name": "composer/package-versions-deprecated", @@ -4627,5 +4632,5 @@ "platform-overrides": { "php": "7.3" }, - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.1.0" } diff --git a/lib/Command/TestPush.php b/lib/Command/TestPush.php index 11ca7ebc3..d4533a394 100644 --- a/lib/Command/TestPush.php +++ b/lib/Command/TestPush.php @@ -85,6 +85,14 @@ protected function configure(): void { * @return int */ protected function execute(InputInterface $input, OutputInterface $output): int { + if (!$this->notificationManager->isFairUseOfFreePushService()) { + $output->writeln('We want to keep offering our push notification service for free, but large'); + $output->writeln('users overload our infrastructure. For this reason we have to rate-limit the'); + $output->writeln('use of push notifications. If you need this feature, consider setting up your'); + $output->writeln('own push server or using Nextcloud Enterprise.'); + return 1; + } + $userId = $input->getArgument('user-id'); $subject = 'Testing push notifications'; diff --git a/lib/Push.php b/lib/Push.php index af3d0a250..1405297c7 100644 --- a/lib/Push.php +++ b/lib/Push.php @@ -295,6 +295,16 @@ protected function sendNotificationsToProxies(): void { return; } + if (!$this->notificationManager->isFairUseOfFreePushService()) { + /** + * We want to keep offering our push notification service for free, but large + * users overload our infrastructure. For this reason we have to rate-limit the + * use of push notifications. If you need this feature, consider setting up your + * own push server or using Nextcloud Enterprise. + */ + return; + } + $client = $this->clientService->newClient(); foreach ($pushNotifications as $proxyServer => $notifications) { try { diff --git a/tests/Unit/PushTest.php b/tests/Unit/PushTest.php index 22eb846b0..118ee9193 100644 --- a/tests/Unit/PushTest.php +++ b/tests/Unit/PushTest.php @@ -394,6 +394,83 @@ public function testPushToDeviceEncryptionError() { $push->pushToDevice(1970, $notification); } + public function testPushToDeviceNoFairUse() { + $push = $this->getPush(['getDevicesForUser', 'encryptAndSign', 'deletePushToken', 'validateToken', 'deletePushTokenByDeviceIdentifier']); + + /** @var INotification|MockObject $notification */ + $notification = $this->createMock(INotification::class); + $notification + ->method('getUser') + ->willReturn('valid'); + + /** @var IUser|MockObject $user */ + $user = $this->createMock(IUser::class); + + $this->userManager->expects($this->once()) + ->method('get') + ->with('valid') + ->willReturn($user); + + $push->expects($this->once()) + ->method('getDevicesForUser') + ->willReturn([ + [ + 'proxyserver' => 'proxyserver', + 'token' => 16, + 'apptype' => 'other', + ], + ]); + + $this->config + ->method('getSystemValue') + ->with('debug', false) + ->willReturn(false); + + $this->l10nFactory + ->method('getUserLanguage') + ->with($user) + ->willReturn('ru'); + + $this->notificationManager->expects($this->once()) + ->method('prepare') + ->with($notification, 'ru') + ->willReturnArgument(0); + + /** @var Key|MockObject $key */ + $key = $this->createMock(Key::class); + + $this->keyManager->expects($this->once()) + ->method('getKey') + ->with($user) + ->willReturn($key); + + $push->expects($this->exactly(1)) + ->method('validateToken') + ->willReturn(true); + + $push->expects($this->exactly(1)) + ->method('encryptAndSign') + ->willReturn(['Payload']); + + $push->expects($this->never()) + ->method('deletePushToken'); + + $this->clientService->expects($this->never()) + ->method('newClient'); + + $this->config->expects($this->once()) + ->method('getSystemValueBool') + ->with('has_internet_connection', true) + ->willReturn(true); + + $this->notificationManager->method('isFairUseOfFreePushService') + ->willReturn(false); + + $push->method('deletePushTokenByDeviceIdentifier') + ->with('123456'); + + $push->pushToDevice(207787, $notification); + } public function dataPushToDeviceSending() { return [ @@ -631,6 +708,9 @@ public function testPushToDeviceSending($isDebug) { ]) ->willThrowException($e); + $this->notificationManager->method('isFairUseOfFreePushService') + ->willReturn(true); + $push->method('deletePushTokenByDeviceIdentifier') ->with('123456'); @@ -762,6 +842,9 @@ public function testPushToDeviceTalkNotification(array $deviceTypes, $isTalkNoti ->with('has_internet_connection', true) ->willReturn(true); + $this->notificationManager->method('isFairUseOfFreePushService') + ->willReturn(true); + $push->pushToDevice(200718, $notification); } }