feat: #2092153 Add drush commands to inspect and recover IP restrictions

Adds two drush commands aimed at the locked-out-administrator scenario from the issue: you still have shell access but the IP restriction stops you logging in, and drush user:login cannot help because the firewall signs the one-time session straight back out.

restrict_by_ip:status [ip] [--user=NAME] lists the configured global, per-user and role ranges as a table and, when given an IP, reports whether each range matches and whether a login from that IP would be allowed (mirroring the firewall's global-or-user logic). Ranges altered at runtime by hook_restrict_by_ip_ranges_alter() implementations are not reflected, and the command says so in its help.

restrict_by_ip:allow <cidr> [--user=NAME] appends a range to the global allow list, or to a user's ranges field with --user. Input is validated with the module's own IPTools, so a bad range fails the command instead of locking the site down harder. Since the per-user ranges moved to a base field (#3283846), plain drush config:set can no longer manage those; this command covers both storages. Re-adding a range that is already allowed reports it as already in place instead of a repeat success.

Commands are Drush 13 attribute-based classes in src/Drush/Commands with AutowireTrait, so there is no drush.services.yml and no hard dependency on drush; drush/drush ^13 is added to require-dev for the kernel tests. The README gains a "Locked out?" section documenting the commands plus the raw config:set recipes (including the quirk that clearing login_range needs '{}' because drush cannot parse '[]').

Tested: kernel tests cover both commands (validation, dedup, unknown user, status table with and without an IP); also verified end to end with real drush on a local site.

#ai-assisted

Closes #2092153

Edited by Max Pogonowski

Merge request reports

Loading