using System.Linq; using System.Web.Mvc; using System.Web.Security; using Hangfire; using JoinExtensions.Enumerable; using LeafWeb.WebCms.Models; using LeafWeb.WebCms.Services; using log4net; using MlkPwgen; using Umbraco.Core; using Umbraco.Web.Mvc; namespace LeafWeb.WebCms.Controllers { public class MembershipController : BaseController { public ActionResult Verify(string email, string token) { var redirectUrl = "/"; var memberService = ApplicationContext.Current.Services.MemberService; var member = memberService.GetByEmail(email); var logger = LogManager.GetLogger(GetType()); if (member == null) { TempData["StatusMessage"] = "Sorry, verification was not found. Please try to register again, or use Contact Us to resolve the issue."; TempData["StatusMessage-Type"] = "alert-danger"; } else if (member.IsApproved) { TempData["StatusMessage"] = "You've already been verified, " + member.Name; TempData["StatusMessage-Type"] = "alert-info"; } else { var storedToken = member.GetValue(LeafWebMemberProperties.VerificationToken); if (string.IsNullOrEmpty(storedToken)) { TempData["StatusMessage"] = $"No verification token exists for this user."; TempData["StatusMessage-Type"] = "alert-danger"; } else if (storedToken != token) { TempData["StatusMessage"] = $"Sorry, your token cannot be found. Please try to register again, or use Contact Us to resolve the issue."; TempData["StatusMessage-Type"] = "alert-danger"; } else { // member is now verified member.IsApproved = true; // remove the verification member.SetValue(LeafWebMemberProperties.VerificationToken, string.Empty); memberService.Save(member); TempData["StatusMessage"] = $"Thank you! Your email is now verified at {member.Email}, use your password to login."; TempData["StatusMessage-Type"] = "alert-success"; logger.InfoFormat($"User {member.Email} verified."); redirectUrl = "membership/login"; } } return Redirect(redirectUrl); } public ActionResult PasswordResetRequest() { var viewModel = new PasswordResetRequestForm(); return PartialView("PasswordResetRequest", viewModel); } [HttpPost] public ActionResult PasswordResetRequest(PasswordResetRequestForm model) { if (!ModelState.IsValid) return CurrentUmbracoPage(); var memberService = ApplicationContext.Current.Services.MemberService; var member = memberService.GetByEmail(model.Email); if (member == null) { // Send notification of attempt to change BackgroundJob.Enqueue( e => e.SendPasswordResetNotMemberEmail(model.Email)); } else { var token = PasswordGenerator.Generate(12, allowed: "0123456789"); member.SetValue(LeafWebMemberProperties.PasswordResetToken, token); memberService.Save(member); // Send Email BackgroundJob.Enqueue( e => e.SendPasswordResetEmail(member.Email)); } // don't acknowledge their email address TempData["StatusMessage"] = $"An email has been sent to {model.Email} with instructions on how to reset your password."; TempData["StatusMessage-Type"] = "alert-success"; return Redirect("/"); } public ActionResult PasswordReset(string email, string token) { var errorMsg = $"Sorry, a valid password reset was not found for user {email}. " + $"Please try resetting again, " + $"or use Contact Us if the issue persists."; if (!string.IsNullOrEmpty(email) && !string.IsNullOrEmpty(token)) { var memberService = ApplicationContext.Current.Services.MemberService; var member = memberService.GetByEmail(email); if (member == null) { // don't acknowledge their email address TempData["StatusMessage"] = errorMsg; TempData["StatusMessage-Type"] = "alert-danger"; } else { var storedToken = member.GetValue(LeafWebMemberProperties.PasswordResetToken); if (string.IsNullOrEmpty(storedToken)) { TempData["StatusMessage"] = errorMsg; TempData["StatusMessage-Type"] = "alert-danger"; } else if (storedToken != token) { TempData["StatusMessage"] = errorMsg; TempData["StatusMessage-Type"] = "alert-danger"; } else { var viewModel = new PasswordResetForm {Email = email, PasswordResetToken = token}; return PartialView(viewModel); } } } return PasswordResetRequest(); } [HttpPost] public ActionResult PasswordReset(PasswordResetForm model) { var redirectUrl = "/"; var errorMsg = $"Sorry, a valid password reset was not found for user {model.Email}. " + $"Please try resetting again, " + $"or use Contact Us if the issue persists."; if (ModelState.IsValid) { var memberService = ApplicationContext.Current.Services.MemberService; var member = memberService.GetByEmail(model.Email); if (member == null) { // don't acknowledge their email address TempData["StatusMessage"] = errorMsg; TempData["StatusMessage-Type"] = "alert-danger"; } else { var storedToken = member.GetValue(LeafWebMemberProperties.PasswordResetToken); if (string.IsNullOrEmpty(storedToken)) { TempData["StatusMessage"] = errorMsg; TempData["StatusMessage-Type"] = "alert-danger"; } else if (storedToken != model.PasswordResetToken) { TempData["StatusMessage"] = errorMsg; TempData["StatusMessage-Type"] = "alert-danger"; } else { try { memberService.SavePassword(member, model.Password); // remove the token member.SetValue(LeafWebMemberProperties.PasswordResetToken, string.Empty); memberService.Save(member); TempData["StatusMessage"] = $"Password updated for {member.Email}, use your new password to login."; TempData["StatusMessage-Type"] = "alert-success"; redirectUrl = "/membership/login"; } catch (MembershipPasswordException) { ModelState.AddModelError("Password", "Please choose a stronger password"); model.Password = model.PasswordVerify = string.Empty; return CurrentUmbracoPage(); //return PartialView(form); } } } } return Redirect(redirectUrl); } [MemberAuthorize(AllowGroup = "Administrator")] public ActionResult UserList() { var leafInputUsers= from li in DataService.GetLeafInputs() group li by li.Email into emailGroup select new UserViewModel { Email = emailGroup.Key, Name = emailGroup.FirstOrDefault().Name, LeafInputCount = emailGroup.Count(), FirstSeen = emailGroup.OrderBy(e => e.Added).FirstOrDefault().Added }; var memberService = ApplicationContext.Current.Services.MemberService; // join leaf input users and memberships together on email address var users = memberService.GetAllMembers() .FullOuterJoinExtEnumerable( leafInputUsers, m => m.Email, uvm => uvm.Email, (member, leafInputUser) => { if (member == null) return leafInputUser; var vm = new UserViewModel { Email = member.Email, Name = member.Name, Member = true, FirstSeen = member.CreateDate }; if (leafInputUser == null) return vm; vm.LeafInputCount = leafInputUser.LeafInputCount; if (leafInputUser.FirstSeen < vm.FirstSeen) vm.FirstSeen = leafInputUser.FirstSeen; return vm; }); return View(users.DistinctBy(u => u.Email).OrderByDescending(u => u.FirstSeen)); } } }