Create User works

This commit is contained in:
2012-12-27 22:04:21 -05:00
parent 05d1ae4ec6
commit 7eff2f343a
32 changed files with 615 additions and 583 deletions
@@ -1,4 +1,4 @@
using MileageTraker.Web.Membership;
using MileageTraker.Web.Utility;
using NUnit.Framework;
namespace Web.Tests.Membership
@@ -12,14 +12,12 @@ namespace Web.Tests.ViewModels
var vm = new CreateUserViewModel();
var email = vm.Email = "bob@dobalina.com";
var firstName = vm.FirstName = "bob";
var lastName = vm.LastName = "dobalina";
var userName = vm.Username = "bob dobalina";
var user = vm.CloneToUser();
var user = vm.ToUser();
Assert.That(user.Email, Is.EqualTo(email));
Assert.That(user.FirstName, Is.EqualTo(firstName));
Assert.That(user.LastName, Is.EqualTo(lastName));
Assert.That(user.Username, Is.EqualTo(userName));
}
}
}
+1 -1
View File
@@ -84,7 +84,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DAL\VehicleImporterTests.cs" />
<Compile Include="Membership\CryptoTests.cs" />
<Compile Include="Utility\CryptoTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utility\AlgorithmsTests.cs" />
<Compile Include="Utility\CustomExtensionsTests.cs" />
+4
View File
@@ -6,6 +6,10 @@
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
+20
View File
@@ -0,0 +1,20 @@
using System.Web.Mvc;
using MileageTraker.Web.DAL;
namespace MileageTraker.Web.Attributes
{
public class UserActivityAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext != null)
{
using (var ds = new DataService())
{
ds.UpdateUserLastActivity(filterContext.HttpContext.User.Identity.Name);
}
}
base.OnActionExecuting(filterContext);
}
}
}
+44 -5
View File
@@ -3,6 +3,20 @@ body {
padding-top: 60px;
}
#content > form {
max-width: 400px;
padding: 10px;
margin: 0 auto 20px;
background-color: whitesmoke;
border: 1px solid #e5e5e5;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.05);
box-shadow: 0 1px 2px rgba(0,0,0,.05);
}
.brand
{
background: url(images/Header.png) no-repeat left center;
@@ -42,6 +56,23 @@ body {
margin: 0;
}
.breadcrumb {
display: inline-block;
margin-bottom: 10px;
}
.form-horizontal .control-label {
width: 140px;
}
.form-horizontal .controls {
margin-left: 160px;
}
.form-horizontal .control-group {
margin-bottom: 10px;
}
footer {
background-color: #101010;
color: #666;
@@ -137,10 +168,17 @@ dl.inline {
padding: 0;
}
.container-fluid {
#content {
padding: 0 10px;
}
.navbar .container-fluid {
padding: 0 10px;
}
.navbar .brand {
}
.input-mini {
width: 60px !important;
}
@@ -166,20 +204,21 @@ dl.inline {
padding: 0;
}
.container-fluid {
#content {
padding: 0 10px;
}
.brand {
background: url(images/Header.mobile.png) no-repeat left center;
height: 28px;
width: 205px;
}
.navbar .container-fluid {
padding: 0 10px;
}
.navbar .brand {
margin-left: 5px;
padding: 10px 0;
}
fieldset legend {
+37 -37
View File
@@ -1,7 +1,6 @@
using System;
using System.Web.Mvc;
using System.Web.Security;
using MileageTraker.Web.Membership;
using MileageTraker.Web.ViewModels.Account;
namespace MileageTraker.Web.Controllers
@@ -21,11 +20,16 @@ namespace MileageTraker.Web.Controllers
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.EmailAddress, model.Password, model.RememberMe))
if (ModelState.IsValid)
{
var success = Membership.ValidateUser(model.Username, model.Password);
if (success)
{
FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
// TODO: send notification to user
return RedirectToLocal(returnUrl);
}
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
@@ -36,48 +40,47 @@ namespace MileageTraker.Web.Controllers
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
WebSecurity.Logout();
FormsAuthentication.SignOut();
// TODO: send notification to user
return RedirectToAction("Index", "CreateLog");
}
[AllowAnonymous]
public ActionResult Register()
{
return View();
}
//[AllowAnonymous]
//public ActionResult Register()
//{
// return View();
//}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Login");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
//[HttpPost]
//[AllowAnonymous]
//[ValidateAntiForgeryToken]
//public ActionResult Register(RegisterModel model)
//{
// if (ModelState.IsValid)
// {
// // Attempt to register the user
// try
// {
// WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
// WebSecurity.Login(model.UserName, model.Password);
// return RedirectToAction("Login");
// }
// catch (MembershipCreateUserException e)
// {
// ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
// }
// }
// If we got this far, something failed, redisplay form
return View(model);
}
// // If we got this far, something failed, redisplay form
// return View(model);
//}
public ActionResult Manage(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: "";
ViewBag.ReturnUrl = Url.Action("Manage");
return View();
@@ -95,9 +98,10 @@ namespace MileageTraker.Web.Controllers
bool changePasswordSucceeded;
try
{
changePasswordSucceeded = WebSecurity.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);
var currentUser = Membership.GetUser(User.Identity.Name, true);
changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
}
catch (Exception ex)
catch (Exception)
{
changePasswordSucceeded = false;
}
@@ -106,11 +110,8 @@ namespace MileageTraker.Web.Controllers
{
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
}
else
{
ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
@@ -129,7 +130,6 @@ namespace MileageTraker.Web.Controllers
{
ChangePasswordSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
}
private static string ErrorCodeToString(MembershipCreateStatus createStatus)
+85 -13
View File
@@ -1,14 +1,15 @@
using System;
using System.Data;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.Models;
using MileageTraker.Web.Context;
using MileageTraker.Web.ViewModels.User;
namespace MileageTraker.Web.Controllers
{
[Authorize(Roles = "Administrator, Developer")]
[UserActivity]
public class UserController : ControllerBase
{
public ActionResult Index()
@@ -18,32 +19,66 @@ namespace MileageTraker.Web.Controllers
public ActionResult Details(Guid id)
{
var user = DataService.GetUser(id);
var user = Membership.GetUser(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
return View(DataService.GetUser(id));
}
public ActionResult Create()
{
return View();
var vm = new CreateUserViewModel
{
AvailableRoles = Roles.GetAllRoles()
};
return View(vm);
}
[HttpPost]
public ActionResult Create(CreateUserViewModel createUserViewModel)
public ActionResult Create(CreateUserViewModel viewModel)
{
if (ModelState.IsValid)
{
var user = createUserViewModel.CloneToUser();
user.UserId = Guid.NewGuid();
//db.Users.Add(user);
//db.SaveChanges();
var hasRoles = viewModel.Roles != null && viewModel.Roles.Any();
MembershipCreateStatus membershipCreateStatus;
var membershipUser =
Membership.CreateUser(
viewModel.Username,
viewModel.Password,
viewModel.Email,
null,
null,
hasRoles,
out membershipCreateStatus);
if (membershipUser == null)
{
ModelState.AddModelError("", ErrorCodeToString(membershipCreateStatus));
viewModel.AvailableRoles = Roles.GetAllRoles();
return View(viewModel);
}
if (hasRoles)
{
Roles.AddUserToRoles(
membershipUser.UserName,
viewModel.Roles);
}
var user = DataService.GetUser(
(Guid) membershipUser.ProviderUserKey);
user.FullName = viewModel.FullName;
DataService.UpdateUserPersonalInfo(user);
return RedirectToAction("Index");
}
return View(createUserViewModel);
viewModel.AvailableRoles = Roles.GetAllRoles();
return View(viewModel);
}
public ActionResult Edit(Guid id)
@@ -61,11 +96,48 @@ namespace MileageTraker.Web.Controllers
{
if (ModelState.IsValid)
{
//db.Entry(user).State = EntityState.Modified;
//db.SaveChanges();
DataService.UpdateUser(user);
return RedirectToAction("Index");
}
return View(user);
}
private static string ErrorCodeToString(MembershipCreateStatus createStatus)
{
// See http://go.microsoft.com/fwlink/?LinkID=177550 for
// a full list of status codes.
switch (createStatus)
{
case MembershipCreateStatus.DuplicateUserName:
return "User name already exists. Please enter a different user name.";
case MembershipCreateStatus.DuplicateEmail:
return "A user name for that e-mail address already exists. Please enter a different e-mail address.";
case MembershipCreateStatus.InvalidPassword:
return "The password provided is invalid. Please enter a valid password value.";
case MembershipCreateStatus.InvalidEmail:
return "The e-mail address provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidAnswer:
return "The password retrieval answer provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidQuestion:
return "The password retrieval question provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidUserName:
return "The user name provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.ProviderError:
return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
case MembershipCreateStatus.UserRejected:
return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
default:
return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
}
}
}
}
@@ -1,21 +1,15 @@
using System;
using System.Data.SqlTypes;
using System.Linq;
using System.Security.Cryptography;
using System.Web;
using System.Web.Security;
using MileageTraker.Web.Context;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
namespace MileageTraker.Web.Membership
namespace MileageTraker.Web.DAL
{
public class CodeFirstMembershipProvider : MembershipProvider
{
#region Properties
private const int TokenSizeInBytes = 16;
public override string ApplicationName
{
get { return GetType().Assembly.GetName().Name; }
@@ -92,15 +86,15 @@ namespace MileageTraker.Web.Membership
return null;
}
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
if (context.Users.Any(usr => usr.Username == username))
if (context.FindUserByUsername(username) != null)
{
status = MembershipCreateStatus.DuplicateUserName;
return null;
}
if (context.Users.Any(usr => usr.Email == email))
if (context.FindUserByUsername(email) != null)
{
status = MembershipCreateStatus.DuplicateEmail;
return null;
@@ -113,28 +107,16 @@ namespace MileageTraker.Web.Membership
Password = hashedPassword,
IsApproved = isApproved,
Email = email,
CreateDate = DateTime.UtcNow,
LastPasswordChangedDate = DateTime.UtcNow,
PasswordFailuresSinceLastSuccess = 0,
LastLoginDate = DateTime.UtcNow,
LastActivityDate = DateTime.UtcNow,
LastLockoutDate = SqlDateTime.MinValue.Value,
IsLockedOut = false,
LastPasswordFailureDate = SqlDateTime.MinValue.Value
Created = DateTime.Now,
FullName = "Temp Name"
};
context.Users.Add(newUser);
context.SaveChanges();
context.AddUser(newUser);
status = MembershipCreateStatus.Success;
return newUser.CloneToMembershipUser(System.Web.Security.Membership.Provider.Name);
return newUser.ToMembershipUser(Membership.Provider.Name);
}
}
public string CreateUserAndAccount(string userName, string password, bool requireConfirmation)
{
return CreateAccount(userName, password, requireConfirmation);
}
public override bool ValidateUser(string username, string password)
{
if (string.IsNullOrEmpty(username))
@@ -145,9 +127,9 @@ namespace MileageTraker.Web.Membership
{
return false;
}
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
User user = context.Users.FirstOrDefault(usr => usr.Username == username);
var user = context.FindUserByUsername(username);
if (user == null)
{
return false;
@@ -165,8 +147,8 @@ namespace MileageTraker.Web.Membership
if (verificationSucceeded)
{
user.PasswordFailuresSinceLastSuccess = 0;
user.LastLoginDate = DateTime.UtcNow;
user.LastActivityDate = DateTime.UtcNow;
user.LastLoginDate = DateTime.Now;
user.LastActivityDate = DateTime.Now;
}
else
{
@@ -174,16 +156,16 @@ namespace MileageTraker.Web.Membership
if (failures < MaxInvalidPasswordAttempts)
{
user.PasswordFailuresSinceLastSuccess += 1;
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastPasswordFailureDate = DateTime.Now;
}
else if (failures >= MaxInvalidPasswordAttempts)
{
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastLockoutDate = DateTime.UtcNow;
user.LastPasswordFailureDate = DateTime.Now;
user.LastLockoutDate = DateTime.Now;
user.IsLockedOut = true;
}
}
context.SaveChanges();
context.UpdateUser(user);
return verificationSucceeded;
}
}
@@ -194,9 +176,9 @@ namespace MileageTraker.Web.Membership
{
return null;
}
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
var user = context.Users.FirstOrDefault(usr => usr.Username == username);
var user = context.FindUserByUsername(username);
if (user == null)
{
return null;
@@ -204,26 +186,23 @@ namespace MileageTraker.Web.Membership
if (userIsOnline)
{
user.LastActivityDate = DateTime.UtcNow;
context.SaveChanges();
user.LastActivityDate = DateTime.Now;
context.UpdateUser(user);
}
return user.CloneToMembershipUser(System.Web.Security.Membership.Provider.Name);
return user.ToMembershipUser(System.Web.Security.Membership.Provider.Name);
}
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
if (providerUserKey is Guid)
{
}
else
if (!(providerUserKey is Guid))
{
return null;
}
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
var user = context.Users.Find(providerUserKey);
var user = context.GetUser((Guid)providerUserKey);
if (user == null)
{
return null;
@@ -231,20 +210,20 @@ namespace MileageTraker.Web.Membership
if (userIsOnline)
{
user.LastActivityDate = DateTime.UtcNow;
context.SaveChanges();
user.LastActivityDate = DateTime.Now;
context.UpdateUser(user);
}
return user.CloneToMembershipUser(System.Web.Security.Membership.Provider.Name);
return user.ToMembershipUser(System.Web.Security.Membership.Provider.Name);
}
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
public override bool ChangePassword(string username, string currentPassword, string newPassword)
{
if (string.IsNullOrEmpty(username))
{
return false;
}
if (string.IsNullOrEmpty(oldPassword))
if (string.IsNullOrEmpty(currentPassword))
{
return false;
}
@@ -252,15 +231,15 @@ namespace MileageTraker.Web.Membership
{
return false;
}
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
User user = context.Users.FirstOrDefault(usr => usr.Username == username);
var user = context.FindUserByUsername(username);
if (user == null)
{
return false;
}
var hashedPassword = user.Password;
var verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, oldPassword));
var verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, currentPassword));
if (verificationSucceeded)
{
user.PasswordFailuresSinceLastSuccess = 0;
@@ -271,15 +250,15 @@ namespace MileageTraker.Web.Membership
if (failures < MaxInvalidPasswordAttempts)
{
user.PasswordFailuresSinceLastSuccess += 1;
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastPasswordFailureDate = DateTime.Now;
}
else if (failures >= MaxInvalidPasswordAttempts)
{
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastLockoutDate = DateTime.UtcNow;
user.LastPasswordFailureDate = DateTime.Now;
user.LastLockoutDate = DateTime.Now;
user.IsLockedOut = true;
}
context.SaveChanges();
context.UpdateUser(user);
return false;
}
var newHashedPassword = Crypto.HashPassword(newPassword);
@@ -288,22 +267,22 @@ namespace MileageTraker.Web.Membership
return false;
}
user.Password = newHashedPassword;
user.LastPasswordChangedDate = DateTime.UtcNow;
context.SaveChanges();
user.LastPasswordChangedDate = DateTime.Now;
context.UpdateUser(user);
return true;
}
}
public override bool UnlockUser(string userName)
{
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
var user = context.Users.FirstOrDefault(usr => usr.Username == userName);
var user = context.FindUserByUsername(userName);
if (user != null)
{
user.IsLockedOut = false;
user.PasswordFailuresSinceLastSuccess = 0;
context.SaveChanges();
context.UpdateUser(user);
return true;
}
return false;
@@ -313,36 +292,22 @@ namespace MileageTraker.Web.Membership
public override int GetNumberOfUsersOnline()
{
var dateActive = CustomExtensions.UserOnlineThreshold();
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
return context.Users.Count(usr => usr.LastActivityDate > dateActive);
return context.GetUsers().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;
}
throw new NotSupportedException();
}
public override string GetUserNameByEmail(string email)
{
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
var user = context.Users.FirstOrDefault(usr => usr.Email == email);
var user = context.FindUserByEmail(email);
if (user != null)
{
return user.Username;
@@ -355,18 +320,18 @@ namespace MileageTraker.Web.Membership
out int totalRecords)
{
var membershipUsers = new MembershipUserCollection();
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
totalRecords = context.Users.Count(user => user.Email == emailToMatch);
totalRecords = context.GetUsers().Count(user => user.Email == emailToMatch);
var users =
context.Users.Where(usr => usr.Email == emailToMatch)
context.GetUsers().Where(usr => usr.Email == emailToMatch)
.OrderBy(usrn => usrn.Username)
.Skip(pageIndex*pageSize)
.Take(pageSize);
foreach (var user in users)
{
membershipUsers.Add(
user.CloneToMembershipUser(System.Web.Security.Membership.Provider.Name));
user.ToMembershipUser(Membership.Provider.Name));
}
}
return membershipUsers;
@@ -376,17 +341,17 @@ namespace MileageTraker.Web.Membership
out int totalRecords)
{
var membershipUsers = new MembershipUserCollection();
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
totalRecords = context.Users.Count(Usr => Usr.Username == usernameToMatch);
totalRecords = context.GetUsers().Count(usr => usr.Username == usernameToMatch);
var users =
context.Users.Where(usr => usr.Username == usernameToMatch)
context.GetUsers().Where(usr => usr.Username == usernameToMatch)
.OrderBy(usrn => usrn.Username)
.Skip(pageIndex*pageSize)
.Take(pageSize);
foreach (var user in users)
{
membershipUsers.Add(user.CloneToMembershipUser(System.Web.Security.Membership.Provider.Name));
membershipUsers.Add(user.ToMembershipUser(Membership.Provider.Name));
}
}
return membershipUsers;
@@ -395,92 +360,76 @@ namespace MileageTraker.Web.Membership
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
var membershipUsers = new MembershipUserCollection();
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
totalRecords = context.Users.Count();
totalRecords = context.GetUsers().Count();
var users =
context.Users
context.GetUsers()
.OrderBy(usrn => usrn.Username)
.Skip(pageIndex*pageSize)
.Take(pageSize);
foreach (var user in users)
{
membershipUsers.Add(user.CloneToMembershipUser(System.Web.Security.Membership.Provider.Name));
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);
}
//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);
}
// if (string.IsNullOrEmpty(password))
// {
// throw new MembershipCreateUserException(MembershipCreateStatus.InvalidPassword);
// }
var hashedPassword = Crypto.HashPassword(password);
if (hashedPassword.Length > 128)
{
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);
}
// 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 = GenerateToken();
}
// 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,
CreateDate = DateTime.UtcNow,
LastPasswordChangedDate = DateTime.UtcNow,
PasswordFailuresSinceLastSuccess = 0,
LastLoginDate = DateTime.UtcNow,
LastActivityDate = DateTime.UtcNow,
LastLockoutDate = SqlDateTime.MinValue.Value,
IsLockedOut = false,
LastPasswordFailureDate = SqlDateTime.MinValue.Value,
ConfirmationToken = token
};
// 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;
}
}
private static string GenerateToken()
{
using (var prng = new RNGCryptoServiceProvider())
{
return GenerateToken(prng);
}
}
private static string GenerateToken(RandomNumberGenerator generator)
{
var tokenBytes = new byte[TokenSizeInBytes];
generator.GetBytes(tokenBytes);
return HttpServerUtility.UrlTokenEncode(tokenBytes);
}
// context.Users.Add(newUser);
// context.SaveChanges();
// return token;
// }
//}
#endregion
@@ -4,7 +4,7 @@ using System.Web.Security;
using MileageTraker.Web.Context;
using MileageTraker.Web.Models;
namespace MileageTraker.Web.Membership
namespace MileageTraker.Web.DAL
{
public class CodeFirstRoleProvider : RoleProvider
{
@@ -101,6 +101,7 @@ namespace MileageTraker.Web.Membership
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotSupportedException();
if (string.IsNullOrEmpty(roleName))
{
return null;
@@ -122,6 +123,7 @@ namespace MileageTraker.Web.Membership
public override void CreateRole(string roleName)
{
throw new NotSupportedException();
if (!string.IsNullOrEmpty(roleName))
{
using (var context = new MileageTrakerContext())
@@ -143,6 +145,7 @@ namespace MileageTraker.Web.Membership
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotSupportedException();
if (string.IsNullOrEmpty(roleName))
{
return false;
@@ -173,10 +176,10 @@ namespace MileageTraker.Web.Membership
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
using (var context = new MileageTrakerContext())
using (var context = new DataService())
{
var users = context.Users.Where(usr => usernames.Contains(usr.Username)).ToList();
var roles = context.Roles.Where(rl => roleNames.Contains(rl.RoleName)).ToList();
var users = context.GetUsers().Where(usr => usernames.Contains(usr.Username)).ToList();
var roles = context.GetRoles().Where(rl => roleNames.Contains(rl.RoleName)).ToList();
foreach (var user in users)
{
foreach (var role in roles)
@@ -186,13 +189,14 @@ namespace MileageTraker.Web.Membership
user.Roles.Add(role);
}
}
context.UpdateUser(user);
}
context.SaveChanges();
}
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotSupportedException();
using (var context = new MileageTrakerContext())
{
foreach (var username in usernames)
+62
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlTypes;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
@@ -440,6 +441,46 @@ namespace MileageTraker.Web.DAL
#endregion
public void AddUser(User user)
{
user.Created = DateTime.Now;
_db.Users.Add(user);
_db.SaveChanges();
}
public void UpdateUser(User user)
{
_db.Entry(user).State = EntityState.Modified;
_db.SaveChanges();
}
/// <summary>
/// Update only fields not needing extra membership provider support
/// </summary>
public void UpdateUserPersonalInfo(User user)
{
var original = GetUser(user.UserId);
original.Comment = user.Comment;
original.Email = user.Email;
original.FullName = user.FullName;
original.Username = user.Username;
UpdateUser(original);
}
public void UpdateUserLastActivity(string username)
{
var user = FindUserByUsername(username);
if (user != null)
{
user.LastActivityDate = DateTime.Now;
UpdateUser(user);
}
}
public IQueryable<User> GetUsers()
{
return _db.Users;
@@ -450,6 +491,27 @@ namespace MileageTraker.Web.DAL
return _db.Users.Find(guid);
}
public User FindUserByUsername(string username)
{
return _db.Users.FirstOrDefault(u => username.Equals(u.Username, StringComparison.InvariantCultureIgnoreCase));
}
public User FindUserByEmail(string email)
{
return _db.Users.FirstOrDefault(u => email.Equals(u.Email, StringComparison.InvariantCultureIgnoreCase));
}
public IQueryable<Role> GetRoles()
{
return _db.Roles;
}
public Role GetRoleByName(string roleName)
{
return
(from role in _db.Roles
where roleName == role.RoleName
select role).FirstOrDefault();
}
}
}
-175
View File
@@ -1,175 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
using MileageTraker.Web.Context;
namespace MileageTraker.Web.Membership
{
public static 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.First(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 Guid GetUserId(string userName)
{
var user = System.Web.Security.Membership.GetUser(userName);
return (Guid) 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 = (CodeFirstMembershipProvider)System.Web.Security.Membership.Provider;
return codeFirstMembership.CreateAccount(userName, password, requireConfirmationToken);
}
public static string CreateUserAndAccount(string userName, string password)
{
return CreateUserAndAccount(userName, password, propertyValues: null);
}
public static string CreateUserAndAccount(string userName, string password, bool requireConfirmation)
{
return CreateUserAndAccount(userName, password, null, requireConfirmation);
}
public static string CreateUserAndAccount(string userName, string password, IDictionary<string, object> values)
{
return CreateUserAndAccount(userName, password, values, requireConfirmationToken: false);
}
private static string CreateUserAndAccount(string userName, string password, object propertyValues = null,
bool requireConfirmationToken = false)
{
var codeFirstMembership = (CodeFirstMembershipProvider)System.Web.Security.Membership.Provider;
//IDictionary<string, object> values = null;
//if (propertyValues != null)
//{
// values = new RouteValueDictionary(propertyValues);
//}
return codeFirstMembership.CreateUserAndAccount(userName, password, requireConfirmationToken);
}
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();
}
}
}
-24
View File
@@ -1,24 +0,0 @@
// <auto-generated />
namespace MileageTraker.Web.Migrations
{
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
public sealed partial class AddMembership : IMigrationMetadata
{
string IMigrationMetadata.Id
{
get { return "201212191949311_AddMembership"; }
}
string IMigrationMetadata.Source
{
get { return null; }
}
string IMigrationMetadata.Target
{
get { return "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"; }
}
}
}
+24
View File
@@ -0,0 +1,24 @@
// <auto-generated />
namespace MileageTraker.Web.Migrations
{
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
public sealed partial class AddMembership : IMigrationMetadata
{
string IMigrationMetadata.Id
{
get { return "201212261822498_AddMembership"; }
}
string IMigrationMetadata.Source
{
get { return null; }
}
string IMigrationMetadata.Target
{
get { return "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"; }
}
}
}
@@ -11,26 +11,25 @@ namespace MileageTraker.Web.Migrations
c => new
{
UserId = c.Guid(nullable: false),
Username = c.String(nullable: false),
Email = c.String(),
Password = c.String(nullable: false),
FirstName = c.String(),
LastName = c.String(),
Username = c.String(nullable: false, maxLength: 64),
Email = c.String(nullable: false, maxLength: 64),
FullName = c.String(nullable: false, maxLength: 128),
Password = c.String(nullable: false, maxLength: 128),
Comment = c.String(),
IsApproved = c.Boolean(nullable: false),
PasswordFailuresSinceLastSuccess = c.Int(nullable: false),
LastPasswordFailureDate = c.DateTime(),
LastActivityDate = c.DateTime(),
LastLockoutDate = c.DateTime(),
LastLoginDate = c.DateTime(),
ConfirmationToken = c.String(),
CreateDate = c.DateTime(),
LastPasswordFailureDate = c.DateTime(nullable: false),
LastActivityDate = c.DateTime(nullable: false),
LastLockoutDate = c.DateTime(nullable: false),
LastLoginDate = c.DateTime(nullable: false),
Created = c.DateTime(nullable: false),
IsLockedOut = c.Boolean(nullable: false),
LastPasswordChangedDate = c.DateTime(),
PasswordVerificationToken = c.String(),
PasswordVerificationTokenExpirationDate = c.DateTime(),
LastPasswordChangedDate = c.DateTime(nullable: false),
PasswordResetToken = c.String(maxLength: 128),
})
.PrimaryKey(t => t.UserId);
.PrimaryKey(t => t.UserId)
.Index(t => t.Username, unique: true)
.Index(t => t.Email, unique: true);
CreateTable(
"Role",
@@ -71,9 +70,8 @@ namespace MileageTraker.Web.Migrations
([UserId]
,[Username]
,[Email]
,[FullName]
,[Password]
,[FirstName]
,[LastName]
,[Comment]
,[IsApproved]
,[PasswordFailuresSinceLastSuccess]
@@ -81,31 +79,26 @@ namespace MileageTraker.Web.Migrations
,[LastActivityDate]
,[LastLockoutDate]
,[LastLoginDate]
,[ConfirmationToken]
,[CreateDate]
,[Created]
,[IsLockedOut]
,[LastPasswordChangedDate]
,[PasswordVerificationToken]
,[PasswordVerificationTokenExpirationDate])
,[PasswordResetToken])
VALUES
('33EA9A48-628A-458C-A9C9-FBB318C3CF0E'
,'james.kolpack'
,'james.kolpack@gmail.com'
,'james.kolpack@gmail.com'
,'James Kolpack'
,'AH6VqEzZky4QfexgSwJIgg5gHrjaKGEk7pxUVBZz7X1Vkl31TlCUz9yTxmJN3/IDag=='
,'James'
,'Kolpack'
,NULL
,1
,0
,'1753-1-1'
,GETDATE()
,'1753-1-1'
,NULL
,NULL
,'1753-1-1'
,'1753-1-1'
,GETDATE()
,0
,GETDATE()
,NULL
,'1753-1-1'
,NULL)");
Sql(@"INSERT INTO [RoleUser]
+57 -37
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.SqlTypes;
using System.Web.Mvc;
using System.Web.Security;
@@ -10,66 +11,85 @@ namespace MileageTraker.Web.Models
{
[Key]
[HiddenInput(DisplayValue = false)]
public virtual Guid UserId { get; set; }
public Guid UserId { get; set; }
[Required]
[Display(Name = "Email")]
[DataType(DataType.EmailAddress)]
public virtual String Username { get; set; }
[StringLength(64)]
public string Username { get; set; }
[HiddenInput(DisplayValue = false)]
[Required]
[StringLength(64)]
[DataType(DataType.EmailAddress)]
public virtual String Email { get; set; }
public string Email { get; set; }
[Required]
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
public string FullName { get; set; }
[Required, DataType(DataType.Password)]
public virtual String Password { get; set; }
public virtual String FirstName { get; set; }
public virtual String LastName { get; set; }
[StringLength(128)]
public string Password { get; set; }
[DataType(DataType.MultilineText)]
public virtual String Comment { get; set; }
public string Comment { get; set; }
[HiddenInput(DisplayValue = false)]
public virtual Boolean IsApproved { get; set; }
public bool IsApproved { get; set; }
[HiddenInput]
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 int PasswordFailuresSinceLastSuccess { get; set; }
[HiddenInput(DisplayValue = false)]
public virtual String ConfirmationToken { get; set; }
[HiddenInput]
public virtual DateTime? CreateDate { get; set; }
[HiddenInput]
public virtual Boolean IsLockedOut { get; set; }
[HiddenInput]
public virtual DateTime? LastPasswordChangedDate { get; set; }
// TODO: change to Password Reset Token
[HiddenInput(DisplayValue = false)]
public virtual String PasswordVerificationToken { get; set; }
[DataType(DataType.Date)]
public DateTime LastPasswordFailureDate { get; set; }
[HiddenInput(DisplayValue = false)]
public virtual DateTime? PasswordVerificationTokenExpirationDate { get; set; }
[DataType(DataType.DateTime)]
public DateTime LastActivityDate { get; set; }
[HiddenInput(DisplayValue = false)]
[DataType(DataType.Date)]
public DateTime LastLockoutDate { get; set; }
[HiddenInput(DisplayValue = false)]
[DataType(DataType.Date)]
public DateTime LastLoginDate { get; set; }
[HiddenInput(DisplayValue = false)]
[DataType(DataType.Date)]
public DateTime Created { get; set; }
[HiddenInput]
public bool IsLockedOut { get; set; }
[HiddenInput]
[DataType(DataType.Date)]
public DateTime LastPasswordChangedDate { get; set; }
[HiddenInput(DisplayValue = false)]
[StringLength(128)]
public string PasswordResetToken { get; set; }
[HiddenInput]
public virtual ICollection<Role> Roles { get; set; }
public MembershipUser CloneToMembershipUser(string providerName)
public User()
{
LastActivityDate = SqlDateTime.MinValue.Value;
LastLockoutDate = SqlDateTime.MinValue.Value;
LastLoginDate = SqlDateTime.MinValue.Value;
LastPasswordChangedDate = SqlDateTime.MinValue.Value;
LastPasswordFailureDate = SqlDateTime.MinValue.Value;
}
public MembershipUser ToMembershipUser(string providerName)
{
return new MembershipUser(providerName, Username, UserId,
Email, null, null,
IsApproved, IsLockedOut, CreateDate.Value,
LastLoginDate.Value, LastActivityDate.Value,
LastPasswordChangedDate.Value, LastLockoutDate.Value);
IsApproved, IsLockedOut, Created,
LastLoginDate, LastActivityDate,
LastPasswordChangedDate, LastLockoutDate);
}
}
}
+21 -2
View File
@@ -86,12 +86,12 @@ $(function () {
text: "<p class=\"loading\">Recent Logs...</p>",
},
style: {
width: 320,
width: 310,
classes: 'qtip-light'
},
position: {
my: "top right",
at: "bottom left"
at: "bottom right"
},
hide: {
fixed: true,
@@ -114,6 +114,19 @@ $(function () {
}
});
$(function() {
// move checkbox elements into their labels
$('label[for]').each(function() {
var $label = $(this);
var $for = $label.attr('for');
var $input = $('input#' + $for + ':checkbox');
if ($input.length > 0) {
$input.prependTo($label);
$label.addClass('checkbox');
}
});
});
$(function() {
// Add active class to nav
var idNavActiveRegex = { 'log-nav': /\/log/i, 'vehicle-nav': /\/vehicle/i };
@@ -160,6 +173,12 @@ $(function() {
}
});
$(function () {
$('input#Username').keyup(function (e) {
$('input#Email').val($(this).val() + "@ethra.org");
});
});
$(function() {
// add qtip
$("a.qtip-modal").each(function () { bindQtipModal($(this)); });
+19
View File
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Web;
namespace MileageTraker.Web.Utility
{
@@ -83,5 +85,22 @@ namespace MileageTraker.Web.Utility
|| existingDate < date && existingNumber < number
|| existingDate > date && existingNumber > number;
}
private const int TokenSizeInBytes = 16;
public static string GenerateToken()
{
using (var prng = new RNGCryptoServiceProvider())
{
return GenerateToken(prng);
}
}
private static string GenerateToken(RandomNumberGenerator generator)
{
var tokenBytes = new byte[TokenSizeInBytes];
generator.GetBytes(tokenBytes);
return HttpServerUtility.UrlTokenEncode(tokenBytes);
}
}
}
@@ -1,10 +1,8 @@
using System;
using System.Globalization;
using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
namespace MileageTraker.Web.Membership
namespace MileageTraker.Web.Utility
{
public static class Crypto
{
@@ -12,34 +10,6 @@ namespace MileageTraker.Web.Membership
private const int Pbkdf2SubkeyLength = 256/8;
private const int SaltSize = 128/8;
private static string Hash(string input, string algorithm = "sha256")
{
if (input == null)
{
throw new ArgumentNullException("input");
}
return Hash(Encoding.UTF8.GetBytes(input), algorithm);
}
private static string Hash(byte[] input, string algorithm = "sha256")
{
if (input == null)
{
throw new ArgumentNullException("input");
}
using (var alg = HashAlgorithm.Create(algorithm))
{
if (alg != null)
{
var hashData = alg.ComputeHash(input);
return BinaryToHex(hashData);
}
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "not supported hash alg", algorithm));
}
}
/* =======================
* HASHED PASSWORD FORMATS
* =======================
@@ -100,20 +70,6 @@ namespace MileageTraker.Web.Membership
return ByteArraysEqual(storedSubkey, generatedSubkey);
}
private 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)
+1 -1
View File
@@ -171,7 +171,7 @@ namespace MileageTraker.Web.Utility
/// </summary>
public static DateTime UserOnlineThreshold()
{
return DateTime.UtcNow.Subtract(
return DateTime.Now.Subtract(
TimeSpan.FromMinutes(
Convert.ToDouble(
System.Web.Security.Membership.UserIsOnlineTimeWindow)));
+1 -4
View File
@@ -1,18 +1,15 @@
using System.ComponentModel.DataAnnotations;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.Utility;
namespace MileageTraker.Web.ViewModels.Account
{
public class LoginViewModel
{
[Required]
[Display(Name = "Email Address")]
public string EmailAddress { get; set; }
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
+32 -9
View File
@@ -1,32 +1,55 @@
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using AutoMapper;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
using MileageTraker.Web.Models;
namespace MileageTraker.Web.ViewModels.User
{
public class CreateUserViewModel
{
[Required]
[StringLength(64)]
[InputSize("small")]
public string Username { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
[InputSize("large")]
public string Email { get; set; }
[Required]
[StringLength(50, MinimumLength = 2)]
public string FirstName { get; set; }
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
[InputSize("medium")]
public string FullName { get; set; }
[Required]
[StringLength(50, MinimumLength = 2)]
public string LastName { get; set; }
[Required, DataType(DataType.Password)]
[StringLength(16, MinimumLength = 6)]
public string Password { get; set; }
public MultiSelectList Roles { get; set; }
public string[] Roles { get; set; }
public IList<string> AvailableRoles { get; set; }
public IList<string> SelectedRoles { get; set; }
static CreateUserViewModel()
{
Mapper.CreateMap<CreateUserViewModel, Models.User>();
Mapper.CreateMap<string, Role>()
.ConvertUsing(
roleName =>
{
using (var ds = new DataService())
{
return ds.GetRoleByName(roleName);
}
});
}
public Models.User CloneToUser()
public Models.User ToUser()
{
var user = new Models.User();
Mapper.Map(this, user);
@@ -2,9 +2,10 @@
@{
Layout = null;
var lowerPropertyName = @CustomExtensions.LowercaseFirst(ViewData.ModelMetadata.PropertyName);
var units = (string)ViewData.ModelMetadata.AdditionalValues["Units"];
var formatHint = (string)ViewData.ModelMetadata.AdditionalValues["FormatHint"];
var editLabel = (bool)ViewData.ModelMetadata.AdditionalValues["EditLabel"];
var values = ViewData.ModelMetadata.AdditionalValues;
var units = values.ContainsKey("Units") ? (string)values["Units"] : null;
var formatHint = values.ContainsKey("FormatHint") ? (string)values["FormatHint"] : null;
var editLabel = values.ContainsKey("EditLabel") ? (bool) values["EditLabel"] : true;
}
<div class="control-group @lowerPropertyName">
+1 -1
View File
@@ -40,7 +40,7 @@
</div>
</div>
</header>
<div class="container-fluid">
<div id="content" class="container-fluid">
@RenderBody()
</div>
<footer>
+10
View File
@@ -0,0 +1,10 @@
@model MileageTraker.Web.ViewModels.User.CreateUserViewModel
@{
Layout = "~/Views/Shared/EditorTemplates/_FieldLayout.cshtml";
}
@Html.CheckBoxListFor(
m => m.Roles,
m => m.AvailableRoles,
m => m,
m => m,
m => m.Roles)
+1
View File
@@ -13,6 +13,7 @@
<fieldset>
<legend></legend>
@Html.EditorForModel()
@Html.Partial("_Roles", Model)
<div class="control-group">
<div class="controls">
<input type="submit" value="Create" class="btn btn-primary" />
+1 -2
View File
@@ -8,9 +8,8 @@
<h2>@ViewBag.Title</h2>
@Html.DisplayFor(m => m.Email)
@Html.DisplayFor(m => m.Username)
@Html.DisplayFor(m => m.FirstName)
@Html.DisplayFor(m => m.LastName)
<dl class="dl-horizontal roles">
<dt>
+17 -5
View File
@@ -18,17 +18,29 @@
@grid.GetHtml(columns:
grid.Columns(
grid.Column("Username", format:
@<text>@Html.Encode(item.Username)
@<text>
<span title="@Html.Encode(item.Email)">
@Html.Encode(item.Username)
</span>
@if (item.LastActivityDate > CustomExtensions.UserOnlineThreshold()) {
<span class='label label-info'>Online</span>
}
@if (item.IsLockedOut) {
<span class='label label-warning' title="@string.Format("Locked out on {0:d}", item.LastLockoutDate)">Locked Out</span>
}</text> ),
grid.Column("FirstName", "First Name"),
grid.Column("LastName", "Last Name"),
grid.Column("Roles", format: item =>
string.Join(", ", Roles.Provider.GetRolesForUser(item.Username) )),
grid.Column("FullName", "Full Name"),
grid.Column("Roles", format:
@<text>
@{ var roles = Roles.Provider.GetRolesForUser(item.Username); }
@if (roles.Length > 0)
{
@Html.Encode(string.Join(", ", roles))
}
else
{
<span class='label label-warning'>No Role</span>
}
</text>),
grid.Column(format:
@<div class='btn-group'>
@Html.ActionLink("Edit", "Edit", new { id = item.UserId }, new { @class = "btn btn-mini" })
+7 -3
View File
@@ -40,12 +40,12 @@
</authentication>
<membership defaultProvider="CodeFirstMembershipProvider">
<providers>
<add name="CodeFirstMembershipProvider" type="MileageTraker.Web.Membership.CodeFirstMembershipProvider" connectionStringName="MileageTrakerContext" />
<add name="CodeFirstMembershipProvider" type="MileageTraker.Web.DAL.CodeFirstMembershipProvider" connectionStringName="MileageTrakerContext" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="CodeFirstRoleProvider">
<providers>
<add name="CodeFirstRoleProvider" type="MileageTraker.Web.Membership.CodeFirstRoleProvider" connectionStringName="MileageTrakerContext" />
<add name="CodeFirstRoleProvider" type="MileageTraker.Web.DAL.CodeFirstRoleProvider" connectionStringName="MileageTrakerContext" />
</providers>
</roleManager>
</system.web>
@@ -57,12 +57,16 @@
<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="0.0.0.0-4.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" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<log4net>
+11 -7
View File
@@ -64,6 +64,9 @@
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="MvcCheckBoxList">
<HintPath>..\packages\MvcCheckBoxList.1.4.3.0\lib\MvcCheckBoxList.dll</HintPath>
</Reference>
<Reference Include="System.configuration" />
<Reference Include="System.Data.Entity" />
<Reference Include="System.Web.ApplicationServices" />
@@ -112,16 +115,15 @@
<Compile Include="Attributes\InputSizeAttribute.cs" />
<Compile Include="Attributes\NoEditLabelAttribute.cs" />
<Compile Include="Attributes\UnitsAttribute.cs" />
<Compile Include="Attributes\UserActivityAttribute.cs" />
<Compile Include="Context\MileageTrakerContext.cs" />
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\CityController.cs" />
<Compile Include="Controllers\ControllerBase.cs" />
<Compile Include="Controllers\EmployeeController.cs" />
<Compile Include="Controllers\UserController.cs" />
<Compile Include="Membership\CodeFirstMembershipProvider.cs" />
<Compile Include="Membership\CodeFirstRoleProvider.cs" />
<Compile Include="Membership\Crypto.cs" />
<Compile Include="Membership\WebSecurity.cs" />
<Compile Include="DAL\CodeFirstMembershipProvider.cs" />
<Compile Include="DAL\CodeFirstRoleProvider.cs" />
<Compile Include="Migrations\201204181847082_InitialMigration.cs" />
<Compile Include="Migrations\201204181847082_InitialMigration.Designer.cs">
<DependentUpon>201204181847082_InitialMigration.cs</DependentUpon>
@@ -130,13 +132,14 @@
<Compile Include="Migrations\201212042021486_AddVehiclePreviousLog.Designer.cs">
<DependentUpon>201212042021486_AddVehiclePreviousLog.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\201212191949311_AddMembership.cs" />
<Compile Include="Migrations\201212191949311_AddMembership.Designer.cs">
<DependentUpon>201212191949311_AddMembership.cs</DependentUpon>
<Compile Include="Migrations\201212261822498_AddMembership.cs" />
<Compile Include="Migrations\201212261822498_AddMembership.Designer.cs">
<DependentUpon>201212261822498_AddMembership.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\Configuration.cs" />
<Compile Include="Models\Role.cs" />
<Compile Include="Models\User.cs" />
<Compile Include="Utility\Crypto.cs" />
<Compile Include="ViewModels\Account\ChangePasswordViewModel.cs" />
<Compile Include="ViewModels\Account\LoginViewModel.cs" />
<Compile Include="ViewModels\Account\RegisterModel.cs" />
@@ -270,6 +273,7 @@
<Content Include="Views\Shared\EditorTemplates\EmailAddress.cshtml" />
<Content Include="Views\Shared\DisplayTemplates\EmailAddress.cshtml" />
<Content Include="Views\Shared\DisplayTemplates\Boolean.cshtml" />
<Content Include="Views\Shared\_Roles.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config">
+1
View File
@@ -11,5 +11,6 @@
<package id="Microsoft.AspNet.Razor" version="2.0.20715.0" targetFramework="net40" />
<package id="Microsoft.AspNet.WebPages" version="2.0.20710.0" targetFramework="net40" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net40" />
<package id="MvcCheckBoxList" version="1.4.3.0" targetFramework="net40" />
<package id="Twitter.Bootstrap" version="2.2.2" targetFramework="net40" />
</packages>