Overview
Comment:Implement maximum number of failed logins
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: f82ba2a474fc6db643d06d6574d6c9414a7f124e37bfe5298d8743c77b8f0a82
User & Date: bohwaz on 2022-09-13 19:20:34
Other Links: branch diff | manifest | tags
Context
2022-09-13
19:48
Add captcha when we reach a number of login attempts check-in: cf3908bb51 user: bohwaz tags: dev
19:20
Implement maximum number of failed logins check-in: f82ba2a474 user: bohwaz tags: dev
19:14
Add DB_OPEN_SQL constant check-in: b38c094aba user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Log.php from [2a01d3f65f] to [cc96833707].

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
	 */
	const LOCKOUT_DELAY = 5*60;

	/**
	 * Number of maximum login attempts in that delay
	 * @var int
	 */
	const LOCKOUT_ATTEMPTS = 4;

	const LOGIN_FAIL = 1;
	const LOGIN_SUCCESS = 2;
	const LOGIN_RECOVER = 3;
	const LOGIN_PASSWORD_CHANGE = 4;
	const LOGIN_CHANGE = 5;
	const LOGIN_AS = 6;







|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
	 */
	const LOCKOUT_DELAY = 5*60;

	/**
	 * Number of maximum login attempts in that delay
	 * @var int
	 */
	const LOCKOUT_ATTEMPTS = 3;

	const LOGIN_FAIL = 1;
	const LOGIN_SUCCESS = 2;
	const LOGIN_RECOVER = 3;
	const LOGIN_PASSWORD_CHANGE = 4;
	const LOGIN_CHANGE = 5;
	const LOGIN_AS = 6;
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
	 */
	static public function isLocked(): bool
	{
		$ip = Utils::getIP();

		// is IP locked out?
		$sql = sprintf('SELECT COUNT(*) FROM logs WHERE type = ? AND ip_address = ? AND created > datetime(\'now\', \'-%d seconds\');', self::LOCKOUT_DELAY);
		$count = $db->firstColumn($sql, self::LOGIN_FAIL, $ip);

		if ($count >= self::LOCKOUT_ATTEMPTS) {
			return true;
		}

		return false;
	}







|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
	 */
	static public function isLocked(): bool
	{
		$ip = Utils::getIP();

		// is IP locked out?
		$sql = sprintf('SELECT COUNT(*) FROM logs WHERE type = ? AND ip_address = ? AND created > datetime(\'now\', \'-%d seconds\');', self::LOCKOUT_DELAY);
		$count = DB::getInstance()->firstColumn($sql, self::LOGIN_FAIL, $ip);

		if ($count >= self::LOCKOUT_ATTEMPTS) {
			return true;
		}

		return false;
	}

Modified src/www/admin/login.php from [38242c527a] to [4ff3564886].

35
36
37
38
39
40
41




42
43
44
45
46
47
48
    Utils::redirect(ADMIN_URL . '');
}

$id_field = DynamicFields::get(DynamicFields::getLoginField());
$id_field_name = $id_field->label;

$form->runIf('login', function () use ($id_field_name, $session) {




    if (!trim((string) f('id'))) {
        throw new UserException(sprintf('L\'identifiant (%s) n\'a pas été renseigné.', $id_field_name));
    }

    if (!trim((string) f('password'))) {
        throw new UserException('Le mot de passe n\'a pas été renseigné.');
    }







>
>
>
>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    Utils::redirect(ADMIN_URL . '');
}

$id_field = DynamicFields::get(DynamicFields::getLoginField());
$id_field_name = $id_field->label;

$form->runIf('login', function () use ($id_field_name, $session) {
    if (Log::isLocked()) {
        throw new UserException("Vous avez dépassé la limite de tentatives de connexion.\nMerci d'attendre 5 minutes avant de ré-essayer de vous connecter.");
    }

    if (!trim((string) f('id'))) {
        throw new UserException(sprintf('L\'identifiant (%s) n\'a pas été renseigné.', $id_field_name));
    }

    if (!trim((string) f('password'))) {
        throw new UserException('Le mot de passe n\'a pas été renseigné.');
    }