using System; using System.Globalization; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin.Security; using HealthchoiceMVC.Models; using System.Configuration; using HealthchoiceMVC.Services; using System.Collections.Generic; using Facebook; using System.Web.Providers.Entities; using Microsoft.AspNet.Identity.EntityFramework; using HealthchoiceMVC.NonDbModels; using System.Data.Entity; using Microsoft.Ajax.Utilities; using System.Web.UI.WebControls.Expressions; using HealthchoiceMVC.ViewModels; namespace HealthchoiceMVC.Controllers { [Authorize] public class AccountController : Controller { private ApplicationSignInManager _signInManager; private ApplicationUserManager _userManager; private HCLocalService service = new HCLocalService(); CommonController common = new CommonController(); private bool noPractices = false; public Int32 practiceId = 0; public AccountController() { } public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager ) { UserManager = userManager; SignInManager = signInManager; } public ApplicationSignInManager SignInManager { get { return _signInManager ?? HttpContext.GetOwinContext().Get(); } private set { _signInManager = value; } } public ApplicationUserManager UserManager { get { return _userManager ?? HttpContext.GetOwinContext().GetUserManager(); } private set { _userManager = value; } } // // GET: /Account/Login [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } // // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); } // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, change to shouldLockout: true var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: var user = await UserManager.FindAsync(model.Email, model.Password); if(user!= null) { switch (user.AccountType) { case 1: //IdentityUserRole role = new IdentityUserRole("practitioner"); Session["userLevel"] = "practitioner"; break; case 7: Session["userLevel"] = "practiceadmin"; break; default: break; } using (HCDBEntities entities = new HCDBEntities()) { //now we check if person exisits var person = await entities.Persons.Where(i => i.LinkedLogin == user.Id).FirstOrDefaultAsync().ConfigureAwait(false); if (person == null) { return View("Error"); } //now check usertype var practicePeople = await entities.PracticePersons.Include(i=> i.Practice) .Where(i => i.PersonId == person.PersonId && i.ActiveIndic ==true).OrderBy(i=> i.Practice.PracticeId) .ToListAsync() .ConfigureAwait(false); if(practicePeople.Count == 0) { return View("Error"); } //get a list of practice this person is tied to List practices = new List(); int practiceId = 0; foreach (PracticePerson practicePerson in practicePeople) { if(practiceId == 0) { var practice = await entities.Practices.Where(i => i.PracticeId == practicePerson.Practice.PracticeId).FirstOrDefaultAsync().ConfigureAwait(false); if(practice.ValidatedDate == null) { ModelState.AddModelError("Email", "Practice has not been activated"); return View(model); } Session["PracticeId"] = practicePerson.Practice.PracticeId; practiceId = practicePerson.Practice.PracticeId; break; } //for (int m = 0; m < practices.Count; m++) //{ // if(practices[m].PracticeId== practice.PracticeId) // { // blAdd = false; // } //} //if (blAdd) //{ // practices.Add(practice); //} } } } //ProviderController pControl = new ProviderController(); //provider p = pControl.GetProvider(user.Id); //if(p.prov_key == 0) //{ // p.prov_first_name = user.FirstName; // p.prov_surname = user.LastName; // p.prov_cell_no = user.ContactNumber; // p.prov_email = user.Email; // //redirect to create_short // return RedirectToAction("CreateShort", "Provider"); //} //var profileData = new UserProfileSessionData //{ // UserId = user.Id, // SessionID = HttpContext.Session.SessionID //}; //this.Session["UserProfile"] = profileData; //UserProfileSessionData.UpdateUserSessionVariables(HttpContext.Session.SessionID, user.Id, user.FirstName + " " + user.LastName, 0, null); var roles = await UserManager.GetRolesAsync(user.Id); if (roles.Contains("SiteAdmin")) { return RedirectToAction("Index", "SiteAdmin"); } return RedirectToAction("Index", "Home"); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: default: ModelState.AddModelError("", "Invalid login attempt."); return View(model); } //return View(model); } // // GET: /Account/VerifyCode [AllowAnonymous] public async Task VerifyCode(string provider, string returnUrl, bool rememberMe) { // Require that the user has already logged in via username/password or external login if (!await SignInManager.HasBeenVerifiedAsync()) { return View("Error"); } return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe }); } // // POST: /Account/VerifyCode [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task VerifyCode(VerifyCodeViewModel model) { if (!ModelState.IsValid) { return View(model); } // The following code protects for brute force attacks against the two factor codes. // If a user enters incorrect codes for a specified amount of time then the user account // will be locked out for a specified amount of time. // You can configure the account lockout settings in IdentityConfig var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser); switch (result) { case SignInStatus.Success: return RedirectToLocal(model.ReturnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.Failure: default: ModelState.AddModelError("", "Invalid code."); return View(model); } } [AllowAnonymous] public ActionResult Thankyou() { return View(); } // // GET: /Account/Register [AllowAnonymous] public ActionResult Register() { PopulateViewBag(); //remove this after testing RegisterViewModel rvm = new RegisterViewModel(); rvm.AccountType=4; //rvm.ConfirmPassword = "Spiders1!"; //rvm.ContactNumber = "0727977277"; //rvm.FirstName = "Pierre"; //rvm.LastName = "Doctor"; //rvm.Password = "Spiders1!"; return View(rvm); //return View(); } [AllowAnonymous] public ActionResult RegisterPractice() { PopulateViewBag("practice"); //remove this after testing RegisterPracticeViewModel rvm = new RegisterPracticeViewModel(); rvm.AccountType = 4; //rvm.ConfirmPassword = "Spiders1!"; //rvm.ContactNumber = "0727977277"; //rvm.FirstName = "Pierre"; //rvm.LastName = "Doctor";using(HCDBEntities //rvm.Password = "Spiders1!"; return View(rvm); //return View(); } [AllowAnonymous] public async Task RegisterPractitioner(string refNo) { practiceId = 0; Person person = new Person(); person.CreatedDate = DateTime.Now; person.DateofBirth = new DateTime(1900, 1, 1); //var pID = Session["PracticeId"]; //if (pID == null) //{ // return HttpNotFound(); //} //var practiceId = Convert.ToInt32(pID); using (HCDBEntities db = new HCDBEntities() ) { var personInvite = await db.PracticeInvites.Where(i => i.PracticeInviteId.ToString() == refNo).FirstOrDefaultAsync().ConfigureAwait(false); if(personInvite == null) { return View("Error"); } practiceId = personInvite.PracticeId; person.FirstName = personInvite.InviteName; person.LastName = personInvite.InviteSurname; person.Gender = ""; var personTypeId = await db.PersonTypes.Where(i => i.Description == "Practitioner").Select(i => i.PersonTypeId).FirstOrDefaultAsync().ConfigureAwait(false); RegisterPractitioner_vm v = new RegisterPractitioner_vm(); v.Practitioner = person; v.prov_discipline_code = 0; v.prov_discipline_desc = ""; v.prov_sub_discipline_desc = ""; v.prov_sub_discipline_key = 0; v.prov_hpcsa_no = ""; v.Password = ""; v.ConfirmPassword = ""; v.Email = personInvite.InviteEmail; PopulateViewBag("practitioner"); if(noPractices) { return View("DenyPractice"); } return View(v); } } [HttpPost] [AllowAnonymous] public async Task RegisterPractitioner(FormCollection formCollection) { int practiceId = 0; string practiceRef = Request.QueryString["refNo"]; using (HCDBEntities db = new HCDBEntities()) { var personInvite = await db.PracticeInvites.Where(i => i.PracticeInviteId.ToString() == practiceRef).FirstOrDefaultAsync().ConfigureAwait(false); if (personInvite == null) { return View("Error"); } practiceId = personInvite.PracticeId; } var md = formCollection["TermsAndConditions"]; if(md == "true,false") { md = "true"; } if (!Convert.ToBoolean(md)) { ModelState.AddModelError(String.Empty, "Please accept our terms and conditions before proceeding"); } var pID = Convert.ToInt32(formCollection["pID"]); //var practiceId = Convert.ToInt32(formCollection["practiceId"]); if(practiceId == 0) { practiceId = pID; } if(practiceId == 0) { ModelState.AddModelError(String.Empty, "Cannot determine practice details"); } RegisterPractitioner_vm v = new RegisterPractitioner_vm(); Person p = new Person { PersonId = Convert.ToInt32(formCollection["Practitioner.PersonId"]), TitleId = Convert.ToInt32(formCollection["Practitioner.TitleId"]), FirstName = formCollection["Practitioner.FirstName"], MiddleName = formCollection["Practitioner.MiddleName"], LastName = formCollection["Practitioner.LastName"], Gender = formCollection["Practitioner.Gender"], IdentityNumber = formCollection["Practitioner.IdentityNumber"], IDTypeId = Convert.ToInt32(formCollection["Practitioner.IDTypeId"]), LinkedLogin = formCollection["Practitioner.LinkedLogin"], DateofBirth = Convert.ToDateTime(formCollection["Practitioner.DateofBirth"]), CreatedDate = Convert.ToDateTime(formCollection["Practitioner.CreatedDate"]) }; v.practiceId = practiceId; v.ContactNumber = formCollection["ContactNumber"]; v.prov_discipline_code = Convert.ToInt32(formCollection["prov_discipline_code"]); v.prov_sub_discipline_key = Convert.ToInt32(formCollection["prov_sub_discipline_key"]); v.prov_hpcsa_no = formCollection["prov_hpcsa_no"]; v.AccountType = Convert.ToInt32(formCollection["AccountType"]); v.Email = formCollection["Email"]; v.Practitioner = p; v.Password = formCollection["Password"]; if (v.Practitioner.IDTypeId.ToString().Equals("1") && v.Practitioner.IdentityNumber.Length != 13) { ModelState.AddModelError(String.Empty, "Your South African ID Number should be 13 digits."); } ApplicationUser user = new ApplicationUser(); bool blUserCreated = false; try { using (HCDBEntities db = new HCDBEntities()) { //now we check if patient exists var existpersonField = await db.PersonFields.Where(i => i.FieldType == "prov_hpcsa_no" && i.FieldValue.Trim() == v.prov_hpcsa_no.Trim()).FirstOrDefaultAsync().ConfigureAwait(false); if (existpersonField != null) { ModelState.AddModelError(String.Empty, "Practitioner with this HPCSA number already exists "); } var personContacts = await db.PersonContacts.Where(c => c.ContactTypeId == 1 & c.ContactValue == v.Email).ToListAsync().ConfigureAwait(false); if (personContacts.Count != 0) { ModelState.AddModelError(String.Empty, "Practitioner with this email address already exists "); } var practitioner = await db.Persons.Where(c => c.IdentityNumber.Trim() == p.IdentityNumber.Trim()).FirstOrDefaultAsync().ConfigureAwait(false); if (practitioner != null) { ModelState.AddModelError(String.Empty, "Practitioner with that ID already exists."); } } if (ModelState.IsValid) { user = new ApplicationUser(); user.UserName = v.Email; user.Email = v.Email; user.FirstName = v.Practitioner.FirstName; user.LastName = v.Practitioner.LastName; user.ContactNumber = v.ContactNumber; //this will be a practice manager user.AccountType = v.AccountType; var result = await UserManager.CreateAsync(user, formCollection["Password"]); if (result.Succeeded) { using (HCDBEntities db = new HCDBEntities()) { using (var myTransaction = db.Database.BeginTransaction()) { blUserCreated = true; p.LinkedLogin = user.Id; db.Entry(p).State = EntityState.Added; await db.SaveChangesAsync(); var practicePerson = new PracticePerson { PersonId = p.PersonId, PracticeId = practiceId, PersonTypeId = await db.PersonTypes.Where(i => i.Description == "Practitioner").Select(i => i.PersonTypeId).FirstOrDefaultAsync().ConfigureAwait(false), ActiveIndic = true }; db.PracticePersons.Add(practicePerson); await db.SaveChangesAsync(); //add contact details //email var personContact = new PersonContact { PersonId = p.PersonId, ContactTypeId = await db.ContactTypes.Where(i => i.Description == "email").Select(i => i.ContactTypeId).FirstOrDefaultAsync().ConfigureAwait(false), ContactClassId = await db.ContactClasses.Where(i => i.Description == "work").Select(i => i.ContactClassId).FirstOrDefaultAsync().ConfigureAwait(false), AlternativeClass = "", ContactValue = v.Email, IsValidated = false }; db.PersonContacts.Add(personContact); await db.SaveChangesAsync(); //phone personContact = new PersonContact { PersonId = p.PersonId, ContactTypeId = await db.ContactTypes.Where(i => i.Description == "cellphone").Select(i => i.ContactTypeId).FirstOrDefaultAsync().ConfigureAwait(false), ContactClassId = await db.ContactClasses.Where(i => i.Description == "work").Select(i => i.ContactClassId).FirstOrDefaultAsync().ConfigureAwait(false), AlternativeClass = "", ContactValue = v.ContactNumber, IsValidated = false }; db.PersonContacts.Add(personContact); await db.SaveChangesAsync(); //add discipline PersonField personField = new PersonField { PersonTypeId = await db.PersonTypes.Where(i => i.Description == "Practitioner").Select(i => i.PersonTypeId).FirstOrDefaultAsync().ConfigureAwait(false), PersonId = p.PersonId, FieldType = "prov_discipline_code", FieldValue = v.prov_discipline_code.ToString() }; db.PersonFields.Add(personField); await db.SaveChangesAsync(); //add sub discipline PersonField personField4 = new PersonField { PersonTypeId = await db.PersonTypes.Where(i => i.Description == "Practitioner").Select(i => i.PersonTypeId).FirstOrDefaultAsync().ConfigureAwait(false), PersonId = p.PersonId, FieldType = "prov_sub_discipline_key", FieldValue = v.prov_sub_discipline_key.ToString() }; db.PersonFields.Add(personField4); await db.SaveChangesAsync(); PersonField personField2 = new PersonField { PersonTypeId = await db.PersonTypes.Where(i => i.Description == "Practitioner").Select(i => i.PersonTypeId).FirstOrDefaultAsync().ConfigureAwait(false), PersonId = p.PersonId, FieldType = "prov_hpcsa_no", FieldValue = v.prov_hpcsa_no.ToString() }; db.PersonFields.Add(personField2); await db.SaveChangesAsync(); myTransaction.Commit(); } } } else { PopulateViewBag("practitioner"); return View(v); } //we got this far so now we send the email link // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // Send an email with this link //set usercreate to false as we are only sending email at this stage blUserCreated = false; //need to add handling for email failure try { // var result = await UserManager.CreateAsync(user, model.Password); await SendConfirmationEmail(user.Id); } catch (Exception exc) { } //redirect to the success page return RedirectToAction("Thankyou", "Account"); } else { PopulateViewBag("practitioner"); return View(v); } } catch (Exception exc) { if (blUserCreated) { UserManager.Delete(user); } PopulateViewBag("practitioner"); return View(v); } } private void PopulateViewBag() { ViewBag.TitleList = service.GetLookUpDropDown("title"); var UserTypeList = service.GetUserTypeList(); List UserTypeListFiltered = new List(); foreach (var usertype in UserTypeList) { //only provider phase 1 if (usertype.Value == "4") //Provider or Patient { UserTypeListFiltered.Add(usertype); } } ViewBag.UserTypeList = UserTypeListFiltered; } private void PopulateViewBag(string type) { var UserTypeList = service.GetUserTypeList(); List UserTypeListFiltered = new List(); List PracticeList = new List(); var NetworkList = service.GetNetworkList(); foreach (var usertype in UserTypeList) { if (type == "practice" && usertype.Text.ToLower() == "practicemanager") { UserTypeListFiltered.Add(usertype); } else { if (usertype.Text.Trim().ToLower() == type.ToLower().Trim()) { UserTypeListFiltered.Add(usertype); } } } using(HCDBEntities db = new HCDBEntities()) { //PracticeList.Add(new SelectListItem { Text = "-Please select-", Value = "" }); var practices = db.Practices.Where(i => i.ActiveIndic == true && i.ValidatedDate != null && i.PracticeId == practiceId).OrderBy(i=> i.PracticeName).ToList(); if(practices != null) { foreach (Practice item in practices) { PracticeList.Add(new SelectListItem { Text = item.PracticeName, Value = item.PracticeId.ToString() }); } } else { if(type== "practitioner") { noPractices = true; } } } ViewBag.PracticeList = PracticeList; ViewBag.UserTypeList = UserTypeListFiltered; switch (type.ToLower().Trim()) { case "practice": ViewBag.NetworkAffiliationList = NetworkList; break; default: break; } var selList = service.GetLookUpDropDown("titleid"); var selected = selList.Where(x => x.Value == "").First(); selected.Selected = true; ViewBag.TitleList = selList; selList = service.GetLookUpDropDown("gender"); selected = selList.Where(x => x.Value == "").First(); selected.Selected = true; ViewBag.GenderList = selList; ViewBag.IdType = service.GetLookUpDropDown("id_no_type").Where(i => i.Text == "South African ID"); ViewBag.Disciplines = service.GetDisciplines(); ViewBag.SubDisciplines = service.GetSubDisciplinesByDisciplineCode(72); } // // POST: /Account/Register [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task Register(RegisterViewModel model) { if (ModelState.IsValid) { //nb! check user email address has not been registered before. using (var context = new ApplicationDbContext()) { //var userStore = new UserStore(context); //var userManager = new UserManager(context); ////ApplicationUser existingUser = userManager.FindByName(name); //return user; } var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; user.FirstName = model.FirstName; user.LastName = model.LastName; user.ContactNumber = model.ContactNumber; user.AccountType = model.AccountType; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { //2019/08/22 //remove signin as user must confirm email address //await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // Send an email with this link await SendConfirmationEmail(user.Id); //doing the same checks we do just after registration var roles = await UserManager.GetRolesAsync(user.Id); //if (roles.Contains("SiteAdmin")) //this does not look right - no role will be assigned at this stage! //{ // return RedirectToAction("Index", "SiteAdmin"); //} //if he has completed his registration, return him to the index page. //2019/08/22 //always redirect to home page after registration as user must confirm email address //if (model.AccountType==4) //Healthcare provider //{ // return RedirectToAction("CreateShort", "Provider"); //} //else //{ // return RedirectToAction("Index", "Home"); //} return RedirectToAction("Index", "Home"); } else { AddErrors(result); } } // If we got this far, something failed, redisplay form PopulateViewBag(); return View(model); } // POST: /Account/Register [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task RegisterPractice(RegisterPracticeViewModel model) { //model.PracticeManagerName = model.FirstName + " " + model.LastName; //model.PracticeManagerContactEmail = model.Email; //model.PracticeManagerContactNumber = model.ContactNumber; ////add these two lines //ModelState["PracticeManagerName"].Errors.Clear(); //ModelState["PracticeManagerContactEmail"].Errors.Clear(); //ModelState["PracticeManagerContactNumber"].Errors.Clear(); var md = model.TermsAndConditions; if(!model.TermsAndConditions) { ModelState["TermsAndConditions"].Errors.Clear(); ModelState["TermsAndConditions"].Errors.Add("Please accept our terms and conditions before proceeding"); } ApplicationUser user = new ApplicationUser(); bool blUserCreated = false; try { //UpdateModel(model); //throws invalidoperationexception if (ModelState.IsValid) { // check user email does not exist user = await UserManager.FindByEmailAsync(model.Email); if (user != null) { //we already have a user registration for this email address ModelState["Email"].Errors.Add("Application user with this email address already exists " + model.Email); } using (HCDBEntities entities = new HCDBEntities()) { //now we check if practice manager exists var personContacts = await entities.PersonContacts.Where(c => c.ContactType.Description == "email" & c.ContactValue == model.Email).Include(i => i.Person).ToListAsync().ConfigureAwait(false); if (personContacts.Count != 0) { ModelState["Email"].Errors.Add("Practice Manager with this email address already exists " + model.Email); } var practice = await entities.Practices.Where(c => c.PracticeNumber == model.PracticeNumber).FirstOrDefaultAsync().ConfigureAwait(false); if (practice != null) { ModelState["PracticeNumber"].Errors.Add("Practice with that number already exists."); } practice = await entities.Practices.Where(c => c.PracticeName.Trim() == model.PracticeName.Trim()).FirstOrDefaultAsync().ConfigureAwait(false); if (practice != null) { ModelState["PracticeName"].Errors.Add("Practice with that name already exists."); } } if (ModelState.IsValid) { Practice regPractice = new Practice(); //create a user first user = new ApplicationUser(); user.UserName = model.Email; user.Email = model.Email; user.FirstName = model.FirstName; user.LastName = model.LastName; user.ContactNumber = model.ContactNumber; //this will be a practice manager user.AccountType = model.AccountType; var result = await UserManager.CreateAsync(user, model.Password); //if account is created we go ahead and //create practice if (result.Succeeded) { blUserCreated = true; using (HCDBEntities entities = new HCDBEntities()) { using (var myTransaction = entities.Database.BeginTransaction()) { //add practice Practice practice = new Practice { PracticeName = model.PracticeName, PracticeTradingName = model.PracticeTradingName, PracticeNumber = model.PracticeNumber, PracticePrimaryContactEmail = model.PracticePrimaryContactEmail, AddressLineOne = model.AddressLineOne, AddressLineTwo = model.AddressLineTwo, CityTown = model.CityTown, AreaSuburb = model.AreaSuburb, PostalCode = model.PostalCode, NetworkAffiliationId = model.NetworkAffiliationId, VatNumber = model.VatNumber, RegistrationNumber = model.RegistrationNumber, PracticePrimaryContactNumber = model.PracticePrimaryContactNumber, ActiveIndic = false, AffiliationNumber = model.AffiliationNumber }; regPractice = practice; entities.Practices.Add(practice); await entities.SaveChangesAsync(); //add practice manager var person = new Person { TitleId = model.TitleId, FirstName = model.FirstName, MiddleName = "", LastName = model.LastName, CreatedDate = DateTime.Now, DateofBirth = new DateTime(1900,1,1), LinkedLogin = user.Id, IDTypeId = model.IDTypeId, IdentityNumber = model.IdentityNumber, Gender = model.Gender, }; entities.Persons.Add(person); await entities.SaveChangesAsync(); //persontype record so we know what this is the practice manager //var personPersontype = new PersonPersonType //{ // PersonTypeId = await entities.PersonTypes.Where(i => i.Description == "Practice Manager").Select(i => i.PersonTypeId).FirstOrDefaultAsync().ConfigureAwait(false), // PersonId = person.PersonId //}; //entities.PersonPersonTypes.Add(personPersontype); //await entities.SaveChangesAsync(); //add this person to the practice var practicePerson = new PracticePerson { PersonId = person.PersonId, PracticeId = practice.PracticeId, PersonTypeId = await entities.PersonTypes.Where(i => i.Description == "Practice Manager").Select(i => i.PersonTypeId).FirstOrDefaultAsync().ConfigureAwait(false), ActiveIndic = true }; entities.PracticePersons.Add(practicePerson); await entities.SaveChangesAsync(); //add practice manager contact details //email var personContact = new PersonContact { PersonId = person.PersonId, ContactTypeId = await entities.ContactTypes.Where(i => i.Description == "email").Select(i => i.ContactTypeId).FirstOrDefaultAsync().ConfigureAwait(false), ContactClassId = await entities.ContactClasses.Where(i => i.Description == "work").Select(i => i.ContactClassId).FirstOrDefaultAsync().ConfigureAwait(false), AlternativeClass = "", ContactValue = model.Email, IsValidated = false }; entities.PersonContacts.Add(personContact); await entities.SaveChangesAsync(); //phone personContact = new PersonContact { PersonId = person.PersonId, ContactTypeId = await entities.ContactTypes.Where(i => i.Description == "cellphone").Select(i => i.ContactTypeId).FirstOrDefaultAsync().ConfigureAwait(false), ContactClassId = await entities.ContactClasses.Where(i => i.Description == "work").Select(i => i.ContactClassId).FirstOrDefaultAsync().ConfigureAwait(false), AlternativeClass = "", ContactValue = user.ContactNumber, IsValidated = false }; entities.PersonContacts.Add(personContact); await entities.SaveChangesAsync(); myTransaction.Commit(); } } //we got this far so now we send the email link // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // Send an email with this link //set usercreate to false as we are only sending email at this stage blUserCreated = false; //need to add handling for email failure try { await SendConfirmationEmail(user.Id); await SendRegistrationEmail(user,regPractice); } catch (Exception exc) { } //redirect to the success page return RedirectToAction("Thankyou", "Account"); } else { AddErrors(result); } } } // If we got this far, something failed, redisplay form PopulateViewBag("practice"); return View(model); } catch (Exception exc) { if(blUserCreated) { UserManager.Delete(user); } PopulateViewBag("practice"); return View(model); } } public async Task SendConfirmationEmail(string userId) { ApplicationDbContext appContext = new ApplicationDbContext(); ApplicationUser user = appContext.Users.Find(userId); string code = await UserManager.GenerateEmailConfirmationTokenAsync(userId); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = userId, code = code }, protocol: Request.Url.Scheme); // setup email details string emailSubject = ConfigurationManager.AppSettings.Get("EmailSubject"); emailSubject = string.Format("Healthchoice - Confirm your account"); string emailBody = "
"; // Warn if on test or dev system //if (ConfigurationManager.AppSettings.Get("EnvironmentSetting") == "TEST") //{ // emailBody += "THIS IS A TEST! THIS IS A TEST!

"; //} emailBody += string.Format("Dear " + user.FirstName + "

Thanks for registering with Healthchoice. We need you to confirm that your email address is setup correctly." + "

" + "

Please click here to go to the website to confirm your email address.", callbackUrl) + "

If you are not " + user.FirstName + ", please ignore this email and/or report this to info@healthchoice.co.za



Regards,

The Healthchoice Team"; emailBody += "
"; await UserManager.SendEmailAsync(userId, emailSubject, emailBody); } public async Task SendValidationConfirmationEmail(string userId) { ApplicationDbContext appContext = new ApplicationDbContext(); ApplicationUser user = appContext.Users.Find(userId); var callbackUrl = Url.Action("Login", "Account",null , protocol: Request.Url.Scheme); // setup email details string emailSubject = ConfigurationManager.AppSettings.Get("EmailSubject"); emailSubject = string.Format("Healthchoice - Practice Activated"); string emailBody = "
"; // Warn if on test or dev system //if (ConfigurationManager.AppSettings.Get("EnvironmentSetting") == "TEST") //{ // emailBody += "THIS IS A TEST! THIS IS A TEST!

"; //} emailBody += string.Format("Dear " + user.FirstName + "

This email is to confirm that the practice you have registered has been activated." + "

" + "

Please click here to login. If you have not validated your email address, please do so before trying to login. ", callbackUrl) + "

If you are not " + user.FirstName + ", please ignore this email and/or report this to info@healthchoice.co.za



Regards,

The Healthchoice Team"; emailBody += "
"; await UserManager.SendEmailAsync(userId, emailSubject, emailBody); } public async Task SendRegistrationEmail(ApplicationUser user, Practice practice) { ApplicationDbContext appContext = new ApplicationDbContext(); var callbackUrlNo = Url.Action("ConfirmAccount", "Account", new { practiceId = practice.PracticeId, userId = user.Id,active= false }, protocol: Request.Url.Scheme); var callbackUrlYes = Url.Action("ConfirmAccount", "Account", new { practiceId = practice.PracticeId, userId = user.Id, active = true }, protocol: Request.Url.Scheme); // setup email details string emailSubject = ConfigurationManager.AppSettings.Get("EmailSubject"); emailSubject = string.Format("Healthchoice - Activate Practive Account"); string emailBody = "
"; emailBody += "Dear Admin

A new practice has registered on Healthchoice. You need to activate the practice.

"; emailBody += "

Practice Name: " + practice.PracticeName + "

"; emailBody += "

Practice Number: " + practice.PracticeNumber + "

"; emailBody += "

Practice Primary Contact Number: " + practice.PracticePrimaryContactNumber + "

"; emailBody += "

Practice Primary Contact Email: " + practice.PracticePrimaryContactEmail + "

"; emailBody += string.Format("

Please click here to activate the practice on Healthchoice.", callbackUrlYes) + "

"; emailBody += string.Format("

Please click here to decline activation on Healthchoice.", callbackUrlNo) + ". The user will be informed.

"; emailBody += "

Regards,

The Healthchoice Team

"; emailBody += "
"; var userToSend = await UserManager.FindByEmailAsync("verification@healthchoice.co.za"); //var userToSend = await UserManager.FindByEmailAsync("hendricks.wayne@gmail.com"); try { await UserManager.SendEmailAsync(userToSend.Id, emailSubject, emailBody); } catch (Exception exc) { throw; } } // // GET: /Account/ConfirmEmail [AllowAnonymous] public async Task ConfirmEmail(string userId, string code) { if (userId == null || code == null) { return View("Error"); } using (HCDBEntities entities = new HCDBEntities()) { //check user exists var user = await UserManager.FindByIdAsync(userId); if (user == null) { return View("Error"); } //now we check if person exisits var person = await entities.Persons.Where(i => i.LinkedLogin == userId).FirstOrDefaultAsync().ConfigureAwait(false); if (person == null) { return View("Error"); } //update person contact details to confirmed var personContact = await entities.PersonContacts.Where(c => c.PersonId == person.PersonId && c.ContactType.Description == "email" & c.ContactValue == user.Email) .FirstOrDefaultAsync() .ConfigureAwait(false); if (personContact == null) { return View("Error"); } personContact.IsValidated = true; personContact.DateValidated = DateTime.Now; //now check usertype var practive = await entities.PracticePersons.Include(i => i.Practice).Where(i => i.PersonId == person.PersonId && i.Practice.ActiveIndic == false).OrderByDescending(i=> i.PracticeId).FirstOrDefaultAsync().ConfigureAwait(false); //var personpersonType = await entities.PersonPersonTypes // .Where(i => i.PersonTypeId == entities.PersonTypes // .Where(k => k.Description == "Practice Manager") // .Select(o => o.PersonTypeId) // .FirstOrDefault()) // .FirstOrDefaultAsync() // .ConfigureAwait(false); //var practice = await entities.Practices // .Where(i => i.PracticeId == entities.PracticePersons //.Where(o => o.PersonPersonTypeId == personpersonType.PersonPersonTypeId && o.ActiveIndic == true) //.Select(l => l.PracticeId) //.FirstOrDefault()).FirstOrDefaultAsync().ConfigureAwait(false); //if(practice == null) //{ // return View("Error"); //} personContact.IsValidated = true; personContact.DateValidated = DateTime.Now; if (user.AccountType == 7) { practive.Practice.ActiveIndic = true; } await entities.SaveChangesAsync(); } //confirm email var result = await UserManager.ConfirmEmailAsync(userId, code); return View(result.Succeeded ? "ConfirmEmail" : "Error"); } [AllowAnonymous] public async Task ConfirmAccount(string practiceId, string userId ,string active) { if (userId == null || practiceId == null) { return View("Error"); } using (HCDBEntities entities = new HCDBEntities()) { //check user exists var user = await UserManager.FindByIdAsync(userId); if (user == null) { return View("Error"); } int practiceID = Convert.ToInt32(practiceId); var practice = await entities.Practices.Where(i=> i.PracticeId == practiceID).FirstOrDefaultAsync().ConfigureAwait(false); if (practice == null) { return View("Error"); } if(Convert.ToBoolean(active)) { practice.ValidatedDate = DateTime.Now; } else { practice.ValidatedDate = null; await entities.SaveChangesAsync(); return View(true ? "DenyAccount" : "Error"); } //now we check if person exisits var person = await entities.Persons.Where(i => i.LinkedLogin == userId).FirstOrDefaultAsync().ConfigureAwait(false); if (person == null) { return View("Error"); } //update person contact details to confirmed var personContact = await entities.PersonContacts.Where(c => c.PersonId == person.PersonId && c.ContactType.Description == "email" & c.ContactValue == user.Email) .FirstOrDefaultAsync() .ConfigureAwait(false); if (personContact == null) { return View("Error"); } //now check usertype await entities.PracticePersons.Include(i => i.Practice).Where(i => i.PersonId == person.PersonId && i.Practice.ActiveIndic == false).OrderByDescending(i => i.PracticeId).FirstOrDefaultAsync().ConfigureAwait(false); await entities.SaveChangesAsync(); if (user.AccountType == 7) { //send email confirming account activated await SendValidationConfirmationEmail(user.Id); } } //confirm email //var result = await UserManager.ConfirmEmailAsync(userId, code); return View(true ? "ConfirmAccount" : "Error"); } // // GET: /Account/ForgotPassword [AllowAnonymous] public ActionResult ForgotPassword() { return View(); } // // POST: /Account/ForgotPassword [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task ForgotPassword(ForgotPasswordViewModel model) { if (ModelState.IsValid) { var user = await UserManager.FindByNameAsync(model.Email); if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id))) { // Don't reveal that the user does not exist or is not confirmed return View("ForgotPasswordConfirmation"); } // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // Send an email with this link string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking here"); return RedirectToAction("ForgotPasswordConfirmation", "Account"); } // If we got this far, something failed, redisplay form return View(model); } // // GET: /Account/ForgotPasswordConfirmation [AllowAnonymous] public ActionResult ForgotPasswordConfirmation() { return View(); } // // GET: /Account/ResetPassword [AllowAnonymous] public ActionResult ResetPassword(string code) { return code == null ? View("Error") : View(); } // // POST: /Account/ResetPassword [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task ResetPassword(ResetPasswordViewModel model) { if (!ModelState.IsValid) { return View(model); } var user = await UserManager.FindByNameAsync(model.Email); if (user == null) { // Don't reveal that the user does not exist return RedirectToAction("ResetPasswordConfirmation", "Account"); } var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password); if (result.Succeeded) { return RedirectToAction("ResetPasswordConfirmation", "Account"); } AddErrors(result); return View(); } // // GET: /Account/ResetPasswordConfirmation [AllowAnonymous] public ActionResult ResetPasswordConfirmation() { return View(); } // // POST: /Account/ExternalLogin [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult ExternalLogin(string provider, string returnUrl) { // Request a redirect to the external login provider return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl })); } // // GET: /Account/SendCode [AllowAnonymous] public async Task SendCode(string returnUrl, bool rememberMe) { var userId = await SignInManager.GetVerifiedUserIdAsync(); if (userId == null) { return View("Error"); } var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(userId); var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList(); return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe }); } // // POST: /Account/SendCode [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task SendCode(SendCodeViewModel model) { if (!ModelState.IsValid) { return View(); } // Generate the token and send it if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider)) { return View("Error"); } return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe }); } // // GET: /Account/ExternalLoginCallback [AllowAnonymous] public async Task ExternalLoginCallback(string returnUrl) { var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); if (loginInfo == null) { return RedirectToAction("Login"); } // Sign in the user with this external login provider if the user already has a login var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false }); case SignInStatus.Failure: default: // If the user does not have an account, then prompt the user to create an account ViewBag.ReturnUrl = returnUrl; ViewBag.LoginProvider = loginInfo.Login.LoginProvider;// added the following lines string userName = null, eMail = null, firstName = null, lastName = null; if (loginInfo.Login.LoginProvider == "Facebook") { var identity = AuthenticationManager.GetExternalIdentity(DefaultAuthenticationTypes.ExternalCookie); var access_token = identity.FindFirstValue("FacebookAccessToken"); var fb = new FacebookClient(access_token); dynamic userInfo = fb.Get("/me?fields=email,gender,first_name,last_name"); // specify the email field eMail = userInfo.email; userName = eMail; firstName = userInfo.first_name; lastName = userInfo.last_name; } PopulateViewBag(); return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = userName, FirstName = firstName, LastName = lastName }); } } // // POST: /Account/ExternalLoginConfirmation [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) { if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "Manage"); } if (ModelState.IsValid) { // Get the information about the user from the external login provider var info = await AuthenticationManager.GetExternalLoginInfoAsync(); if (info == null) { return View("ExternalLoginFailure"); } var user = new ApplicationUser { UserName = model.UserName, Email = model.UserName, FirstName = model.FirstName, LastName = model.LastName, ContactNumber = model.ContactNumber, AccountType = model.AccountType, EmailConfirmed = true }; var result = await UserManager.CreateAsync(user); if (result.Succeeded) { result = await UserManager.AddLoginAsync(user.Id, info.Login); if (result.Succeeded) { await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); //return RedirectToLocal(returnUrl); //if (model.UserName != model.Email) //{ // await SendConfirmationEmail(user.Id); // return RedirectToAction("Index", "Home"); //} //else //{ return RedirectToLocal(returnUrl); //} } } AddErrors(result); } PopulateViewBag(); ViewBag.ReturnUrl = returnUrl; return View(model); } // // POST: /Account/LogOff [HttpPost] [ValidateAntiForgeryToken] public ActionResult LogOff() { AuthenticationManager.SignOut(); return RedirectToAction("Index", "Home"); } // // GET: /Account/ExternalLoginFailure [AllowAnonymous] public ActionResult ExternalLoginFailure() { return View(); } protected override void Dispose(bool disposing) { if (disposing) { if (_userManager != null) { _userManager.Dispose(); _userManager = null; } if (_signInManager != null) { _signInManager.Dispose(); _signInManager = null; } } base.Dispose(disposing); } #region Helpers // Used for XSRF protection when adding external logins private const string XsrfKey = "XsrfId"; private IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } } private void AddErrors(IdentityResult result) { foreach (var error in result.Errors) { ModelState.AddModelError("", error); } } private ActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } return RedirectToAction("Index", "Home"); } internal class ChallengeResult : HttpUnauthorizedResult { public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null) { } public ChallengeResult(string provider, string redirectUri, string userId) { LoginProvider = provider; RedirectUri = redirectUri; UserId = userId; } public string LoginProvider { get; set; } public string RedirectUri { get; set; } public string UserId { get; set; } public override void ExecuteResult(ControllerContext context) { var properties = new AuthenticationProperties { RedirectUri = RedirectUri }; if (UserId != null) { properties.Dictionary[XsrfKey] = UserId; } context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); } } #endregion } }