/// <summary> /// Updates the last visit date for user. /// </summary> /// <param name="userId">The user ID of the user to update the date for.</param> public static async Task UpdateLastVisitDateForUserAsync(int userId) { var user = await UserGuiHelper.GetUserAsync(userId); if (user == null) { // not found return; } user.LastVisitedDate = DateTime.Now; using (var adapter = new DataAccessAdapter()) { await adapter.SaveEntityAsync(user).ConfigureAwait(false); } }
/// <summary> /// Toggles the ban flag value. /// </summary> /// <param name="userId">The user ID of the user to toggle the ban flag.</param> /// <returns>Tuple with two boolean flags. First value is toggle result, Second value is the new banflag value. /// true if toggle was succesful, false otherwise /// </returns> public static async Task <(bool toggleResult, bool newBanFlagValue)> ToggleBanFlagValueAsync(int userId) { var user = await UserGuiHelper.GetUserAsync(userId); if (user == null) { return(false, false); } var newBanFlagValue = !user.IsBanned; user.IsBanned = newBanFlagValue; using (var adapter = new DataAccessAdapter()) { var saveResult = await adapter.SaveEntityAsync(user).ConfigureAwait(false); return(saveResult, newBanFlagValue); } }
/// <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; } } }
/// <summary> /// Deletes the user with the ID passed in. Will reset all posts made by the user to the userid 0. /// </summary> /// <param name="userId">The user ID.</param> /// <remarks>Can't delete user 0</remarks> /// <returns>true if succeeded, false otherwise</returns> public static async Task <bool> DeleteUserAsync(int userId) { if (userId <= 1) { // can't delete the Anonymous user nor the admin user return(false); } var toDelete = await UserGuiHelper.GetUserAsync(userId); if (toDelete == null) { // user doesn't exist return(false); } if (toDelete.NickName == "Admin") { // can't delete admin return(false); } using (var adapter = new DataAccessAdapter()) { await adapter.StartTransactionAsync(IsolationLevel.ReadCommitted, "DeleteUser").ConfigureAwait(false); try { // we'll first update all PostedByUserId fields of all messages which are posted by the user to delete. var messageUpdater = new MessageEntity { PostedByUserID = 0 }; // reset to AC. await adapter.UpdateEntitiesDirectlyAsync(messageUpdater, new RelationPredicateBucket(MessageFields.PostedByUserID.Equal(userId))) .ConfigureAwait(false); // set the startuser of threads started by this user to 0 var threadUpdater = new ThreadEntity { StartedByUserID = 0 }; await adapter.UpdateEntitiesDirectlyAsync(threadUpdater, new RelationPredicateBucket(ThreadFields.StartedByUserID.Equal(userId))) .ConfigureAwait(false); // remove the user from the UserRoles set, as the user shouldn't be in any roles. await adapter.DeleteEntitiesDirectlyAsync(typeof(RoleUserEntity), new RelationPredicateBucket(RoleUserFields.UserID.Equal(userId))) .ConfigureAwait(false); // delete all bookmarks of user await adapter.DeleteEntitiesDirectlyAsync(typeof(BookmarkEntity), new RelationPredicateBucket(BookmarkFields.UserID.Equal(userId))) .ConfigureAwait(false); // delete all audit data // first fetch it, then delete all entities from the collection, as the audit data is in an inheritance hierarchy of TargetPerEntity which can't // be deleted directly from the db. var auditData = await adapter.FetchQueryAsync(new QueryFactory().User.Where(UserFields.UserID.Equal(userId))).ConfigureAwait(false); await adapter.DeleteEntityCollectionAsync(auditData).ConfigureAwait(false); // set IP bans set by this user to userid 0 var ipbanUpdater = new IPBanEntity { IPBanSetByUserID = 0 }; await adapter.UpdateEntitiesDirectlyAsync(ipbanUpdater, new RelationPredicateBucket(IPBanFields.IPBanSetByUserID.Equal(userId))) .ConfigureAwait(false); // delete threadsubscriptions await adapter.DeleteEntitiesDirectlyAsync(typeof(ThreadSubscriptionEntity), new RelationPredicateBucket(ThreadSubscriptionFields.UserID.Equal(userId))) .ConfigureAwait(false); // remove supportqueuethread claims await adapter.DeleteEntitiesDirectlyAsync(typeof(SupportQueueThreadEntity), new RelationPredicateBucket(SupportQueueThreadFields.ClaimedByUserID.Equal(userId))) .ConfigureAwait(false); // set all placed in queue references to userid 0, so the threads stay in the queues. var supportQueueThreadUpdater = new SupportQueueThreadEntity { PlacedInQueueByUserID = 0 }; await adapter.UpdateEntitiesDirectlyAsync(supportQueueThreadUpdater, new RelationPredicateBucket(SupportQueueThreadFields.PlacedInQueueByUserID.Equal(userId))) .ConfigureAwait(false); // now delete the actual user entity await adapter.DeleteEntityAsync(toDelete).ConfigureAwait(false); adapter.Commit(); return(true); } catch { adapter.Rollback(); throw; } } }