Ok, you have login form and you want to ban users for 5 minutes if they get password/user wrong. User can try few times in a row until banned.
LOGIN_FAILS table:
- id PK, serial/auto_increment
- ipaddress int/text/whatever you prefer
- added DATETIME/TIMESTAMP
SQL:
SELECT IF(COUNT(id) < 3, 'false', 'true') AS is_banned FROM LOGIN_FAILS WHERE ipaddress='1.2.3.4' AND added BETWEEN (NOW() - INTERVAL '5 minutes') AND NOW();
This can be visualized as
Ban check timeblock: #####
Failures: 1,2,3
Failures are set to time range:
Time ->
========1==2=3==========
========######==========
Now you could try again once in a row:
========1######=========
Now you could try again twice in a row:
========1==2######======
But the correct approach would be holding this time block for 5 minutes
========######==========
Now you can try again three times in a row
========1==2=3######====
^^^^^^ Ignored
But you don't want to use current time as blocks (0:00-0:05, 0:05-0:10, etc) because if ban happens at 0:04 the next ban check time block is 0:05 (= only 1 minute ban).
So what has to be added/modified to given SQL statement so that user can always try N times in a row and then hold in temporary ban for X minutes?
Edit
So something like
SELECT
IF(COUNT(id) < 3, 'false', 'true') AS is_banned
FROM
LOGIN_FAILS
WHERE
ipaddress='1.2.3.4' AND
added
BETWEEN
(
SELECT
MIN(added) AS min
FROM
LOGIN_FAILS
WHERE
ipaddress='1.2.3.4' AND
added <= (NOW() - INTERVAL 5 minutes)
ORDER BY
added
LIMIT 3
)
AND
NOW()