public ILoginProcess GetActiveProcess(IEntitySession session, LoginProcessType processType, string token) { Util.Check(!string.IsNullOrWhiteSpace(token), "Process token may not be null"); var context = session.Context; //get process without expiration checking, we check it later var query = from p in session.EntitySet <ILoginProcess>() where p.ProcessType == processType && p.Token == token select p; var process = query.FirstOrDefault(); context.ThrowIfNull(process, ClientFaultCodes.ObjectNotFound, "Process", "Login process not found."); if (process.Status != LoginProcessStatus.Active) { return(null); } if (process.FailCount >= _settings.MaxFailCount) { process.Status = LoginProcessStatus.AbortedAsFraud; OnLoginEvent(context, LoginEventType.ProcessAborted, process.Login, "Aborted - too many failures."); session.SaveChanges(); return(null); } var userName = process.Login.UserName; if (process.ExpiresOn < App.TimeService.UtcNow) { process.Status = LoginProcessStatus.Expired; OnLoginEvent(context, LoginEventType.ProcessAborted, process.Login, "Expired."); session.SaveChanges(); return(null); } return(process); }
private string GetPinNotificationType(LoginProcessType processType) { switch(processType) { case LoginProcessType.FactorVerification: return LoginNotificationTypes.FactorVerifyPin; case LoginProcessType.MultiFactorLogin: return LoginNotificationTypes.MultiFactorPin; case LoginProcessType.PasswordReset: return LoginNotificationTypes.PasswordResetPin; default: Util.Throw("Invalid process type {0}, failed to match pin notification type.", processType); return null; } }
public TimeSpan GetExpirationPeriod(LoginProcessType processType) { switch (processType) { case LoginProcessType.PasswordReset: return(_settings.PasswordResetTimeWindow); case LoginProcessType.FactorVerification: return(_settings.FactorVerificationTimeWindow); case LoginProcessType.MultiFactorLogin: default: return(_settings.MultiFactorLoginTimeWindow); } }
private string GetPinNotificationType(LoginProcessType processType) { switch (processType) { case LoginProcessType.FactorVerification: return(LoginNotificationTypes.FactorVerifyPin); case LoginProcessType.MultiFactorLogin: return(LoginNotificationTypes.MultiFactorPin); case LoginProcessType.PasswordReset: return(LoginNotificationTypes.PasswordResetPin); default: Util.Throw("Invalid process type {0}, failed to match pin notification type.", processType); return(null); } }
public ILoginProcess GetActiveProcess(OperationContext context, LoginProcessType processType, string token) { Util.Check(!string.IsNullOrWhiteSpace(token), "Process token may not be null"); var session = context.OpenSystemSession(); var hash = Util.StableHash(token); //get process without expiration checking, we check it later var query = from p in session.EntitySet <ILoginProcess>() where p.ProcessType == processType && p.TokenHash == hash && p.Token == token select p; var process = query.FirstOrDefault(); if (process == null) { LogIncident(context, LoginIncidentType, "ProcessNotFound", "Login process not found.", null, token); return(null); } if (process.Status != LoginProcessStatus.Active) { return(null); } if (process.FailCount >= _settings.MaxFailCount) { process.Status = LoginProcessStatus.AbortedAsFraud; session.SaveChanges(); LogIncident(context, LoginIncidentType, "Aborted", "Login process aborted after too many failures.", process.Login, token); return(null); } var userName = process.Login.UserName; if (process.ExpiresOn < App.TimeService.UtcNow) { process.Status = LoginProcessStatus.Expired; session.SaveChanges(); LogIncident(context, LoginIncidentType, "Expired", "Login process expired.", process.Login, token); return(null); } return(process); }
public ILoginProcess StartProcess(ILogin login, LoginProcessType processType, string token) { var session = EntityHelper.GetSession(login); //Figure out steps var pendingFactors = ExtraFactorTypes.None; switch(processType) { case LoginProcessType.PasswordReset: pendingFactors = login.PasswordResetFactors; if(pendingFactors == ExtraFactorTypes.None) pendingFactors = _settings.DefaultPasswordResetFactors; OnLoginEvent(session.Context, LoginEventType.PasswordResetStarted, login); LogIncident(session.Context, "PasswordReset", "Started", "Password reset started for " + login.UserName, login, login.UserName); break; case LoginProcessType.MultiFactorLogin: pendingFactors = login.MultiFactorLoginFactors; if(pendingFactors == ExtraFactorTypes.None) pendingFactors = ExtraFactorTypes.Email; OnLoginEvent(session.Context, LoginEventType.MultiFactorLoginStarted, login); break; case LoginProcessType.FactorVerification: //we do not specify steps for factor verification - whatever factor is started (with SendPin), we complete it OnLoginEvent(session.Context, LoginEventType.FactorVerificationStarted, login); break; } //For password reset process see if we need to set Obscured flag, indicating that we need to hide information // when returning info to the client - to avoid detecting if user's email exists in the database. var processFlags = LoginProcessFlags.None; if(processType == LoginProcessType.PasswordReset) { // First check if we have global flag in settings, but flag in Login can override it. bool isObscured = _settings.Options.IsSet(LoginModuleOptions.ConcealMembership); // A flag in login can of if(login.Flags.IsSet(LoginFlags.DoNotConcealMembership)) isObscured = false; if (isObscured) processFlags |= LoginProcessFlags.Obscured; } //create an entity var process = session.NewEntity<ILoginProcess>(); process.Login = login; process.ProcessType = processType; process.Token = token; process.PendingFactors = pendingFactors; process.Flags = processFlags; var expPeriod = GetExpirationPeriod(processType); process.ExpiresOn = App.TimeService.UtcNow.Add(expPeriod); process.Status = LoginProcessStatus.Active; session.SaveChanges(); return process; }
public TimeSpan GetExpirationPeriod(LoginProcessType processType) { switch(processType) { case LoginProcessType.PasswordReset: return _settings.PasswordResetTimeWindow; case LoginProcessType.FactorVerification: return _settings.FactorVerificationTimeWindow; case LoginProcessType.MultiFactorLogin: default: return _settings.MultiFactorLoginTimeWindow; } }
public ILoginProcess GetActiveProcess(OperationContext context, LoginProcessType processType, string token) { Util.Check(!string.IsNullOrWhiteSpace(token), "Process token may not be null"); var session = context.OpenSystemSession(); var hash = Util.StableHash(token); //get process without expiration checking, we check it later var query = from p in session.EntitySet<ILoginProcess>() where p.ProcessType == processType && p.TokenHash == hash && p.Token == token select p; var process = query.FirstOrDefault(); if(process == null) { LogIncident(context, LoginIncidentType, "ProcessNotFound", "Login process not found.", null, token); return null; } if(process.Status != LoginProcessStatus.Active) return null; if (process.FailCount >= _settings.MaxFailCount) { process.Status = LoginProcessStatus.AbortedAsFraud; session.SaveChanges(); LogIncident(context, LoginIncidentType, "Aborted", "Login process aborted after too many failures.", process.Login, token); return null; } var userName = process.Login.UserName; if(process.ExpiresOn < App.TimeService.UtcNow) { process.Status = LoginProcessStatus.Expired; session.SaveChanges(); LogIncident(context, LoginIncidentType, "Expired", "Login process expired.", process.Login, token); return null; } return process; }
//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 ILoginProcess StartProcess(ILogin login, LoginProcessType processType, string token) { var session = EntityHelper.GetSession(login); //Figure out steps var pendingFactors = ExtraFactorTypes.None; switch (processType) { case LoginProcessType.PasswordReset: pendingFactors = login.PasswordResetFactors; if (pendingFactors == ExtraFactorTypes.None) { pendingFactors = _settings.DefaultPasswordResetFactors; } OnLoginEvent(session.Context, LoginEventType.PasswordResetStarted, login); break; case LoginProcessType.MultiFactorLogin: pendingFactors = login.MultiFactorLoginFactors; if (pendingFactors == ExtraFactorTypes.None) { pendingFactors = ExtraFactorTypes.Email; } OnLoginEvent(session.Context, LoginEventType.MultiFactorLoginStarted, login); break; case LoginProcessType.FactorVerification: //we do not specify steps for factor verification - whatever factor is started (with SendPin), we complete it OnLoginEvent(session.Context, LoginEventType.FactorVerificationStarted, login); break; } //For password reset process see if we need to set Obscured flag, indicating that we need to hide information // when returning info to the client - to avoid detecting if user's email exists in the database. var processFlags = LoginProcessFlags.None; if (processType == LoginProcessType.PasswordReset) { // First check if we have global flag in settings, but flag in Login can override it. bool isObscured = _settings.Options.IsSet(LoginModuleOptions.ConcealMembership); // A flag in login can of if (login.Flags.IsSet(LoginFlags.DoNotConcealMembership)) { isObscured = false; } if (isObscured) { processFlags |= LoginProcessFlags.Obscured; } } //create an entity var process = session.NewEntity <ILoginProcess>(); process.Login = login; process.ProcessType = processType; process.Token = token; process.PendingFactors = pendingFactors; process.Flags = processFlags; var expPeriod = GetExpirationPeriod(processType); process.ExpiresOn = App.TimeService.UtcNow.Add(expPeriod); process.Status = LoginProcessStatus.Active; session.SaveChanges(); return(process); }
//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); }