Therefore, I want to replace the current ipb_address
field with a
number of nullable fields, including address (username or IP address,
as it is now), namespace, page, exempted groups, and permission. If
all of the non-null fields match, the block will apply.
I like the idea. I don't think it is too complicated for core. It
should be 100% backwards compatible if done correctly (just make
namespace and page default to NULL, exempted groups default to
ipblock-exempt [ok, that's a permission, not a group, but that
shouldn't be too much of a problem] for ip blocks and NULL for
username blocks and permission default to edit and move, or whatever
the appropriate combination is). The new functionality can then be put
on a new Special:AdvancedBlock page.
In the process of doing all this, the User::isBlocked() and
User::isBlockedFrom() methods should be deprecated. It would make
everything much simpler if it all went through userCan().