hoping that fixes the tzo factor option

... It needs unitary testing
This commit is contained in:
2019-11-14 14:09:06 +00:00
parent 343c613622
commit 28067d12b2
8 changed files with 77 additions and 27 deletions

View File

@ -26,10 +26,10 @@ namespace Yavsc.Controllers
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
const string nextPageTokenKey = "nextPageTokenKey";
const int defaultLen = 10;
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
// private readonly ISmsSender _smsSender;
private readonly ILogger _logger;
@ -323,6 +323,19 @@ namespace Yavsc.Controllers
_siteSettings.Audience));
return res;
}
private async Task<EmailSentViewModel> SendEMailFactorAsync(ApplicationUser user, string provider)
{
var code = await _userManager.GenerateTwoFactorTokenAsync(user, provider);
var callbackUrl = Url.Action("VerifyCode", "Account",
new { userId = user.Id, code, provider }, protocol: "https", host: Startup.Authority);
var res = await _emailSender.SendEmailAsync(user.UserName, user.Email,
this._localizer["AccountEmailFactorTitle"],
string.Format(this._localizer["AccountEmailFactorBody"],
_siteSettings.Title, callbackUrl, _siteSettings.Slogan,
_siteSettings.Audience, code));
return res;
}
//
// POST: /Account/LogOff
[HttpPost(Constants.LogoutPath)]
@ -366,7 +379,7 @@ namespace Yavsc.Controllers
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl });
return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe= true });
}
if (result.IsLockedOut)
{
@ -465,13 +478,41 @@ namespace Yavsc.Controllers
IdentityResult result=null;
try {
result = await _userManager.ConfirmEmailAsync(user, code);
_dbContext.SaveChanges(userId);
}
catch (Exception ex)
{
_logger.LogError(ex.StackTrace);
_logger.LogError(ex.Message);
}
return View(result.Succeeded ? "ConfirmEmail" : "Error");
return View(result.Succeeded ? "EmailConfirmed" : "Error");
}
// GET: /Account/ConfirmTwoFactorToken
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ConfirmTwoFactorToken(string userId, string code)
{
if (userId == null || code == null)
{
return View("Error");
}
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return View("Error");
}
bool result=false;
try {
result = await _userManager.VerifyTwoFactorTokenAsync(user, Constants.DefaultFactor, code);
_dbContext.SaveChanges(userId);
}
catch (Exception ex)
{
_logger.LogError(ex.StackTrace);
_logger.LogError(ex.Message);
}
return View(result ? "EmailConfirmed" : "Error");
}
//
@ -607,7 +648,7 @@ namespace Yavsc.Controllers
//
// GET: /Account/SendCode
[HttpGet, AllowAnonymous]
public async Task<ActionResult> SendCode(string returnUrl = null, bool rememberMe = false)
public async Task<ActionResult> SendCode(string returnUrl = null, bool rememberMe = true)
{
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
@ -615,11 +656,8 @@ namespace Yavsc.Controllers
return View("Error", new Exception("No Two factor authentication user"));
}
var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user);
var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
}
@ -645,7 +683,7 @@ namespace Yavsc.Controllers
{
return View("Error", new Exception("No mobile app service was activated"));
}
else // if (model.SelectedProvider == Constants.EMailFactor || model.SelectedProvider == "Default" )
else
if (model.SelectedProvider == Constants.SMSFactor)
{
return View("Error", new Exception("No SMS service was activated"));
@ -653,7 +691,7 @@ namespace Yavsc.Controllers
}
else // if (model.SelectedProvider == Constants.EMailFactor || model.SelectedProvider == "Default" )
{
var sent = await this.SendEMailForConfirmAsync(user);
var sent = await this.SendEMailFactorAsync(user, model.SelectedProvider);
}
return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
}
@ -662,7 +700,7 @@ namespace Yavsc.Controllers
// GET: /Account/VerifyCode
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> VerifyCode(string provider, bool rememberMe, string returnUrl = null)
public async Task<IActionResult> VerifyCode(string code, string provider, bool rememberMe=true, string returnUrl = null)
{
// Require that the user has already logged in via username/password or external login
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
@ -670,7 +708,8 @@ namespace Yavsc.Controllers
{
return View("Error", new Exception("user is null"));
}
return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });
// it may be a GET response from some email url, or the web response to second fqctor requirement
return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe, Code = code });
}
//
@ -690,12 +729,14 @@ namespace Yavsc.Controllers
// will be locked out for a specified amount of time.
_logger.LogWarning("Signin with code: {0} {1}", model.Provider, model.Code);
var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser);
var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberMe);
if (result.Succeeded)
{
ViewData["StatusMessage"] = "Your code was verified";
_logger.LogInformation($"Signed in. returning to {model.ReturnUrl}");
if (model.ReturnUrl!=null)
return Redirect(model.ReturnUrl);
else RedirectToAction("Index","Home");
}
if (result.IsLockedOut)
{