/// <summary> /// Adds the specified user names to the specified roles for the configured applicationName. /// </summary> /// <param name="userNames">A string array of user names to be added to the specified roles.</param> /// <param name="roleNames">A string array of the role names to add the specified user names to.</param> public override void AddUsersToRoles(string[] userNames, string[] roleNames) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { IQueryable<Role> roles = context.Role.Where(MatchRoleApplication()).Where(ProviderUtils.BuildContainsExpression<Role, string>(r => r.Name, roleNames)); if (roles.Count() != roleNames.Length) { throw new ProviderException("Role not found."); } IQueryable<User> users = context.User.Where(MatchUserApplication()).Where(ProviderUtils.BuildContainsExpression<User, string>(u => u.Username, userNames)); if (users.Count() != userNames.Length) { throw new ProviderException("User not found."); } try { foreach (User user in users) { foreach (Role role in roles) { // Check whether user is already in role if (IsUserInRole(user.Username, role.Name)) { throw new ProviderException(string.Format("User is already in role '{0}'.", role.Name)); } user.Role.Add(role); } } context.SaveChanges(false); } catch (Exception ex) { if (WriteExceptionsToEventLog) { WriteToEventLog(ex, "AddUsersToRoles"); } else { throw; } } finally { context.Connection.Close(); } } }
/// <summary> /// When overridden in a derived class, deletes all user-profile data for profiles in which the last activity date occurred before the specified date. /// </summary> /// <returns>The number of profiles deleted from the data source.</returns> /// <param name="authenticationOption">One of the <see cref="T:System.Web.Profile.ProfileAuthenticationOption" /> values, specifying /// whether anonymous, authenticated, or both types of profiles are deleted.</param> /// <param name="userInactiveSinceDate">A <see cref="T:System.DateTime" /> that identifies which user profiles are considered /// inactive. If the <see cref="P:System.Web.Profile.ProfileInfo.LastActivityDate" /> value of a user profile occurs on or before /// this date and time, the profile is considered inactive.</param> public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { int num = 0; using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { IQueryable<Profile> profiles = context.User.Where(MatchUserApplication()) .Where(ApplyAuthenticationOption(authenticationOption)) .Where(u => u.LastActivityDate <= userInactiveSinceDate.ToUniversalTime()) .Select(u => u.Profile); foreach (Profile profile in profiles) { context.DeleteObject(profile); num++; } context.SaveChanges(); } return num; }
/// <summary> /// When overridden in a derived class, returns the number of profiles in which the last activity date occurred on or before the specified date. /// </summary> /// <returns>The number of profiles in which the last activity date occurred on or before the specified date.</returns> /// <param name="authenticationOption">One of the <see cref="T:System.Web.Profile.ProfileAuthenticationOption" /> values, specifying /// whether anonymous, authenticated, or both types of profiles are returned.</param> /// <param name="userInactiveSinceDate">A <see cref="T:System.DateTime" /> that identifies which user profiles are considered inactive. /// If the <see cref="P:System.Web.Profile.ProfileInfo.LastActivityDate" /> of a user profile occurs on or before this date and time, /// the profile is considered inactive.</param> public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { IQueryable<Profile> profiles = context.User.Where(MatchUserApplication()) .Where(ApplyAuthenticationOption(authenticationOption)) .Where(u => u.LastActivityDate <= userInactiveSinceDate.ToUniversalTime()) .Select(u => u.Profile); return profiles.Count(); } }
/// <summary> /// Updates information about a user in the data source. /// </summary> /// <param name="membershipUser">A <see cref="T:System.Web.Security.MembershipUser" /> object that represents the user to update and the updated information for the user.</param> public override void UpdateUser(MembershipUser membershipUser) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user = GetUser(u => u.Username == membershipUser.UserName, context); user.Email = membershipUser.Email; user.Comment = membershipUser.Comment; user.IsApproved = membershipUser.IsApproved; context.SaveChanges(); } }
/// <summary> /// Resets a user's password to a new, automatically generated password. /// </summary> /// <returns>The new password for the specified user.</returns> /// <param name="username">The user to reset the password for.</param> /// <param name="answer">The password answer for the specified user.</param> public override string ResetPassword(string username, string answer) { if (!EnablePasswordReset) { throw new NotSupportedException("Password reset is not enabled."); } if (answer == null && RequiresQuestionAndAnswer) { UpdateFailureCount(username, "passwordAnswer"); throw new ProviderException("Password answer required for password reset."); } string newPassword = Membership.GeneratePassword(NEWPASSWORDLENGTH, MinRequiredNonAlphanumericCharacters); ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, newPassword, true); OnValidatingPassword(args); if (args.Cancel) { if (args.FailureInformation != null) { throw args.FailureInformation; } throw new MembershipPasswordException("Reset password canceled due to password validation failure."); } using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user = GetUser(u => u.Username == username, context); if (Convert.ToBoolean(user.IsLockedOut)) { throw new MembershipPasswordException("The supplied user is locked out."); } if (RequiresQuestionAndAnswer && !CheckPassword(answer, user.PasswordAnswer)) { UpdateFailureCount(username, "passwordAnswer"); throw new MembershipPasswordException("Incorrect password answer."); } try { user.Password = EncodePassword(newPassword); user.LastPasswordChangedDate = DateTime.Now; context.SaveChanges(); return newPassword; } catch { throw new MembershipPasswordException("User not found, or user is locked out. Password not Reset."); } } }
/// <summary> /// Gets information from the data source for a user. Provides an option to update the last-activity date/time stamp for the user. /// </summary> /// <returns>A <see cref="T:System.Web.Security.MembershipUser" /> object populated with the specified user's information from the data source.</returns> /// <param name="username">The name of the user to get information for.</param> /// <param name="userIsOnline">true to update the last-activity date/time stamp for the user; false to return user information without updating the last-activity date/time stamp for the user.</param> public override MembershipUser GetUser(string username, bool userIsOnline) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { MembershipUser membershipUser = null; User user; try { user = GetUser(u => u.Username == username, context); } catch (ProviderException) { user = null; } if (user != null) { membershipUser = GetMembershipUserFromPersistedEntity(user); if (userIsOnline) { user.LastActivityDate = DateTime.Now; context.SaveChanges(); } } return membershipUser; } }
/// <summary> /// Gets the number of users currently accessing the application. /// </summary> /// <returns>The number of users currently accessing the application.</returns> public override int GetNumberOfUsersOnline() { TimeSpan onlineSpan = new TimeSpan(0, Membership.UserIsOnlineTimeWindow, 0); DateTime compareTime = DateTime.Now.Subtract(onlineSpan); using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { return context.User.Where(MatchApplication()).Where(u => u.LastActivityDate > compareTime).Distinct().Count(); } }
/// <summary> /// Gets a collection of membership users where the user name contains the specified user name to match. /// </summary> /// <returns> /// A <see cref="T:System.Web.Security.MembershipUserCollection" /> collection that contains a page of <paramref name="pageSize" /><see cref="T:System.Web.Security.MembershipUser" /> objects beginning at the page specified by <paramref name="pageIndex" />. /// </returns> /// <param name="usernameToMatch">The user name to search for.</param> /// <param name="pageIndex">The index of the page of results to return. <paramref name="pageIndex" /> is zero-based.</param> /// <param name="pageSize">The size of the page of results to return.</param> /// <param name="totalRecords">The total number of matched users.</param> public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { MembershipUserCollection membershipUsers = new MembershipUserCollection(); using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { IOrderedQueryable<User> users = context.User.Where(MatchApplication()).Where(u => u.Username.Contains(usernameToMatch)).OrderBy(u => u.Username); totalRecords = users.Count(); if (users.Count() > 0) { foreach (User user in users.Skip(pageIndex * pageSize).Take(pageSize)) { membershipUsers.Add(GetMembershipUserFromPersistedEntity(user)); } } return membershipUsers; } }
/// <summary> /// Adds a new membership user to the data source. /// </summary> /// <returns>A <see cref="T:System.Web.Security.MembershipUser" /> object populated with the information for the newly created user.</returns> /// <param name="username">The user name for the new user.</param> /// <param name="password">The password for the new user.</param> /// <param name="email">The e-mail address for the new user.</param> /// <param name="passwordQuestion">The password question for the new user.</param> /// <param name="passwordAnswer">The password answer for the new user</param> /// <param name="isApproved">Whether or not the new user is approved to be validated.</param> /// <param name="providerUserKey">The unique identifier from the membership data source for the user.</param> /// <param name="status">A <see cref="T:System.Web.Security.MembershipCreateStatus" /> enumeration value indicating whether the user was created successfully.</param> public override MembershipUser CreateUser( string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { // Validate username/password ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, password, true); OnValidatingPassword(args); if (args.Cancel) { status = MembershipCreateStatus.InvalidPassword; return null; } if (RequiresUniqueEmail && GetUserNameByEmail(email) != string.Empty) { status = MembershipCreateStatus.DuplicateEmail; return null; } // Check whether user with passed username already exists MembershipUser user; try { user = GetUser(username, false); } catch (ProviderException) { user = null; } if (user == null) { DateTime creationDate = DateTime.Now; if (providerUserKey == null) { providerUserKey = Guid.NewGuid(); } else { if (!(providerUserKey is Guid)) { status = MembershipCreateStatus.InvalidProviderUserKey; return null; } } using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User newUser = new User { Id = (Guid)providerUserKey, Username = username, Email = email, IsApproved = isApproved, CreationDate = creationDate, IsAnonymous = false, Application = ProviderUtils.EnsureApplication(ApplicationName, context), Password = EncodePassword(password), PasswordQuestion = passwordQuestion, PasswordAnswer = passwordAnswer, LastLoginDate = creationDate, LastPasswordChangedDate = creationDate, LastActivityDate = creationDate, IsOnline = false, IsLockedOut = false, LastLockedOutDate = creationDate, FailedPasswordAttemptCount = 0, FailedPasswordAttemptWindowStart = creationDate, FailedPasswordAnswerAttemptCount = 0, FailedPasswordAnswerAttemptWindowStart = creationDate }; try { context.AddToUser(newUser); context.SaveChanges(); status = MembershipCreateStatus.Success; } catch { status = MembershipCreateStatus.UserRejected; } } return GetUser(username, false); } status = MembershipCreateStatus.DuplicateUserName; return null; }
/// <summary> /// Gets a list of all the roles for the configured applicationName. /// </summary> /// <returns>A string array containing the names of all the roles stored in the data source for the configured applicationName.</returns> public override string[] GetAllRoles() { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { return context.Role.Where(MatchRoleApplication()).Select(r => r.Name).ToArray(); } }
/// <summary> /// Removes a role from the data source for the configured applicationName. /// </summary> /// <param name="roleName">The name of the role to delete.</param> /// <param name="throwOnPopulatedRole">If true, throw an exception if <paramref name="roleName"/> has one or more members and do not delete <paramref name="roleName"/>.</param> /// <returns> /// true if the role was successfully deleted; otherwise, false. /// </returns> public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { // Validate role if (!RoleExists(roleName)) { throw new ProviderException("Role does not exist."); } if (throwOnPopulatedRole && GetUsersInRole(roleName).Length > 0) { throw new ProviderException("Cannot delete a populated role."); } using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { Role role = GetRole(r => r.Name == roleName, context); if (role == null) { return false; } try { context.DeleteObject(role); context.SaveChanges(); } catch (Exception ex) { if (WriteExceptionsToEventLog) { WriteToEventLog(ex, "DeleteRole"); return false; } throw; } return true; } }
/// <summary> /// Adds a new role to the data source for the configured applicationName. /// </summary> /// <param name="roleName">The name of the role to create.</param> public override void CreateRole(string roleName) { // Validate role name if (roleName.Contains(",")) { throw new ArgumentException("Role names cannot contain commas."); } if (RoleExists(roleName)) { throw new ProviderException("Role name already exists."); } try { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { Application application = ProviderUtils.EnsureApplication(ApplicationName, context); // Create new role Role newRole = new Role { Id = Guid.NewGuid(), Name = roleName, Application = application }; context.AddToRole(newRole); context.SaveChanges(); } } catch (Exception ex) { if (WriteExceptionsToEventLog) { WriteToEventLog(ex, "CreateRole"); } else { throw; } } }
/// <summary> /// When overridden in a derived class, deletes profile properties and information for profiles that match the supplied list of user names. /// </summary> /// <returns>The number of profiles deleted from the data source.</returns> /// <param name="usernames">A string array of user names for profiles to be deleted.</param> public override int DeleteProfiles(string[] usernames) { int num = 0; using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { IQueryable<User> users = context.User.Include("Profile").Where(u => usernames.Contains(u.Username) && u.Profile != null); foreach (User user in users) { context.DeleteObject(user.Profile); num++; } context.SaveChanges(); } return num; }
/// <summary> /// Gets the property values from database. /// </summary> /// <param name="userName">Name of the user.</param> /// <param name="propertiesValues">The property values.</param> private void ExtractPropertyValuesFromDatabase(string userName, SettingsPropertyValueCollection propertiesValues) { string[] propertyNames = null; string propertiesValuesSerialized = null; byte[] propertiesValuesBinary = null; using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { User user = context.User.Include("Profile").Where(MatchUserApplication()).Where(u => u.Username == userName && u.Profile != null).FirstOrDefault(); if (user != null) { propertyNames = user.Profile.PropertyNames.Split(new[] { ':' }); propertiesValuesSerialized = user.Profile.PropertyValuesString; propertiesValuesBinary = user.Profile.PropertyValuesBinary; // Update user user.LastActivityDate = DateTime.Now; context.SaveChanges(); } } ParseDataFromDatabase(propertyNames, propertiesValuesSerialized, propertiesValuesBinary, propertiesValues); }
/// <summary> /// Sets the values of the specified group of property settings. /// </summary> /// <param name="context">A <see cref="T:System.Configuration.SettingsContext" /> describing the current application usage.</param> /// <param name="properties">A <see cref="T:System.Configuration.SettingsPropertyValueCollection" /> representing the group /// of property settings to set.</param> public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection properties) { string username = (string)context["UserName"]; if (string.IsNullOrEmpty(username) || properties.Count < 1) { return; } bool userIsAuthenticated = (bool)context["IsAuthenticated"]; string propertiesNames = string.Empty; string propertiesValuesSerialized = string.Empty; byte[] propertiesValuesBinary = null; PrepareDataForSaving(ref propertiesNames, ref propertiesValuesSerialized, ref propertiesValuesBinary, properties, userIsAuthenticated); if (propertiesNames.Length != 0) { using (EFProviders.MemberShip dataContext = new EFProviders.MemberShip(connectionString)) { // Attempt to load user with associated profile User user = dataContext.User.Include("Profile").Where(MatchUserApplication()).Where(u => u.Username == username).FirstOrDefault(); if (user == null) { throw new ArgumentException("user"); } if (user.Profile == null) { // Create new profile user.Profile = new Profile(); } // Set profile values user.Profile.PropertyNames = propertiesNames; user.Profile.PropertyValuesString = propertiesValuesSerialized; user.Profile.PropertyValuesBinary = propertiesValuesBinary; user.Profile.LastUpdatedDate = DateTime.Now; dataContext.SaveChanges(); } } }
/// <summary> /// Processes a request to update the password for a membership user. /// </summary> /// <returns>true if the password was updated successfully; otherwise, false.</returns> /// <param name="username">The user to update the password for.</param> /// <param name="oldPassword">The current password for the specified user.</param> /// <param name="newPassword">The new password for the specified user.</param> public override bool ChangePassword(string username, string oldPassword, string newPassword) { // Check if user is authenticated if (!ValidateUser(username, oldPassword)) { return false; } // Notify that password is going to change ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, newPassword, true); OnValidatingPassword(args); if (args.Cancel) { if (args.FailureInformation != null) { throw args.FailureInformation; } throw new MembershipPasswordException("Change password canceled due to new password validation failure."); } using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user = GetUser(u => u.Username == username, context); user.Password = EncodePassword(newPassword); user.LastPasswordChangedDate = DateTime.Now; try { context.SaveChanges(); return true; } catch { return false; } } }
/// <summary> /// Processes a request to update the password question and answer for a membership user. /// </summary> /// <returns>true if the password question and answer are updated successfully; otherwise, false.</returns> /// <param name="username">The user to change the password question and answer for.</param> /// <param name="password">The password for the specified user.</param> /// <param name="newPasswordQuestion">The new password question for the specified user.</param> /// <param name="newPasswordAnswer">The new password answer for the specified user.</param> public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { // Check if user is authenticated if (!ValidateUser(username, password)) { return false; } using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user = GetUser(u => u.Username == username, context); user.PasswordAnswer = EncodePassword(newPasswordAnswer); user.PasswordQuestion = newPasswordQuestion; try { context.SaveChanges(); return true; } catch { return false; } } }
/// <summary> /// Gets a list of the roles that a specified user is in for the configured applicationName. /// </summary> /// <param name="username">The user to return a list of roles for.</param> /// <returns>A string array containing the names of all the roles that the specified user is in for the configured applicationName.</returns> public override string[] GetRolesForUser(string username) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { if (!EFMembershipProvider.CheckUser(username, ApplicationName, context)) { throw new ArgumentNullException("username"); } return (from u in context.User where u.Username == username && u.Application.Name == ApplicationName from r in u.Role where r.Application.Name == ApplicationName select r.Name).ToArray(); } }
/// <summary> /// Removes a user from the membership data source. /// </summary> /// <returns>true if the user was successfully deleted; otherwise, false.</returns> /// <param name="username">The name of the user to delete.</param> /// <param name="deleteAllRelatedData">true to delete data related to the user from the database; false to leave data related to the user in the database.</param> public override bool DeleteUser(string username, bool deleteAllRelatedData) { try { using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user; try { user = GetUser(u => u.Username == username, context); if (user == null) { return false; } } catch (ProviderException) { return false; } context.DeleteObject(user); context.SaveChanges(); if (deleteAllRelatedData) { // TODO: delete user related data } return true; } } catch { return false; } }
/// <summary> /// Gets a list of users in the specified role for the configured applicationName. /// </summary> /// <param name="roleName">The name of the role to get the list of users for.</param> /// <returns> /// A string array containing the names of all the users who are members of the specified role for the configured applicationName. /// </returns> public override string[] GetUsersInRole(string roleName) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { Role role = GetRole(r => r.Name == roleName, context); if (role == null) { throw new ProviderException("Role not found."); } if (!role.User.IsLoaded) { role.User.Load(); } return role.User.Select(u => u.Name).ToArray(); } }
/// <summary> /// Gets a collection of all the users in the data source in pages of data. /// </summary> /// <returns> /// A <see cref="T:System.Web.Security.MembershipUserCollection" /> collection that contains a page of <paramref name="pageSize" /><see cref="T:System.Web.Security.MembershipUser" /> objects beginning at the page specified by <paramref name="pageIndex" />. /// </returns> /// <param name="pageIndex">The index of the page of results to return. <paramref name="pageIndex" /> is zero-based.</param> /// <param name="pageSize">The size of the page of results to return.</param> /// <param name="totalRecords">The total number of matched users.</param> public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { MembershipUserCollection users = new MembershipUserCollection(); // Retrieve all users for the current application name from the database using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { totalRecords = context.User.Where(MatchApplication()).Distinct().Count(); if (totalRecords <= 0) { return users; } IEnumerable<User> userEntities = context.User.Where(MatchApplication()).OrderBy(u => u.Username).Skip(pageIndex * pageSize).Take(pageSize); foreach (User user in userEntities) { users.Add(GetMembershipUserFromPersistedEntity(user)); } return users; } }
/// <summary> /// Gets a value indicating whether the specified user is in the specified role for the configured applicationName. /// </summary> /// <param name="username">The user name to search for.</param> /// <param name="roleName">The role to search in.</param> /// <returns>true if the specified user is in the specified role for the configured applicationName; otherwise, false.</returns> public override bool IsUserInRole(string username, string roleName) { try { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { if (!EFMembershipProvider.CheckUser(username, ApplicationName, context)) { return false; } return (from u in context.User where u.Username == username && u.Application.Name == ApplicationName from r in u.Role where r.Name == roleName && r.Application.Name == ApplicationName select r).Count() > 0; } } catch (Exception ex) { if (WriteExceptionsToEventLog) { WriteToEventLog(ex, "IsUserInRole"); } throw; } }
/// <summary> /// Gets the password for the specified user name from the data source. /// </summary> /// <returns>The password for the specified user name.</returns> /// <param name="username">The user to retrieve the password for.</param> /// <param name="answer">The password answer for the user.</param> public override string GetPassword(string username, string answer) { if (!EnablePasswordRetrieval) { throw new ProviderException("Password Retrieval Not Enabled."); } if (PasswordFormat == MembershipPasswordFormat.Hashed) { throw new ProviderException("Cannot retrieve Hashed passwords."); } string password = string.Empty; using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user = GetUser(u => u.Username == username, context); // Check whether the user is locked out if (Convert.ToBoolean(user.IsLockedOut)) { throw new MembershipPasswordException("The supplied user is locked out."); } if (RequiresQuestionAndAnswer && !CheckPassword(answer, user.PasswordAnswer)) { UpdateFailureCount(username, "passwordAnswer"); throw new MembershipPasswordException("Incorrect password answer."); } if (PasswordFormat == MembershipPasswordFormat.Encrypted) { password = UnEncodePassword(user.Password); } } return password; }
/// <summary> /// Removes the specified user names from the specified roles for the configured applicationName. /// </summary> /// <param name="userNames">A string array of user names to be removed from the specified roles.</param> /// <param name="roleNames">A string array of role names to remove the specified user names from.</param> public override void RemoveUsersFromRoles(string[] userNames, string[] roleNames) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { IQueryable<Role> roles = context.Role.Where(MatchRoleApplication()).Where(ProviderUtils.BuildContainsExpression<Role, string>(r => r.Name, roleNames)); if (roles.Count() != roleNames.Length) { throw new ProviderException("Role not found."); } IQueryable<User> users = context.User.Include("Role").Where(MatchUserApplication()).Where(ProviderUtils.BuildContainsExpression<User, string>(u => u.Username, userNames)); if (users.Count() != userNames.Length) { throw new ProviderException("User not found."); } try { foreach (User user in users) { foreach (Role role in roles) { /*if (!user.Role.IsLoaded) { user.Role.Load(); }*/ if (user.Role.Contains(role)) { user.Role.Remove(role); } } } context.SaveChanges(); } catch (Exception ex) { if (WriteExceptionsToEventLog) { WriteToEventLog(ex, "RemoveUsersFromRoles"); } else { throw; } } } }
/// <summary> /// Gets the user name associated with the specified e-mail address. /// </summary> /// <returns>The user name associated with the specified e-mail address. If no match is found, return null.</returns> /// <param name="email">The e-mail address to search for.</param> public override string GetUserNameByEmail(string email) { try { using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user = GetUser(u => u.Email == email, context); return user == null ? string.Empty : user.Username; } } catch { return string.Empty; } }
/// <summary> /// Gets a value indicating whether the specified role name already exists in the role data source for the configured applicationName. /// </summary> /// <returns>true if the role name already exists in the data source for the configured applicationName; otherwise, false.</returns> /// <param name="roleName">The name of the role to search for in the data source.</param> public override bool RoleExists(string roleName) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { try { return GetRole(r => r.Name == roleName, context) != null; } catch (ProviderException) { return false; } } }
/// <summary> /// Clears a lock so that the membership user can be validated. /// </summary> /// <returns>true if the membership user was successfully unlocked; otherwise, false.</returns> /// <param name="username">The membership user whose lock status you want to clear.</param> public override bool UnlockUser(string username) { try { using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user; try { user = GetUser(u => u.Username == username, context); if (user == null) { return false; } } catch (ProviderException) { return false; } user.LastLockedOutDate = DateTime.Now; context.SaveChanges(); return true; } } catch { return false; } }
/// <summary> /// A helper method that performs the checks and updates associated with password failure tracking. /// </summary> /// <param name="username">The username.</param> /// <param name="failureType">Type of the failure.</param> private void UpdateFailureCount(string username, string failureType) { using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user = GetUser(u => u.Username == username, context); DateTime windowStart = new DateTime(); int failureCount = 0; if (failureType == "password") { failureCount = Convert.ToInt32(user.FailedPasswordAttemptCount); windowStart = Convert.ToDateTime(user.FailedPasswordAttemptWindowStart); } if (failureType == "passwordAnswer") { failureCount = Convert.ToInt32(user.FailedPasswordAnswerAttemptCount); windowStart = Convert.ToDateTime(user.FailedPasswordAnswerAttemptWindowStart); } DateTime windowEnd = windowStart.AddMinutes(PasswordAttemptWindow); if (failureCount == 0 || DateTime.Now > windowEnd) { // First password failure or outside of PasswordAttemptWindow. // Start a new password failure count from 1 and a new window starting now. if (failureType == "password") { user.FailedPasswordAttemptCount = 1; user.FailedPasswordAttemptWindowStart = DateTime.Now; } if (failureType == "passwordAnswer") { user.FailedPasswordAnswerAttemptCount = 1; user.FailedPasswordAnswerAttemptWindowStart = DateTime.Now; } try { context.SaveChanges(); } catch { throw new ProviderException("Unable to update failure count and window start."); } } else { if (failureCount++ >= MaxInvalidPasswordAttempts) { // Max password attempts have exceeded the failure threshold. Lock out the user. user.IsLockedOut = true; user.LastLockedOutDate = DateTime.Now; try { context.SaveChanges(); } catch { throw new ProviderException("Unable to lock out user."); } } else { // Max password attempts have not exceeded the failure threshold. Update // the failure counts. Leave the window the same. if (failureType == "password") { user.FailedPasswordAttemptCount = failureCount; } if (failureType == "passwordAnswer") { user.FailedPasswordAnswerAttemptCount = failureCount; } try { context.SaveChanges(); } catch { throw new ProviderException("Unable to update failure count."); } } } } }
/// <summary> /// Verifies that the specified user name and password exist in the data source. /// </summary> /// <returns>true if the specified username and password are valid; otherwise, false.</returns> /// <param name="username">The name of the user to validate.</param> /// <param name="password">The password for the specified user.</param> public override bool ValidateUser(string username, string password) { bool isValid = false; using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString)) { User user; try { user = GetUser(u => u.Username == username, context); if (user == null) { return false; } } catch (ProviderException) { return false; } if (CheckPassword(password, user.Password)) { if (user.IsApproved && !user.IsLockedOut) { isValid = true; user.LastActivityDate = DateTime.Now; user.LastLoginDate = DateTime.Now; context.SaveChanges(); } } else { UpdateFailureCount(username, "password"); } return isValid; } }
/// <summary> /// When overridden in a derived class, retrieves user profile data for all profiles in the data source. /// </summary> /// <returns>A <see cref="T:System.Web.Profile.ProfileInfoCollection" /> containing user-profile information for all profiles in the data source.</returns> /// <param name="authenticationOption">One of the <see cref="T:System.Web.Profile.ProfileAuthenticationOption" /> values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param> /// <param name="pageIndex">The index of the page of results to return.</param> /// <param name="pageSize">The size of the page of results to return.</param> /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param> public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) { ProfileInfoCollection profileCollection = new ProfileInfoCollection(); using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString)) { IQueryable<ProfileInfo> profiles = context.User.Where(MatchUserApplication()) .Where(ApplyAuthenticationOption(authenticationOption)) .Skip(pageIndex * pageSize) .Take(pageSize) .Select(u => new ProfileInfo(u.Username, u.IsAnonymous, u.LastActivityDate, u.Profile.LastUpdatedDate, GetSize(u))); foreach (ProfileInfo profileInfo in profiles) { profileCollection.Add(profileInfo); } totalRecords = context.User.Where(MatchUserApplication()).Where(ApplyAuthenticationOption(authenticationOption)).Count(); return profileCollection; } }