public async Task SendPinAsync(ILoginProcess process, ILoginExtraFactor factor, string factorValue = null, string pin = null) { Util.Check(process.Login == factor.Login, "LoginProcess tries to use login factor not assigned to process's login."); var session = EntityHelper.GetSession(process); var activeAlready = GetActiveConfirmationProcesses(factor, LoginProcessType.FactorVerification); session.Context.ThrowIf(activeAlready.Count > 2, ClientFaultCodes.InvalidAction, "Factor", "Cannot send pin - several pins already sent and are waiting for confirmation."); process.CurrentFactor = factor; if (factor.FactorType == ExtraFactorTypes.GoogleAuthenticator) { //do not generate or send pin } else { Util.Check(_settings.MessagingService != null, "Login messaging service not provided, cannot send pin."); pin = pin ?? _settings.PinGenerator(process, factor); if (string.IsNullOrWhiteSpace(factorValue)) { factorValue = factor.FactorValue; } process.CurrentPin = pin; var logMsg = Util.SafeFormat("Pin sent to user {0} using factor '{1}'. ", factor.Login.UserName, factorValue); OnLoginEvent(session.Context, LoginEventType.PinSent, factor.Login, logMsg); await _settings.MessagingService.SendMessage(session.Context, LoginMessageType.Pin, factor, process); } session.SaveChanges(); }
public static void SetVerified(this ILoginExtraFactor factor, DateTime now) { Util.Check(factor != null, "factor parameter may not be null."); var session = EntityHelper.GetSession(factor); factor.VerifiedOn = now; }
public void SendPin(ILoginProcess process, ILoginExtraFactor factor, string factorValue = null, string pin = null) { Util.Check(process.Login == factor.Login, "LoginProcess tries to use login factor not assigned to process's login."); var session = EntityHelper.GetSession(process); var activeAlready = GetActiveConfirmationProcesses(factor, LoginProcessType.FactorVerification); session.Context.ThrowIf(activeAlready.Count > 2, ClientFaultCodes.InvalidAction, "Factor", "Cannot send pin - several pins already sent and are waiting for confirmation."); process.CurrentFactor = factor; if (factor.FactorType == ExtraFactorTypes.GoogleAuthenticator) { //do not generate or send pin } else { pin = pin ?? _settings.PinGenerator(process, factor); //login factor may be coming from user (password reset), or from factor record (verify email) if (string.IsNullOrWhiteSpace(factorValue)) { factorValue = factor.FactorValue; } process.CurrentPin = pin; SendPin(process, factor.FactorType, factorValue, pin); } session.SaveChanges(); var logMsg = StringHelper.SafeFormat("Pin sent to user {0} using factor '{1}'. ", factor.Login.UserName, factorValue); OnLoginEvent(session.Context, LoginEventType.PinSent, factor.Login, logMsg); }
//This metod is a default pin generator and is referenced by LoginModuleSettings.PinGenerator public static string DefaultGeneratePin(ILoginProcess process, ILoginExtraFactor factor) { switch(factor.FactorType) { case ExtraFactorTypes.Phone: case ExtraFactorTypes.Email: default: return RandomHelper.GenerateRandomString(3, CharKinds.UpperLetter) + RandomHelper.GenerateRandomString(5, CharKinds.Digit); } }
public string GetGoogleAuthenticatorQRUrl(ILoginExtraFactor factor) { Util.Check(factor.FactorType == ExtraFactorTypes.GoogleAuthenticator, "The extra factor type should be GoogleAuthenticator."); var secret = factor.FactorValue; var identity = StringHelper.SafeFormat(_settings.GoogleAuthenticatorIdentityTemplate, App.AppName, factor.Login.UserName); var url = GoogleAuthenticator.GoogleAuthenticatorUtil.GetQRUrl(identity, secret); return(url); }
private LoginExtraFactor ToModel(ILoginExtraFactor factor) { var objFactor = new LoginExtraFactor() { Id = factor.Id, Type = factor.FactorType, Confirmed = factor.VerifiedOn != null, Value = factor.FactorValue }; return(objFactor); }
public Task SendMessage(OperationContext context, LoginMessageType messageType, ILoginExtraFactor factor, ILoginProcess process = null) { if (messageType == LoginMessageType.Pin) { PinMessages.Add(new PinInfoMessage() { Pin = process.CurrentPin, Email = process.CurrentFactor.FactorValue }); } return(Task.CompletedTask); }
//This metod is a default pin generator and is referenced by LoginModuleSettings.PinGenerator public static string DefaultGeneratePin(ILoginProcess process, ILoginExtraFactor factor) { switch (factor.FactorType) { case ExtraFactorTypes.Phone: return(RandomHelper.GenerateSafeRandomNumber(5)); case ExtraFactorTypes.Email: default: return(RandomHelper.GenerateSafeRandomWord(10)); } }
//to account for multiple pins sent (user might be tired of waiting for first pin, click again and make another pin sent) public IList <ILoginProcess> GetActiveConfirmationProcesses(ILoginExtraFactor factor, LoginProcessType processType) { var session = EntityHelper.GetSession(factor); var utcNow = App.TimeService.UtcNow; var query = from p in session.EntitySet <ILoginProcess>() where p.ExpiresOn > utcNow && p.ProcessType == processType && p.CurrentFactor == factor && p.Status == LoginProcessStatus.Active && p.FailCount < _settings.MaxFailCount orderby p.CreatedOn descending select p; var processes = query.ToList(); return(processes); }
public LoginExtraFactor UpdateFactor(ILoginExtraFactor fc, string value) { var session = EntityHelper.GetSession(fc); if (fc.FactorType == ExtraFactorTypes.GoogleAuthenticator) { value = GoogleAuthenticator.GoogleAuthenticatorUtil.GenerateSecret(); } fc.FactorValue = value; if (fc.FactorType == ExtraFactorTypes.GoogleAuthenticator) { fc.SetVerified(App.TimeService.UtcNow); } else { fc.VerifiedOn = null; } return(ToModel(fc)); }
private LoginExtraFactor ToModel(ILoginExtraFactor factor) { var objFactor = new LoginExtraFactor() { Id = factor.Id, Type = factor.FactorType, Confirmed = factor.VerifiedOn != null, Value = factor.Info.DecryptString(_settings.EncryptionChannelName) }; return objFactor; }
public LoginExtraFactor UpdateFactor(ILoginExtraFactor fc, string value) { var session = EntityHelper.GetSession(fc); if (fc.FactorType == ExtraFactorTypes.GoogleAuthenticator) value = GoogleAuthenticator.GoogleAuthenticatorUtil.GenerateSecret(); fc.Info = session.NewOrUpdate(fc.Info, value, _settings.EncryptionChannelName); fc.InfoHash = Util.StableHash(value); if (fc.FactorType == ExtraFactorTypes.GoogleAuthenticator) fc.SetVerified(App.TimeService.UtcNow); else fc.VerifiedOn = null; return ToModel(fc); }
public string GetGoogleAuthenticatorQRUrl(ILoginExtraFactor factor) { Util.Check(factor.FactorType == ExtraFactorTypes.GoogleAuthenticator, "The extra factor type should be GoogleAuthenticator."); var secret = factor.Info.DecryptString(_settings.EncryptionChannelName); var identity = StringHelper.SafeFormat(_settings.GoogleAuthenticatorIdentityTemplate, App.AppName, factor.Login.UserName); var url = GoogleAuthenticator.GoogleAuthenticatorUtil.GetQRUrl(identity, secret); return url; }
public void SendPin(ILoginProcess process, ILoginExtraFactor factor, string factorValue = null, string pin = null) { Util.Check(process.Login == factor.Login, "LoginProcess tries to use login factor not assigned to process's login."); var session = EntityHelper.GetSession(process); var activeAlready = GetActiveConfirmationProcesses(factor, LoginProcessType.FactorVerification); session.Context.ThrowIf(activeAlready.Count > 2, ClientFaultCodes.InvalidAction, "Factor", "Cannot send pin - several pins already sent and are waiting for confirmation."); process.CurrentFactor = factor; if (factor.FactorType == ExtraFactorTypes.GoogleAuthenticator) { //do not generate or send pin } else { pin = pin ?? _settings.PinGenerator(process, factor); if (string.IsNullOrWhiteSpace(factorValue)) factorValue = factor.Info.DecryptString(_settings.EncryptionChannelName); process.CurrentPin = pin; SendPin(process, factor.FactorType, factorValue, pin); } session.SaveChanges(); var logMsg = StringHelper.SafeFormat("Pin sent to user {0} using factor '{1}'. ", factor.Login.UserName, factorValue); OnLoginEvent(session.Context, LoginEventType.PinSent, factor.Login, logMsg); }
//to account for multiple pins sent (user might be tired of waiting for first pin, click again and make another pin sent) public IList<ILoginProcess> GetActiveConfirmationProcesses(ILoginExtraFactor factor, LoginProcessType processType) { var session = EntityHelper.GetSession(factor); var utcNow = App.TimeService.UtcNow; var query = from p in session.EntitySet<ILoginProcess>() where p.ExpiresOn > utcNow && p.ProcessType == processType && p.CurrentFactor == factor && p.Status == LoginProcessStatus.Active && p.FailCount < _settings.MaxFailCount orderby p.CreatedOn descending select p; var processes = query.ToList(); return processes; }
public string GeneratePin(ILoginProcess process, ILoginExtraFactor factor) { return _settings.PinGenerator(process, factor); }
public string GeneratePin(ILoginProcess process, ILoginExtraFactor factor) { return(_settings.PinGenerator(process, factor)); }