Nearing feature complete for driver auth

This commit is contained in:
2013-01-09 21:33:57 -05:00
parent 0b4c7914b3
commit bc019923d2
49 changed files with 609 additions and 335 deletions
+13 -13
View File
@@ -7,15 +7,15 @@ namespace Web.Tests.Utility
[TestFixture]
public class AlgorithmsTests
{
private const int _existingNumber = 2;
private const int ExistingNumber = 2;
private readonly DateTime _existingDate = DateTime.Today.AddDays(-1);
[Test]
public void IsChronological_True_If_Greater_And_After()
{
var date = _existingDate.AddDays(1);
const int number = _existingNumber + 1;
var result = Algorithms.IsChronological(_existingDate, _existingNumber, date, number);
const int number = ExistingNumber + 1;
var result = Algorithms.IsChronological(_existingDate, ExistingNumber, date, number);
Assert.That(result);
}
@@ -24,8 +24,8 @@ namespace Web.Tests.Utility
public void IsChronological_False_If_LessThan_And_After()
{
var date = _existingDate.AddDays(1);
const int number = _existingNumber - 1;
var result = Algorithms.IsChronological(_existingDate, _existingNumber, date, number);
const int number = ExistingNumber - 1;
var result = Algorithms.IsChronological(_existingDate, ExistingNumber, date, number);
Assert.That(result, Is.False);
}
@@ -34,8 +34,8 @@ namespace Web.Tests.Utility
public void IsChronological_True_If_LessThan_And_Before()
{
var date = _existingDate.AddDays(-1);
const int number = _existingNumber - 1;
var result = Algorithms.IsChronological(_existingDate, _existingNumber, date, number);
const int number = ExistingNumber - 1;
var result = Algorithms.IsChronological(_existingDate, ExistingNumber, date, number);
Assert.That(result, Is.True);
}
@@ -44,8 +44,8 @@ namespace Web.Tests.Utility
public void IsChronological_False_If_GreaterThan_And_Before()
{
var date = _existingDate.AddDays(-1);
const int number = _existingNumber + 1;
var result = Algorithms.IsChronological(_existingDate, _existingNumber, date, number);
const int number = ExistingNumber + 1;
var result = Algorithms.IsChronological(_existingDate, ExistingNumber, date, number);
Assert.That(result, Is.False);
}
@@ -54,8 +54,8 @@ namespace Web.Tests.Utility
public void IsChronological_True_If_Same_And_Before()
{
var date = _existingDate.AddDays(-1);
const int number = _existingNumber;
var result = Algorithms.IsChronological(_existingDate, _existingNumber, date, number);
const int number = ExistingNumber;
var result = Algorithms.IsChronological(_existingDate, ExistingNumber, date, number);
Assert.That(result, Is.True);
}
@@ -65,8 +65,8 @@ namespace Web.Tests.Utility
public void IsChronological_True_If_Greater_And_SameTime()
{
var date = _existingDate;
const int number = _existingNumber + 1;
var result = Algorithms.IsChronological(_existingDate, _existingNumber, date, number);
const int number = ExistingNumber + 1;
var result = Algorithms.IsChronological(_existingDate, ExistingNumber, date, number);
Assert.That(result, Is.True);
}
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MileageTraker.Web.Utility;
using NUnit.Framework;
@@ -0,0 +1,137 @@
using System;
using MileageTraker.Web.Models;
using MileageTraker.Web.ViewModels.Log;
using NUnit.Framework;
namespace Web.Tests.ViewModels.Log
{
[TestFixture]
public class LogViewModelTests
{
[Test]
public void GetLog_Converts_To_Log()
{
var logId = 1;
var cityName = "My Town";
var date = DateTime.Today;
var endOdometer = "1234";
var driver = "name";
var ethraId = "4567";
string gasPurchased = "2.546";
var mileageLogType = new MileageLogTypeWrapper { Enum = MileageLogType.Commuting };
var viewModel =
new LogViewModel
{
LogId = logId,
CityName = cityName,
Date = date,
EndOdometer = endOdometer,
UserFullName = driver,
VehicleId = ethraId,
GasPurchased = gasPurchased,
LogType = mileageLogType
};
var log = viewModel.GetLog();
Assert.That(log.LogId, Is.EqualTo(logId));
Assert.That(log.CityName, Is.EqualTo(cityName));
Assert.That(log.Date, Is.EqualTo(date));
Assert.That(log.EndOdometer.ToString(), Is.EqualTo(endOdometer));
Assert.That(log.VehicleId, Is.EqualTo(ethraId));
Assert.That(log.GasPurchased.ToString(), Is.EqualTo(gasPurchased));
Assert.That(log.LogType.Enum, Is.EqualTo(mileageLogType.Enum));
}
[Test]
public void UpdateLog_Converts_To_Log()
{
var viewModelLogId = 1;
var viewModelCityName = "My Town";
var viewModelDate = DateTime.Today;
var viewModelEndOdometer = "1234";
var viewModelDriver = "name";
var viewModelVehicleId = "4567";
string viewModelGasPurchased = "2.546";
var viewModelLogType = new MileageLogTypeWrapper { Enum = MileageLogType.Commuting };
var viewModel =
new LogViewModel
{
LogId = viewModelLogId,
CityName = viewModelCityName,
Date = viewModelDate,
EndOdometer = viewModelEndOdometer,
UserFullName = viewModelDriver,
VehicleId = viewModelVehicleId,
GasPurchased = viewModelGasPurchased,
LogType = viewModelLogType
};
var logUser = new User{Username = "log"};
var logSource = "here";
var log =
new MileageTraker.Web.Models.Log
{
LogId = 2,
CityName = "Different Town",
Date = DateTime.MinValue,
EndOdometer = 1,
VehicleId = "1",
GasPurchased = 1.0,
LogType = new MileageLogTypeWrapper { Enum = MileageLogType.GasPurchase },
User = logUser,
Source = logSource
};
viewModel.UpdateLog(log);
Assert.That(log.LogId, Is.EqualTo(viewModelLogId));
Assert.That(log.CityName, Is.EqualTo(viewModelCityName));
Assert.That(log.Date, Is.EqualTo(viewModelDate));
Assert.That(log.EndOdometer.ToString(), Is.EqualTo(viewModelEndOdometer));
Assert.That(log.VehicleId, Is.EqualTo(viewModelVehicleId));
Assert.That(log.GasPurchased.ToString(), Is.EqualTo(viewModelGasPurchased));
Assert.That(log.LogType.Enum, Is.EqualTo(viewModelLogType.Enum));
Assert.That(log.User, Is.EqualTo(logUser));
Assert.That(log.Source, Is.EqualTo(logSource));
}
[Test]
public void Constructor_FromLog()
{
var logId = 1;
var cityName = "My Town";
var date = DateTime.Today;
var endOdometer = 1234;
var driver = "name";
var ethraId = "4567";
var gasPurchased = 2.546;
var mileageLogType = new MileageLogTypeWrapper { Enum = MileageLogType.Commuting };
var log =
new MileageTraker.Web.Models.Log
{
LogId = logId,
CityName = cityName,
Date = date,
EndOdometer = endOdometer,
VehicleId = ethraId,
GasPurchased = gasPurchased,
LogType = mileageLogType
};
var viewModel = new LogViewModel(log);
Assert.That(viewModel.LogId, Is.EqualTo(logId));
Assert.That(viewModel.CityName, Is.EqualTo(cityName));
Assert.That(viewModel.Date, Is.EqualTo(date));
Assert.That(viewModel.EndOdometer, Is.EqualTo(endOdometer.ToString()));
Assert.That(viewModel.VehicleId, Is.EqualTo(ethraId));
Assert.That(viewModel.GasPurchased, Is.EqualTo(gasPurchased.ToString()));
Assert.That(viewModel.LogType.Enum, Is.EqualTo(mileageLogType.Enum));
}
}
}
@@ -34,7 +34,6 @@ namespace Web.Tests.ViewModels
var email = vm.Email = "bob@dobalina.com";
var username = vm.Username = "bobdobalina";
var fullName = vm.FullName = "Bob Dobalina";
var roles = vm.Roles = new [] {"Administrator", "Developer"};
var userId = vm.UserId = Guid.NewGuid();
vm.UserId = Guid.NewGuid();
+4 -3
View File
@@ -89,9 +89,10 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utility\AlgorithmsTests.cs" />
<Compile Include="Utility\CustomExtensionsTests.cs" />
<Compile Include="ViewModels\CreateLogViewModelTests.cs" />
<Compile Include="ViewModels\CreateUserViewModelTests.cs" />
<Compile Include="ViewModels\EditUserViewModelTests.cs" />
<Compile Include="ViewModels\CreateLog\CreateLogViewModelTests.cs" />
<Compile Include="ViewModels\Log\LogViewModelTests.cs" />
<Compile Include="ViewModels\User\CreateUserViewModelTests.cs" />
<Compile Include="ViewModels\User\EditUserViewModelTests.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="DAL\Vehicles.xls">
Binary file not shown.
+1
View File
@@ -9,6 +9,7 @@ namespace MileageTraker.Web.Attributes
{
if (filterContext != null)
{
// TODO: capture current user
var controller = filterContext.RouteData.Values["controller"].ToString();
var action = filterContext.RouteData.Values["action"].ToString();
var loggerName = string.Format("{0}Controller.{1}", controller, action);
+3 -13
View File
@@ -3,6 +3,7 @@ using System.Web.Mvc;
using System.Web.Security;
using MileageTraker.Web.DAL;
using MileageTraker.Web.Email;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
using MileageTraker.Web.ViewModels.Account;
@@ -146,20 +147,9 @@ namespace MileageTraker.Web.Controllers
var user = DataService.FindUserByUsername(viewModel.Username);
if (user != null && Request.Url != null)
{
var passwordResetToken = Algorithms.GenerateToken();
var url = Request.Url.Scheme +
@"://" +
Request.Url.Authority +
Url.Action("NewPassword", "Account",
new NewPasswordViewModel
{
UserId = user.UserId,
PasswordResetToken = passwordResetToken
});
user.PasswordResetToken = passwordResetToken;
DataService.UpdateUser(user);
var email = new EmailNotificationService();
email.NotifyResetPassword(user,url);
var resetPasswordUrl = ResetPassword(user);
email.SendResetPassword(user, resetPasswordUrl);
}
TempData["StatusMessage"] = "Please check your email - we have sent a request for you to reset the password.";
+44
View File
@@ -1,6 +1,10 @@
using System;
using System.Web.Mvc;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
using MileageTraker.Web.ViewModels.Account;
namespace MileageTraker.Web.Controllers
{
@@ -28,5 +32,45 @@ namespace MileageTraker.Web.Controllers
base.OnException(filterContext);
}
protected string GetCookieValue(string key)
{
return
HttpContext.Request.Cookies[key] != null
? HttpContext.Request.Cookies[key].Value
: null;
}
protected void SetCookieValue(string key, string value)
{
var cookies = HttpContext.Response.Cookies;
var httpCookie = cookies[key];
if (httpCookie == null) return;
httpCookie.Value = value;
httpCookie.Expires = DateTime.MaxValue;
}
protected string LinkForUrlAction(string urlAction)
{
return
string.Format("{0}://{1}{2}",
Request.Url.Scheme, Request.Url.Authority, urlAction);
}
protected string ResetPassword(User user)
{
var passwordResetToken = Algorithms.GenerateToken();
var url = LinkForUrlAction(
Url.Action("NewPassword", "Account",
new NewPasswordViewModel
{
UserId = user.UserId,
PasswordResetToken = passwordResetToken
}));
user.PasswordResetToken = passwordResetToken;
DataService.UpdateUser(user);
return url;
}
}
}
+6 -18
View File
@@ -6,6 +6,7 @@ using MileageTraker.Web.ViewModels.CreateLog;
namespace MileageTraker.Web.Controllers
{
[Authorize(Roles = "Driver, Administrator, Developer")]
public class CreateLogController : ControllerBase
{
private const string CookeNameVehicleid = "mr_vehicleId";
@@ -72,10 +73,12 @@ namespace MileageTraker.Web.Controllers
return View("Index", model);
}
public PartialViewResult RecentLogs(string employeeName)
public PartialViewResult RecentLogs()
{
var logs = DataService.GetRecentLogsByEmployee(employeeName);
ViewData["employeeName"] = employeeName;
var username = User.Identity.Name;
var user = DataService.FindUserByUsername(username);
var logs = DataService.GetRecentLogsByUsername(user.Username);
ViewData["name"] = user.FullName;
return PartialView(logs);
}
@@ -92,20 +95,5 @@ namespace MileageTraker.Web.Controllers
Date = DateTime.Today
};
}
private string GetCookieValue(string key)
{
return
HttpContext.Request.Cookies[key] != null
? HttpContext.Request.Cookies[key].Value
: null;
}
private void SetCookieValue(string key, string value)
{
var cookies = HttpContext.Response.Cookies;
cookies[key].Value = value;
cookies[key].Expires = DateTime.MaxValue;
}
}
}
+20 -21
View File
@@ -3,7 +3,6 @@ using System.Linq;
using System.Web.Mvc;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
using MileageTraker.Web.ViewModels;
using MileageTraker.Web.ViewModels.Log;
@@ -84,7 +83,8 @@ namespace MileageTraker.Web.Controllers
public ViewResult Details(int id)
{
var log = DataService.GetLog(id);
return View(log);
var viewModel = new LogViewModel(log);
return View(viewModel);
}
public ActionResult PreviousDetails(int id)
@@ -121,22 +121,24 @@ namespace MileageTraker.Web.Controllers
public ActionResult Create()
{
var log = new Log { Date = DateTime.Today };
var viewModel = new LogViewModel { Date = DateTime.Today };
var vehicleId = Request["vehicleId"];
if (vehicleId != null)
{
log.VehicleId = vehicleId;
viewModel.VehicleId = vehicleId;
}
return View(log);
return View(viewModel);
}
[HttpPost]
[ActionLog]
public ActionResult Create(Log log)
public ActionResult Create(LogViewModel viewModel)
{
if (ModelState.IsValid)
{
var log = viewModel.GetLog();
log.User = DataService.FindUserByFullName(viewModel.UserFullName);
log.Source = HttpContext.Request.Url.AbsolutePath;
log.UserHostAddress = HttpContext.Request.UserHostAddress;
log.UserAgent = HttpContext.Request.UserAgent;
@@ -147,42 +149,39 @@ namespace MileageTraker.Web.Controllers
return RedirectToAction("Index");
}
return View(log);
return View(viewModel);
}
public ActionResult Edit(int id)
{
var log = DataService.GetLog(id);
return View(log);
var logViewModel = new LogViewModel(log);
return View(logViewModel);
}
[HttpPost]
[ActionLog]
public ActionResult Edit(Log log)
public ActionResult Edit(LogViewModel viewModel)
{
RemoveModelStateErrors();
if (ModelState.IsValid)
{
var log = DataService.GetLog(viewModel.LogId);
viewModel.UpdateLog(log);
log.User = DataService.FindUserByFullName(viewModel.UserFullName);
DataService.UpdateLog(log);
TempData["StatusMessage"] = "Log updated";
return RedirectToAction("Details", new{id = log.LogId});
}
return View(log);
}
private void RemoveModelStateErrors()
{
ModelState.Remove("Source");
ModelState.Remove("UserAgent");
ModelState.Remove("UserHostAddress");
ModelState.Remove("VehiclePreviousLogId");
ModelState.Remove("VehiclePreviousLog");
return View(viewModel);
}
public ActionResult Delete(int id)
{
var log = DataService.GetLog(id);
return View(log);
var viewModel = new LogViewModel(log);
return View(viewModel);
}
[HttpPost, ActionName("Delete")]
+39 -12
View File
@@ -2,6 +2,9 @@
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using MileageTraker.Web.Email;
using MileageTraker.Web.ViewModels;
using MileageTraker.Web.ViewModels.Account;
using MileageTraker.Web.ViewModels.User;
namespace MileageTraker.Web.Controllers
@@ -21,6 +24,8 @@ namespace MileageTraker.Web.Controllers
return View(users);
}
//todo: add export
public ActionResult Details(Guid id)
{
var user = Membership.GetUser(id);
@@ -48,17 +53,26 @@ namespace MileageTraker.Web.Controllers
return Json(user == null, JsonRequestBehavior.AllowGet);
}
public JsonResult EmailAvailable(string email)
public JsonResult FullNameAvailable(string fullname)
{
var user = DataService.FindUserByEmail(email);
var user = DataService.FindUserByFullName(fullname);
return Json(user == null, JsonRequestBehavior.AllowGet);
}
public JsonResult ExistsByFullName(string userFullName)
{
var user = DataService.FindUserByFullName(userFullName);
return Json(user != null, JsonRequestBehavior.AllowGet);
}
public ActionResult Create()
{
var vm = new CreateUserViewModel
{
AvailableRoles = Roles.GetAllRoles()
Roles = new CheckBoxViewModel{
Available = Roles.GetAllRoles(),
Selected = new []{"Driver"} // default driver
}
};
return View(vm);
@@ -73,7 +87,7 @@ namespace MileageTraker.Web.Controllers
var membershipUser =
Membership.CreateUser(
viewModel.Username,
viewModel.Password,
"uninitialized_state",
viewModel.Email,
null,
null,
@@ -83,26 +97,36 @@ namespace MileageTraker.Web.Controllers
if (membershipUser == null)
{
ModelState.AddModelError("", ErrorCodeToString(membershipCreateStatus));
viewModel.AvailableRoles = Roles.GetAllRoles();
viewModel.Roles.Available = Roles.GetAllRoles();
return View(viewModel);
}
if (viewModel.Roles != null && viewModel.Roles.Any())
if (viewModel.Roles.Selected != null && viewModel.Roles.Selected.Any())
{
Roles.AddUserToRoles(
membershipUser.UserName,
viewModel.Roles);
viewModel.Roles.Selected);
}
var user = DataService.GetUser((Guid) membershipUser.ProviderUserKey);
user.FullName = viewModel.FullName;
DataService.UpdateUserPersonalInfo(user);
if (viewModel.SetPassword)
{
TempData["StatusMessage"] = "User " + user.Username + " created";
return RedirectToAction("SetPassword", new { id = user.UserId });
}
var email = new EmailNotificationService();
var resetPasswordUrl = ResetPassword(user);
email.SendInitializePassword(user, resetPasswordUrl);
TempData["StatusMessage"] = "User " + user.Username + " created, invitation sent to " + user.Email;
return RedirectToAction("Index");
}
viewModel.AvailableRoles = Roles.GetAllRoles();
viewModel.Roles.Available = Roles.GetAllRoles();
return View(viewModel);
}
@@ -116,8 +140,11 @@ namespace MileageTraker.Web.Controllers
var vm = new EditUserViewModel(user)
{
Roles = Roles.GetRolesForUser(user.Username),
AvailableRoles = Roles.GetAllRoles()
Roles = new CheckBoxViewModel
{
Selected = Roles.GetRolesForUser(user.Username),
Available = Roles.GetAllRoles()
}
};
return View(vm);
@@ -133,11 +160,11 @@ namespace MileageTraker.Web.Controllers
DataService.UpdateUserPersonalInfo(user);
Roles.RemoveUserFromRoles(user.Username, Roles.GetAllRoles());
if (viewModel.Roles != null && viewModel.Roles.Any())
if (viewModel.Roles != null)
{
Roles.AddUserToRoles(
user.Username,
viewModel.Roles);
viewModel.Roles.Selected);
}
TempData["StatusMessage"] = "Changes saved for " + user.Username;
-1
View File
@@ -63,7 +63,6 @@ namespace MileageTraker.Web.Controllers
return View(vehicle);
}
[AllowAnonymous]
public JsonResult Exists(string vehicleId)
{
var vehicle = DataService.GetVehicle(vehicleId);
+20 -10
View File
@@ -34,7 +34,11 @@ namespace MileageTraker.Web.DAL
log.VehiclePreviousLog = previousLog;
var nextLog = SearchNextLog(log);
if (nextLog != null)
{
nextLog.VehiclePreviousLog = log;
nextLog.User = _db.Users.Find(nextLog.User.UserId);
_db.Entry(nextLog).State = EntityState.Modified;
}
_db.SaveChanges();
@@ -43,14 +47,7 @@ namespace MileageTraker.Web.DAL
public void UpdateLog(Log log)
{
_db.Logs.Attach(log);
var original = _db.Logs.Find(log.LogId);
// ignore these properties while updating
log.Created = original.Created;
log.Source = original.Source;
log.UserAgent = original.UserAgent;
log.UserHostAddress = original.UserHostAddress;
// note: assumes log is already attached to current context
// remove from the list
var nextLog =
@@ -58,7 +55,11 @@ namespace MileageTraker.Web.DAL
where l.VehiclePreviousLogId == log.LogId
select l).FirstOrDefault();
if (nextLog != null)
{
nextLog.VehiclePreviousLogId = log.VehiclePreviousLogId;
nextLog.User = _db.Users.Find(nextLog.User.UserId);
_db.Entry(nextLog).State = EntityState.Modified;
}
log.VehiclePreviousLog = null;
log.VehiclePreviousLogId = null;
@@ -69,8 +70,13 @@ namespace MileageTraker.Web.DAL
log.VehiclePreviousLogId = previousLog.LogId;
var newNextLog = SearchNextLog(log);
if (newNextLog != null)
{
newNextLog.VehiclePreviousLogId = log.LogId;
newNextLog.User = _db.Users.Find(newNextLog.User.UserId);
_db.Entry(newNextLog).State = EntityState.Modified;
}
log.User = _db.Users.Find(log.User.UserId);
_db.Entry(log).State = EntityState.Modified;
_db.SaveChanges();
@@ -83,7 +89,11 @@ namespace MileageTraker.Web.DAL
var nextLog = GetNextLog(log.LogId);
if (nextLog != null)
{
nextLog.VehiclePreviousLog = log.VehiclePreviousLog;
nextLog.User = _db.Users.Find(nextLog.User.UserId);
_db.Entry(nextLog).State = EntityState.Modified;
}
_db.Logs.Remove(log);
_db.SaveChanges();
@@ -247,11 +257,11 @@ namespace MileageTraker.Web.DAL
return logs;
}
public IEnumerable<Log> GetRecentLogsByEmployee(string employeeName)
public IEnumerable<Log> GetRecentLogsByUsername(string username)
{
return
(from l in _db.Logs
where l.User.FullName == employeeName
where l.User.Username == username
orderby l.Created descending
select l)
.Take(3)
-5
View File
@@ -18,11 +18,6 @@ namespace MileageTraker.Web.DAL
ExcelWriter.WriteXls(vehicles, filename, WorksheetTitle, WorksheetName);
}
public static void Export(IEnumerable<Vehicle> vehicles, Stream stream)
{
ExcelWriter.WriteXls(vehicles, stream, WorksheetTitle, WorksheetName);
}
public static byte[] Export(IEnumerable<Vehicle> vehicles)
{
return ExcelWriter.WriteXls(vehicles, WorksheetTitle, WorksheetName);
+18 -6
View File
@@ -12,11 +12,13 @@ namespace MileageTraker.Web.Email
{
//private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private readonly string _resetPasswordBody;
private readonly string _resetPasswordFromAddress;
private readonly string _emaialFromAddress;
private readonly string _resetPasswordSubject;
private readonly string _resetPasswordBody;
private readonly SmtpClient _smtpClient;
private string _initializePasswordSubject;
private string _initializePasswordBody;
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Object"/> class.
@@ -26,9 +28,13 @@ namespace MileageTraker.Web.Email
{
_smtpClient = new SmtpClient();
_resetPasswordBody = ConfigurationManager.AppSettings["ResetPasswordBody"];
_resetPasswordFromAddress = ConfigurationManager.AppSettings["ResetPasswordFromAddress"];
_emaialFromAddress = ConfigurationManager.AppSettings["EmailFromAddress"];
_resetPasswordSubject = ConfigurationManager.AppSettings["ResetPasswordSubject"];
_resetPasswordBody = ConfigurationManager.AppSettings["ResetPasswordBody"];
_initializePasswordSubject = ConfigurationManager.AppSettings["InitializePasswordSubject"];
_initializePasswordBody = ConfigurationManager.AppSettings["InitializetPasswordBody"];
}
/// <summary>
@@ -36,10 +42,16 @@ namespace MileageTraker.Web.Email
/// </summary>
/// <param name="user">To this user.</param>
/// <param name="url">Reset url</param>
public void NotifyResetPassword(User user, string url)
public void SendResetPassword(User user, string url)
{
var body = string.Format(_resetPasswordBody, url);
_smtpClient.Send(new MailMessage(_resetPasswordFromAddress, user.Email, _resetPasswordSubject, body));
_smtpClient.Send(new MailMessage(_emaialFromAddress, user.Email, _resetPasswordSubject, body));
}
public void SendInitializePassword(User user, string url)
{
var body = string.Format(_initializePasswordBody, url, user.FullName);
_smtpClient.Send(new MailMessage(_emaialFromAddress, user.Email, _initializePasswordSubject, body));
}
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ namespace MileageTraker.Web.Migrations
,'{1}'
,'{2}'
,'{3}'
,''
,'uninitialized_state'
,NULL
,{4}
,0
@@ -6,11 +6,15 @@ namespace MileageTraker.Web.Migrations
{
public override void Up()
{
CreateIndex("User", "FullName", unique: true);
DropIndex("User", "IX_Email");
DropColumn("Log", "EmployeeName");
}
public override void Down()
{
DropIndex("User", "IX_FullName");
CreateIndex("User", "Email", unique: true);
AddColumn("Log", "EmployeeName", c => c.String(nullable: false));
Sql(@"UPDATE [Log]
SET [Log].EmployeeName = [User].FullName
+3 -30
View File
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
namespace MileageTraker.Web.Models
@@ -10,58 +9,33 @@ namespace MileageTraker.Web.Models
public class Log : IValidatableObject
{
[Key]
[HiddenInput(DisplayValue = false)]
public int LogId { get; set; }
[Required]
[Remote("Exists", "Vehicle", ErrorMessage = "ID not found")]
[StringLength(6, MinimumLength = 4, ErrorMessage = "Enter 4 digit number")]
[Display(Name = "Vehicle ID")]
[InputSize("mini")]
[RegularExpression(@"\d+", ErrorMessage = "Enter only numbers")]
public string VehicleId { get; set; }
[Required]
[Range(1, 500000, ErrorMessage = "Between 1 and 500k")]
[Display(Name = "End Odometer")]
[InputSize("small")]
[Units("Miles")]
public int EndOdometer { get; set; }
[Required]
[Display(Name = "Type")]
[NoEditLabel]
public MileageLogTypeWrapper LogType { get; set; }
[Required]
[StringLength(64, MinimumLength = 3, ErrorMessage = "Minimum 3 characters")]
[InputSize("medium")]
public string CityName { get; set; }
//[Required]
//[Display(Name = "Employee / Driver")]
//[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
//[InputSize("medium")]
//public string EmployeeName { get; set; }
[Required]
[Display(Name = "Employee / Driver")]
[HiddenInput(DisplayValue = false)]
public virtual User User { get; set; }
[Range(0, 50)]
[DisplayFormat(DataFormatString = "{0:0.000}", ApplyFormatInEditMode = true)]
[Units("Gallons")]
[FormatHint("n.nnnn")]
[InputSize("mini")]
public double GasPurchased { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = @"{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[DenyFutureDate(ErrorMessage = "Future date")]
[FormatHint("mm/dd/yyyy")]
[InputSize("small")]
public DateTime Date { get; set; }
[Display(Name = "Time Created")]
@@ -72,13 +46,10 @@ namespace MileageTraker.Web.Models
/// <summary>
/// url route that was used to create this instance, ie 'CreateLog\Confirm' or 'Logs\Create'
/// </summary>
[HiddenInput(DisplayValue = false)]
public string Source { get; set; }
[HiddenInput(DisplayValue = false)]
public string UserHostAddress { get; set; }
[HiddenInput(DisplayValue = false)]
public string UserAgent { get; set; }
[HiddenInput(DisplayValue = false)]
@@ -103,9 +74,11 @@ namespace MileageTraker.Web.Models
ValidationResult result = null;
try
{
var dataService = new DataService();
using (var dataService = new DataService())
{
dataService.ValidateOdometerChronology(VehicleId, EndOdometer, Date);
}
}
catch (ChronologicalOrderException ex)
{
result = new ValidationResult(ex.Message, new[] { "EndOdometer" });
+32 -67
View File
@@ -1,24 +1,16 @@
$(function () {
$("tbody > tr:odd").addClass("odd");
$("input:submit, .ui-button").button();
$("input#Date").datepicker({ maxDate: '+0d' });
$(".display-field-container")
.filter(".source,.userHostAddress,.userAgent")
.children(".display-label")
.css('text-decoration', 'underline')
.click(function () {
$(this).parent().children('.display-field').toggle();
})
.end()
.children('.display-field').hide();
$("input#CityName").autocomplete({
source: "/City/Autocomplete",
minLength: 2
});
$("input#EmployeeName, input#Assigned").autocomplete({
$("input#EmployeeName, input#Assigned, input#UserFullName").autocomplete({
source: "/Employee/Autocomplete",
minLength: 2
});
$("form select#Year").change(function () {
$.getJSON('/Log/GetValidLogMonths', { year: $(this).val() }, function (months) {
var options = '<option>Select Month</option>';
@@ -28,7 +20,9 @@ $(function () {
$("form select#Month").html(options);
});
});
$("input#ModelYear,input#Price,input#VehicleId,input#EndOdometer,input#GasPurchased").numeric();
$(".report-miles").append('&nbsp;<span class="muted">&#9652;</span>').each(function () {
var content = $(this).next('.report-calculation');
$(this).qtip({
@@ -57,58 +51,16 @@ $(function () {
}
});
});
});
if ($("input#EmployeeName").filter(':not(:hidden)').filter(':not(.search-query)').length > 0) {
$("input#EmployeeName")
.after('<span id="icon-employee-history" class="add-on"><i class="icon-search" /></span>')
.add('#icon-employee-history')
.wrapAll('<div class="input-append"></div>');
function employeeHistoryKeydownHandler(data) {
employeeHistoryIconUpdate($(data.target), $("#icon-employee-history"));
}
function employeeHistoryIconUpdate($input, $icon) {
if (!$input.hasClass("input-validation-error") // not invalid
&& $input.attr("value").length > 0) // has text
$icon.removeClass("transparent");
else
$icon.addClass("transparent");
}
$("input#EmployeeName").change(employeeHistoryKeydownHandler).keydown(employeeHistoryKeydownHandler);
employeeHistoryIconUpdate($("input#EmployeeName"), $("#icon-employee-history"));
$("#icon-employee-history").qtip({
content: {
text: "<p class=\"loading\">Recent Logs...</p>",
},
style: {
width: 310,
classes: 'qtip-light'
},
position: {
my: "top right",
at: "bottom right"
},
hide: {
fixed: true,
delay: 500
},
events: {
show: function(event, api) {
// add recent logs to a div if it exists
$(function () {
var $recentLogs = $("#RecentLogs");
if ($recentLogs.length > 0) {
$.ajax({
url: "/CreateLog/RecentLogs",
data: {
employeeName: $("input#EmployeeName").val()
},
success: function (data) {
api.set("content.text", data);
}
});
}
$recentLogs.append(data);
}
});
}
@@ -119,16 +71,18 @@ $(function() {
$('label[for]').each(function() {
var $label = $(this);
var $for = $label.attr('for');
var $input = $('input#' + $for + ':checkbox');
if ($input.length > 0) {
if ($for.length > 0) {
var $input = $('input#' + $for + ',input[name="' + $for + '"]');
if ($input.filter(':checkbox').length > 0) {
$input.prependTo($label);
$label.addClass('checkbox');
}
}
});
});
$(function() {
// Add active class to nav
$(function() {
var idNavActiveRegex = {
'log-nav': /\/log/i,
'vehicle-nav': /\/vehicle/i,
@@ -161,8 +115,8 @@ $(function () {
.prepend('<i class="icon-user icon-white" /> ');
});
$(function() {
// Convert MVC3 WebGrid paging to Bootstrap
$(function() {
var $paging = $('table.table tfoot tr td');
var $currentPage =
@@ -177,9 +131,20 @@ $(function() {
}
});
// auto complete email address based on username
$(function () {
$('input#Username').keyup(function (e) {
$('input#Email').val($(this).val() + "@ethra.org");
$('.create-user input#FullName').keyup(function () {
var fullName = $(this).val();
var names = fullName.split(' '); ///[a-z().]+(\s+[a-z().]+)+/i.test(fullName)
if (names.length > 1) {
var username = names[0][0] + names[names.length - 1];
$('.create-user input#Username').val(username);
$('.create-user input#Email').val(username + "@ethra.org");
}
});
$('.create-user input#Username').keyup(function () {
$('.create-user input#Email').val($(this).val() + "@ethra.org");
});
});
@@ -198,7 +163,7 @@ $(function() {
ajax: {
url: element.attr('href')
},
text: "<p class=\"loading\">Recent Logs...</p>"
text: "<p class=\"loading\">...</p>"
},
hide: {
fixed: true,
+5 -2
View File
@@ -48,10 +48,13 @@ namespace MileageTraker.Web.Utility
// write the data
items.Zip(
CustomExtensions.GetNumbers().Skip(3),
(vehicle, r) =>
(item, r) =>
properties.Zip(CustomExtensions.GetNumbers(),
(p, c) => {
var value = p.GetValue(vehicle);
// TODO: Fix this
if (item is User)
return (string)null;
var value = p.GetValue(item);
string formatString = null;
@@ -19,7 +19,7 @@ namespace MileageTraker.Web.ViewModels.Account
public string Username { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[StringLength(16, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
+10
View File
@@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace MileageTraker.Web.ViewModels
{
public class CheckBoxViewModel
{
public IList<string> Available { get; set; }
public string[] Selected { get; set; }
}
}
@@ -27,8 +27,8 @@ namespace MileageTraker.Web.ViewModels.CreateLog
DateHowLongAgo = (DateTime.Today - Date).ToVerboseStringHistoric();
var dataService = new DataService();
using (var dataService = new DataService())
{
var endOdometer = int.Parse(createLogViewModel.EndOdometer);
var date = createLogViewModel.Date;
@@ -52,3 +52,4 @@ namespace MileageTraker.Web.ViewModels.CreateLog
}
}
}
}
+3 -12
View File
@@ -62,17 +62,6 @@ namespace MileageTraker.Web.ViewModels.CreateLog
Mapper.CreateMap<string, double>().ConvertUsing(Convert.ToDouble);
Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
Mapper.CreateMap<CreateLogViewModel, Models.Log>();
Mapper.CreateMap<Models.Log, CreateLogViewModel>()
.ForMember(vm => vm.Date, opt => opt.MapFrom(m => m.Date.ToString("d")));
}
public CreateLogViewModel()
{
}
public CreateLogViewModel(Models.Log log)
{
Mapper.Map(log, this);
}
public Models.Log GetLog()
@@ -94,9 +83,11 @@ namespace MileageTraker.Web.ViewModels.CreateLog
ValidationResult result = null;
try
{
var dataService = new DataService();
using (var dataService = new DataService())
{
dataService.ValidateOdometerChronology(VehicleId, int.Parse(EndOdometer), Date);
}
}
catch (Exception ex)
{
result = new ValidationResult(ex.Message, new [] {"EndOdometer"});
+138
View File
@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using AutoMapper;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
namespace MileageTraker.Web.ViewModels.Log
{
public class LogViewModel : IValidatableObject
{
[HiddenInput(DisplayValue = false)]
public int LogId { get; set; }
[Required(ErrorMessage = "Required")]
[Remote("Exists", "Vehicle", ErrorMessage = "ID not found")]
[StringLength(6, MinimumLength = 4, ErrorMessage = "Must be a 4 digit number")]
[Display(Name = "Vehicle ID")]
[InputSize("mini")]
[RegularExpression(@"\d+", ErrorMessage = "Must be all numbers")]
public string VehicleId { get; set; }
[Required(ErrorMessage = "Required")]
[Range(1, 500000, ErrorMessage = "Between 1 and 500k")]
[Display(Name = "End Odometer")]
[Units("Miles")]
[InputSize("small")]
[RegularExpression(@"\d+", ErrorMessage = "Must be all numbers")]
public string EndOdometer { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "Type")]
[NoEditLabel]
public MileageLogTypeWrapper LogType { get; set; }
[Required(ErrorMessage = "Required")]
[Remote("ExistsByFullName", "User", ErrorMessage = "User with this name doesn't exist")]
[StringLength(128)]
[Display(Name = "Driver Name")]
[InputSize("medium")]
public string UserFullName { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "City Name")]
[InputSize("medium")]
[StringLength(64, MinimumLength = 3, ErrorMessage = "Minimum 3 characters")]
public string CityName { get; set; }
[Display(Name = "Gas Purchased")]
[DisplayFormat(DataFormatString = "{0:0.000}", ApplyFormatInEditMode = true)]
[Units("Gallons")]
[FormatHint("n.nnnn")]
[InputSize("mini")]
public string GasPurchased { get; set; }
[Required(ErrorMessage = "Required")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = @"{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[DenyFutureDate(ErrorMessage = "Future date")]
[FormatHint("mm/dd/yyyy")]
[InputSize("small")]
public DateTime Date { get; set; }
[Display(Name = "Time Created")]
[DisplayFormat(DataFormatString = @"{0:MM/dd/yyyy h:mm tt}")]
[HiddenInput]
public DateTime Created { get; set; }
static LogViewModel()
{
Mapper.CreateMap<string, int>().ConvertUsing(Convert.ToInt32);
Mapper.CreateMap<string, double>().ConvertUsing(Convert.ToDouble);
Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
Mapper.CreateMap<LogViewModel, Models.Log>();
Mapper.CreateMap<Models.Log, LogViewModel>()
.ForMember(vm => vm.Date, opt => opt.MapFrom(m => m.Date.ToString("d")));
}
public LogViewModel()
{
}
public LogViewModel(Models.Log log)
{
Mapper.Map(log, this);
}
public Models.Log GetLog()
{
var log = new Models.Log();
Mapper.Map(this, log);
return log;
}
public void UpdateLog(Models.Log log)
{
Mapper.DynamicMap(this, log);
//TODO use automapper somehow
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (LogType == MileageLogType.GasPurchase
&& (string.IsNullOrEmpty(GasPurchased) || double.Parse(GasPurchased) == 0))
yield return new ValidationResult("Enter amount of gas purchased", new [] {"GasPurchased"});
if (LogType.Value == 0)
yield return new ValidationResult("Required", new[] { "LogType" });
ValidationResult chronologyResult = null;
try
{
using (var dataService = new DataService())
{
dataService.ValidateOdometerChronology(VehicleId, int.Parse(EndOdometer), Date);
}
}
catch (Exception ex)
{
chronologyResult = new ValidationResult(ex.Message, new [] {"EndOdometer"});
}
if (chronologyResult != null)
yield return chronologyResult;
using (var dataService = new DataService())
{
var user = dataService.FindUserByFullName(UserFullName);
if (user == null)
{
yield return new ValidationResult("User with this name doesn't exist", new[] { "UserFullName" });
}
}
}
}
}
+13 -11
View File
@@ -5,8 +5,15 @@ using MileageTraker.Web.Attributes;
namespace MileageTraker.Web.ViewModels.User
{
public class CreateUserViewModel : RolesViewModel
public class CreateUserViewModel
{
[Required]
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
[InputSize("medium")]
[Remote("FullNameAvailable", "User", ErrorMessage = "Name already in use")]
public string FullName { get; set; }
[Required]
[StringLength(64)]
[InputSize("small")]
@@ -17,19 +24,14 @@ namespace MileageTraker.Web.ViewModels.User
[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")]
[Remote("EmailAvailable", "User", ErrorMessage = "Email already in use")]
public string Email { get; set; }
[Required]
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
[InputSize("medium")]
public string FullName { get; set; }
public CheckBoxViewModel Roles { get; set; }
[Required, DataType(DataType.Password)]
[StringLength(16, MinimumLength = 6)]
[InputSize("medium")]
public string Password { get; set; }
[Required]
[Display(Name = "Set password now instead of emailing ")]
[NoEditLabel]
public bool SetPassword { get; set; }
static CreateUserViewModel()
{
+11 -10
View File
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using AutoMapper;
@@ -7,11 +6,17 @@ using MileageTraker.Web.Attributes;
namespace MileageTraker.Web.ViewModels.User
{
public class EditUserViewModel : RolesViewModel
public class EditUserViewModel
{
[HiddenInput(DisplayValue = false)]
public Guid UserId { get; set; }
[Required]
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
[InputSize("medium")]
public string FullName { get; set; }
[Required]
[StringLength(64)]
[InputSize("small")]
@@ -23,11 +28,7 @@ namespace MileageTraker.Web.ViewModels.User
[InputSize("large")]
public string Email { get; set; }
[Required]
[StringLength(128)]
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
[InputSize("medium")]
public string FullName { get; set; }
public CheckBoxViewModel Roles { get; set; }
static EditUserViewModel()
{
@@ -46,9 +47,9 @@ namespace MileageTraker.Web.ViewModels.User
public void UpdateUser(Models.User user)
{
user.Username = this.Username;
user.FullName = this.FullName;
user.Email = this.Email;
user.Username = Username;
user.FullName = FullName;
user.Email = Email;
}
}
}
-10
View File
@@ -1,10 +0,0 @@
using System.Collections.Generic;
namespace MileageTraker.Web.ViewModels.User
{
public class RolesViewModel
{
public string[] Roles { get; set; }
public IList<string> AvailableRoles { get; set; }
}
}
+2 -2
View File
@@ -65,7 +65,8 @@
@Html.HiddenFor(model => model.LogType.Value)
@Html.DisplayFor(model => model.CityName)
@Html.HiddenFor(model => model.CityName)
@* // Html.HiddenFor(model => model.CityName) is losing capitalization *@
<input type="hidden" name="CityName" value="@Model.CityName"/>
<dl class="dl-horizontal gas">
<dt>
@@ -84,7 +85,6 @@
</dl>
@Html.HiddenFor(model => model.GasPurchased)
<dl class="dl-horizontal date">
<dt>
@Html.DisplayNameFor(m => m.Date)
+4
View File
@@ -19,3 +19,7 @@
</div>
</fieldset>
}
<div id="RecentLogs" class="center-content well">
</div>
+2 -9
View File
@@ -4,7 +4,7 @@
@if (Model.Any())
{
<h5>Recent Logs for @ViewData["employeeName"]</h5>
<h5>Recent Logs for @ViewData["name"]</h5>
<table class="table">
<thead>
<tr>
@@ -43,12 +43,5 @@
}
else
{
if (!string.IsNullOrEmpty(ViewData["employeeName"].ToString()))
{
<h5>Mileage history not found for employee "@ViewData["employeeName"]"</h5>
}
else
{
<h5>Please enter employee name</h5>
}
<p>Mileage history not found for <strong>@ViewData["name"]</strong></p>
}
+1 -1
View File
@@ -1,4 +1,4 @@
@model MileageTraker.Web.Models.Log
@model MileageTraker.Web.ViewModels.Log.LogViewModel
@{
ViewBag.Title = "Create Log";
+1 -1
View File
@@ -1,4 +1,4 @@
@model MileageTraker.Web.Models.Log
@model MileageTraker.Web.ViewModels.Log.LogViewModel
@{
ViewBag.Title = "Delete Log";
+1 -1
View File
@@ -1,4 +1,4 @@
@model MileageTraker.Web.Models.Log
@model MileageTraker.Web.ViewModels.Log.LogViewModel
@{
ViewBag.Title = "Log Details";
+1 -1
View File
@@ -1,4 +1,4 @@
@model MileageTraker.Web.Models.Log
@model MileageTraker.Web.ViewModels.Log.LogViewModel
@{
ViewBag.Title = "Edit Log";
+1 -1
View File
@@ -56,7 +56,7 @@
grid.Column("GasPurchased", "Gas", item => item.GasPurchased > 0 ? String.Format("{0:0.000}", item.GasPurchased) : string.Empty),
grid.Column("Date", format: item => item.Date.ToString("d")),
grid.Column("CityName", "City Name"),
grid.Column("EmployeeName", "Employee Name", item => item.User != null ? item.User.FullName : ""),
grid.Column("Driver Name", format: item => item.User != null ? item.User.FullName : ""),
grid.Column(format:
@<div class='btn-group'>
@Html.ActionLink("Edit", "Edit", new { id = item.LogId }, new { @class = "btn btn-mini" })
@@ -0,0 +1,11 @@
@model MileageTraker.Web.ViewModels.CheckBoxViewModel
@{
Layout = "~/Views/Shared/EditorTemplates/_FieldLayout.cshtml";
ViewData.ModelMetadata.DisplayName = "Roles";
}
@Html.CheckBoxListFor(
m => m.Selected,
m => m.Available,
m => m,
m => m,
m => m.Selected)
@@ -11,9 +11,5 @@
{
@Html.Editor(prop.PropertyName)
}
else
{
}
}
}
+5 -3
View File
@@ -23,14 +23,16 @@
<span class="brand"></span>
<div class="nav-collapse collapse">
<ul class="nav">
@if (Roles.IsUserInRole(User.Identity.Name, "Administrator")
|| Roles.IsUserInRole(User.Identity.Name, "Developer"))
@if (User.IsInRole("Driver") || User.IsInRole("Developer") || User.IsInRole("Administrator"))
{
<li>@Html.ActionLink("Enter Log", "Index", "CreateLog")</li>
}
@if (User.IsInRole("Developer") || User.IsInRole("Administrator"))
{
<li id="log-nav">@Html.ActionLink("Logs", "Index", "Log")</li>
<li id="vehicle-nav">@Html.ActionLink("Vehicles", "Index", "Vehicle")</li>
<li id="user-nav">@Html.ActionLink("Users", "Index", "User")</li>
}
<li>@Html.ActionLink("Enter Log", "Index", "CreateLog")</li>
</ul>
<section id="account-management">
@Html.Partial("_NavAccountInfo")
+1 -2
View File
@@ -8,13 +8,12 @@
<h2 class="center-content">@ViewBag.Title</h2>
@using (Html.BeginForm("Create", "User", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
@using (Html.BeginForm("Create", "User", FormMethod.Post, new { @class = "form-horizontal well center-content create-user" }))
{
@Html.Partial("_ValidationSummary")
<fieldset>
<legend></legend>
@Html.EditorForModel()
@Html.Partial("_Roles", Model)
<div class="form-actions">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
+2 -2
View File
@@ -13,6 +13,8 @@
<div class="center-content well">
@Html.DisplayFor(m => m.FullName)
<dl class="dl-horizontal username">
<dt>
@Html.DisplayNameFor(m => m.Username)
@@ -25,8 +27,6 @@
@Html.DisplayFor(m => m.Email)
@Html.DisplayFor(m => m.FullName)
<dl class="dl-horizontal roles">
<dt>
@Html.DisplayNameFor(m => m.Roles)
-1
View File
@@ -18,7 +18,6 @@
<legend></legend>
@Html.EditorForModel()
@Html.Partial("_Roles", Model)
<div class="form-actions">
<input type="submit" value="Save" class="btn btn-primary" />
+2 -2
View File
@@ -25,6 +25,7 @@
@grid.GetHtml(columns:
grid.Columns(
grid.Column("FullName", "Full Name"),
grid.Column("Username", format:
@<text>
<span title="@Html.Encode(item.Email)">
@@ -37,7 +38,6 @@
LastLockoutDate = item.LastLockoutDate,
IsApproved = item.IsApproved})
</text> ),
grid.Column("FullName", "Full Name"),
grid.Column("Roles", format:
@<text>
@{var roles = Roles.Provider.GetRolesForUser(item.Username);}
@@ -50,7 +50,7 @@
<span class='label label-warning'>No Role</span>
}
</text>),
grid.Column("LastActivityDate", "Last Activity", format:
grid.Column("LastActivityDate", "Last Activity",
@<text>
@Html.Partial("_LastActivity", (DateTime)item.LastActivityDate)
</text>),
-10
View File
@@ -1,10 +0,0 @@
@model MileageTraker.Web.ViewModels.User.RolesViewModel
@{
Layout = "~/Views/Shared/EditorTemplates/_FieldLayout.cshtml";
}
@Html.CheckBoxListFor(
m => m.Roles,
m => m.AvailableRoles,
m => m,
m => m,
m => m.Roles)
+4 -2
View File
@@ -13,9 +13,11 @@
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="enableSimpleMembership" value="false" />
<add key="ResetPasswordBody" value="Please open this link to set a new password: {0}" />
<add key="ResetPasswordFromAddress" value="Mileage Traker &lt;noreply@ethra.org&gt;" />
<add key="EmailFromAddress" value="Mileage Traker &lt;noreply@ethra.org&gt;" />
<add key="ResetPasswordSubject" value="New Password Request" />
<add key="ResetPasswordBody" value="Please open this link to set a new password: {0}" />
<add key="InitializePasswordSubject" value="Initialize Mileage Traker Account" />
<add key="InitializetPasswordBody" value="Hello {1}, please open this link to set up your password on Mileage Traker: {0}" />
</appSettings>
<system.net>
<mailSettings>
+3 -2
View File
@@ -161,14 +161,15 @@
<Compile Include="ViewModels\Account\LoginViewModel.cs" />
<Compile Include="ViewModels\Account\NewPasswordViewModel.cs" />
<Compile Include="ViewModels\Account\RegisterModel.cs" />
<Compile Include="ViewModels\CheckBoxViewModel.cs" />
<Compile Include="ViewModels\EmployeeMileageItem.cs" />
<Compile Include="ViewModels\EmployeeMileageViewModel.cs" />
<Compile Include="ViewModels\Log\LogViewModel.cs" />
<Compile Include="ViewModels\Log\LogIndexViewModel.cs" />
<Compile Include="ViewModels\Log\LogPartialDetails.cs" />
<Compile Include="ViewModels\User\SetPasswordViewModel.cs" />
<Compile Include="ViewModels\User\CreateUserViewModel.cs" />
<Compile Include="ViewModels\User\EditUserViewModel.cs" />
<Compile Include="ViewModels\User\RolesViewModel.cs" />
<Compile Include="ViewModels\Vehicle\VehicleMileageViewModel.cs" />
<Compile Include="ViewModels\Vehicle\VehiclePartialDetails.cs" />
<Compile Include="ViewModels\Vehicle\VehicleMileageItem.cs" />
@@ -295,13 +296,13 @@
<Content Include="Views\Shared\EditorTemplates\EmailAddress.cshtml" />
<Content Include="Views\Shared\DisplayTemplates\EmailAddress.cshtml" />
<Content Include="Views\Shared\DisplayTemplates\Boolean.cshtml" />
<Content Include="Views\User\_Roles.cshtml" />
<Content Include="Views\User\SetPassword.cshtml" />
<Content Include="Views\Shared\_StatusMessage.cshtml" />
<Content Include="Views\User\_UserStatusLabels.cshtml" />
<Content Include="Views\Account\ResetPassword.cshtml" />
<Content Include="Views\Account\NewPassword.cshtml" />
<Content Include="Views\User\_LastActivity.cshtml" />
<Content Include="Views\Shared\EditorTemplates\CheckBoxViewModel.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config">