So If I understand the changes I think this is what happened:
Previously attempts per account name were recorded and if they were above the limit set the account was blocked.
However this means that you can test for the existence of an account by triggering the block. So this was removed.
So even if we put a generic message back - that still yields information about the attempt as because it's done within a test to see if the user exists - it's only triggered when a username exists.
So if we want the behaviour back whereby you can trigger a block based on attempting to reset an account separate from the IP block either:
1) We'd need to block the account but not notify the user that got blocked.
2) We'd need to record all attempted usernames in a way that we could block by username even if the username wasn't a username corresponding to a user.I don't think we could assume that any non existant username is equivalent. Although this would be a nice way to speed up blocking attempts at enumerating usernames it would be possible to use this to identify valid usernames.for example. If you trigger the block and get notified on say 5 usernames that don't exist - and then retry after you are unblocked with 4 that you know don't exist and another username - you would get blocked (and notified) if and only if the fourth didn't exist. Thereby allowing you to test. Although I guess this is complicated by that this behaviour would be influence by any use of the form.
I feel like 1) is worse behaviour. As this would mean that a legitimate user would not be notified they were blocked, leading to confusion as to why they were not getting a password reset email.
For 2 things to consider:
Currently we use the UID in the flood as an identifier - this doesn't work for usernames that don't have a UID because they don't exist.
One option would be to store a list of attempted usernames and a unique id (perhaps a negative integer as this would never be a UID?)
But that seems excessive we could store the UID for existing accounts, and the username for attempts on accounts that don't exist.What happens if a username that doesn't exist is blocked - is then created. At that point we'd want to remove any block. I think if we split storage between uid for usernames that exist and username for ones that don't we don't have to worry about this.
The only downside I can see with storing non existing usernames and user ids is that it would mean that the storage would be different so would that mean you could use a timing attack to work out if a username exists? Is this something that is worth considering?
So if we wanted to go with option 2 is all that is required to add back a generic error message, and for submissions that valid to meet the test:
if ($account && $account->id() && $account->isActive()) {
call isAllowed with the provided username as the indentifier and if disallowed set the same message.