/// <summary> /// Resets the password for the user related to the password token specified to the newPassword specified /// It'll then remove the password reset token entity specified /// </summary> /// <param name="newPassword">the new password specified</param> /// <param name="passwordResetToken">the reset token. Will be removed in this method if password reset is successful</param> /// <returns>true if successful, false otherwise</returns> public static async Task <bool> ResetPasswordAsync(string newPassword, PasswordResetTokenEntity passwordResetToken) { if (string.IsNullOrWhiteSpace(newPassword) || passwordResetToken == null) { return(false); } using (var adapter = new DataAccessAdapter()) { var q = new QueryFactory().User.Where(UserFields.UserID.Equal(passwordResetToken.UserID)); var user = await adapter.FetchFirstAsync(q).ConfigureAwait(false); if (user == null) { return(false); } user.Password = HnDGeneralUtils.HashPassword(newPassword, performPreMD5Hashing: true); var uow = new UnitOfWork2(); uow.AddForSave(user); uow.AddForDelete(passwordResetToken); var toReturn = await uow.CommitAsync(adapter); return(toReturn == 2); } }
/// <summary> /// Registers a new user, using the properties of this class. /// </summary> /// <param name="nickName">Name of the nick.</param> /// <param name="dateOfBirth">The date of birth.</param> /// <param name="emailAddress">The email address.</param> /// <param name="emailAddressIsPublic">flag to signal if the emailaddress is visible for everyone or not</param> /// <param name="iconUrl">The icon URL.</param> /// <param name="ipNumber">The ip number.</param> /// <param name="location">The location.</param> /// <param name="occupation">The occupation.</param> /// <param name="signature">The signature.</param> /// <param name="website">The website.</param> /// <param name="emailData">The email data.</param> /// <param name="autoSubscribeThreads">Default value when user creates new threads.</param> /// <param name="defaultMessagesPerPage">Messages per page to display</param> /// <returns> /// UserID of new user or 0 if registration failed. /// </returns> public static async Task <int> RegisterNewUserAsync(string nickName, DateTime?dateOfBirth, string emailAddress, bool emailAddressIsPublic, string iconUrl, string ipNumber, string location, string occupation, string signature, string website, Dictionary <string, string> emailData, bool autoSubscribeThreads, short defaultMessagesPerPage) { var newUser = new UserEntity { AmountOfPostings = 0, DateOfBirth = dateOfBirth, EmailAddress = emailAddress, EmailAddressIsPublic = emailAddressIsPublic, IPNumber = ipNumber, IconURL = iconUrl, IsBanned = false, JoinDate = DateTime.Now, Location = location, NickName = nickName, Occupation = occupation, Signature = signature, Website = website }; var password = HnDGeneralUtils.GenerateRandomPassword(); newUser.Password = HnDGeneralUtils.HashPassword(password, performPreMD5Hashing: true); //Preferences newUser.AutoSubscribeToThread = autoSubscribeThreads; newUser.DefaultNumberOfMessagesPerPage = defaultMessagesPerPage; //Fetch the SystemDataEntity to use the "DefaultUserTitleNewUser" as the user title & the "DefaultRoleNewUser" as the roleID of the newly //created RoleUserEntity. var systemData = await SystemGuiHelper.GetSystemSettingsAsync(); newUser.UserTitleID = systemData.DefaultUserTitleNewUser; newUser.RoleUser.Add(new RoleUserEntity { RoleID = systemData.DefaultRoleNewUser }); // first encode fields which could lead to cross-site-scripting attacks EncodeUserTextFields(newUser); // now save the new user entity and the new RoleUser entity recursively in one go. using (var adapter = new DataAccessAdapter()) { if (await adapter.SaveEntityAsync(newUser).ConfigureAwait(false)) { // all ok, Email the password await HnDGeneralUtils.EmailPassword(password, emailAddress, emailData); } } return(newUser.UserID); }
/// <summary> /// Initializes the system, by running a stored procedure passing in the new admin password. /// </summary> /// <param name="newAdminPassword"></param> /// <param name="emailAddress"></param> /// <returns></returns> public static async Task Initialize(string newAdminPassword, string emailAddress) { if (string.IsNullOrWhiteSpace(newAdminPassword)) { return; } var passwordHashed = HnDGeneralUtils.HashPassword(newAdminPassword, performPreMD5Hashing: true); using (var adapter = new DataAccessAdapter()) { await ActionProcedures.InstallAsync(emailAddress, passwordHashed, adapter, CancellationToken.None); CacheController.PurgeResultsets(CacheKeys.AnonymousUserQueryResultset); } }
private static void ConvertUsers() { // as in the new version we'll just use plain text, we'll reset all signatures to the empty string and users have to type in their signatures again. Console.WriteLine("Converting users."); using (var adapter = new DataAccessAdapter()) { Console.WriteLine("\tResetting all signature texts with 1 statement."); var updater = new UserEntity() { Signature = string.Empty }; Console.Write("\t\tUpdating users..."); var result = adapter.UpdateEntitiesDirectly(updater, null); Console.WriteLine("\tDONE. Users updated: {0}", result); Console.WriteLine("\n\tRehashing passwords with PBKDF2..."); var allUsers = (EntityCollection <UserEntity>)adapter.FetchQuery(new QueryFactory().User); Console.WriteLine("\t\tNumber of users to process: {0}", allUsers.Count); int count = 0; foreach (var user in allUsers) { count++; user.Password = HnDGeneralUtils.HashPassword(user.Password, performPreMD5Hashing: false); if (count % 500 == 0) { Console.WriteLine("\t\tRehashed {0} users", count); } } Console.WriteLine("\t\tDONE rehashing, persisting entities in batches to database"); adapter.BatchSize = 150; adapter.SaveEntityCollection(allUsers); Console.WriteLine("\tDONE rehashing passwords"); Console.WriteLine("DONE converting users."); } }
/// <summary> /// Updates the given user's profile data using the values of the properties of this class. /// </summary> /// <param name="userId">The user ID.</param> /// <param name="dateOfBirth">The date of birth.</param> /// <param name="emailAddress">The email address.</param> /// <param name="emailAddressIsPublic">flag to signal if the emailaddress is visible for everyone or not</param> /// <param name="iconUrl">The icon URL.</param> /// <param name="location">The location.</param> /// <param name="occupation">The occupation.</param> /// <param name="password">The password.</param> /// <param name="signature">The signature.</param> /// <param name="website">The website.</param> /// <param name="userTitleId">The user title ID.</param> /// <param name="autoSubscribeThreads">Default value when user creates new threads.</param> /// <param name="defaultMessagesPerPage">Messages per page to display</param> /// <param name="isBanned">flag whether the user is banned or not. Can be null, in which case the value is left untouched</param> /// <param name="roleIds">The RoleIDs of the roles the user is in. Can be null, in which case no roles are updated</param> /// <returns>true if succeeded, false otherwise</returns> public static async Task <bool> UpdateUserProfileAsync(int userId, DateTime?dateOfBirth, string emailAddress, bool emailAddressIsPublic, string iconUrl, string location, string occupation, string password, string signature, string website, int userTitleId, bool autoSubscribeThreads, short defaultMessagesPerPage, bool?isBanned = null, List <int> roleIds = null) { var user = await UserGuiHelper.GetUserAsync(userId); if (user == null) { // not found return(false); } user.DateOfBirth = dateOfBirth; user.EmailAddress = emailAddress; user.EmailAddressIsPublic = emailAddressIsPublic; user.IconURL = iconUrl; user.Location = location; user.Occupation = occupation; user.UserTitleID = userTitleId; if (isBanned.HasValue) { user.IsBanned = isBanned.Value; } if (!string.IsNullOrWhiteSpace(password)) { user.Password = HnDGeneralUtils.HashPassword(password, performPreMD5Hashing: true); } user.Signature = signature; user.Website = website; //Preferences user.AutoSubscribeToThread = autoSubscribeThreads; user.DefaultNumberOfMessagesPerPage = defaultMessagesPerPage; // first encode fields which could lead to cross-site-scripting attacks EncodeUserTextFields(user); if (roleIds != null) { // Add new entities for the user for all roleid's in the list specified. We'll first delete the ones the user is already in below directly foreach (var roleId in roleIds) { user.RoleUser.Add(new RoleUserEntity() { RoleID = roleId }); } } using (var adapter = new DataAccessAdapter()) { await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "Update User Info").ConfigureAwait(false); try { if (roleIds != null) { // first remove the user from all roles, we'll do that directly. await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleUserEntity), new RelationPredicateBucket(RoleUserFields.UserID.Equal(userId))) .ConfigureAwait(false); } // then save everything in one go. var toReturn = await adapter.SaveEntityAsync(user).ConfigureAwait(false); adapter.Commit(); return(toReturn); } catch { adapter.Rollback(); throw; } } }