Admin auth functionally complete
This commit is contained in:
@@ -6,7 +6,6 @@ body {
|
|||||||
.center-content {
|
.center-content {
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
padding: 10px;
|
|
||||||
margin: 0 auto 20px;
|
margin: 0 auto 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +77,6 @@ footer {
|
|||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert .close {
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qtip-content dt {
|
.qtip-content dt {
|
||||||
line-height: 10px;
|
line-height: 10px;
|
||||||
width: 110px;
|
width: 110px;
|
||||||
@@ -211,7 +206,6 @@ dl.inline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.center-content {
|
.center-content {
|
||||||
padding: 5px;
|
|
||||||
margin: 0 auto 10px;
|
margin: 0 auto 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.Security;
|
using System.Web.Security;
|
||||||
|
using MileageTraker.Web.DAL;
|
||||||
using MileageTraker.Web.ViewModels.Account;
|
using MileageTraker.Web.ViewModels.Account;
|
||||||
|
|
||||||
namespace MileageTraker.Web.Controllers
|
namespace MileageTraker.Web.Controllers
|
||||||
@@ -22,17 +23,28 @@ namespace MileageTraker.Web.Controllers
|
|||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
var success = Membership.ValidateUser(model.Username, model.Password);
|
try
|
||||||
if (success)
|
|
||||||
{
|
{
|
||||||
FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
|
var success = Membership.ValidateUser(model.Username, model.Password);
|
||||||
TempData["StatusMessage"] = "Logged in as " + model.Username;
|
if (success)
|
||||||
return RedirectToLocal(returnUrl);
|
{
|
||||||
|
FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
|
||||||
|
TempData["StatusMessage"] = "Logged in as " + model.Username;
|
||||||
|
return RedirectToLocal(returnUrl);
|
||||||
|
}
|
||||||
|
ModelState.AddModelError("", "The user name or password provided is incorrect.");
|
||||||
|
}
|
||||||
|
catch (UserAccountDisabledException)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError("", "Account is disabled for " + model.Username + ".");
|
||||||
|
}
|
||||||
|
catch (UserLockedOutException)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError("", "Too many failed password attempts for " + model.Username + ". Account is locked.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got this far, something failed, redisplay form
|
// If we got this far, something failed, redisplay form
|
||||||
ModelState.AddModelError("", "The user name or password provided is incorrect.");
|
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,9 +52,10 @@ namespace MileageTraker.Web.Controllers
|
|||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
public ActionResult LogOff()
|
public ActionResult LogOff()
|
||||||
{
|
{
|
||||||
|
TempData["StatusMessage"] = User.Identity.Name + " logged off";
|
||||||
|
|
||||||
FormsAuthentication.SignOut();
|
FormsAuthentication.SignOut();
|
||||||
|
|
||||||
TempData["StatusMessage"] = "Logged off";
|
|
||||||
return RedirectToAction("Index", "CreateLog");
|
return RedirectToAction("Index", "CreateLog");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +94,7 @@ namespace MileageTraker.Web.Controllers
|
|||||||
ViewBag.StatusMessage =
|
ViewBag.StatusMessage =
|
||||||
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
|
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
|
||||||
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
|
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
|
||||||
: "";
|
: null;
|
||||||
ViewBag.ReturnUrl = Url.Action("Manage");
|
ViewBag.ReturnUrl = Url.Action("Manage");
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
@@ -108,7 +121,7 @@ namespace MileageTraker.Web.Controllers
|
|||||||
|
|
||||||
if (changePasswordSucceeded)
|
if (changePasswordSucceeded)
|
||||||
{
|
{
|
||||||
TempData["StatusMessage"] = ManageMessageId.ChangePasswordSuccess;
|
TempData["StatusMessage"] = "Your password has been changed.";
|
||||||
return RedirectToAction("Manage");
|
return RedirectToAction("Manage");
|
||||||
}
|
}
|
||||||
ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
|
ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace MileageTraker.Web.Controllers
|
|||||||
[HttpParamAction]
|
[HttpParamAction]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ActionLog]
|
[ActionLog]
|
||||||
public ViewResult Confirm(CreateLogViewModel model)
|
public ActionResult Confirm(CreateLogViewModel model)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
@@ -59,7 +59,16 @@ namespace MileageTraker.Web.Controllers
|
|||||||
log.UserHostAddress = HttpContext.Request.UserHostAddress;
|
log.UserHostAddress = HttpContext.Request.UserHostAddress;
|
||||||
log.UserAgent = HttpContext.Request.UserAgent;
|
log.UserAgent = HttpContext.Request.UserAgent;
|
||||||
DataService.AddLog(log);
|
DataService.AddLog(log);
|
||||||
return View("Success", model);
|
TempData["StatusMessage-Type"] = "alert-success";
|
||||||
|
TempData["StatusMessage"] =
|
||||||
|
@"You've successfully created an entry
|
||||||
|
for <strong>" + model.EmployeeName + @"</strong>
|
||||||
|
traveling to <strong>" + model.CityName + @"</strong>
|
||||||
|
on <strong>" + model.Date.ToShortDateString() + @"</strong>
|
||||||
|
in Vehicle Id <strong>" + model.VehicleId + @"</strong>
|
||||||
|
ending in <strong>" + model.EndOdometer + @"</strong>
|
||||||
|
miles on the odometer.";
|
||||||
|
return RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
return View("Index", model);
|
return View("Index", model);
|
||||||
|
|||||||
@@ -24,6 +24,18 @@ namespace MileageTraker.Web.Controllers
|
|||||||
return View(DataService.GetUser(id));
|
return View(DataService.GetUser(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JsonResult UsernameAvailable(string username)
|
||||||
|
{
|
||||||
|
var user = DataService.FindUserByUsername(username);
|
||||||
|
return Json(user == null, JsonRequestBehavior.AllowGet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonResult EmailAvailable(string email)
|
||||||
|
{
|
||||||
|
var user = DataService.FindUserByEmail(email);
|
||||||
|
return Json(user == null, JsonRequestBehavior.AllowGet);
|
||||||
|
}
|
||||||
|
|
||||||
public ActionResult Create()
|
public ActionResult Create()
|
||||||
{
|
{
|
||||||
var vm = new CreateUserViewModel
|
var vm = new CreateUserViewModel
|
||||||
@@ -111,7 +123,7 @@ namespace MileageTraker.Web.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
TempData["StatusMessage"] = "Changes saved for " + user.Username;
|
TempData["StatusMessage"] = "Changes saved for " + user.Username;
|
||||||
return RedirectToAction("Index");
|
return RedirectToAction("Details", new { id = viewModel.UserId});
|
||||||
}
|
}
|
||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
@@ -132,7 +144,6 @@ namespace MileageTraker.Web.Controllers
|
|||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
// ChangePassword will throw an exception rather than return false in certain failure scenarios.
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DataService.UpdateUserPassword(viewModel.UserId, viewModel.NewPassword);
|
DataService.UpdateUserPassword(viewModel.UserId, viewModel.NewPassword);
|
||||||
@@ -149,6 +160,58 @@ namespace MileageTraker.Web.Controllers
|
|||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ActionResult DisableUser(Guid id)
|
||||||
|
{
|
||||||
|
var user = DataService.GetUser(id);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return HttpNotFound();
|
||||||
|
}
|
||||||
|
user.IsApproved = false;
|
||||||
|
DataService.UpdateUser(user);
|
||||||
|
|
||||||
|
TempData["StatusMessage"] = user.Username + " disabled";
|
||||||
|
|
||||||
|
if (Request.UrlReferrer != null)
|
||||||
|
return Redirect(Request.UrlReferrer.AbsolutePath);
|
||||||
|
return RedirectToAction("Index");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult EnableUser(Guid id)
|
||||||
|
{
|
||||||
|
var user = DataService.GetUser(id);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return HttpNotFound();
|
||||||
|
}
|
||||||
|
user.IsApproved = true;
|
||||||
|
DataService.UpdateUser(user);
|
||||||
|
|
||||||
|
TempData["StatusMessage"] = user.Username + " enabled";
|
||||||
|
|
||||||
|
if (Request.UrlReferrer != null)
|
||||||
|
return Redirect(Request.UrlReferrer.AbsolutePath);
|
||||||
|
return RedirectToAction("Index");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult UnlockUser(Guid id)
|
||||||
|
{
|
||||||
|
var user = DataService.GetUser(id);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return HttpNotFound();
|
||||||
|
}
|
||||||
|
user.IsLockedOut = false;
|
||||||
|
user.PasswordFailuresSinceLastSuccess = 0;
|
||||||
|
DataService.UpdateUser(user);
|
||||||
|
|
||||||
|
TempData["StatusMessage"] = user.Username + " unlocked";
|
||||||
|
|
||||||
|
if (Request.UrlReferrer != null)
|
||||||
|
return Redirect(Request.UrlReferrer.AbsolutePath);
|
||||||
|
return RedirectToAction("Index");
|
||||||
|
}
|
||||||
|
|
||||||
private static string ErrorCodeToString(MembershipCreateStatus createStatus)
|
private static string ErrorCodeToString(MembershipCreateStatus createStatus)
|
||||||
{
|
{
|
||||||
// See http://go.microsoft.com/fwlink/?LinkID=177550 for
|
// See http://go.microsoft.com/fwlink/?LinkID=177550 for
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ namespace MileageTraker.Web.Controllers
|
|||||||
}
|
}
|
||||||
return View(vehicle);
|
return View(vehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
public JsonResult Exists(string vehicleId)
|
public JsonResult Exists(string vehicleId)
|
||||||
{
|
{
|
||||||
var vehicle = DataService.GetVehicle(vehicleId);
|
var vehicle = DataService.GetVehicle(vehicleId);
|
||||||
|
|||||||
@@ -136,11 +136,11 @@ namespace MileageTraker.Web.DAL
|
|||||||
}
|
}
|
||||||
if (!user.IsApproved)
|
if (!user.IsApproved)
|
||||||
{
|
{
|
||||||
return false;
|
throw new UserAccountDisabledException();
|
||||||
}
|
}
|
||||||
if (user.IsLockedOut)
|
if (user.IsLockedOut)
|
||||||
{
|
{
|
||||||
return false;
|
throw new UserLockedOutException();
|
||||||
}
|
}
|
||||||
var hashedPassword = user.Password;
|
var hashedPassword = user.Password;
|
||||||
var verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, password));
|
var verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, password));
|
||||||
|
|||||||
@@ -475,6 +475,8 @@ namespace MileageTraker.Web.DAL
|
|||||||
var user = GetUser(userId);
|
var user = GetUser(userId);
|
||||||
user.Password = Crypto.HashPassword(password);
|
user.Password = Crypto.HashPassword(password);
|
||||||
user.LastPasswordChangedDate = DateTime.Now;
|
user.LastPasswordChangedDate = DateTime.Now;
|
||||||
|
user.IsLockedOut = false;
|
||||||
|
user.PasswordFailuresSinceLastSuccess = 0;
|
||||||
UpdateUser(user);
|
UpdateUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MileageTraker.Web.DAL
|
||||||
|
{
|
||||||
|
public class UserAccountDisabledException : Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MileageTraker.Web.DAL
|
||||||
|
{
|
||||||
|
public class UserLockedOutException : Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -253,7 +253,8 @@ $(function () {
|
|||||||
},
|
},
|
||||||
unhighlight: function (element) {
|
unhighlight: function (element) {
|
||||||
$(element).closest(".control-group").removeClass("error");
|
$(element).closest(".control-group").removeClass("error");
|
||||||
}
|
},
|
||||||
|
debug: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using MileageTraker.Web.Models;
|
|
||||||
|
|
||||||
namespace MileageTraker.Web.Utility
|
namespace MileageTraker.Web.Utility
|
||||||
{
|
{
|
||||||
@@ -182,11 +181,5 @@ namespace MileageTraker.Web.Utility
|
|||||||
Convert.ToDouble(
|
Convert.ToDouble(
|
||||||
System.Web.Security.Membership.UserIsOnlineTimeWindow)));
|
System.Web.Security.Membership.UserIsOnlineTimeWindow)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsOnline(this User user)
|
|
||||||
{
|
|
||||||
return user.LastActivityDate != null
|
|
||||||
&& user.LastActivityDate > UserOnlineThreshold();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Web.Mvc;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using MileageTraker.Web.Attributes;
|
using MileageTraker.Web.Attributes;
|
||||||
|
|
||||||
@@ -9,12 +10,14 @@ namespace MileageTraker.Web.ViewModels.User
|
|||||||
[Required]
|
[Required]
|
||||||
[StringLength(64)]
|
[StringLength(64)]
|
||||||
[InputSize("small")]
|
[InputSize("small")]
|
||||||
|
[Remote("UsernameAvailable", "User", ErrorMessage = "Username already in use")]
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[DataType(DataType.EmailAddress)]
|
[DataType(DataType.EmailAddress)]
|
||||||
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
|
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
|
||||||
[InputSize("large")]
|
[InputSize("large")]
|
||||||
|
[Remote("EmailAvailable", "User", ErrorMessage = "Email already in use")]
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@using (Html.BeginForm("Login", "Account", new { ViewBag.ReturnUrl }, FormMethod.Post, new {@class = "form-login"})) {
|
@using (Html.BeginForm("Login", "Account", new { ViewBag.ReturnUrl }, FormMethod.Post, new {@class = "form-login"})) {
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<div class="header"></div>
|
<div class="header"></div>
|
||||||
|
|
||||||
<h2>@ViewBag.Title</h2>
|
<h2>@ViewBag.Title</h2>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
ViewBag.Title = "Enter Mileage Log";
|
ViewBag.Title = "Enter Mileage Log";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
@using (Html.BeginForm("Index", "CreateLog", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
@using (Html.BeginForm("Index", "CreateLog", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
@model MileageTraker.Web.ViewModels.CreateLog.CreateLogViewModel
|
|
||||||
@{
|
|
||||||
ViewBag.Title = "Success";
|
|
||||||
}
|
|
||||||
|
|
||||||
<p class="alert alert-success center-content">
|
|
||||||
You've successfully created an entry
|
|
||||||
for <strong>@Html.DisplayTextFor(m => m.EmployeeName)</strong>
|
|
||||||
traveling to <strong>@Html.DisplayTextFor(m => m.CityName)</strong>
|
|
||||||
on <strong>@Html.Encode(Model.Date.ToShortDateString())</strong>
|
|
||||||
in Vehicle Id <strong>@Html.DisplayTextFor(m => m.VehicleId)</strong>
|
|
||||||
ending in <strong>@Html.DisplayTextFor(m => m.EndOdometer)</strong>
|
|
||||||
miles on the odometer.
|
|
||||||
</p>
|
|
||||||
<p class="center-content">
|
|
||||||
@Html.ActionLink("Create another", "Index", null, new { @class = "btn" })
|
|
||||||
</p>
|
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
@{ Html.RenderPartial("BackToLogs"); }
|
@{ Html.RenderPartial("BackToLogs"); }
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
@using (Html.BeginForm("Create", "Log", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
@using (Html.BeginForm("Create", "Log", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
@{ Html.RenderPartial("BackToLogs"); }
|
@{ Html.RenderPartial("BackToLogs"); }
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
<div class="center-content label label-warning">Are you sure you wish to delete this log?</div>
|
<div class="center-content label label-warning">Are you sure you wish to delete this log?</div>
|
||||||
|
|||||||
@@ -15,9 +15,6 @@
|
|||||||
<li class="previous">
|
<li class="previous">
|
||||||
@Html.ActionLink("Previous", "PreviousDetails", new { id = Model.LogId })
|
@Html.ActionLink("Previous", "PreviousDetails", new { id = Model.LogId })
|
||||||
</li>
|
</li>
|
||||||
@if(TempData["Message"] != null) { // so, yeah, span doesn't go here, but it renders
|
|
||||||
<span class="alert">@TempData["Message"]</span>
|
|
||||||
}
|
|
||||||
<li class="next">
|
<li class="next">
|
||||||
@Html.ActionLink("Next", "NextDetails", new { id = Model.LogId })
|
@Html.ActionLink("Next", "NextDetails", new { id = Model.LogId })
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
@{ Html.RenderPartial("BackToLogs"); }
|
@{ Html.RenderPartial("BackToLogs"); }
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
@using (Html.BeginForm("Edit", "Log", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
@using (Html.BeginForm("Edit", "Log", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
@{ Html.RenderPartial("BackToLogs"); }
|
@{ Html.RenderPartial("BackToLogs"); }
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2>@ViewBag.Title</h2>
|
<h2>@ViewBag.Title</h2>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
@{ Html.RenderPartial("BackToLogs"); }
|
@{ Html.RenderPartial("BackToLogs"); }
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2>@ViewBag.Title</h2>
|
<h2>@ViewBag.Title</h2>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
@if (TempData.ContainsKey("StatusMessage"))
|
@if (TempData.ContainsKey("StatusMessage"))
|
||||||
{
|
{
|
||||||
<p class="center-content alert alert-info">
|
<p class="center-content alert @Html.Raw(TempData["StatusMessage-Type"])">
|
||||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||||
@TempData["StatusMessage"]
|
@Html.Raw(TempData["StatusMessage"])
|
||||||
</p>
|
</p>
|
||||||
} else if (ViewBag.StatusMessage != null)
|
} else if (ViewBag.StatusMessage != null)
|
||||||
{
|
{
|
||||||
<p class="center-content alert alert-info">
|
<p class="center-content alert">
|
||||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||||
@ViewBag.StatusMessage
|
@ViewBag.StatusMessage
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -12,9 +12,20 @@
|
|||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
<div class="center-content well">
|
<div class="center-content well">
|
||||||
|
|
||||||
|
<dl class="dl-horizontal username">
|
||||||
|
<dt>
|
||||||
|
@Html.DisplayNameFor(m => m.Username)
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
@Html.Encode(Model.Username)
|
||||||
|
@Html.Partial("_UserStatusLabels")
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
@Html.DisplayFor(m => m.Email)
|
@Html.DisplayFor(m => m.Email)
|
||||||
@Html.DisplayFor(m => m.Username)
|
|
||||||
|
@Html.DisplayFor(m => m.FullName)
|
||||||
|
|
||||||
<dl class="dl-horizontal roles">
|
<dl class="dl-horizontal roles">
|
||||||
<dt>
|
<dt>
|
||||||
@@ -33,7 +44,7 @@
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<dl class="dl-horizontal lastActivity">
|
<dl class="dl-horizontal lastActivityDate">
|
||||||
<dt>
|
<dt>
|
||||||
@Html.DisplayNameFor(m => m.LastActivityDate)
|
@Html.DisplayNameFor(m => m.LastActivityDate)
|
||||||
</dt>
|
</dt>
|
||||||
@@ -50,14 +61,73 @@
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<dl class="dl-horizontal lastLoginDate">
|
||||||
|
<dt>
|
||||||
|
@Html.DisplayNameFor(m => m.LastLoginDate)
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
@if (!Model.LastLoginDate.IsSqlMinValue())
|
||||||
|
{
|
||||||
|
@Html.Encode(Model.LastLoginDate)
|
||||||
|
<span class="muted">(@Html.Encode((DateTime.Now - Model.LastLoginDate).ToVerboseStringHistoric()))</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span class='label label-info'>Never Logged In</span>
|
||||||
|
}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<dl class="dl-horizontal lastPasswordChangedDate">
|
||||||
|
<dt>
|
||||||
|
@Html.DisplayNameFor(m => m.LastPasswordChangedDate)
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
@if (!Model.LastPasswordChangedDate.IsSqlMinValue())
|
||||||
|
{
|
||||||
|
@Html.Encode(Model.LastPasswordChangedDate)
|
||||||
|
<span class="muted">(@Html.Encode((DateTime.Now - Model.LastPasswordChangedDate).ToVerboseStringHistoric()))</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span class='label label-info'>Never Changed</span>
|
||||||
|
}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
@if (Model.IsLockedOut) {
|
@if (Model.IsLockedOut) {
|
||||||
<p class="alert alert-info">
|
<dl class="dl-horizontal lastLockoutDate">
|
||||||
Locked out on @Html.DisplayTextFor(m => m.LastLockoutDate)
|
<dt>
|
||||||
</p>
|
Lockout Password Date
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
@if (!Model.LastLockoutDate.IsSqlMinValue())
|
||||||
|
{
|
||||||
|
@Html.Encode(Model.LastLockoutDate)
|
||||||
|
<span class="muted">(@Html.Encode((DateTime.Now - Model.LastLockoutDate).ToVerboseStringHistoric()))</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span class='label label-info'>Never Locked (?)</span>
|
||||||
|
}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-toolbar center-content">
|
<div class="btn-toolbar center-content">
|
||||||
@Html.ActionLink("Edit", "Edit", new { id = Model.UserId }, new { @class = "btn" })
|
@Html.ActionLink("Edit", "Edit", new { id = Model.UserId }, new { @class = "btn" })
|
||||||
@Html.ActionLink("Set Password", "SetPassword", new { id = Model.UserId }, new { @class = "btn" })
|
@Html.ActionLink("Set Password", "SetPassword", new { id = Model.UserId }, new { @class = "btn" })
|
||||||
|
@if (Model.IsApproved)
|
||||||
|
{
|
||||||
|
@Html.ActionLink("Disable Account", "DisableUser", new {id = Model.UserId}, new {@class = "btn"})
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@Html.ActionLink("Enable Account", "EnableUser", new {id = Model.UserId}, new {@class = "btn"})
|
||||||
|
}
|
||||||
|
@if (Model.IsLockedOut)
|
||||||
|
{
|
||||||
|
@Html.ActionLink("Unlock", "UnlockUser", new {id = Model.UserId}, new {@class = "btn"})
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
@{ Html.RenderPartial("BackToUsers"); }
|
@{ Html.RenderPartial("BackToUsers"); }
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
@using (Html.BeginForm("Edit", "User", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
@using (Html.BeginForm("Edit", "User", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||||
@@ -25,5 +27,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<div class="btn-toolbar center-content">
|
<div class="btn-toolbar center-content">
|
||||||
@Html.ActionLink("Set Password", "SetPassword", new { id = Model.UserId }, new { @class = "btn" })
|
@Html.ActionLink("Details", "Details", new { id = Model.UserId }, new { @class = "btn" })
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+15
-18
@@ -1,5 +1,5 @@
|
|||||||
@using MileageTraker.Web.Utility
|
@using MileageTraker.Web.Models
|
||||||
@model IEnumerable<MileageTraker.Web.Models.User>
|
@model IEnumerable<User>
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewBag.Title = "Users";
|
ViewBag.Title = "Users";
|
||||||
@@ -21,23 +21,20 @@
|
|||||||
grid.Columns(
|
grid.Columns(
|
||||||
grid.Column("Username", format:
|
grid.Column("Username", format:
|
||||||
@<text>
|
@<text>
|
||||||
<span title="@Html.Encode(item.Email)">
|
<span title="@Html.Encode(item.Email)">
|
||||||
@Html.Encode(item.Username)
|
@Html.Encode(item.Username)
|
||||||
</span>
|
</span>
|
||||||
@if (item.LastActivityDate > CustomExtensions.UserOnlineThreshold()) {
|
@Html.Partial("_UserStatusLabels",
|
||||||
<span class='label label-info'>Online</span>
|
new User{
|
||||||
}
|
LastActivityDate = item.LastActivityDate,
|
||||||
@if (item.IsLockedOut) {
|
IsLockedOut = item.IsLockedOut,
|
||||||
<span class='label label-warning' title="@string.Format("Locked out on {0:d}", item.LastLockoutDate)">Locked Out</span>
|
LastLockoutDate = item.LastLockoutDate,
|
||||||
}
|
IsApproved = item.IsApproved})
|
||||||
@if (!item.IsApproved)
|
</text> ),
|
||||||
{
|
|
||||||
<span class='label label-inverse'>Account Disabled</span>
|
|
||||||
}</text> ),
|
|
||||||
grid.Column("FullName", "Full Name"),
|
grid.Column("FullName", "Full Name"),
|
||||||
grid.Column("Roles", format:
|
grid.Column("Roles", format:
|
||||||
@<text>
|
@<text>
|
||||||
@{ var roles = Roles.Provider.GetRolesForUser(item.Username); }
|
@{var roles = Roles.Provider.GetRolesForUser(item.Username);}
|
||||||
@if (roles.Length > 0)
|
@if (roles.Length > 0)
|
||||||
{
|
{
|
||||||
@Html.Encode(string.Join(", ", roles))
|
@Html.Encode(string.Join(", ", roles))
|
||||||
@@ -49,8 +46,8 @@
|
|||||||
</text>),
|
</text>),
|
||||||
grid.Column(format:
|
grid.Column(format:
|
||||||
@<div class='btn-group'>
|
@<div class='btn-group'>
|
||||||
@Html.ActionLink("Edit", "Edit", new { id = item.UserId }, new { @class = "btn btn-mini" })
|
@*Html.ActionLink("Edit", "Edit", new { id = item.UserId }, new { @class = "btn btn-mini" })*@
|
||||||
@Html.ActionLink("Details", "Details", new { id = item.UserId }, new { @class = "btn btn-mini" })
|
@Html.ActionLink("Details / Edit", "Details", new { id = item.UserId }, new { @class = "btn btn-mini" })
|
||||||
</div>)
|
</div>)
|
||||||
),
|
),
|
||||||
htmlAttributes: new { @class = "table table-striped table-bordered table-hover table-condensed"},
|
htmlAttributes: new { @class = "table table-striped table-bordered table-hover table-condensed"},
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
ViewBag.Title = "Change Password";
|
ViewBag.Title = "Change Password";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
@using (Html.BeginForm("SetPassword", "User", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
@using (Html.BeginForm("SetPassword", "User", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
@using MileageTraker.Web.Utility
|
||||||
|
@model MileageTraker.Web.Models.User
|
||||||
|
|
||||||
|
@if (Model.LastActivityDate > CustomExtensions.UserOnlineThreshold())
|
||||||
|
{
|
||||||
|
<span class='label label-info'>Online</span>
|
||||||
|
}
|
||||||
|
@if (Model.IsLockedOut)
|
||||||
|
{
|
||||||
|
<span class='label label-warning' title="@string.Format("Locked out on {0:d} (too many failed login attempts)", Model.LastLockoutDate)">Locked Out</span>
|
||||||
|
}
|
||||||
|
@if (!Model.IsApproved)
|
||||||
|
{
|
||||||
|
<span class='label label-inverse'>Account Disabled</span>
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
@{ Html.RenderPartial("BackToVehicles"); }
|
@{ Html.RenderPartial("BackToVehicles"); }
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
@using (Html.BeginForm("Create", "Vehicle", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
@using (Html.BeginForm("Create", "Vehicle", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
@{ Html.RenderPartial("BackToVehicles"); }
|
@{ Html.RenderPartial("BackToVehicles"); }
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content">@ViewBag.Title</h2>
|
<h2 class="center-content">@ViewBag.Title</h2>
|
||||||
|
|
||||||
@using (Html.BeginForm("Edit", "Vehicle", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
@using (Html.BeginForm("Edit", "Vehicle", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||||
|
|||||||
+3
-1
@@ -124,6 +124,8 @@
|
|||||||
<Compile Include="Controllers\UserController.cs" />
|
<Compile Include="Controllers\UserController.cs" />
|
||||||
<Compile Include="DAL\CodeFirstMembershipProvider.cs" />
|
<Compile Include="DAL\CodeFirstMembershipProvider.cs" />
|
||||||
<Compile Include="DAL\CodeFirstRoleProvider.cs" />
|
<Compile Include="DAL\CodeFirstRoleProvider.cs" />
|
||||||
|
<Compile Include="DAL\UserAccountDisabledException.cs" />
|
||||||
|
<Compile Include="DAL\UserLockedOutException.cs" />
|
||||||
<Compile Include="Migrations\201204181847082_InitialMigration.cs" />
|
<Compile Include="Migrations\201204181847082_InitialMigration.cs" />
|
||||||
<Compile Include="Migrations\201204181847082_InitialMigration.Designer.cs">
|
<Compile Include="Migrations\201204181847082_InitialMigration.Designer.cs">
|
||||||
<DependentUpon>201204181847082_InitialMigration.cs</DependentUpon>
|
<DependentUpon>201204181847082_InitialMigration.cs</DependentUpon>
|
||||||
@@ -234,7 +236,6 @@
|
|||||||
<Content Include="Scripts\jquery.validate.min.js" />
|
<Content Include="Scripts\jquery.validate.min.js" />
|
||||||
<Content Include="Scripts\modernizr-2.6.2.js" />
|
<Content Include="Scripts\modernizr-2.6.2.js" />
|
||||||
<Content Include="Scripts\Shared\Site.js" />
|
<Content Include="Scripts\Shared\Site.js" />
|
||||||
<Content Include="Views\CreateLog\Success.cshtml" />
|
|
||||||
<Content Include="Web.config">
|
<Content Include="Web.config">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -278,6 +279,7 @@
|
|||||||
<Content Include="Views\User\_Roles.cshtml" />
|
<Content Include="Views\User\_Roles.cshtml" />
|
||||||
<Content Include="Views\User\SetPassword.cshtml" />
|
<Content Include="Views\User\SetPassword.cshtml" />
|
||||||
<Content Include="Views\Shared\_StatusMessage.cshtml" />
|
<Content Include="Views\Shared\_StatusMessage.cshtml" />
|
||||||
|
<Content Include="Views\User\_UserStatusLabels.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="packages.config">
|
<Content Include="packages.config">
|
||||||
|
|||||||
Reference in New Issue
Block a user