Refactor reserving a username

There's actually a bug in this, we get an InternalError when the first username attempt is taken and we try a second one. I don't have time to debug that right now. At least the code is deduped now.

Follow-on from #2467.