Code First Membership Provider before Migration

This commit is contained in:
2012-12-18 15:17:00 -05:00
parent 2bcca06b7e
commit 9f6e2a0702
12 changed files with 1224 additions and 10 deletions
@@ -1,13 +1,22 @@
using System.Data.Entity;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using MileageTraker.Web.Models;
namespace MileageTraker.Web.Models
namespace MileageTraker.Web.Context
{
public class MileageTrakerContext : DbContext
{
public DbSet<Log> Logs { get; set; }
public DbSet<Vehicle> Vehicles { get; set; }
public DbSet<City> Cities { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
/*
* WebSecurity.Register("Demo", "123456", "demo@demo.com", true, "Demo", "Demo");
Roles.CreateRole("Admin");
Roles.AddUserToRole("Demo", "Admin");
*/
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
+1
View File
@@ -4,6 +4,7 @@ using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using MileageTraker.Web.Context;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
using MileageTraker.Web.ViewModels;
+1
View File
@@ -3,6 +3,7 @@ using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Web;
using MileageTraker.Web.Context;
using MileageTraker.Web.Models;
namespace MileageTraker.Web.DAL
@@ -0,0 +1,550 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Web;
using System.Web.Security;
using MileageTraker.Web.Context;
using MileageTraker.Web.Models;
namespace MileageTraker.Web.Membership
{
public class CodeFirstMembershipProvider : MembershipProvider
{
#region Properties
private const int TokenSizeInBytes = 16;
public override string ApplicationName
{
get { return GetType().Assembly.GetName().Name; }
set { 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(password))
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
if (string.IsNullOrEmpty(email))
{
status = MembershipCreateStatus.InvalidEmail;
return null;
}
var hashedPassword = Crypto.HashPassword(password);
if (hashedPassword.Length > 128)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
using (var context = new MileageTrakerContext())
{
if (context.Users.Any(usr => usr.Username == username))
{
status = MembershipCreateStatus.DuplicateUserName;
return null;
}
if (context.Users.Any(usr => usr.Email == email))
{
status = MembershipCreateStatus.DuplicateEmail;
return null;
}
var newUser = new User
{
UserId = Guid.NewGuid(),
Username = username,
Password = hashedPassword,
IsApproved = isApproved,
Email = email,
CreateDate = DateTime.UtcNow,
LastPasswordChangedDate = DateTime.UtcNow,
PasswordFailuresSinceLastSuccess = 0,
LastLoginDate = DateTime.UtcNow,
LastActivityDate = DateTime.UtcNow,
LastLockoutDate = DateTime.UtcNow,
IsLockedOut = false,
LastPasswordFailureDate = DateTime.UtcNow
};
context.Users.Add(newUser);
context.SaveChanges();
status = MembershipCreateStatus.Success;
return new MembershipUser(System.Web.Security.Membership.Provider.Name, newUser.Username, newUser.UserId,
newUser.Email, null, null,
newUser.IsApproved, newUser.IsLockedOut, newUser.CreateDate.Value,
newUser.LastLoginDate.Value, newUser.LastActivityDate.Value,
newUser.LastPasswordChangedDate.Value, newUser.LastLockoutDate.Value);
}
}
public string CreateUserAndAccount(string userName, string password, bool requireConfirmation,
IDictionary<string, object> values)
{
return CreateAccount(userName, password, requireConfirmation);
}
public override bool ValidateUser(string username, string password)
{
if (string.IsNullOrEmpty(username))
{
return false;
}
if (string.IsNullOrEmpty(password))
{
return false;
}
using (var context = new MileageTrakerContext())
{
User user = context.Users.FirstOrDefault(usr => usr.Username == username);
if (user == null)
{
return false;
}
if (!user.IsApproved)
{
return false;
}
if (user.IsLockedOut)
{
return false;
}
var hashedPassword = user.Password;
var verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, password));
if (verificationSucceeded)
{
user.PasswordFailuresSinceLastSuccess = 0;
user.LastLoginDate = DateTime.UtcNow;
user.LastActivityDate = DateTime.UtcNow;
}
else
{
var failures = user.PasswordFailuresSinceLastSuccess;
if (failures < MaxInvalidPasswordAttempts)
{
user.PasswordFailuresSinceLastSuccess += 1;
user.LastPasswordFailureDate = DateTime.UtcNow;
}
else if (failures >= MaxInvalidPasswordAttempts)
{
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastLockoutDate = DateTime.UtcNow;
user.IsLockedOut = true;
}
}
context.SaveChanges();
return verificationSucceeded;
}
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
if (string.IsNullOrEmpty(username))
{
return null;
}
using (var context = new MileageTrakerContext())
{
User user = context.Users.FirstOrDefault(Usr => Usr.Username == username);
if (user == null)
{
return null;
}
if (userIsOnline)
{
user.LastActivityDate = DateTime.UtcNow;
context.SaveChanges();
}
return new MembershipUser(System.Web.Security.Membership.Provider.Name, user.Username, user.UserId, user.Email,
null, null,
user.IsApproved, user.IsLockedOut, user.CreateDate.Value, user.LastLoginDate.Value,
user.LastActivityDate.Value, user.LastPasswordChangedDate.Value,
user.LastLockoutDate.Value);
}
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
if (providerUserKey is Guid)
{
}
else
{
return null;
}
using (var context = new MileageTrakerContext())
{
User user;
user = context.Users.Find(providerUserKey);
if (user == null)
{
return null;
}
if (userIsOnline)
{
user.LastActivityDate = DateTime.UtcNow;
context.SaveChanges();
}
return new MembershipUser(System.Web.Security.Membership.Provider.Name, user.Username, user.UserId, user.Email,
null, null,
user.IsApproved, user.IsLockedOut, user.CreateDate.Value, user.LastLoginDate.Value,
user.LastActivityDate.Value, user.LastPasswordChangedDate.Value,
user.LastLockoutDate.Value);
}
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
if (string.IsNullOrEmpty(username))
{
return false;
}
if (string.IsNullOrEmpty(oldPassword))
{
return false;
}
if (string.IsNullOrEmpty(newPassword))
{
return false;
}
using (var context = new MileageTrakerContext())
{
User user = context.Users.FirstOrDefault(Usr => Usr.Username == username);
if (user == null)
{
return false;
}
var hashedPassword = user.Password;
var verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, oldPassword));
if (verificationSucceeded)
{
user.PasswordFailuresSinceLastSuccess = 0;
}
else
{
var failures = user.PasswordFailuresSinceLastSuccess;
if (failures < MaxInvalidPasswordAttempts)
{
user.PasswordFailuresSinceLastSuccess += 1;
user.LastPasswordFailureDate = DateTime.UtcNow;
}
else if (failures >= MaxInvalidPasswordAttempts)
{
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastLockoutDate = DateTime.UtcNow;
user.IsLockedOut = true;
}
context.SaveChanges();
return false;
}
var newHashedPassword = Crypto.HashPassword(newPassword);
if (newHashedPassword.Length > 128)
{
return false;
}
user.Password = newHashedPassword;
user.LastPasswordChangedDate = DateTime.UtcNow;
context.SaveChanges();
return true;
}
}
public override bool UnlockUser(string userName)
{
using (var context = new MileageTrakerContext())
{
var user = context.Users.FirstOrDefault(Usr => Usr.Username == userName);
if (user != null)
{
user.IsLockedOut = false;
user.PasswordFailuresSinceLastSuccess = 0;
context.SaveChanges();
return true;
}
return false;
}
}
public override int GetNumberOfUsersOnline()
{
var dateActive =
DateTime.UtcNow.Subtract(
TimeSpan.FromMinutes(Convert.ToDouble(System.Web.Security.Membership.UserIsOnlineTimeWindow)));
using (var context = new MileageTrakerContext())
{
return context.Users.Count(usr => usr.LastActivityDate > dateActive);
}
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
if (string.IsNullOrEmpty(username))
{
return false;
}
using (var Context = new MileageTrakerContext())
{
var user = Context.Users.FirstOrDefault(Usr => Usr.Username == username);
if (user != null)
{
Context.Users.Remove(user);
Context.SaveChanges();
return true;
}
return false;
}
}
public override string GetUserNameByEmail(string email)
{
using (var context = new MileageTrakerContext())
{
var user = context.Users.FirstOrDefault(usr => usr.Email == 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 MileageTrakerContext())
{
totalRecords = context.Users.Count(Usr => Usr.Email == emailToMatch);
var users =
context.Users.Where(usr => usr.Email == emailToMatch)
.OrderBy(usrn => usrn.Username)
.Skip(pageIndex*pageSize)
.Take(pageSize);
foreach (var user in users)
{
membershipUsers.Add(new MembershipUser(System.Web.Security.Membership.Provider.Name, user.Username, user.UserId,
user.Email, null, null,
user.IsApproved, user.IsLockedOut, user.CreateDate.Value,
user.LastLoginDate.Value, user.LastActivityDate.Value,
user.LastPasswordChangedDate.Value, user.LastLockoutDate.Value));
}
}
return membershipUsers;
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize,
out int totalRecords)
{
var MembershipUsers = new MembershipUserCollection();
using (var Context = new MileageTrakerContext())
{
totalRecords = Context.Users.Where(Usr => Usr.Username == usernameToMatch).Count();
var Users =
Context.Users.Where(Usr => Usr.Username == usernameToMatch)
.OrderBy(Usrn => Usrn.Username)
.Skip(pageIndex*pageSize)
.Take(pageSize);
foreach (var user in Users)
{
MembershipUsers.Add(new MembershipUser(System.Web.Security.Membership.Provider.Name, user.Username, user.UserId,
user.Email, null, null,
user.IsApproved, user.IsLockedOut, user.CreateDate.Value,
user.LastLoginDate.Value, user.LastActivityDate.Value,
user.LastPasswordChangedDate.Value, user.LastLockoutDate.Value));
}
}
return MembershipUsers;
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
var MembershipUsers = new MembershipUserCollection();
using (var Context = new MileageTrakerContext())
{
totalRecords = Context.Users.Count();
var Users = Context.Users.OrderBy(Usrn => Usrn.Username).Skip(pageIndex*pageSize).Take(pageSize);
foreach (var user in Users)
{
MembershipUsers.Add(new MembershipUser(System.Web.Security.Membership.Provider.Name, user.Username, user.UserId,
user.Email, null, null,
user.IsApproved, user.IsLockedOut, user.CreateDate.Value,
user.LastLoginDate.Value, user.LastActivityDate.Value,
user.LastPasswordChangedDate.Value, user.LastLockoutDate.Value));
}
}
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.Where(Usr => Usr.Username == userName).Any())
{
throw new MembershipCreateUserException(MembershipCreateStatus.DuplicateUserName);
}
var token = string.Empty;
if (requireConfirmationToken)
{
token = GenerateToken();
}
var NewUser = new User
{
UserId = Guid.NewGuid(),
Username = userName,
Password = hashedPassword,
IsApproved = !requireConfirmationToken,
Email = string.Empty,
CreateDate = DateTime.UtcNow,
LastPasswordChangedDate = DateTime.UtcNow,
PasswordFailuresSinceLastSuccess = 0,
LastLoginDate = DateTime.UtcNow,
LastActivityDate = DateTime.UtcNow,
LastLockoutDate = DateTime.UtcNow,
IsLockedOut = false,
LastPasswordFailureDate = DateTime.UtcNow,
ConfirmationToken = token
};
Context.Users.Add(NewUser);
Context.SaveChanges();
return token;
}
}
private static string GenerateToken()
{
using (var prng = new RNGCryptoServiceProvider())
{
return GenerateToken(prng);
}
}
internal static string GenerateToken(RandomNumberGenerator generator)
{
var tokenBytes = new byte[TokenSizeInBytes];
generator.GetBytes(tokenBytes);
return HttpServerUtility.UrlTokenEncode(tokenBytes);
}
#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
}
}
+217
View File
@@ -0,0 +1,217 @@
using System;
using System.Linq;
using System.Web.Security;
using MileageTraker.Web.Context;
using MileageTraker.Web.Models;
namespace MileageTraker.Web.Membership
{
public class CodeFirstRoleProvider : RoleProvider
{
public override string ApplicationName
{
get { return GetType().Assembly.GetName().Name; }
set { ApplicationName = GetType().Assembly.GetName().Name; }
}
public override bool RoleExists(string roleName)
{
if (string.IsNullOrEmpty(roleName))
{
return false;
}
using (var context = new MileageTrakerContext())
{
Role role = context.Roles.FirstOrDefault(rl => rl.RoleName == roleName);
return role != null;
}
}
public override bool IsUserInRole(string username, string roleName)
{
if (string.IsNullOrEmpty(username))
{
return false;
}
if (string.IsNullOrEmpty(roleName))
{
return false;
}
using (var context = new MileageTrakerContext())
{
User user;
user = context.Users.FirstOrDefault(usr => usr.Username == username);
if (user == null)
{
return false;
}
var role = context.Roles.FirstOrDefault(rl => rl.RoleName == roleName);
if (role == null)
{
return false;
}
return user.Roles.Contains(role);
}
}
public override string[] GetAllRoles()
{
using (var context = new MileageTrakerContext())
{
return context.Roles.Select(rl => rl.RoleName).ToArray();
}
}
public override string[] GetUsersInRole(string roleName)
{
if (string.IsNullOrEmpty(roleName))
{
return null;
}
using (var context = new MileageTrakerContext())
{
Role role = context.Roles.FirstOrDefault(rl => rl.RoleName == roleName);
if (role != null)
{
return role.Users.Select(usr => usr.Username).ToArray();
}
return null;
}
}
public override string[] GetRolesForUser(string username)
{
if (string.IsNullOrEmpty(username))
{
return null;
}
using (var context = new MileageTrakerContext())
{
User user;
user = context.Users.FirstOrDefault(Usr => Usr.Username == username);
if (user != null)
{
return user.Roles.Select(rl => rl.RoleName).ToArray();
}
return null;
}
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
if (string.IsNullOrEmpty(roleName))
{
return null;
}
if (string.IsNullOrEmpty(usernameToMatch))
{
return null;
}
using (var context = new MileageTrakerContext())
{
return (from rl in context.Roles
from usr in rl.Users
where rl.RoleName == roleName && usr.Username.Contains(usernameToMatch)
select usr.Username).ToArray();
}
}
public override void CreateRole(string roleName)
{
if (!string.IsNullOrEmpty(roleName))
{
using (var context = new MileageTrakerContext())
{
Role role = context.Roles.FirstOrDefault(rl => rl.RoleName == roleName);
if (role == null)
{
var newRole = new Role
{
RoleId = Guid.NewGuid(),
RoleName = roleName
};
context.Roles.Add(newRole);
context.SaveChanges();
}
}
}
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
if (string.IsNullOrEmpty(roleName))
{
return false;
}
using (var context = new MileageTrakerContext())
{
var role = context.Roles.FirstOrDefault(rl => rl.RoleName == roleName);
if (role == null)
{
return false;
}
if (throwOnPopulatedRole)
{
if (role.Users.Any())
{
return false;
}
}
else
{
role.Users.Clear();
}
context.Roles.Remove(role);
context.SaveChanges();
return true;
}
}
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
using (var context = new MileageTrakerContext())
{
var users = context.Users.Where(usr => usernames.Contains(usr.Username)).ToList();
var roles = context.Roles.Where(rl => roleNames.Contains(rl.RoleName)).ToList();
foreach (var user in users)
{
foreach (var role in roles)
{
if (!user.Roles.Contains(role))
{
user.Roles.Add(role);
}
}
}
context.SaveChanges();
}
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
using (var context = new MileageTrakerContext())
{
foreach (var username in usernames)
{
var us = username;
var user = context.Users.FirstOrDefault(u => u.Username == us);
if (user != null)
{
foreach (var roleName in roleNames)
{
var rl = roleName;
var role = user.Roles.FirstOrDefault(r => r.RoleName == rl);
if (role != null)
{
user.Roles.Remove(role);
}
}
}
}
context.SaveChanges();
}
}
}
}
+171
View File
@@ -0,0 +1,171 @@
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
namespace MileageTraker.Web.Membership
{
public static class Crypto
{
private const int TokenSizeInBytes = 16;
private const int Pbkdf2Count = 1000;
private const int Pbkdf2SubkeyLength = 256/8;
private const int SaltSize = 128/8;
public static string GenerateSalt(int byteLength = SaltSize)
{
var Buff = new byte[byteLength];
using (var Prng = new RNGCryptoServiceProvider())
{
Prng.GetBytes(Buff);
}
return Convert.ToBase64String(Buff);
}
public static string Hash(string input, string algorithm = "sha256")
{
if (input == null)
{
throw new ArgumentNullException("input");
}
return Hash(Encoding.UTF8.GetBytes(input), algorithm);
}
public static string Hash(byte[] input, string algorithm = "sha256")
{
if (input == null)
{
throw new ArgumentNullException("input");
}
using (HashAlgorithm alg = HashAlgorithm.Create(algorithm))
{
if (alg != null)
{
byte[] hashData = alg.ComputeHash(input);
return BinaryToHex(hashData);
}
else
{
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "not supported hash alg", algorithm));
}
}
}
public static string SHA1(string input)
{
return Hash(input, "sha1");
}
public static string SHA256(string input)
{
return Hash(input, "sha256");
}
/* =======================
* HASHED PASSWORD FORMATS
* =======================
*
* Version 0:
* PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations.
* (See also: SDL crypto guidelines v5.1, Part III)
* Format: { 0x00, salt, subkey }
*/
public static string HashPassword(string password)
{
if (password == null)
{
throw new ArgumentNullException("password");
}
byte[] salt;
byte[] subkey;
using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, Pbkdf2Count))
{
salt = deriveBytes.Salt;
subkey = deriveBytes.GetBytes(Pbkdf2SubkeyLength);
}
var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength];
Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, Pbkdf2SubkeyLength);
return Convert.ToBase64String(outputBytes);
}
// hashedPassword must be of the format of HashWithPassword (salt + Hash(salt+input)
public static bool VerifyHashedPassword(string hashedPassword, string password)
{
if (hashedPassword == null)
{
throw new ArgumentNullException("hashedPassword");
}
if (password == null)
{
throw new ArgumentNullException("password");
}
byte[] hashedPasswordBytes = Convert.FromBase64String(hashedPassword);
// Verify a version 0 (see comment above) password hash.
if (hashedPasswordBytes.Length != (1 + SaltSize + Pbkdf2SubkeyLength) || hashedPasswordBytes[0] != 0x00)
{
// Wrong length or version header.
return false;
}
var salt = new byte[SaltSize];
Buffer.BlockCopy(hashedPasswordBytes, 1, salt, 0, SaltSize);
var storedSubkey = new byte[Pbkdf2SubkeyLength];
Buffer.BlockCopy(hashedPasswordBytes, 1 + SaltSize, storedSubkey, 0, Pbkdf2SubkeyLength);
byte[] generatedSubkey;
using (var deriveBytes = new Rfc2898DeriveBytes(password, salt, Pbkdf2Count))
{
generatedSubkey = deriveBytes.GetBytes(Pbkdf2SubkeyLength);
}
return ByteArraysEqual(storedSubkey, generatedSubkey);
}
internal static string BinaryToHex(byte[] data)
{
var hex = new char[data.Length*2];
for (int iter = 0; iter < data.Length; iter++)
{
var hexChar = ((byte) (data[iter] >> 4));
hex[iter*2] = (char) (hexChar > 9 ? hexChar + 0x37 : hexChar + 0x30);
hexChar = ((byte) (data[iter] & 0xF));
hex[iter*2 + 1] = (char) (hexChar > 9 ? hexChar + 0x37 : hexChar + 0x30);
}
return new string(hex);
}
// Compares two byte arrays for equality. The method is specifically written so that the loop is not optimized.
[MethodImpl(MethodImplOptions.NoOptimization)]
private static bool ByteArraysEqual(byte[] a, byte[] b)
{
if (ReferenceEquals(a, b))
{
return true;
}
if (a == null || b == null || a.Length != b.Length)
{
return false;
}
bool areSame = true;
for (int i = 0; i < a.Length; i++)
{
areSame &= (a[i] == b[i]);
}
return areSame;
}
}
}
+186
View File
@@ -0,0 +1,186 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Routing;
using System.Web.Security;
using MileageTraker.Web.Context;
namespace MileageTraker.Web.Membership
{
public sealed class WebSecurity
{
public static HttpContextBase Context
{
get { return new HttpContextWrapper(HttpContext.Current); }
}
public static HttpRequestBase Request
{
get { return Context.Request; }
}
public static HttpResponseBase Response
{
get { return Context.Response; }
}
public static IPrincipal User
{
get { return Context.User; }
}
public static bool IsAuthenticated
{
get { return User.Identity.IsAuthenticated; }
}
public static MembershipCreateStatus Register(string username, string password, string email, bool isApproved,
string firstName, string lastName)
{
MembershipCreateStatus createStatus;
System.Web.Security.Membership.CreateUser(username, password, email, null, null, isApproved, Guid.NewGuid(),
out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
using (var context = new MileageTrakerContext())
{
var user = context.Users.FirstOrDefault(usr => usr.Username == username);
user.FirstName = firstName;
user.LastName = lastName;
context.SaveChanges();
}
if (isApproved)
{
FormsAuthentication.SetAuthCookie(username, false);
}
}
return createStatus;
}
public static Boolean Login(string username, string password, bool persistCookie = false)
{
var success = System.Web.Security.Membership.ValidateUser(username, password);
if (success)
{
FormsAuthentication.SetAuthCookie(username, persistCookie);
}
return success;
}
public static void Logout()
{
FormsAuthentication.SignOut();
}
public static MembershipUser GetUser(string username)
{
return System.Web.Security.Membership.GetUser(username);
}
public static bool ChangePassword(string userName, string currentPassword, string newPassword)
{
var success = false;
try
{
var currentUser = System.Web.Security.Membership.GetUser(userName, true);
success = currentUser.ChangePassword(currentPassword, newPassword);
}
catch (ArgumentException)
{
}
return success;
}
public static bool DeleteUser(string username)
{
return System.Web.Security.Membership.DeleteUser(username);
}
public static int GetUserId(string userName)
{
var user = System.Web.Security.Membership.GetUser(userName);
return (int) user.ProviderUserKey;
}
public static string CreateAccount(string userName, string password)
{
return CreateAccount(userName, password, requireConfirmationToken: false);
}
public static string CreateAccount(string userName, string password, bool requireConfirmationToken = false)
{
var codeFirstMembership = System.Web.Security.Membership.Provider as CodeFirstMembershipProvider;
return codeFirstMembership.CreateAccount(userName, password, requireConfirmationToken);
}
public static string CreateUserAndAccount(string userName, string password)
{
return CreateUserAndAccount(userName, password, propertyValues: null, requireConfirmationToken: false);
}
public static string CreateUserAndAccount(string userName, string password, bool requireConfirmation)
{
return CreateUserAndAccount(userName, password, propertyValues: null, requireConfirmationToken: requireConfirmation);
}
public static string CreateUserAndAccount(string userName, string password, IDictionary<string, object> values)
{
return CreateUserAndAccount(userName, password, propertyValues: values, requireConfirmationToken: false);
}
public static string CreateUserAndAccount(string userName, string password, object propertyValues = null,
bool requireConfirmationToken = false)
{
var codeFirstMembership = System.Web.Security.Membership.Provider as CodeFirstMembershipProvider;
IDictionary<string, object> values = null;
if (propertyValues != null)
{
values = new RouteValueDictionary(propertyValues);
}
return codeFirstMembership.CreateUserAndAccount(userName, password, requireConfirmationToken, values);
}
public static List<MembershipUser> FindUsersByEmail(string Email, int PageIndex, int PageSize)
{
int totalRecords;
return
System.Web.Security.Membership.FindUsersByEmail(Email, PageIndex, PageSize, out totalRecords)
.Cast<MembershipUser>()
.ToList();
}
public static List<MembershipUser> FindUsersByName(string Username, int PageIndex, int PageSize)
{
int totalRecords;
return
System.Web.Security.Membership.FindUsersByName(Username, PageIndex, PageSize, out totalRecords)
.Cast<MembershipUser>()
.ToList();
}
public static List<MembershipUser> GetAllUsers(int PageIndex, int PageSize)
{
int totalRecords;
return
System.Web.Security.Membership.GetAllUsers(PageIndex, PageSize, out totalRecords).Cast<MembershipUser>().ToList();
}
public static void InitializeDatabaseConnection(string connectionStringName, string userTableName, string userIdColumn,
string userNameColumn, bool autoCreateTables)
{
}
public static void InitializeDatabaseConnection(string connectionString, string providerName, string userTableName,
string userIdColumn, string userNameColumn, bool autoCreateTables)
{
}
}
}
+4 -5
View File
@@ -1,18 +1,17 @@
using MileageTraker.Web.Context;
namespace MileageTraker.Web.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<Models.MileageTrakerContext>
internal sealed class Configuration : DbMigrationsConfiguration<MileageTrakerContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(MileageTraker.Web.Models.MileageTrakerContext context)
protected override void Seed(MileageTrakerContext context)
{
// This method will be called after migrating to the latest version.
+19
View File
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace MileageTraker.Web.Models
{
public class Role
{
[Key]
public virtual Guid RoleId { get; set; }
[Required]
public virtual string RoleName { get; set; }
public virtual string Description { get; set; }
public virtual ICollection<User> Users { get; set; }
}
}
+41
View File
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace MileageTraker.Web.Models
{
public class User
{
[Key]
public virtual Guid UserId { get; set; }
[Required]
public virtual String Username { get; set; }
public virtual String Email { get; set; }
[Required, DataType(DataType.Password)]
public virtual String Password { get; set; }
public virtual String FirstName { get; set; }
public virtual String LastName { get; set; }
[DataType(DataType.MultilineText)]
public virtual String Comment { get; set; }
public virtual Boolean IsApproved { get; set; }
public virtual int PasswordFailuresSinceLastSuccess { get; set; }
public virtual DateTime? LastPasswordFailureDate { get; set; }
public virtual DateTime? LastActivityDate { get; set; }
public virtual DateTime? LastLockoutDate { get; set; }
public virtual DateTime? LastLoginDate { get; set; }
public virtual String ConfirmationToken { get; set; }
public virtual DateTime? CreateDate { get; set; }
public virtual Boolean IsLockedOut { get; set; }
public virtual DateTime? LastPasswordChangedDate { get; set; }
public virtual String PasswordVerificationToken { get; set; }
public virtual DateTime? PasswordVerificationTokenExpirationDate { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
}
+14 -2
View File
@@ -12,6 +12,7 @@
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="enableSimpleMembership" value="false" />
</appSettings>
<system.web>
<customErrors mode="RemoteOnly" />
@@ -34,6 +35,17 @@
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
<membership defaultProvider="CodeFirstMembershipProvider">
<providers>
<add name="CodeFirstMembershipProvider" type="MileageTraker.Web.Membership.CodeFirstMembershipProvider" connectionStringName="MileageTrakerContext" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="CodeFirstRoleProvider">
<providers>
<clear />
<add name="CodeFirstRoleProvider" type="MileageTraker.Web.Membership.CodeFirstRoleProvider" connectionStringName="MileageTrakerContext" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
@@ -43,11 +55,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="4.0.0.0"/>
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+9 -1
View File
@@ -67,7 +67,9 @@
<Reference Include="MoreLinq, Version=1.0.11522.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\morelinq.1.0\lib\net35\MoreLinq.dll</HintPath>
</Reference>
<Reference Include="System.configuration" />
<Reference Include="System.Data.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll</HintPath>
@@ -105,9 +107,14 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Context\MileageTrakerContext.cs" />
<Compile Include="Controllers\CityController.cs" />
<Compile Include="Controllers\ControllerBase.cs" />
<Compile Include="Controllers\EmployeeController.cs" />
<Compile Include="Membership\CodeFirstMembershipProvider.cs" />
<Compile Include="Membership\CodeFirstRoleProvider.cs" />
<Compile Include="Membership\Crypto.cs" />
<Compile Include="Membership\WebSecurity.cs" />
<Compile Include="Migrations\201204181847082_InitialMigration.cs" />
<Compile Include="Migrations\201204181847082_InitialMigration.Designer.cs">
<DependentUpon>201204181847082_InitialMigration.cs</DependentUpon>
@@ -117,6 +124,8 @@
<DependentUpon>201212042021486_AddVehiclePreviousLog.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\Configuration.cs" />
<Compile Include="Models\Role.cs" />
<Compile Include="Models\User.cs" />
<Compile Include="Utility\ActionLogAttribute.cs" />
<Compile Include="Utility\HttpParamActionAttribute.cs" />
<Compile Include="ViewModels\EmployeeMileageItem.cs" />
@@ -140,7 +149,6 @@
<Compile Include="Models\City.cs" />
<Compile Include="Models\Log.cs" />
<Compile Include="Models\MileageLogType.cs" />
<Compile Include="Models\MileageTrakerContext.cs" />
<Compile Include="Models\Vehicle.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utility\CustomExtensions.cs" />