using System; using System.Data.SqlTypes; using System.Linq; using System.Web.Mvc; using System.Web.Security; using MileageTraker.Web.Attributes; using MileageTraker.Web.Email; using MileageTraker.Web.Utility; using MileageTraker.Web.ViewModels; using MileageTraker.Web.ViewModels.User; namespace MileageTraker.Web.Controllers { [Authorize(Roles = "Administrator, Developer")] public class UserController : ControllerBase { public ActionResult Index() { var users = DataService .GetUsers() .ToList() .OrderBy(u => u.Username); return View(users); } [ActionLog] public ActionResult Export() { var users = DataService.GetUsers(); var userViewModels = users .ToList() .OrderBy(u => u.Username) .Select(log => new ExportUserViewModel(log)); var name = string.Format( "MileageTrakerUsers_{0:MM-dd-yyyy}", DateTime.Today); var export = ExcelWriter.WriteXls(userViewModels, name, name); return File(export, "application/ms-excel", name + ".xls"); } public ActionResult Details(Guid id) { var user = Membership.GetUser(id); if (user == null) { return HttpNotFound(); } return View(DataService.GetUser(id)); } public ActionResult DetailsFullName(string employeeName) { var user = DataService.FindUserByFullName(employeeName); if (user == null) { user = DataService.FindUserByUsername(employeeName); if (user == null) { TempData["StatusMessage"] = "User " + employeeName + " not found"; return RedirectToAction("Index"); } } return View("Details", user); } public JsonResult UsernameAvailable(string username) { var user = DataService.FindUserByUsername(username); return Json(user == null, JsonRequestBehavior.AllowGet); } public JsonResult FullNameAvailable(string fullname) { 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 { Roles = new CheckBoxViewModel{ Available = Roles.GetAllRoles(), Selected = new []{"Driver"} // default driver } }; return View(vm); } [ActionLog] [HttpPost] public ActionResult Create(CreateUserViewModel viewModel) { if (ModelState.IsValid) { MembershipCreateStatus membershipCreateStatus; var membershipUser = Membership.CreateUser( viewModel.Username, "uninitialized_state", viewModel.Email, null, null, true, out membershipCreateStatus); if (membershipUser == null) { ModelState.AddModelError("", ErrorCodeToString(membershipCreateStatus)); viewModel.Roles.Available = Roles.GetAllRoles(); return View(viewModel); } if (viewModel.Roles != null) { Roles.AddUserToRoles( membershipUser.UserName, 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.Roles.Available = Roles.GetAllRoles(); return View(viewModel); } [HttpGet] public JsonResult SendInvite(Guid userId) { var user = DataService.GetUser(userId); var resetPasswordUrl = ResetPassword(user); var email = new EmailNotificationService(); email.SendInitializePassword(user, resetPasswordUrl); return Json(true, JsonRequestBehavior.AllowGet); } [HttpGet] public ActionResult SendResetPassword(Guid userId) { var user = DataService.GetUser(userId); var resetPasswordUrl = ResetPassword(user); var email = new EmailNotificationService(); email.SendResetPassword(user, resetPasswordUrl); TempData["StatusMessage"] = "Reset password sent to User " + user.Username + " at " + user.Email; return RedirectToAction("Details", new { id = userId}); } [Authorize(Roles = "Developer")] public ActionResult InviteUninitialized() { var uninitializedUsers = (from user in DataService.GetUsers() where user.LastPasswordChangedDate == SqlDateTime.MinValue.Value && user.LastActivityDate == SqlDateTime.MinValue.Value && user.IsApproved orderby user.Username select user).ToList(); return View(uninitializedUsers); } public ActionResult Edit(Guid id) { var user = DataService.GetUser(id); if (user == null) { return HttpNotFound(); } var vm = new EditUserViewModel(user) { Roles = new CheckBoxViewModel { Selected = Roles.GetRolesForUser(user.Username), Available = Roles.GetAllRoles() } }; return View(vm); } [ActionLog] [HttpPost] public ActionResult Edit(EditUserViewModel viewModel) { if (ModelState.IsValid) { var user = DataService.GetUser(viewModel.UserId); viewModel.UpdateUser(user); DataService.UpdateUserPersonalInfo(user); Roles.RemoveUserFromRoles(user.Username, Roles.GetAllRoles()); if (viewModel.Roles != null) { Roles.AddUserToRoles( user.Username, viewModel.Roles.Selected); } TempData["StatusMessage"] = "Changes saved for " + user.Username; return RedirectToAction("Details", new { id = viewModel.UserId}); } return View(viewModel); } public ActionResult SetPassword(Guid id) { var user = Membership.GetUser(id); if (user == null) return HttpNotFound(); var viewModel = new SetPasswordViewModel {UserId = id, Username = user.UserName}; return View(viewModel); } [HttpPost] public ActionResult SetPassword(SetPasswordViewModel viewModel) { if (ModelState.IsValid) { DataService.UpdateUserPassword(viewModel.UserId, viewModel.NewPassword); TempData["StatusMessage"] = "Password set for " + viewModel.Username; return RedirectToAction("Details", new { id = viewModel.UserId}); } // If we got this far, something failed, redisplay form return View(viewModel); } [ActionLog] public ActionResult DisableUser(Guid id) { var user = DataService.GetUser(id); if (user == null) { return HttpNotFound(); } if (user.Username == User.Identity.Name) { TempData["StatusMessage"] = "Cannot disable yourself!"; TempData["StatusMessage-Type"] = "alert-error"; } else { user.IsApproved = false; DataService.UpdateUser(user); TempData["StatusMessage"] = user.Username + " disabled"; } if (Request.UrlReferrer != null) return Redirect(Request.UrlReferrer.AbsolutePath); return RedirectToAction("Index"); } [ActionLog] 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"); } [ActionLog] 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"); } [Authorize(Roles = "Driver, Administrator, Developer")] public JsonResult Autocomplete(string term) { var employees = DataService.GetUserFullNamesAutocomplete(term); return Json(employees, JsonRequestBehavior.AllowGet); } 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."; } } } }