From a32681789dec31eece3e7f01e384d29391f18453 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 15 Aug 2023 08:04:32 +0200 Subject: [PATCH] feat: Expose if the own IP is allowed to bypass bruteforce protection Signed-off-by: Joas Schilling --- .../Security/Bruteforce/Capabilities.php | 32 +++++++------------ lib/private/Security/Bruteforce/Throttler.php | 2 +- .../Security/Bruteforce/CapabilitiesTest.php | 15 ++++++--- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/lib/private/Security/Bruteforce/Capabilities.php b/lib/private/Security/Bruteforce/Capabilities.php index 60cf3086f2db9..4eada3d05f51c 100644 --- a/lib/private/Security/Bruteforce/Capabilities.php +++ b/lib/private/Security/Bruteforce/Capabilities.php @@ -3,9 +3,11 @@ declare(strict_types=1); /** + * @copyright Copyright (c) 2023 Joas Schilling * @copyright Copyright (c) 2017 Roeland Jago Douma * * @author J0WI + * @author Joas Schilling * @author Julius Härtl * @author Roeland Jago Douma * @@ -32,33 +34,21 @@ use OCP\IRequest; class Capabilities implements IPublicCapability, IInitialStateExcludedCapability { - /** @var IRequest */ - private $request; - - /** @var Throttler */ - private $throttler; + public function __construct( + private IRequest $request, + private Throttler $throttler, + ) { + } /** - * Capabilities constructor. - * - * @param IRequest $request - * @param Throttler $throttler + * @return array{bruteforce: array{delay: int, allow-listed: bool}} */ - public function __construct(IRequest $request, - Throttler $throttler) { - $this->request = $request; - $this->throttler = $throttler; - } - public function getCapabilities(): array { - if (version_compare(\OC::$server->getConfig()->getSystemValueString('version', '0.0.0.0'), '12.0.0.0', '<')) { - return []; - } - return [ 'bruteforce' => [ - 'delay' => $this->throttler->getDelay($this->request->getRemoteAddress()) - ] + 'delay' => $this->throttler->getDelay($this->request->getRemoteAddress()), + 'allow-listed' => $this->throttler->isIPWhitelisted($this->request->getRemoteAddress()), + ], ]; } } diff --git a/lib/private/Security/Bruteforce/Throttler.php b/lib/private/Security/Bruteforce/Throttler.php index 2ee4c23cd1ef6..5c4f4d320b1d2 100644 --- a/lib/private/Security/Bruteforce/Throttler.php +++ b/lib/private/Security/Bruteforce/Throttler.php @@ -110,7 +110,7 @@ public function registerAttempt(string $action, * @param string $ip * @return bool */ - private function isIPWhitelisted(string $ip): bool { + public function isIPWhitelisted(string $ip): bool { if (isset($this->ipIsWhitelisted[$ip])) { return $this->ipIsWhitelisted[$ip]; } diff --git a/tests/lib/Security/Bruteforce/CapabilitiesTest.php b/tests/lib/Security/Bruteforce/CapabilitiesTest.php index 1c2bbb6bc53b2..d3463d307c00e 100644 --- a/tests/lib/Security/Bruteforce/CapabilitiesTest.php +++ b/tests/lib/Security/Bruteforce/CapabilitiesTest.php @@ -52,18 +52,24 @@ protected function setUp(): void { ); } - public function testGetCapabilities() { + public function testGetCapabilities(): void { $this->throttler->expects($this->atLeastOnce()) ->method('getDelay') ->with('10.10.10.10') ->willReturn(42); + $this->throttler->expects($this->atLeastOnce()) + ->method('isIPWhitelisted') + ->with('10.10.10.10') + ->willReturn(true); + $this->request->method('getRemoteAddress') ->willReturn('10.10.10.10'); $expected = [ 'bruteforce' => [ - 'delay' => 42 + 'delay' => 42, + 'allow-listed' => true, ] ]; $result = $this->capabilities->getCapabilities(); @@ -71,7 +77,7 @@ public function testGetCapabilities() { $this->assertEquals($expected, $result); } - public function testGetCapabilitiesOnCli() { + public function testGetCapabilitiesOnCli(): void { $this->throttler->expects($this->atLeastOnce()) ->method('getDelay') ->with('') @@ -82,7 +88,8 @@ public function testGetCapabilitiesOnCli() { $expected = [ 'bruteforce' => [ - 'delay' => 0 + 'delay' => 0, + 'allow-listed' => false, ] ]; $result = $this->capabilities->getCapabilities();