aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Security/Ip/BruteforceAllowList.php
blob: fb837690a7becffb0ce18b13ca88abdd0dbe082c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php

declare(strict_types=1);

/**
 * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */
namespace OC\Security\Ip;

use OCP\IAppConfig;
use OCP\Security\Ip\IFactory;

class BruteforceAllowList {
	/** @var array<string, bool> */
	protected array $ipIsAllowListed = [];

	public function __construct(
		private readonly IAppConfig $appConfig,
		private readonly IFactory $factory,
	) {
	}

	/**
	 * Check if the IP is allowed to bypass bruteforce protection
	 */
	public function isBypassListed(string $ip): bool {
		if (isset($this->ipIsAllowListed[$ip])) {
			return $this->ipIsAllowListed[$ip];
		}

		try {
			$address = $this->factory->addressFromString($ip);
		} catch (\InvalidArgumentException) {
			$this->ipIsAllowListed[$ip] = false;
			return false;
		}

		foreach ($this->appConfig->searchKeys('bruteForce', 'whitelist_') as $key) {
			$rangeString = $this->appConfig->getValueString('bruteForce', $key);
			try {
				$range = $this->factory->rangeFromString($rangeString);
			} catch (\InvalidArgumentException) {
				continue;
			}

			$allowed = $range->contains($address);
			if ($allowed) {
				$this->ipIsAllowListed[$ip] = true;
				return true;
			}
		}

		$this->ipIsAllowListed[$ip] = false;
		return false;
	}
}