As discussed in #2888 a quite simple implementation that should do the job. Heaps more could be done as mentioned in the comments but might not be needed.
It took me couple hours to understand all the authentication/login flows as there are lots of different components now such as Auth, SessionAuth, SessionInitializer, Access, etc. and it wasn't clear where to put things to make it work universally while still being clear about when it happens etc.
Also had to add couple of events eg for failed logins. The most important part is really to register a failed login attempt when there is one (we often authenticate eg API requests etc even though the user didn't, or we always authenticate first against session then regular auth adapter etc which makes things complicated). And it is important to check whether IP is blocked when trying to attempt to log in. All those parts should be covered.
When an IP is blocked, I did not want to block any already logged in users in the UI. This could be annoying when a company shares the same IP and it would otherwise even block the super user.
The superuser has a diagnostic page to unblock all users and a console command. Can also document in a FAQ how to do it through the SQL database directly.
For system settings and diagnostics page screens see screenshot tests.
Functionality wise you specify two values: X amount of login retries allowed in Y amount of minutes. If you have more than X amount of logins within Y amount of minutes, you are blocked and cannot log in. Even when successful token provided for example. You can only log in again, when some time has passed and you had less than X amount of login retries within the last Y amount of minutes. There is no specific lock out time that you can configure so if people lock themselves out they can use UI again after eg 30 min or 60min. By default we allow 20 logins within 60 minutes. When sharing an IP within an office those 20 logins could be reached within an hour but should be maybe fine. Hard to find the right balance here.
You can also whitelist and blacklist specific IPs.
I'll try to write some more tests for the different login failures once the PR is reviewed.
Haven't tested, but wondering if using "Webcron" (calling the archiver with token_auth in url) will still work if the according account got locked down.
Just tested it, but it works as it is only an API test.
But realizing now that the UI is sending API requests so there is pretty much no way to keep the UI working for a logged in user when the IP got blocked by a different user. Will need to block the entire UI as it current behaviour it would only block partial UI and look broken.