using System; using System.Data.Entity; using System.Linq; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using EnVisage.Code.BLL; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.Owin.Security; using EnVisage.Models; using EnVisage.Code; using System.Net; using EnVisage.Code.Cache; using EnVisage.Code.UserVoice; using EnVisage.Code.Session; using Microsoft.IdentityModel.Claims; using System.Security.Principal; using System.Threading; using System.Web.Script.Serialization; using EnVisage.App_Start; using EnVisage.Code.Validation; using Resources; using Microsoft.IdentityModel.Web; using Prevu.Core.Main; using EnVisage.Properties; namespace EnVisage.Controllers { [Authorize] public class AccountController : BaseController { #region Properties private IUserManager UserManager { get; } #endregion #region Constructors and Overrides public AccountController(ApplicationUserManager appUserManager, IUserManager userManager) { AppUserManager = appUserManager; UserManager = userManager; } protected override void Dispose(bool disposing) { if (disposing && AppUserManager != null) { AppUserManager.Dispose(); AppUserManager = null; } base.Dispose(disposing); } #endregion #region Properties private ApplicationUserManager AppUserManager { get; set; } // Used for XSRF protection when adding external logins private const string XsrfKey = "XsrfId"; private IAuthenticationManager AuthenticationManager => HttpContext.GetOwinContext().Authentication; #endregion #region Actions // // GET: /Account/Login [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } [AllowAnonymous] public ActionResult SSOFailureNoLocalAccount() { return View(); } [Authorize] public void SSOLogOff() { Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(""), new string[0]); } [Authorize] public async Task SSOLoginConfirmation() { IClaimsPrincipal principal = Thread.CurrentPrincipal as IClaimsPrincipal; if (principal == null) { Logger.Log(NLog.LogLevel.Debug, "user name from principal is null. in SSOLoginConfirmation()", ""); ssoDefault(); return null; } var identity = (IClaimsIdentity)principal.Identity; if (identity.Name == null) Logger.Log(NLog.LogLevel.Debug, "user name from identity is null. in SSOLoginConfirmation()", ""); if (identity.Name != null) { Logger.Log(NLog.LogLevel.Debug, "user name from adfs." + identity.Name, ""); string username = identity.Name; string[] splprm = { "\\" }; string[] names = username.Split(splprm, StringSplitOptions.None); if (names.Length >= 2) username = names[1]; var user = await AppUserManager.FindByNameAsync(username); if (user != null) { if (user.Type == (int)UserType.Active) { identity.Claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id)); //----Create UserVoice Token UserVoiceApi userVoice = new UserVoiceApi(); string ssoToken = UserVoiceGenerator.create(userVoice.GetUserJsonObject(user)); //if (!SessionManager.Exists(Constants.USERVOICE_SSO_TOKEN)) if ((!SessionManager.Exists(Code.Constants.USERVOICE_SSO_TOKEN)) || string.IsNullOrEmpty(ssoToken)) { SessionManager.SetValue(Code.Constants.USERVOICE_SSO_TOKEN, ssoToken); HttpCookie ssoTokenCookie = new HttpCookie(Code.Constants.USERVOICE_COOKIE_CONTEXT); ssoTokenCookie[Code.Constants.USERVOICE_SSO_TOKEN] = ssoToken; ssoTokenCookie.Expires = DateTime.Now.AddDays(30d); Response.Cookies.Add(ssoTokenCookie); } EnVisageEntities cntx = new EnVisageEntities(); var aspuser = cntx.AspNetUsers.FirstOrDefault(x => x.Id == user.Id); if (aspuser != null) { aspuser.LastLoginDate = aspuser.LoginDate; aspuser.LoginDate = DateTime.Now; cntx.Entry(aspuser).State = EntityState.Modified; cntx.SaveChanges(); } } } return user; } return null; } [HttpGet] public ActionResult ssoAuthRefresh() { return View(); } // // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { try { var user = await AppUserManager.FindAsync(model.UserName, model.Password); if (user != null) { if (user.Type == (int)Code.UserType.Active) { await SignInAsync(user, model.RememberMe); //----Create UserVoice Token UserVoiceApi userVoice = new UserVoiceApi(); string ssoToken = UserVoiceGenerator.create(userVoice.GetUserJsonObject(user)); if (!SessionManager.Exists(Code.Constants.USERVOICE_SSO_TOKEN) || string.IsNullOrEmpty(ssoToken)) { SessionManager.SetValue(Code.Constants.USERVOICE_SSO_TOKEN, ssoToken); HttpCookie ssoTokenCookie = new HttpCookie(Code.Constants.USERVOICE_COOKIE_CONTEXT); ssoTokenCookie[Code.Constants.USERVOICE_SSO_TOKEN] = ssoToken; ssoTokenCookie.Expires = DateTime.Now.AddDays(30d); Response.Cookies.Add(ssoTokenCookie); } EnVisageEntities cntx = new EnVisageEntities(); var aspuser = cntx.AspNetUsers.FirstOrDefault(x => x.Id == user.Id); if (aspuser != null) { aspuser.LastLoginDate = aspuser.LoginDate; aspuser.LoginDate = DateTime.Now; cntx.Entry(aspuser).State = EntityState.Modified; cntx.SaveChanges(); } return RedirectToLocal(returnUrl, user.Id); } ModelState.AddModelError("", Messages.Account_NotActive); } else { //var LDAPLogin="planit\\serverLogin"; //For directory lookup //var LDAPPass = "serverPass"; //DirectoryEntry entry = new DirectoryEntry("LDAP://planitserver/OU=People,O=planit", LDAPLogin, LDAPPass); // //DirectorySearcher search = new DirectorySearcher( // // entry, // // "(uid=" + "planit\\" + model.UserName + ")", // // new string[] { "uid" } // //); // //search.SearchScope = System.DirectoryServices.SearchScope.Subtree; // //SearchResult found = search.FindOne(); // //if (found == null){ // // ModelState.AddModelError("", "Invalid username or password."); // // return View(model); // //} //bool result; //using(var context = new PrincipalContext(ContextType.Domain, "planit", LDAPLogin, LDAPPass)) { // //Username and password for authentication. // result = context.ValidateCredentials("planit\\" + model.UserName, model.Password); //} //if (result) //{ // var newuser = new ApplicationUser(); // newuser.UserName = model.UserName; // var creationResult = await AppUserManager.CreateAsync(user, model.Password); // if (creationResult.Succeeded) // creationResult = AppUserManager.AddToRole(newuser.Id, "User"); // await SignInAsync(newuser, model.RememberMe); // return RedirectToLocal(returnUrl); //} //else ModelState.AddModelError("", Messages.Account_InvalidUserNameOrPassword); } } catch (Exception ex) { LogException(ex); } } // If we got this far, something failed, redisplay form return View(model); } // // GET: /Account/Register [AllowAnonymous] [Obsolete] public ActionResult Register() { return View(); } // // POST: /Account/Register [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] [Obsolete] public async Task Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.UserName }; var result = await AppUserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); } AddErrors(result); } // If we got this far, something failed, redisplay form return View(model); } // // POST: /Account/Disassociate [HttpPost] [ValidateAntiForgeryToken] [Obsolete] public async Task Disassociate(string loginProvider, string providerKey) { IdentityResult result = await AppUserManager.RemoveLoginAsync(User.Identity.GetID(), new UserLoginInfo(loginProvider, providerKey)); ManageMessageId? message = result.Succeeded ? ManageMessageId.RemoveLoginSuccess : ManageMessageId.Error; return RedirectToAction("Manage", new { Message = message }); } // // GET: /Account/Manage public ActionResult Manage(ManageMessageId? message) { ViewBag.StatusMessage = message == ManageMessageId.ChangePasswordSuccess ? Messages.Account_PasswordHasBeenChanged : message == ManageMessageId.SetPasswordSuccess ? Messages.Account_PasswordHasBeenSet : message == ManageMessageId.RemoveLoginSuccess ? Messages.Account_ExternalLoginWasRemoved : message == ManageMessageId.Error ? Messages.Common_ErrorHasOccured : ""; ViewBag.HasLocalPassword = HasPassword(); ViewBag.ReturnUrl = Url.Action("Manage"); var userId = User.Identity.GetID(); var user = DbContext.AspNetUsers.Find(userId); var model = new ManageUserViewModel { Email = user.Email, Phone = user.PhoneNumber, PreferredResourceAllocation = user.PreferredResourceAllocation, PreferredTotalsDisplaying = user.PreferredTotalsDisplaying, ShowAutomaticViews = user.ShowAutomaticViews, FirstName = user.FirstName, LastName = user.LastName, UserName = user.UserName, OverUnderCoefficient = Convert.ToDouble(user.OverUnderCoefficient), DomainUser = HttpContext.User.Identity.isSSO() }; return View(model); } // // POST: /Account/Manage [HttpPost] [ValidateAntiForgeryToken] public async Task Manage(ManageUserViewModel model) { bool hasPassword = HasPassword(); ViewBag.HasLocalPassword = hasPassword; ViewBag.ReturnUrl = Url.Action("Manage"); if (hasPassword) { if (ModelState.IsValid) { IdentityResult result = await AppUserManager.ChangePasswordAsync(User.Identity.GetID(), model.OldPassword, model.NewPassword); if (result.Succeeded) return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess }); AddErrors(result); } } else { // User does not have a password so remove any validation errors caused by a missing OldPassword field ModelState state = ModelState["OldPassword"]; if (state != null) state.Errors.Clear(); if (ModelState.IsValid) { IdentityResult result = await AppUserManager.AddPasswordAsync(User.Identity.GetID(), model.NewPassword); if (result.Succeeded) return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess }); AddErrors(result); } } // If we got this far, something failed, redisplay form return View(model); } // // POST: /Account/ChangeEmail [HttpPost] [ValidateAntiForgeryToken] public JsonResult ChangeEmailAndPhone(ManageUserViewModel model) { try { #region remove validation errors for password fields because of weak initial implementatiton // ToDo: separate model to two models for each form separately model.TrimStringProperties(); // User does not have a password so remove any validation errors caused by a missing OldPassword field ModelState state = ModelState["OldPassword"]; if (state != null) state.Errors.Clear(); state = ModelState["NewPassword"]; if (state != null) state.Errors.Clear(); state = ModelState["ConfirmPassword"]; if (state != null) state.Errors.Clear(); #endregion var userId = User.Identity.GetID(); if (model == null || ContentLocker.IsLock("User", userId, User.Identity.Name)) { ModelState.AddModelError(string.Empty, Messages.Account_UpdatedByAnotherUser); return new FailedJsonResult(ModelState); } if (ModelState.IsValid) { var user = AppUserManager.FindById(userId); if (user.Email != model.Email) user.Email = model.Email; if (user.PhoneNumber != model.Phone) user.PhoneNumber = model.Phone; if (user.FirstName != model.FirstName) user.FirstName = model.FirstName; if (user.LastName != model.LastName) user.LastName = model.LastName; user.PreferredResourceAllocation = model.PreferredResourceAllocation; user.PreferredTotalsDisplaying = model.PreferredTotalsDisplaying; user.ShowAutomaticViews = model.ShowAutomaticViews; user.OverUnderCoefficient = Convert.ToDecimal(model.OverUnderCoefficient); AppUserManager.Update(user); new UsersCache().Invalidate(); ContentLocker.RemoveLock("User", userId, User.Identity.Name); return new SuccessJsonResult(); } } catch (BLLException blEx) // handle any system specific error { // display error message if required if (blEx.DisplayError) ModelState.AddModelError(string.Empty, blEx.Message); else // if display not requried then display modal form with general error message { LogException(blEx); ModelState.AddModelError(string.Empty, Messages.Accoun_SaveUser_Error); } } catch (Exception exception) // handle any unexpected error { LogException(exception); ModelState.AddModelError(string.Empty, Messages.Accoun_SaveUser_Error); } return new FailedJsonResult(ModelState); } // // POST: /Account/ExternalLogin [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] [Obsolete] 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/ExternalLoginCallback [AllowAnonymous] [Obsolete] 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 user = await AppUserManager.FindAsync(loginInfo.Login); if (user != null) { await SignInAsync(user, false); return RedirectToLocal(returnUrl, user.Id); } // If the user does not have an account, then prompt the user to create an account ViewBag.ReturnUrl = returnUrl; ViewBag.LoginProvider = loginInfo.Login.LoginProvider; return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = loginInfo.DefaultUserName }); } // // POST: /Account/LinkLogin [HttpPost] [ValidateAntiForgeryToken] public ActionResult LinkLogin(string provider) { // Request a redirect to the external login provider to link a login for the current user return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account"), User.Identity.GetID()); } // // GET: /Account/LinkLoginCallback public async Task LinkLoginCallback() { var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetID()); if (loginInfo == null) { return RedirectToAction("Manage", new { Message = ManageMessageId.Error }); } var result = await AppUserManager.AddLoginAsync(User.Identity.GetID(), loginInfo.Login); return result.Succeeded ? RedirectToAction("Manage") : RedirectToAction("Manage", new { Message = ManageMessageId.Error }); } // // POST: /Account/ExternalLoginConfirmation [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) { if (User.Identity.IsAuthenticated) { return RedirectToAction("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 }; var result = await AppUserManager.CreateAsync(user); if (result.Succeeded) { result = await AppUserManager.AddLoginAsync(user.Id, info.Login); if (result.Succeeded) { await SignInAsync(user, false); return RedirectToLocal(returnUrl, user.Id); } } AddErrors(result); } ViewBag.ReturnUrl = returnUrl; return View(model); } // // POST: /Account/LogOff [HttpPost] [ValidateAntiForgeryToken] public ActionResult LogOff() { if (!HttpContext.User.Identity.isSSO()) { AuthenticationManager.SignOut(); SessionManager.Remove(Code.Constants.USERVOICE_SSO_TOKEN); return RedirectToAction("Index", "Home"); } else { string absoluteUrl = HttpContext.Request.Url.AbsoluteUri; string replyUrl = absoluteUrl.Substring(0, absoluteUrl.LastIndexOf("/") + 1); WSFederationAuthenticationModule.FederatedSignOut(null, new Uri(replyUrl)); return RedirectToAction("Account", "Login"); } } // // GET: /Account/ExternalLoginFailure [AllowAnonymous] public ActionResult ExternalLoginFailure() { return View(); } [ChildActionOnly] [Obsolete] public ActionResult RemoveAccountList() { var linkedAccounts = AppUserManager.GetLogins(User.Identity.GetID()); ViewBag.ShowRemoveButton = HasPassword() || linkedAccounts.Count > 1; return (ActionResult)PartialView("_RemoveAccountPartial", linkedAccounts); } // // GET: /Account/Activate [AllowAnonymous] public ActionResult Activate(string userId) { if (String.IsNullOrEmpty(userId)) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); var user = AppUserManager.FindById(userId); if (user == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); if (user.Type != (int)UserType.Pending) ModelState.AddModelError("", Messages.Account_AlreadyActivated); var activatedUser = new ActivationUserModel { Email = user.Email, UserName = user.UserName, Password = string.Empty, ConfirmationPassword = string.Empty, UserId = user.Id }; return View(activatedUser); } // // POST: /Accont/Activate [AllowAnonymous] [HttpPost] public async Task Activate(ActivationUserModel model) { if (ModelState.IsValid) { if (!string.IsNullOrWhiteSpace(model.UserId)) { ApplicationDbContext cnt = new ApplicationDbContext(); var userManager = new UserManager(new UserStore(cnt)); var user = userManager.FindById(model.UserId); if (user == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); if (user.Type != (int)UserType.Pending) { ModelState.AddModelError("", Messages.Account_AlreadyActivated); return View(); } bool hasPassword = HasPassword(user.Id); if (hasPassword) { var result = await AppUserManager.RemovePasswordAsync(user.Id); if (!result.Succeeded) { AddErrors(result); return View(); } } var addPwdResult = await AppUserManager.AddPasswordAsync(user.Id, model.Password); if (!addPwdResult.Succeeded) { AddErrors(addPwdResult); return View(); } var passwordHash = userManager.PasswordHasher.HashPassword(model.Password); user.PasswordHash = passwordHash; user.Type = (int)UserType.Active; cnt.SaveChanges(); await SignInAsync(user, false); return RedirectToAction("Index", "Home"); } ModelState.AddModelError("", Messages.Account_UserDoesNotExist); } return View(); } [AllowAnonymous] public ActionResult ForgotPassword() { return View(new ForgotPasswordModel()); } [HttpPost] [ValidateAntiForgeryToken] [AllowAnonymous] public async Task ForgotPassword(ForgotPasswordModel model) { if (ModelState.IsValid) { try { var request = await UserManager.CreateResetPasswordTokenByEmailAsync(model.Email, Settings.Default.ForgotPasswordLinkTTLDays); if (request != null) { MailManager.SendRestorePasswordMessage(request.Email, request.Token, request.UserName); model.Sent = true; } } catch (BLLException blEx) // handle any system specific error { // display error message if required if (blEx.DisplayError) ModelState.AddModelError(string.Empty, blEx.Message); else // if display not requried then display modal form with general error message { LogException(blEx); SetErrorScript(); } } catch (Exception exception) // handle any unexpected error { LogException(exception); SetErrorScript(); } } return View(model); } [HttpPost] public async Task ResetPassword(string userId) { try { var request = await UserManager.CreateResetPasswordTokenByIdAsync(userId, Settings.Default.ForgotPasswordLinkTTLDays); if (request != null) MailManager.SendRestorePasswordMessage(request.Email, request.Token, request.UserName); return Json(new { status = "OK" }); } catch (Exception exception) // handle any unexpected error { LogException(exception); return Json(new { status = "ERROR" }); } } [AllowAnonymous] public ActionResult RestorePassword(Guid? token) { var model = new RestorePasswordModel(); try { if (!token.HasValue || Guid.Empty.Equals(token)) { model.State = RestorePasswordModel.PageState.TokenIsEmpty; return View(model); } model.Token = token.Value; using (var db = new EnVisageEntities()) { var request = db.PasswordResetRequests.AsNoTracking().Include(t => t.AspNetUser).FirstOrDefault(t => t.Token == token); if (request == null) { model.State = RestorePasswordModel.PageState.TokenDoesNotExist; return View(model); } var user = request.AspNetUser; if (user != null) model.Email = user.Email; else { throw new BLLException(Messages.Account_TtokenDoesNotMatchAnyExistingUser_); } if (request.ValidUntil < DateTime.Now) { model.State = RestorePasswordModel.PageState.TokenExpired; return View(model); } } } catch (BLLException blEx) // handle any system specific error { // display error message if required if (blEx.DisplayError) ModelState.AddModelError(string.Empty, blEx.Message); else // if display not requried then display modal form with general error message { LogException(blEx); SetErrorScript(); } } catch (Exception exception) // handle any unexpected error { LogException(exception); SetErrorScript(); } return View(model); } [HttpPost] [ValidateAntiForgeryToken] [AllowAnonymous] public async Task RestorePassword(RestorePasswordModel model) { if (ModelState.IsValid) { try { if (RestorePasswordModel.PageState.Initial.Equals(model.State)) { using (var db = new EnVisageEntities()) { var request = db.PasswordResetRequests.FirstOrDefault(t => t.Token == model.Token); if (request == null) { model.State = RestorePasswordModel.PageState.TokenDoesNotExist; return View(model); } if (request.ValidUntil < DateTime.Now) { model.State = RestorePasswordModel.PageState.TokenExpired; return View(model); } var user = db.AspNetUsers.FirstOrDefault(t => t.Id == request.UserId); if (user == null) throw new BLLException(Messages.Account_TtokenDoesNotMatchAnyExistingUser_); // make link expired request.ValidUntil = DateTime.Now.AddMinutes(-1); db.Entry(request).State = EntityState.Modified; // reset password var removePwdResult = AppUserManager.RemovePassword(user.Id); if (!removePwdResult.Succeeded) throw new BLLException(Messages.Account_SystemCannotRemovePassword, false); var addPwdResult = AppUserManager.AddPassword(user.Id, model.Password); if (!addPwdResult.Succeeded) { AddErrors(addPwdResult); return View(model); } // make user able to enter web portal user.Type = (int)UserType.Active; // commit all changes db.SaveChanges(); } model.State = RestorePasswordModel.PageState.Restored; } else if (RestorePasswordModel.PageState.TokenExpired.Equals(model.State)) { var request = await UserManager.CreateResetPasswordTokenByEmailAsync(model.Email, Settings.Default.ForgotPasswordLinkTTLDays); if (request != null) { MailManager.SendRestorePasswordMessage(request.Email, request.Token, request.UserName); model.State = RestorePasswordModel.PageState.TokenResent; } } } catch (BLLException blEx) // handle any system specific error { // display error message if required if (blEx.DisplayError) ModelState.AddModelError(string.Empty, blEx.Message); else // if display not requried then display modal form with general error message { LogException(blEx); ModelState.AddModelError(string.Empty, Messages.AccountController_RestorePassword_Error); } } catch (Exception exception) // handle any unexpected error { LogException(exception); ModelState.AddModelError(string.Empty, Messages.AccountController_RestorePassword_Error); } } return View(model); } #endregion #region Private Methods private void ssoDefault() { var principal = Thread.CurrentPrincipal; var i = principal.Identity as System.Security.Claims.ClaimsIdentity; if (principal == null) Logger.Log(NLog.LogLevel.Debug, "user name from principal is null. in ssoDefault()", ""); if (i == null) Logger.Log(NLog.LogLevel.Debug, "user name from principal.Identity is null. in ssoDefault()", ""); string username = principal.Identity.Name; Logger.Log(NLog.LogLevel.Debug, "user name from adfs." + username, ""); string[] splprm = { "\\" }; string[] names = username.Split(splprm, StringSplitOptions.None); if (names.Length >= 2) username = names[1]; var user = AppUserManager.FindByNameAsync(username).Result; if (user != null) { if (user.Type == (int)UserType.Active) { i.AddClaim(new System.Security.Claims.Claim(ClaimTypes.NameIdentifier, user.Id)); UserVoiceApi userVoice = new UserVoiceApi(); string ssoToken = UserVoiceGenerator.create(userVoice.GetUserJsonObject(user)); if (!SessionManager.Exists(Code.Constants.USERVOICE_SSO_TOKEN) || string.IsNullOrEmpty(ssoToken)) { SessionManager.SetValue(Code.Constants.USERVOICE_SSO_TOKEN, ssoToken); HttpCookie ssoTokenCookie = new HttpCookie(Code.Constants.USERVOICE_COOKIE_CONTEXT); ssoTokenCookie[Code.Constants.USERVOICE_SSO_TOKEN] = ssoToken; ssoTokenCookie.Expires = DateTime.Now.AddDays(30d); Response.Cookies.Add(ssoTokenCookie); } } } } private async Task SignInAsync(ApplicationUser user, bool isPersistent) { AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); var identity = await AppUserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); // identity.AddClaim(new System.Security.Claims.Claim("PrevuID",user.Id.ToString(),"PrevuID")); var authProps = new AuthenticationProperties { IsPersistent = isPersistent }; if (isPersistent) authProps.ExpiresUtc = DateTime.UtcNow.AddHours(12); AuthenticationManager.SignIn(authProps, identity); } private void AddErrors(IdentityResult result) { foreach (var error in result.Errors) { ModelState.AddModelError("", error); } } private bool HasPassword() { return HasPassword(User.Identity.GetID()); } private bool HasPassword(string id) { if (string.IsNullOrWhiteSpace(id)) return false; var user = AppUserManager.FindById(id); if (user != null) return user.PasswordHash != null; return false; } private ActionResult RedirectToLocal(string returnUrl, string userId) { if (!string.IsNullOrWhiteSpace(returnUrl) && Url.IsLocalUrl(returnUrl) && returnUrl != "/") { return Redirect(returnUrl); } //first of all, need to check if we have LastVisitedPage stored for the user Guid userGuid; if (Guid.TryParse(userId, out userGuid) && !SecurityManager.IsResourceOnlyAccess(userId)) { var lastVisitedPage = UserManager.GetPagePreferencesValue(Code.Constants.USER_PREFERENCE_LASTPAGE_URL, Code.Constants.USER_PREFERENCE_LASTPAGE_SECTION, Code.Constants.USER_PREFERENCE_LASTPAGE_SECTION, userGuid); if (!string.IsNullOrWhiteSpace(lastVisitedPage)) return Redirect(lastVisitedPage); } SecurityManager.DefaultPageWithArea page = SecurityManager.RedirectToDefaultPage(userId); return RedirectToAction(page.Action, page.Controller, page.Parameters); } #endregion #region Models public enum ManageMessageId { ChangePasswordSuccess, SetPasswordSuccess, RemoveLoginSuccess, Error } private class ChallengeResult : HttpUnauthorizedResult { public ChallengeResult(string provider, string redirectUri, string userId = null) { LoginProvider = provider; RedirectUri = redirectUri; UserId = userId; } public string LoginProvider { get; } public string RedirectUri { get; } public string UserId { get; } 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 } }