484 lines
12 KiB
C#
484 lines
12 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Web.Security;
|
|
using MileageTraker.Web.Models;
|
|
using MileageTraker.Web.Utility;
|
|
|
|
namespace MileageTraker.Web.DAL
|
|
{
|
|
public class CodeFirstMembershipProvider : MembershipProvider
|
|
{
|
|
public const string UninitializedPassword = "uninitialized_state";
|
|
|
|
#region Properties
|
|
|
|
public override string ApplicationName
|
|
{
|
|
get { return GetType().Assembly.GetName().Name; }
|
|
set
|
|
{
|
|
if (value == null) throw new ArgumentNullException("value");
|
|
ApplicationName = GetType().Assembly.GetName().Name;
|
|
}
|
|
}
|
|
|
|
public override int MaxInvalidPasswordAttempts
|
|
{
|
|
get { return 5; }
|
|
}
|
|
|
|
public override int MinRequiredNonAlphanumericCharacters
|
|
{
|
|
get { return 0; }
|
|
}
|
|
|
|
public override int MinRequiredPasswordLength
|
|
{
|
|
get { return 6; }
|
|
}
|
|
|
|
public override int PasswordAttemptWindow
|
|
{
|
|
get { return 0; }
|
|
}
|
|
|
|
public override MembershipPasswordFormat PasswordFormat
|
|
{
|
|
get { return MembershipPasswordFormat.Hashed; }
|
|
}
|
|
|
|
public override string PasswordStrengthRegularExpression
|
|
{
|
|
get { return String.Empty; }
|
|
}
|
|
|
|
public override bool RequiresUniqueEmail
|
|
{
|
|
get { return true; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Functions
|
|
|
|
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion,
|
|
string passwordAnswer, bool isApproved, object providerUserKey,
|
|
out MembershipCreateStatus status)
|
|
{
|
|
if (string.IsNullOrEmpty(username))
|
|
{
|
|
status = MembershipCreateStatus.InvalidUserName;
|
|
return null;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(email))
|
|
{
|
|
status = MembershipCreateStatus.InvalidEmail;
|
|
return null;
|
|
}
|
|
|
|
string hashedPassword = null;
|
|
if (password != UninitializedPassword)
|
|
hashedPassword = Crypto.HashPassword(password);
|
|
if (hashedPassword != null && hashedPassword.Length > 128)
|
|
{
|
|
status = MembershipCreateStatus.InvalidPassword;
|
|
return null;
|
|
}
|
|
|
|
using (var context = new DataService())
|
|
{
|
|
if (context.FindUserByUsername(username) != null)
|
|
{
|
|
status = MembershipCreateStatus.DuplicateUserName;
|
|
return null;
|
|
}
|
|
|
|
if (context.FindUserByUsername(email) != null)
|
|
{
|
|
status = MembershipCreateStatus.DuplicateEmail;
|
|
return null;
|
|
}
|
|
|
|
var newUser = new User
|
|
{
|
|
UserId = Guid.NewGuid(),
|
|
Username = username,
|
|
Password = hashedPassword,
|
|
IsApproved = isApproved,
|
|
Email = email,
|
|
Created = DateTime.Now,
|
|
FullName = "Temp Name"
|
|
};
|
|
|
|
context.AddUser(newUser);
|
|
status = MembershipCreateStatus.Success;
|
|
return newUser.ToMembershipUser(Membership.Provider.Name);
|
|
}
|
|
}
|
|
|
|
public override bool ValidateUser(string username, string password)
|
|
{
|
|
if (string.IsNullOrEmpty(username))
|
|
{
|
|
return false;
|
|
}
|
|
if (string.IsNullOrEmpty(password))
|
|
{
|
|
return false;
|
|
}
|
|
using (var context = new DataService())
|
|
{
|
|
var user = context.FindUserByUsername(username);
|
|
if (user == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (!user.IsApproved)
|
|
{
|
|
throw new UserAccountDisabledException();
|
|
}
|
|
if (user.IsLockedOut)
|
|
{
|
|
throw new UserLockedOutException();
|
|
}
|
|
var hashedPassword = user.Password;
|
|
|
|
if (hashedPassword == null)
|
|
throw new UninitializedAccountException();
|
|
|
|
var verificationSucceeded =Crypto.VerifyHashedPassword(hashedPassword, password);
|
|
if (verificationSucceeded)
|
|
{
|
|
user.PasswordFailuresSinceLastSuccess = 0;
|
|
user.LastLoginDate = DateTime.Now;
|
|
user.LastActivityDate = DateTime.Now;
|
|
}
|
|
else
|
|
{
|
|
var failures = user.PasswordFailuresSinceLastSuccess;
|
|
if (failures < MaxInvalidPasswordAttempts)
|
|
{
|
|
user.PasswordFailuresSinceLastSuccess += 1;
|
|
user.LastPasswordFailureDate = DateTime.Now;
|
|
}
|
|
else if (failures >= MaxInvalidPasswordAttempts)
|
|
{
|
|
user.LastPasswordFailureDate = DateTime.Now;
|
|
user.LastLockoutDate = DateTime.Now;
|
|
user.IsLockedOut = true;
|
|
}
|
|
}
|
|
context.UpdateUser(user);
|
|
return verificationSucceeded;
|
|
}
|
|
}
|
|
|
|
public override MembershipUser GetUser(string username, bool userIsOnline)
|
|
{
|
|
if (string.IsNullOrEmpty(username))
|
|
{
|
|
return null;
|
|
}
|
|
using (var context = new DataService())
|
|
{
|
|
var user = context.FindUserByUsername(username);
|
|
if (user == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (userIsOnline)
|
|
{
|
|
user.LastActivityDate = DateTime.Now;
|
|
context.UpdateUser(user);
|
|
}
|
|
return user.ToMembershipUser(System.Web.Security.Membership.Provider.Name);
|
|
}
|
|
}
|
|
|
|
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
|
|
{
|
|
if (!(providerUserKey is Guid))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
using (var context = new DataService())
|
|
{
|
|
var user = context.GetUser((Guid)providerUserKey);
|
|
if (user == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (userIsOnline)
|
|
{
|
|
user.LastActivityDate = DateTime.Now;
|
|
context.UpdateUser(user);
|
|
}
|
|
return user.ToMembershipUser(System.Web.Security.Membership.Provider.Name);
|
|
}
|
|
}
|
|
|
|
public override bool ChangePassword(string username, string currentPassword, string newPassword)
|
|
{
|
|
if (string.IsNullOrEmpty(username))
|
|
{
|
|
return false;
|
|
}
|
|
if (string.IsNullOrEmpty(currentPassword))
|
|
{
|
|
return false;
|
|
}
|
|
if (string.IsNullOrEmpty(newPassword))
|
|
{
|
|
return false;
|
|
}
|
|
using (var context = new DataService())
|
|
{
|
|
var user = context.FindUserByUsername(username);
|
|
if (user == null)
|
|
{
|
|
return false;
|
|
}
|
|
var hashedPassword = user.Password;
|
|
var verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, currentPassword));
|
|
if (verificationSucceeded)
|
|
{
|
|
user.PasswordFailuresSinceLastSuccess = 0;
|
|
}
|
|
else
|
|
{
|
|
var failures = user.PasswordFailuresSinceLastSuccess;
|
|
if (failures < MaxInvalidPasswordAttempts)
|
|
{
|
|
user.PasswordFailuresSinceLastSuccess += 1;
|
|
user.LastPasswordFailureDate = DateTime.Now;
|
|
}
|
|
else if (failures >= MaxInvalidPasswordAttempts)
|
|
{
|
|
user.LastPasswordFailureDate = DateTime.Now;
|
|
user.LastLockoutDate = DateTime.Now;
|
|
user.IsLockedOut = true;
|
|
}
|
|
context.UpdateUser(user);
|
|
return false;
|
|
}
|
|
var newHashedPassword = Crypto.HashPassword(newPassword);
|
|
if (newHashedPassword.Length > 128)
|
|
{
|
|
return false;
|
|
}
|
|
user.Password = newHashedPassword;
|
|
user.LastPasswordChangedDate = DateTime.Now;
|
|
context.UpdateUser(user);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public override bool UnlockUser(string userName)
|
|
{
|
|
using (var context = new DataService())
|
|
{
|
|
var user = context.FindUserByUsername(userName);
|
|
if (user != null)
|
|
{
|
|
user.IsLockedOut = false;
|
|
user.PasswordFailuresSinceLastSuccess = 0;
|
|
context.UpdateUser(user);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public override int GetNumberOfUsersOnline()
|
|
{
|
|
var dateActive = CustomExtensions.UserOnlineThreshold();
|
|
using (var context = new DataService())
|
|
{
|
|
return context.GetUsers().Count(usr => usr.LastActivityDate > dateActive);
|
|
}
|
|
}
|
|
|
|
public override bool DeleteUser(string username, bool deleteAllRelatedData)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
public override string GetUserNameByEmail(string email)
|
|
{
|
|
using (var context = new DataService())
|
|
{
|
|
var user = context.FindUserByEmail(email);
|
|
if (user != null)
|
|
{
|
|
return user.Username;
|
|
}
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize,
|
|
out int totalRecords)
|
|
{
|
|
var membershipUsers = new MembershipUserCollection();
|
|
using (var context = new DataService())
|
|
{
|
|
totalRecords = context.GetUsers().Count(user => user.Email == emailToMatch);
|
|
var users =
|
|
context.GetUsers().Where(usr => usr.Email == emailToMatch)
|
|
.OrderBy(usrn => usrn.Username)
|
|
.Skip(pageIndex*pageSize)
|
|
.Take(pageSize);
|
|
foreach (var user in users)
|
|
{
|
|
membershipUsers.Add(
|
|
user.ToMembershipUser(Membership.Provider.Name));
|
|
}
|
|
}
|
|
return membershipUsers;
|
|
}
|
|
|
|
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize,
|
|
out int totalRecords)
|
|
{
|
|
var membershipUsers = new MembershipUserCollection();
|
|
using (var context = new DataService())
|
|
{
|
|
totalRecords = context.GetUsers().Count(usr => usr.Username == usernameToMatch);
|
|
var users =
|
|
context.GetUsers().Where(usr => usr.Username == usernameToMatch)
|
|
.OrderBy(usrn => usrn.Username)
|
|
.Skip(pageIndex*pageSize)
|
|
.Take(pageSize);
|
|
foreach (var user in users)
|
|
{
|
|
membershipUsers.Add(user.ToMembershipUser(Membership.Provider.Name));
|
|
}
|
|
}
|
|
return membershipUsers;
|
|
}
|
|
|
|
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
|
|
{
|
|
var membershipUsers = new MembershipUserCollection();
|
|
using (var context = new DataService())
|
|
{
|
|
totalRecords = context.GetUsers().Count();
|
|
var users =
|
|
context.GetUsers()
|
|
.OrderBy(usrn => usrn.Username)
|
|
.Skip(pageIndex*pageSize)
|
|
.Take(pageSize);
|
|
|
|
foreach (var user in users)
|
|
{
|
|
membershipUsers.Add(user.ToMembershipUser(Membership.Provider.Name));
|
|
}
|
|
}
|
|
return membershipUsers;
|
|
}
|
|
|
|
//public string CreateAccount(string userName, string password, bool requireConfirmationToken)
|
|
//{
|
|
// if (string.IsNullOrEmpty(userName))
|
|
// {
|
|
// throw new MembershipCreateUserException(MembershipCreateStatus.InvalidUserName);
|
|
// }
|
|
|
|
// if (string.IsNullOrEmpty(password))
|
|
// {
|
|
// throw new MembershipCreateUserException(MembershipCreateStatus.InvalidPassword);
|
|
// }
|
|
|
|
// var hashedPassword = Crypto.HashPassword(password);
|
|
// if (hashedPassword.Length > 128)
|
|
// {
|
|
// throw new MembershipCreateUserException(MembershipCreateStatus.InvalidPassword);
|
|
// }
|
|
|
|
// using (var context = new MileageTrakerContext())
|
|
// {
|
|
// if (context.Users.Any(usr => usr.Username == userName))
|
|
// {
|
|
// throw new MembershipCreateUserException(MembershipCreateStatus.DuplicateUserName);
|
|
// }
|
|
|
|
// var token = string.Empty;
|
|
// if (requireConfirmationToken)
|
|
// {
|
|
// token = Algorithms.GenerateToken();
|
|
// }
|
|
|
|
// var newUser = new User
|
|
// {
|
|
// UserId = Guid.NewGuid(),
|
|
// Username = userName,
|
|
// Password = hashedPassword,
|
|
// IsApproved = !requireConfirmationToken,
|
|
// Email = string.Empty,
|
|
// Created = DateTime.Now,
|
|
// LastPasswordChangedDate = DateTime.Now,
|
|
// PasswordFailuresSinceLastSuccess = 0,
|
|
// LastLoginDate = SqlDateTime.MinValue.Value,
|
|
// LastActivityDate = SqlDateTime.MinValue.Value,
|
|
// LastLockoutDate = SqlDateTime.MinValue.Value,
|
|
// IsLockedOut = false,
|
|
// LastPasswordFailureDate = SqlDateTime.MinValue.Value
|
|
// };
|
|
|
|
// context.Users.Add(newUser);
|
|
// context.SaveChanges();
|
|
// return token;
|
|
// }
|
|
//}
|
|
|
|
#endregion
|
|
|
|
#region Not Supported
|
|
|
|
//CodeFirstMembershipProvider does not support password retrieval scenarios.
|
|
public override bool EnablePasswordRetrieval
|
|
{
|
|
get { return false; }
|
|
}
|
|
|
|
//CodeFirstMembershipProvider does not support password reset scenarios.
|
|
public override bool EnablePasswordReset
|
|
{
|
|
get { return false; }
|
|
}
|
|
|
|
//CodeFirstMembershipProvider does not support question and answer scenarios.
|
|
public override bool RequiresQuestionAndAnswer
|
|
{
|
|
get { return false; }
|
|
}
|
|
|
|
public override string GetPassword(string username, string answer)
|
|
{
|
|
throw new NotSupportedException("Consider using methods from WebSecurity module.");
|
|
}
|
|
|
|
public override string ResetPassword(string username, string answer)
|
|
{
|
|
throw new NotSupportedException("Consider using methods from WebSecurity module.");
|
|
}
|
|
|
|
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion,
|
|
string newPasswordAnswer)
|
|
{
|
|
throw new NotSupportedException("Consider using methods from WebSecurity module.");
|
|
}
|
|
|
|
//CodeFirstMembershipProvider does not support UpdateUser because this method is useless.
|
|
public override void UpdateUser(MembershipUser user)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |