private async Task <Device> PrepareUserDevice(AuthenticationViewModel authModel, User user, string middleName, string securityCardFormatted) { string debugStr = ""; var firstName = authModel.FirstName; var lastName = authModel.LastName; var demoUser = user?.IsDemo.GetValueOrDefault(false) ?? false; //User user = await RestroomUnitOfWork.Get<User>().FirstOrDefaultAsync(m => m.Badge == authModel.Badge && m.FirstName == firstName && m.LastName == lastName); //if (user != null && !user.Active) // throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $"user is not active. debugStr: {debugStr}"); //var demoUser = user?.IsDemo ?? false; ////var demoUser = await IsDemoUserAsync(authModel.FirstName, authModel.LastName, authModel.Badge); ////debugStr = "After getting Demo User: "******"After getting Employee, Found:{(employee != null)}"; // if (employee == null) // throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $" User not found. debugStr: {debugStr}"); // if (!string.Equals(employee.FirstName, firstName, StringComparison.OrdinalIgnoreCase) || !string.Equals(employee.LastName, lastName, StringComparison.OrdinalIgnoreCase)) // throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $" User names are not match. debugStr: {debugStr}"); // middleName = employee.MiddleName; // securityCardFormatted = employee.SecurityCardFormatted; //} try { var device = await RestroomUnitOfWork.Get <Device>().FirstOrDefaultAsync(m => m.DeviceGuid == authModel.DeviceGuid); debugStr = $"after getting device and user. DeviceGuid:{authModel.DeviceGuid}, Badge: {authModel.Badge}"; if (device != null && !device.Active) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $" device is not Active.", debugStr); } if (!demoUser && device != null && device.Confirm2FAExpires != null && device.Confirm2FAExpires > DateTime.Now) { throw new FriendlyException(FriendlyExceptionType.UnExpiredValid2FAuth, $" device has an unexpired security code. new code can't be generated unless the previous code expires.", debugStr); } UserDevice userDevice = null; if (user != null && device != null) { userDevice = await RestroomUnitOfWork.Get <UserDevice>() .FirstOrDefaultAsync(m => m.DeviceId == device.DeviceId && m.UserId == user.UserId); } if (device == null) { device = new Device { Active = true, DeviceGuid = authModel.DeviceGuid, DeviceModel = authModel.DeviceModel, DeviceOS = authModel.DeviceOS, LastUsed = DateTime.Now }; } device.DeviceSessionId = Guid.NewGuid().ToString(); //device.PhoneNumber = authModel.PhoneNumber; device.Confirm2FACode = GenerateRandomCode(6); device.Confirm2FAExpires = DateTime.Now.AddMinutes(ValidInMinutes2FactAuth); device.Confirmed2FACode = false; device.LastUsed = DateTime.Now; if (user == null) { user = new User { Active = true, Badge = authModel.Badge, }; } user.SecurityCardFormatted = securityCardFormatted; user.FirstName = firstName; user.LastName = lastName; user.MiddleName = middleName; user = RestroomUnitOfWork.PrepUser(user); device = RestroomUnitOfWork.PrepDevice(device); debugStr = $"Before SaveChanges on user and device. DeviceGuid:{authModel.DeviceGuid}, Badge: {authModel.Badge}"; await RestroomUnitOfWork.SaveChangesAsync(); if (userDevice == null) { userDevice = new UserDevice(); userDevice.Active = true; } userDevice.LastLogon = DateTime.Now; userDevice.UserId = user.UserId; userDevice.DeviceId = device.DeviceId; debugStr = $"Before SaveChanges on userDevice. DeviceGuid:{authModel.DeviceGuid}, Badge: {authModel.Badge}"; await RestroomUnitOfWork.SaveUserDeviceAsync(userDevice); return(device); } catch (FriendlyException ex) { throw; } catch (Exception ex) { throw new Exception("Inside PrepareUserDevice, " + debugStr, ex); } }
/// <summary> /// /// </summary> /// <param name="operatorInfo"></param> /// <returns></returns> /// <exception cref="FriendlyException"></exception> public async Task <OperatorInfoViewModel> GetOperatorInfoAsync(OperatorInfoViewModel operatorInfo) { string debugStr = ""; Logger.WriteDebug("GetOperatorInfoAsync called."); try { if (!operatorInfo.Agreed) { throw new FriendlyException(FriendlyExceptionType.AccessDenied); } if (string.IsNullOrWhiteSpace(operatorInfo.DeviceGuid)) { throw new FriendlyException(FriendlyExceptionType.DeviceIsNotSupported); } if (!operatorInfo.Validating && string.IsNullOrWhiteSpace(operatorInfo.Badge)) { throw new FriendlyException(FriendlyExceptionType.AccessDenied); } //if (!operatorInfo.Validating && string.IsNullOrWhiteSpace(operatorInfo.CardNumber)) // throw new FriendlyException(FriendlyExceptionType.AccessDenied); if (operatorInfo.Validating && string.IsNullOrWhiteSpace(operatorInfo.DeviceSessionId)) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedSessionMismatch); } // --------------------------------------some sanity check! if ((operatorInfo.FirstName?.Length ?? 0) > 255) { throw new FriendlyException(FriendlyExceptionType.AccessDenied, "FirstName is too long."); } if ((operatorInfo.LastName?.Length ?? 0) > 255) { throw new FriendlyException(FriendlyExceptionType.AccessDenied, "LastName is too long."); } if ((operatorInfo.Badge?.Length ?? 0) > 10) { throw new FriendlyException(FriendlyExceptionType.AccessDenied, "Badge is too long."); } //if ((operatorInfo.CardNumber?.Length ?? 0) > 25) // throw new FriendlyException(FriendlyExceptionType.AccessDenied, "Card number is too long."); //---------------------------------------- var badge = operatorInfo.Badge?.Trim().PadLeft(6, '0'); debugStr = "Before getting Demo User for badge: " + badge; var user = await RestroomUnitOfWork.Get <User>().FirstOrDefaultAsync(m => m.Badge == badge); if (user == null) { throw new FriendlyException(FriendlyExceptionType.AccessHasBeenRevoked, "", debugStr); } if (!user.Active) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, "", debugStr); } //var demoUser = await IsDemoUserAsync(operatorInfo.FirstName, operatorInfo.LastName, badge); var demoUser = user.IsDemo.GetValueOrDefault(false); debugStr = "After getting Demo User: "******"After getting Employee, DemoUser: {demoUser}, Found:{(employee != null)}"; if (employee == null && !demoUser) { var s = $"GetOperatorInfo. Employee not found." + $"debugStr: {debugStr}"; Logger.Write(s); WriteLog(operatorInfo, s); //await InvalidateOperatorAsync(badge); throw new FriendlyException(FriendlyExceptionType.AccessDenied); } else if (employee != null && ( !string.Equals(employee.LastName, operatorInfo.LastName, StringComparison.OrdinalIgnoreCase) || //!string.Equals(employeeCardNumber, cardNumber, StringComparison.OrdinalIgnoreCase) || //!employee.SecurityCardEnabled.GetValueOrDefault(false) || // After the issue raise with one of the employees "Joseph Seibel", Michael decided to disabled this check (!string.Equals(employee.FirstName, operatorInfo.FirstName, StringComparison.OrdinalIgnoreCase) && !string.Equals(employee.MiddleName, operatorInfo.FirstName, StringComparison.OrdinalIgnoreCase))) ) { //var s = $"GetOperatorInfo. Employee badge: {badge} found but names or card # {cardNumber} were not match."; var s = $"GetOperatorInfo. Employee badge: {badge} found but names were not match."; s += $"Entered: FirstName: {employee?.FirstName??""}, LastName: {employee?.LastName??""}"; Logger.Write(s); WriteLog(operatorInfo, s); //await InvalidateOperatorAsync(badge); throw new FriendlyException(FriendlyExceptionType.AccessDenied); } if (demoUser) { CurrentUserName = "******"; } else { CurrentUserName = employee.Name; } var device = await RestroomUnitOfWork.Get <Device>() .FirstOrDefaultAsync(m => m.DeviceGuid == operatorInfo.DeviceGuid); //User user = await RestroomUnitOfWork.Get<User>().FirstOrDefaultAsync(m => m.Badge == badge); //if (!string.Equals(user?.LastName, operatorInfo.LastName) || // (!string.Equals(user?.FirstName, operatorInfo.FirstName) && // !string.Equals(user?.MiddleName, operatorInfo.FirstName))) // user = null; //debugStr = $"after getting device and user. DeviceGuid:{operatorInfo.DeviceGuid}, Badge: {badge}"; if (!demoUser) { if (operatorInfo.Validating && device == null) { throw new FriendlyException(FriendlyExceptionType.AccessDenied, "", debugStr); } if (device != null && !device.Active) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $"debugStr: {debugStr}"); } } //if (user != null && !user.Active) // throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive,"", debugStr); if (operatorInfo.Validating && (device == null || !device.Active || device.DeviceSessionId != operatorInfo.DeviceSessionId)) { if (device == null) { throw new FriendlyException(FriendlyExceptionType.AccessDenied); } if (!device.Active) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive); } throw new FriendlyException(FriendlyExceptionType.AccessDeniedSessionMismatch); } if (operatorInfo.Validating && (user == null || !user.Active)) { throw new FriendlyException(user == null ? FriendlyExceptionType.AccessHasBeenRevoked : FriendlyExceptionType.AccessDeniedNotActive); } UserDevice userDevice = null; if (device != null) { userDevice = await RestroomUnitOfWork.Get <UserDevice>() .FirstOrDefaultAsync(m => m.DeviceId == device.DeviceId && m.UserId == user.UserId); } if (device == null) { device = new Device { Active = true, //demoUser, DeviceGuid = operatorInfo.DeviceGuid, DeviceModel = operatorInfo.DeviceModel, DeviceOS = operatorInfo.DeviceOS, LastUsed = DateTime.Now }; device.DeviceSessionId = Guid.NewGuid().ToString(); //CreateDeviceSessionId(operatorInfo); } else { //try //{ if (operatorInfo.Validating && device.DeviceSessionId != operatorInfo.DeviceSessionId) { Logger.WriteError($"Badge:{badge}, Validating but sessions are not match!"); throw new FriendlyException(FriendlyExceptionType.AccessDenied); } if (device.DeviceSessionId != operatorInfo.DeviceSessionId) { device.DeviceSessionId = Guid.NewGuid().ToString(); } //var ticket = FormsAuthentication.Decrypt(device.DeviceSessionId); //if (ticket == null || ticket.Name != operatorInfo.DeviceGuid) // throw new FriendlyException(FriendlyExceptionType.AccessDenied); //if (ticket.Expired) // device.DeviceSessionId = CreateDeviceSessionId(operatorInfo); //} //catch (Exception ex) //{ // Logger.WriteError(ex.Message); // throw new FriendlyException(FriendlyExceptionType.AccessDenied); //} } if (user == null) { user = new User { Active = true, Badge = badge, }; } user.SecurityCardFormatted = employee?.SecurityCardFormatted; user.FirstName = demoUser?"Demo":(employee?.FirstName ?? ""); user.LastName = demoUser?"User":(employee?.LastName ?? ""); user.MiddleName = employee?.MiddleName ?? ""; var confirmation = new Confirmation { Badge = badge, Agreed = operatorInfo.Agreed, IncidentDateTime = operatorInfo.IncidentDateTime, DeviceId = operatorInfo.DeviceGuid, Active = true }; device.LastUsed = DateTime.Now; user = RestroomUnitOfWork.PrepUser(user); device = RestroomUnitOfWork.PrepDevice(device); confirmation = RestroomUnitOfWork.PrepConfirmation(confirmation); await RestroomUnitOfWork.SaveChangesAsync(); if (userDevice == null) { userDevice = new UserDevice(); userDevice.Active = true; //demoUser || device.DeviceId==default(long) || (!string.IsNullOrWhiteSpace(operatorInfo.DeviceSessionId) && operatorInfo.DeviceSessionId == device.DeviceSessionId); } userDevice.LastLogon = DateTime.Now; userDevice.UserId = user.UserId; userDevice.DeviceId = device.DeviceId; userDevice = await RestroomUnitOfWork.SaveUserDeviceAsync(userDevice); operatorInfo.DeviceSessionId = device.DeviceSessionId; operatorInfo.SessionApproved = user.Active && userDevice.Active && device.Active; } catch (FriendlyException ex) { Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message); if (ex.ExceptionType != FriendlyExceptionType.AccessDeniedNotActive) { throw; } operatorInfo.SessionApproved = false; } catch (DbEntityValidationException ex) { Logger.WriteError("DbEntityValidationException, debugStr:" + debugStr + ", Error:" + ex.Message); foreach (var eve in ex.EntityValidationErrors) { Logger.WriteError($"Entity of type \"{eve.Entry.Entity.GetType().Name}\" in state \"{eve.Entry.State}\" has the following validation errors:"); foreach (var ve in eve.ValidationErrors) { Logger.WriteError($"- Property: \"{ve.PropertyName}\", Error: \"{ve.ErrorMessage}\""); } } operatorInfo.SessionApproved = false; } catch (Exception ex) { Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message); operatorInfo.SessionApproved = false; } return(operatorInfo); }
public async Task <AuthenticationViewModel> ValidateSecurityCode(AuthenticationViewModel authModel) { string debugStr = ""; Logger.WriteDebug("ValidateSecurityCode called."); var jobTitle = ""; try { authModel = SanitizeModel(authModel); User user = await RestroomUnitOfWork.Get <User>().FirstOrDefaultAsync(m => m.Badge == authModel.Badge); if (user == null || !user.Active) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $"user is not active.", debugStr); } var demoUser = user.IsDemo.GetValueOrDefault(false); //var demoUser = await IsDemoUserAsync(authModel.FirstName, authModel.LastName, authModel.Badge); //debugStr = "After getting Demo User: "******"", ""); authModel.SessionApproved = true; authModel.DeviceSessionId = tempDevice.DeviceSessionId; return(authModel); } var employee = await EmployeeRepository.GetEmployeeByBadgeAsync(authModel.Badge); debugStr = $"After getting Employee, Found:{(employee != null)}"; if (employee == null) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $" User not found.", debugStr); } jobTitle = employee.JobTitle; var device = await RestroomUnitOfWork.Get <Device>().FirstOrDefaultAsync(m => m.DeviceGuid == authModel.DeviceGuid); debugStr = $"after getting device and user. DeviceGuid:{authModel.DeviceGuid}, Badge: {authModel.Badge}"; if (device == null || !device.Active) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $" device is not Active.", debugStr); } debugStr = $"after getting device and user. DeviceGuid:{authModel.DeviceGuid}, Badge: {authModel.Badge}, UserId:{user.UserId}, DeviceId:{device.DeviceId}"; UserDevice userDevice; userDevice = await RestroomUnitOfWork.Get <UserDevice>() .FirstOrDefaultAsync(m => m.DeviceId == device.DeviceId && m.UserId == user.UserId); if (userDevice == null || !userDevice.Active) { throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $"userDevice is not active.", debugStr); } debugStr = $"before checking 2Factor Auth. Client 2FACode:{authModel.Confirm2FACode}, DeviceGuid:{authModel.DeviceGuid}, Badge: {authModel.Badge}, UserId:{user.UserId}, DeviceId:{device.DeviceId}" + $", 2FACode Expires:{device.Confirm2FAExpires?.ToString("yyyy-MM-dd HH:mm:ss")}"; if (device.Confirm2FAExpires >= DateTime.Now && device.Confirm2FACode == authModel.Confirm2FACode) { device.Confirmed2FACode = true; device.DeviceSessionId = Guid.NewGuid().ToString(); } else { throw new FriendlyException(FriendlyExceptionType.InvalidOrExpired2FAuth, $"Security Code is invalid or expired.", debugStr); } device = RestroomUnitOfWork.PrepDevice(device); await RestroomUnitOfWork.SaveChangesAsync(); authModel.CanAddRestroom = Config.JobTitlesAccessToAddRestroom.Any(m => m == jobTitle); authModel.CanEditRestroom = Config.JobTitlesAccessToEditRestroom.Any(m => m == jobTitle); authModel.DeviceSessionId = device.DeviceSessionId; authModel.SessionApproved = true; } catch (FriendlyException ex) { Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message); if (ex.ExceptionType != FriendlyExceptionType.AccessDeniedNotActive) { throw; } authModel.SessionApproved = false; } catch (DbEntityValidationException ex) { Logger.WriteError("DbEntityValidationException, debugStr:" + debugStr + ", Error:" + ex.Message); foreach (var eve in ex.EntityValidationErrors) { Logger.WriteError($"Entity of type \"{eve.Entry.Entity.GetType().Name}\" in state \"{eve.Entry.State}\" has the following validation errors:"); foreach (var ve in eve.ValidationErrors) { Logger.WriteError($"- Property: \"{ve.PropertyName}\", Error: \"{ve.ErrorMessage}\""); } } authModel.SessionApproved = false; } catch (Exception ex) { Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message); authModel.SessionApproved = false; } return(authModel); }