I could have sworn that this used to be a thing, where you could "poke a hole" in a large rangeblock with a more specific block with different settings. However, I can't find any evidence of this in the manual, so my memory must just be corrupted.
This week I was trying to help the WikiEd team with an issue with their dashboard. Their dashboard is hosted in a Linode range, which is blocked both globally and locally on enwiki as a web host provider with multiple open proxies. Their dashboard uses oauth to make edits on behalf of their users. They provided the specific IP address their dashboard uses for this. I attempted to block the specific IP address they were using anon-only account creation allowed, but this did not work. Instead, I needed to change the rangeblock that was affecting them to be anonymous-only, with account creation allowed. This is not ideal for a hosting provider such as Linode, because it potentially allows any number of VPN services and open proxies to continue operating. We have run into this in other cases as well, for example, I recently received a request from a WMF affiliate that was attempting to run an editathon from a single IP address, but which was being affected by a checkuserblock on a wideish range (I think it was an IPv4 /19). In both cases, there is a single IP or range that we want to allow logged-in editing from, while keeping the wider range blocked.
- 2001:1234:5678::/48 is blocked, account creation blocked
- 2001:1234:5678::1:2:3:4 is blocked, anonymous only
A user at 2001:1234:5678::1:2:3:4 cannot register an account or edit from an existing account.
A user at 2001:1234:5678::1:2:3:4 can register an account or edit from an existing account, but cannot edit anonymously. A user anywhere else in the /48 rangeblock cannot register an account or edit from an existing account.
Essentially, instead of checking all IP address blocks that could apply, only use the settings from the most specific IP address or range that is blocked.
This does not require any changes to the block interface. In fact, when looking at Special:Contributions, MediaWiki already shows only the most specific IP address block. It only requires that the check when a user goes to edit or to create an account only look at the most specific block that is affecting their IP, rather than all blocks affecting their IP.
I think this change could be made in getUserBlock() by checking whether there are DatabaseBlocks with different targets, and if so choosing the one with the longest prefix, or perhaps using DatabaseBlock:chooseMostSpecificBlock().