Skip to content

Commit 2a370ea

Browse files
fixup! feat(services): add log and login/session services
1 parent b48f36c commit 2a370ea

2 files changed

Lines changed: 54 additions & 2 deletions

File tree

lib/LoginStats.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99

1010
namespace OCA\ServerInfo;
1111

12+
use OCP\IConfig;
1213
use OCP\IDBConnection;
1314

1415
class LoginStats {
1516
public function __construct(
17+
private IConfig $config,
1618
private IDBConnection $db,
1719
) {
1820
}
@@ -23,10 +25,22 @@ public function __construct(
2325
* bruteforceAttempts1h: int,
2426
* bruteforceTotal: int,
2527
* topIps: list<array{ip: string, count: int}>,
26-
* available: bool
28+
* available: bool,
29+
* reason?: string
2730
* }
2831
*/
2932
public function getStats(): array {
33+
if ($this->usesRedisBruteforceBackend()) {
34+
return [
35+
'bruteforceAttempts24h' => 0,
36+
'bruteforceAttempts1h' => 0,
37+
'bruteforceTotal' => 0,
38+
'topIps' => [],
39+
'available' => false,
40+
'reason' => 'redis_backend',
41+
];
42+
}
43+
3044
try {
3145
$total = $this->countAttempts();
3246
} catch (\Throwable) {
@@ -48,6 +62,14 @@ public function getStats(): array {
4862
];
4963
}
5064

65+
private function usesRedisBruteforceBackend(): bool {
66+
if ($this->config->getSystemValueBool('auth.bruteforce.protection.force.database', false)) {
67+
return false;
68+
}
69+
$distributed = ltrim($this->config->getSystemValueString('memcache.distributed', ''), '\\');
70+
return $distributed === 'OC\Memcache\Redis';
71+
}
72+
5173
private function countAttempts(?int $sinceTimestamp = null): int {
5274
$qb = $this->db->getQueryBuilder();
5375
$qb->select($qb->func()->count('id'))->from('bruteforce_attempts');

tests/lib/LoginStatsTest.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,18 @@
1111

1212
use OCA\ServerInfo\LoginStats;
1313
use OCP\DB\QueryBuilder\IQueryBuilder;
14+
use OCP\IConfig;
1415
use OCP\IDBConnection;
1516
use OCP\Server;
17+
use PHPUnit\Framework\MockObject\MockObject;
1618
use Test\TestCase;
1719

1820
/**
1921
* @group DB
2022
*/
2123
class LoginStatsTest extends TestCase {
2224
private IDBConnection $db;
25+
private IConfig&MockObject $config;
2326
private LoginStats $instance;
2427

2528
private const IP_A = '10.0.0.1';
@@ -29,7 +32,10 @@ class LoginStatsTest extends TestCase {
2932
protected function setUp(): void {
3033
parent::setUp();
3134
$this->db = Server::get(IDBConnection::class);
32-
$this->instance = new LoginStats($this->db);
35+
$this->config = $this->createMock(IConfig::class);
36+
$this->config->method('getSystemValueBool')->willReturn(false);
37+
$this->config->method('getSystemValueString')->willReturn('');
38+
$this->instance = new LoginStats($this->config, $this->db);
3339
$this->cleanUp();
3440
}
3541

@@ -61,6 +67,29 @@ private function insertAttempt(string $ip, int $occurred): void {
6167
$qb->executeStatement();
6268
}
6369

70+
public function testRedisBackendReturnsUnavailable(): void {
71+
$config = $this->createMock(IConfig::class);
72+
$config->method('getSystemValueBool')->willReturn(false);
73+
$config->method('getSystemValueString')->willReturn('OC\Memcache\Redis');
74+
$instance = new LoginStats($config, $this->db);
75+
76+
$result = $instance->getStats();
77+
78+
$this->assertFalse($result['available']);
79+
$this->assertSame('redis_backend', $result['reason']);
80+
}
81+
82+
public function testForceDatabaseOverridesRedis(): void {
83+
$config = $this->createMock(IConfig::class);
84+
$config->method('getSystemValueBool')->willReturn(true);
85+
$config->method('getSystemValueString')->willReturn('OC\Memcache\Redis');
86+
$instance = new LoginStats($config, $this->db);
87+
88+
$result = $instance->getStats();
89+
90+
$this->assertTrue($result['available']);
91+
}
92+
6493
public function testReturnShape(): void {
6594
$result = $this->instance->getStats();
6695

@@ -114,6 +143,7 @@ public function testTopIpsShape(): void {
114143

115144
$result = $this->instance->getStats();
116145

146+
$this->assertIsArray($result['topIps']);
117147
foreach ($result['topIps'] as $entry) {
118148
$this->assertArrayHasKey('ip', $entry);
119149
$this->assertArrayHasKey('count', $entry);

0 commit comments

Comments
 (0)