public bool AddCredential(IUserIdentity user, Security.ICredential credential) { if (user != null && credential != null) { UserPasswordCredential up = credential as UserPasswordCredential; //this is the only type of credential we can use if (up != null) { UsernamePassword hist = up.ToHistoryPair(); //this is what we store in history if (UserPasswordProviderFactory.Instance.ComplexityChecker.IsValid(up.password)) //validate it meets complexity rules { //get the existing credential this will replace, or this may be all together new PersistedCredential curCred = GetPersisted(user.Uid, hist.UserName); if (curCred != null) { PasswordHistory <UsernamePassword> history = GetHistory(user.Uid, hist.UserName); if (!history.MatchesHistory(UsernamePassword.Matches, hist)) //can't add this since it's matching a current history in range { history.Add(hist); //delete and set the new password if (ReplaceCredential(user.Uid, hist.UserName, hist.Password)) { this.historyProvider.Update(user.Uid, history); return(true); } } } else //no existing cred, so this is a new one - but already meets complexity rule { PasswordHistory <UsernamePassword> history = GetHistory(user.Uid, hist.UserName); if (!history.MatchesHistory(UsernamePassword.Matches, hist)) //can't add this since it's matching a current history in range { history.Add(hist); //delete and set the new password if (this.storeProvider.AddCredential(user.Uid, this, hist.UserName, hist.Password)) //the hist is already salted { this.historyProvider.Update(user.Uid, history); //update the history return(true); } } } } //inside this level we have a valid password by complexity } } return(false); }
public bool ReplaceCredential(IUserIdentity user, Security.ICredential existing, Security.ICredential proposed) { if (user != null && existing != null && proposed != null) { UserPasswordCredential toRemove = existing as UserPasswordCredential; //this is the only type of credential we can use UserPasswordCredential toAdd = proposed as UserPasswordCredential; //this is the only type of credential we can use if (toRemove != null && toAdd != null) { PersistedCredential cred = GetPersisted(user.Uid, toRemove.UserName.ToLowerInvariant()); if (cred != null && toRemove.Matches(cred)) //has to be currently valid to do a replace { UsernamePassword up = toAdd.ToHistoryPair(); if (toRemove.UserName.ToLowerInvariant().Equals(toAdd.UserName.ToLowerInvariant())) { PasswordHistory <UsernamePassword> hist = GetHistory(user.Uid, up.UserName); if (!hist.MatchesHistory(UsernamePassword.Matches, up)) //check for historic collision { if (ReplaceCredential(user.Uid, up.UserName, up.Password)) { hist.Add(up); this.historyProvider.Update(user.Uid, hist); return(true); } } } else //different usernames being used { if (this.storeProvider.DeleteCredential(user.Uid, this, toRemove.UserName.ToLowerInvariant())) { this.historyProvider.Delete(user.Uid); //TODO -- this we need to fix by userId,type if (this.storeProvider.AddCredential(user.Uid, this, up.UserName, up.Password)) { PasswordHistory <UsernamePassword> hist = GetHistory(user.Uid, up.UserName); this.historyProvider.Update(user.Uid, hist); return(true); } } } } } } return(false); }