admin: allow assigning a reserved username to a user via the admin console

Add users.Service.UpdateUsernameAdmin, which skips the
config.ReservedUsernames block that self-service UpdateUsername enforces.
Operators need to be able to hand a reserved word to a specific account
even though regular users can't claim it themselves.
This commit is contained in:
Astra 2026-09-15 12:04:26 +01:00
parent 2ffdb1beb5
commit d83034e8dc
4 changed files with 50 additions and 4 deletions

View file

@ -127,6 +127,30 @@ func TestServiceUsernameReservedBlocksNewClaimsButKeepsExisting(t *testing.T) {
}
}
// TestServiceUpdateUsernameAdminBypassesReserved locks in that the admin
// console can deliberately assign a config.ReservedUsernames word to an
// account, even though self-service UpdateUsername refuses the same claim.
func TestServiceUpdateUsernameAdminBypassesReserved(t *testing.T) {
ctx := context.Background()
store := memory.NewUserStore()
target, err := store.Create(ctx, domain.User{AccessHash: 1, Phone: "15550000005", FirstName: "Target"})
if err != nil {
t.Fatalf("create target: %v", err)
}
svc := NewService(store, WithReservedUsernames([]string{"admin"}))
if _, err := svc.UpdateUsername(ctx, target.ID, "admin"); !errors.Is(err, domain.ErrUsernameInvalid) {
t.Fatalf("self-service claim of reserved username err = %v, want username invalid", err)
}
u, err := svc.UpdateUsernameAdmin(ctx, target.ID, "admin")
if err != nil {
t.Fatalf("admin claim of reserved username: %v", err)
}
if u.Username != "admin" {
t.Fatalf("admin claim of reserved username: got username %q, want %q", u.Username, "admin")
}
}
// marksbotOverrideStore wraps memory.UserStore to serve domain.VerifierBotUser()
// for a fixed username lookup, since memory.UserStore.Create always assigns an
// id from its own auto-increment sequence and can never produce the fixed