Current project:
- ASP.NET 4.7.2
- MVC 5
- C# 7.2
- Repository Pattern
I am experiencing a very strange issue with a migrated database. The old database could not be salvaged (wrong design, badly entered data, the works), so a completely new system was designed and built for the customer.
Due to the bad state of the data, migration had to be punted through Excel, so that the data could be cleaned up and some complex calculations and validation done to certain fields.
I re-imported the data in such a way that for the users, their PasswordHash and SecurityStamp fields were null values (the default setting). I then ran a headless script in the browser (an ActionResult that simply redirected back to /Home/Index once it was done) that went through all users and assigned them a random GUID as a password. The intent was that a password reset eMail would be sent out for everyone.
Unfortunately, for 102 users out of over 2,000, this headless script was unable to update the user. As in, the PasswordHash and SecurityStamp remained null.
This problem has now extended to the password reset eMail that was sent out. The link in each eMail works, in that it is able to reset 95% of all accounts, but for these 102 accounts it is utterly unable to clear, set or reset the password. I have tried to debug this, but the debugger does not dive into UserManager (understandable), and so I cannot see where and how it fails.
Since 95% of all accounts are functioning just fine, the only thing I can come up with is that there is something wrong with the database such that UserManager cannot update those particular rows. Unfortunately, a close examination of the User table does not show any specific differences between the 102 affected accounts and any unaffected account - there is no consistency with those 102 accounts that pops out.
Attempts to set both fields to some value through MSSQL, including empty strings, makes no difference.
Suggestions? Frankly, I have no clue what needs showing or what further questions I should be asking at this time.
EDIT
A MASSIVE WHISKY-TANGO-FOXTROT moment here, folks.
Turns out that there IS a commonality between all of the accounts… the USERNAMES all have non-digit, non-integer characters. Like a plus (+) or a dash (-). Problem is, dashes are common in many domain names (to say nothing of the eMail user name itself), and pluses are used extensively in plus-addressing for certain providers like gMail.
I have confirmed that the addition of a plus or a dash in any part of the username causes any sort of a set, delete or reset of a password to fail via UserManager.
I have done this by choosing a user that hasn’t yet made use of their reset link, changed their username so it had a dash, tried (and failed!) to reset the password, then removed the dash and tried again (and succeeded!).
So clearly anything in a username that isn’t a-z, 0-9 and . causes UserManager to fail spectacularly.
How this happens is beyond me. I literally can’t even.
I am looking for direction and guidance on this one, because my mind is nothing more than a multitude of small shrapnel all over my office right now. I need to be able to accept dashes and pluses in usernames without borking the entire password set/delete/reset functionality.
Please also understand that this system leverages the DotNet system -- everything that is happening here is outside the scope of anything I have personally touched. The only possible way that anything is creeping in is that a normal username entry via a web form has its username “sanitized” such that things like dashes and pluses are not actually as such in the UserName database field.