/// <summary>
        ///
        /// </summary>
        /// <param name="restroomId"></param>
        /// <param name="startPage"></param>
        /// <param name="numRecords"></param>
        /// <param name="earliestDate"></param>
        /// <returns></returns>
        public async Task <Feedback[]> GetFeedbacksAsync(int restroomId, int?startPage = null, int?numRecords = null, DateTime?earliestDate = null)
        {
            if (!LoggedIn)
            {
                var restroom = await RestroomUnitOfWork.GetRestroomAsync(restroomId);

                if (!restroom.IsPublic)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }
            }

            var feedbacks = RestroomUnitOfWork.Get <entity.Feedback>().Where(f => f.RestroomId == restroomId);

            if (earliestDate.HasValue)
            {
                feedbacks = feedbacks.Where(f => f.AddDateTime >= earliestDate.Value);
            }

            if (numRecords.HasValue)
            {
                feedbacks = feedbacks
                            .OrderByDescending(f => f.AddDateTime)
                            .Skip(startPage.GetValueOrDefault() * numRecords.Value)
                            .Take(numRecords.Value);
            }

            var result = await feedbacks.ToListAsync();

            return(result.Select(Feedback.FromDataAccess).ToArray());
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="feedback"></param>
        /// <returns></returns>
        public async Task <Feedback> SaveFeedbackAsync(Feedback feedback)
        {
            if (feedback == null)
            {
                throw new FriendlyException(FriendlyExceptionType.InvalidModelState);
            }
            Logger.WriteDebug("Feedback:" + JsonConvert.SerializeObject(feedback));
            if (!LoggedIn)
            {
                var restroom = await RestroomUnitOfWork.GetRestroomAsync(feedback.RestroomId);

                if (!restroom.IsPublic)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }
            }

            if (LoggedIn && feedback.Badge != ClaimsPrincipal.Current.Identity.Name)
            {
                throw new UnauthorizedAccessException("You can't post a feedback for someone else.");
            }
            if (feedback.Rating < 3 && string.IsNullOrWhiteSpace(feedback.FeedbackText))
            {
                throw new FriendlyException(FriendlyExceptionType.FeedbackTextRequired);
            }
            var result = await RestroomUnitOfWork.SaveFeedbackAsync(feedback.ToDataAccess());

            return(Feedback.FromDataAccess(result));
        }
        //private string CreateDeviceSessionId(OperatorInfoViewModel operatorInfo)
        //{
        //    var expires = DateTime.Now.AddMonths(6);
        //    var userData = new SecurityUserInfo
        //    {
        //        //DeviceId = operatorInfo.DeviceId,
        //        DeviceModel = operatorInfo.DeviceModel,
        //        //DeviceName = operatorInfo.DeviceName,
        //        //Badge = badge,
        //        CreationDateTime = DateTime.Now,
        //        Expires = expires
        //    };
        //    var authTicket = new FormsAuthenticationTicket(
        //        AthenticationVersion,
        //        operatorInfo.DeviceGuid,
        //        DateTime.Now,
        //        expires, // expiry
        //        true, //do not remember
        //        JsonConvert.SerializeObject(userData),
        //        "");
        //    return FormsAuthentication.Encrypt(authTicket);

        //}


        ///// <summary>
        /////
        ///// </summary>
        ///// <param name="firstName"></param>
        ///// <param name="lastName"></param>
        ///// <param name="badge"></param>
        ///// <param name="cardNumber"></param>
        ///// <param name="deviceSessionId"></param>
        ///// <returns></returns>
        //public async Task<bool> IsValidSessionAsync(string firstName, string lastName, string badge, string cardNumber, string deviceSessionId)
        //{
        //    if (string.IsNullOrWhiteSpace(badge) ||  string.IsNullOrWhiteSpace(cardNumber) || string.IsNullOrWhiteSpace(deviceSessionId) )
        //        return false;
        //    try
        //    {
        //        var ticket = FormsAuthentication.Decrypt(deviceSessionId);
        //        if (ticket != null && !ticket.Expired)
        //        {
        //            var userData = ticket.UserData;
        //            if (!string.IsNullOrWhiteSpace(userData))
        //            {
        //                var securityUserInfo = JsonConvert.DeserializeObject<SecurityUserInfo>(userData);
        //                if (securityUserInfo != null)
        //                {

        //                    badge = badge.Trim().PadLeft(6, '0');
        //                    var demoUser = await IsDemoUserAsync(firstName, lastName, badge);
        //                    if (demoUser)
        //                        return true;

        //                    var employee = await EmployeeRepository.GetEmployeeByBadgeAsync(badge);
        //                    Logger.WriteDebug("After getting Employee");
        //                    if (employee == null)
        //                        return false;


        //                    var device = await RestroomUnitOfWork.Get<Device>().FirstOrDefaultAsync(m => m.DeviceGuid == ticket.Name);
        //                    User user = await RestroomUnitOfWork.Get<User>().FirstOrDefaultAsync(m => m.Badge == badge && (m.FirstName==firstName || (m.MiddleName!=null && m.MiddleName==firstName))&& m.LastName==lastName);


        //                    if (device == null || user == null)
        //                        return false;
        //                    if (!device.Active || device.DeviceSessionId != deviceSessionId)
        //                        return false;
        //                    if (!user.Active)
        //                        return false;

        //                    var userDevice = await RestroomUnitOfWork.Get<UserDevice>().FirstOrDefaultAsync(m => m.DeviceId == device.DeviceId && m.UserId == user.UserId);
        //                    if (userDevice == null || !userDevice.Active)
        //                        return false;

        //                    return true;
        //                }
        //            }
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.WriteError(ex.Message);
        //        return false;
        //    }



        //    return false;
        //}


        /// <summary>
        ///
        /// </summary>
        /// <param name="badge"></param>
        /// <param name="deviceGuid"></param>
        /// <param name="deviceSessionId"></param>
        /// <returns></returns>
        public async Task <Tuple <bool, string, string> > IsValidSessionAsync(string badge, string deviceGuid, string deviceSessionId)
        {
            if (string.IsNullOrWhiteSpace(badge) || string.IsNullOrWhiteSpace(deviceSessionId) || string.IsNullOrWhiteSpace(deviceGuid))
            {
                return(new Tuple <bool, string, string>(false, "", ""));
            }
            try
            {
                badge = badge.Trim().PadLeft(6, '0');

                var device = await RestroomUnitOfWork.Get <Device>().FirstOrDefaultAsync(m => m.DeviceSessionId == deviceSessionId && m.DeviceGuid == deviceGuid);

                if (device == null || !device.Active)
                {
                    return(new Tuple <bool, string, string>(false, "", ""));
                }

                var user = await RestroomUnitOfWork.Get <User>().FirstOrDefaultAsync(m => m.Badge == badge && m.Active);

                if (user == null || user.Badge != badge || !user.Active)
                {
                    return(new Tuple <bool, string, string>(false, "", ""));
                }

                var userDevice = await RestroomUnitOfWork.Get <UserDevice>().FirstOrDefaultAsync(m => m.DeviceId == device.DeviceId && m.UserId == user.UserId);

                if (userDevice == null || !userDevice.Active)
                {
                    return(new Tuple <bool, string, string>(false, "", ""));
                }

                //var firstName = user.FirstName;
                //var lastName = user.LastName;
                //var demoUser = await IsDemoUserAsync(operatorInfo.FirstName, operatorInfo.LastName, badge);
                var demoUser = user.IsDemo.GetValueOrDefault(false);

                //var demoUser = await IsDemoUserAsync(firstName, lastName, badge);
                if (demoUser)
                {
                    return(new Tuple <bool, string, string>(true, "", "demo-user"));
                }

                var employee = await EmployeeRepository.GetEmployeeByBadgeAsync(user.Badge);

                if (employee == null)// || employee.SecurityCardFormatted != user.SecurityCardFormatted)
                {
                    return(new Tuple <bool, string, string>(false, "", ""));
                }

                return(new Tuple <bool, string, string>(true, employee.JobTitle, employee.NTLogin));
            }
            catch (Exception ex)
            {
                Logger.WriteError(ex.Message);
                return(new Tuple <bool, string, string>(false, "", ""));
            }
        }
        internal async Task <Restroom> GetRestroomAsync(int restroomId)
        {
            Entity.Contact contact   = null;
            var            restroomD = await RestroomUnitOfWork.GetRestroomAsync(restroomId);

            if (restroomD != null && restroomD.ContactId.HasValue)
            {
                contact = RestroomUnitOfWork.GetById <Entity.Contact, int>(restroomD.ContactId.Value);
            }

            return(restroomD == null ? null : Restroom.FromDataAccess(restroomD, contact));
        }
Exemple #5
0
 internal async void SaveOperatorAcknowledgementToDisclaimer(string badge, bool agreed, string deviceId, string sessionId, DateTime incidentDateTime)
 {
     InvalidateOperator(badge);
     var obj = new Confirmation
     {
         Badge            = badge,
         Agreed           = agreed,
         IncidentDateTime = incidentDateTime,
         DeviceId         = deviceId,
         Active           = true
     };
     await RestroomUnitOfWork.SaveConfirmationAsync(obj);
 }
        internal async Task <Restroom[]> GetRestroomsNearbyAsync(string routeAlpha, string direction, float?lat, float?longt, int?distance = null, bool publicRestrooms = true, bool pending = false)
        {
            var restrooms = await RestroomUnitOfWork.GetRestroomsNearbyAsync(routeAlpha, direction, lat, longt, distance, publicRestrooms, pending);

            var contactIds = restrooms.Where(m => m.ContactId.HasValue).Select(m => m.ContactId);
            var contacts   = RestroomUnitOfWork.Get <Entity.Contact>().Where(c => contactIds.Contains(c.ContactId));
            var result     = new List <Restroom>();

            foreach (var r in restrooms)
            {
                result.Add(Restroom.FromDataAccess(r, contacts.FirstOrDefault(c => c.ContactId == r.ContactId)));
            }
            //return result.Select(Restroom.FromDataAccess).ToArray();
            return(result.ToArray());
        }
        internal async Task <Log> WriteLogAsync(BaseViewModel model, string description)
        {
            var log = new Log
            {
                DeviceId    = model.DeviceGuid,
                DeviceOS    = model.DeviceOS,
                DeviceModel = model.DeviceModel,
                Description = description,
            };

            //using (var db = new RestroomContext())
            //{
            //    db.SaveLog(log);
            //}

            return(await RestroomUnitOfWork.SaveLogAsync(log));
        }
 internal async Task <int> InvalidateOperatorAsync(string badge)
 {
     return(await RestroomUnitOfWork.InvalidateOperatorAsync(badge));
 }
        /// <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);
        }
        internal List <Restroom> GetRestroomList()
        {
            var result = RestroomUnitOfWork.GetRestroomList();

            return(result.Select(Restroom.FromDataAccess) /*.Where(r => r.Active)*/.ToList());
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="FriendlyException"></exception>
        public async Task DisclaimerResponse(DisclaimerViewModel model)
        {
            const string methodName = "DisclaimerResponse";
            string       debugStr   = "";

            Logger.WriteDebug($"{methodName} called.");

            try
            {
                if (model == null)
                {
                    throw new FriendlyException(FriendlyExceptionType.InvalidModelState);
                }

                if (!model.Agreed)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }

                if (string.IsNullOrWhiteSpace(model.DeviceSessionId))
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }

                if (string.IsNullOrWhiteSpace(model.DeviceGuid))
                {
                    throw new FriendlyException(FriendlyExceptionType.DeviceIsNotSupported);
                }

                if (string.IsNullOrWhiteSpace(model.Badge))
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }


                // --------------------------------------some sanity check!
                if (model.Badge?.Length > 10)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied, "Badge is too long.");
                }

                //----------------------------------------
                var badge = model.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 = $"{methodName}. Employee not found." + $"debugStr: {debugStr}";
                    Logger.Write(s);
                    WriteLog(model, s);
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }


                if (demoUser)
                {
                    CurrentUserName = "******";
                }
                else
                {
                    CurrentUserName = employee.Name;
                }

                debugStr = $"Getting device for {model.DeviceGuid}";
                var device = await RestroomUnitOfWork.Get <Device>()
                             .FirstOrDefaultAsync(m => m.DeviceGuid == model.DeviceGuid);

                if (device == null || !device.Active)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $"debugStr: {debugStr}");
                }

                debugStr = $"Getting userDevice for device:{model.DeviceGuid} and user: {user.UserId}";
                var 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, $"debugStr: {debugStr}");
                }



                var confirmation = new Confirmation
                {
                    Badge            = badge,
                    Agreed           = model.Agreed,
                    IncidentDateTime = model.IncidentDateTime,
                    DeviceId         = model.DeviceGuid,
                    SessionId        = model.DeviceSessionId,
                    Active           = true
                };

                RestroomUnitOfWork.PrepConfirmation(confirmation);
                await RestroomUnitOfWork.SaveChangesAsync();
            }
            catch (FriendlyException ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                throw;
            }
            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}\"");
                    }
                }
                throw new FriendlyException(FriendlyExceptionType.Other, "Server could not process your request. please try again later.");
            }
            catch (Exception ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                throw new FriendlyException(FriendlyExceptionType.Other, "Server could not process your request. please try again later.");
            }
        }
        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="authModel"></param>
        /// <returns></returns>
        /// <exception cref="FriendlyException"></exception>
        public async Task <bool> SendSecurityCode(AuthenticationViewModel authModel)
        {
            string debugStr = "";

            Logger.WriteDebug("SendSecurityCode called.");
            try
            {
                authModel = SanitizeModel(authModel);
            }
            catch (Exception e)
            {
                return(false);
            }

            var firstName             = authModel.FirstName;
            var lastName              = authModel.LastName;
            var middleName            = "";
            var securityCardFormatted = "";

            try
            {
                //User user = await RestroomUnitOfWork.Get<User>().FirstOrDefaultAsync(m => m.Badge == authModel.Badge && m.FirstName == firstName && m.LastName == lastName);
                // I am not going to match the FirstName and LastName against RestroomFinder User Table because if a person changes his/her firsName/lastname, eventhough EDW has the new name, checking against our
                // application database will cause save error because the user (below) returns null, so we try to create a new user with the the same badge which already exists with different name/lastname exists in the database and badge is unique!
                // We only need to validate FistName and LastName against EmployeeDW (we are doing below)
                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) ?? 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);
                    }
                    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);
                    }
                    middleName            = employee.MiddleName;
                    securityCardFormatted = employee.SecurityCardFormatted;
                }

                debugStr = "Before PrepareUserDevice.";
                var device = await PrepareUserDevice(authModel, user, middleName, securityCardFormatted);

                debugStr = $"Before SendSecurityCodeBySms. DeviceGuid:{authModel.DeviceGuid}, Badge: {authModel.Badge}, Phone: {authModel.PhoneNumber}";
                // For development, I am temporarily comment this.
                await SendSecurityCodeBySms(authModel.PhoneNumber, $"Your ACTransit RestroomFinder security code is: {device.Confirm2FACode}\r\n Enter at SecurityCode field w/in 5 minutes.");

                return(true);
            }
            catch (FriendlyException ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                if (ex.ExceptionType != FriendlyExceptionType.AccessDeniedNotActive)
                {
                    throw;
                }
                authModel.SessionApproved = false;
                return(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;
                return(false);
            }
            catch (Exception ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                authModel.SessionApproved = false;
                return(false);
            }
        }
        public async Task <AuthenticationViewModel> Authenticate(AuthenticationViewModel authModel)
        {
            string debugStr = "";

            Logger.WriteDebug("Authenticate called.");

            try
            {
                authModel = SanitizeModel(authModel);

                if (string.IsNullOrWhiteSpace(authModel.DeviceGuid))
                {
                    throw new FriendlyException(FriendlyExceptionType.DeviceIsNotSupported);
                }

                if (string.IsNullOrWhiteSpace(authModel.DeviceSessionId))
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedSessionMismatch);
                }


                var badge = authModel.Badge;
                debugStr = "Before getting User for badge: " + badge;
                User user = await RestroomUnitOfWork.Get <User>().FirstOrDefaultAsync(m => m.Badge == badge);

                if (user == null || !user.Active)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $"user is not active.", debugStr);
                }
                var demoUser = user.IsDemo.GetValueOrDefault(false);
                debugStr = "After getting User, isDemoUser: "******"After getting Employee, Found:{(employee != null)}";

                if (employee == null)
                {
                    var s = $"Authenticate. Employee not found." + $"debugStr: {debugStr}";
                    Logger.Write(s);
                    WriteLog(authModel, s);
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }
                else if (
                    !string.Equals(employee.LastName, authModel.LastName, StringComparison.OrdinalIgnoreCase) ||
                    (!string.Equals(employee.FirstName, authModel.FirstName, StringComparison.OrdinalIgnoreCase) &&
                     !string.Equals(employee.MiddleName, authModel.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(authModel, s);
                    //await InvalidateOperatorAsync(badge);
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }


                CurrentUserName = employee.Name;


                var device = await RestroomUnitOfWork.Get <Device>()
                             .FirstOrDefaultAsync(m => m.DeviceGuid == authModel.DeviceGuid);

                if (device == null || !device.Active)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive);
                }

                //User user = await RestroomUnitOfWork.Get<User>().FirstOrDefaultAsync(m => m.Badge == badge);
                //debugStr = $"after getting device and user. DeviceGuid:{authModel.DeviceGuid}, Badge: {badge}";

                //if (user==null || !user.Active)
                //    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, debugStr);

                UserDevice userDevice = null;
                userDevice = await RestroomUnitOfWork.Get <UserDevice>()
                             .FirstOrDefaultAsync(m => m.DeviceId == device.DeviceId && m.UserId == user.UserId);

                if (userDevice == null || !userDevice.Active)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }

                if (device.DeviceSessionId != authModel.DeviceSessionId)
                {
                    Logger.WriteError($"Badge:{badge}, Sessions are not match!");
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }


                authModel.CanAddRestroom  = Config.JobTitlesAccessToAddRestroom.Any(m => m == employee.JobTitle);
                authModel.CanEditRestroom = Config.JobTitlesAccessToEditRestroom.Any(m => m == employee.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.CanAddRestroom  = false;
                authModel.CanEditRestroom = false;
                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.CanAddRestroom  = false;
                authModel.CanEditRestroom = false;
                authModel.SessionApproved = false;
            }
            catch (Exception ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                authModel.CanAddRestroom  = false;
                authModel.CanEditRestroom = false;
                authModel.SessionApproved = false;
            }
            return(authModel);
        }
        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);
        }
 protected DomainServiceBase(string username)
 {
     UnitOfWork = new RestroomUnitOfWork(username);
     Logger     = new Logger();
 }
Exemple #17
0
 internal async void InvalidateOperator(string badge)
 {
     await RestroomUnitOfWork.InvalidateOperatorAsync(badge);
 }
        internal async Task <Restroom> SaveRestroomAsync(Restroom model)
        {
            Entity.Restroom restroom = null;
            if (model.RestroomId > 0)
            {
                var r = await RestroomUnitOfWork.GetRestroomAsync(model.RestroomId);

                restroom = model.ToDataAccessFrom(r);
                Logger.WriteDebug("SaveRestroomAsync->After GetRestroomAsync and ToDataAccessFrom:" + JsonConvert.SerializeObject(restroom));
            }
            else
            {
                restroom           = model.ToDataAccess();
                restroom.UpdUserId = CurrentUserName;
            }

            var hasContact     = false;
            var contactChanged = false;


            hasContact = !string.IsNullOrWhiteSpace(model.ContactName) ||
                         !string.IsNullOrWhiteSpace(model.ContactTitle) ||
                         !string.IsNullOrWhiteSpace(model.ContactEmail) ||
                         !string.IsNullOrWhiteSpace(model.ContactPhone);
            Entity.Contact contact = null;

            if (!hasContact && restroom.ContactId.HasValue && restroom.ContactId > 0)
            {
                restroom.ContactId = null;
                restroom.Contact   = null;
            }

            else if (restroom.ContactId.HasValue && restroom.ContactId > 0)
            {
                contact = await RestroomUnitOfWork.GetByIdAsync <Entity.Contact, int>(restroom.ContactId.Value);

                if (contact.ContactName != model.ContactName ||
                    contact.Title != model.ContactTitle ||
                    contact.Email != model.ContactEmail ||
                    contact.Phone != model.ContactPhone ||
                    contact.ServiceProvider != model.ServiceProvider
                    )
                {
                    contactChanged = true;
                }
            }

            if (contactChanged || (hasContact && (!restroom.ContactId.HasValue || restroom.ContactId == 0)))
            {
                contact = new Entity.Contact
                {
                    Title           = model.ContactTitle,
                    Email           = model.ContactEmail,
                    Phone           = model.ContactPhone,
                    ContactName     = model.ContactName,
                    ServiceProvider = model.ServiceProvider
                };
                contact          = RestroomUnitOfWork.Create(contact);
                restroom.Contact = contact;
            }


            //restroom.Active = true;
            restroom.StatusListId = 1;  // always pending...
            try
            {
                var savedModel = await RestroomUnitOfWork.SaveRestroomAsync(restroom);

                return(savedModel == null ? null : Restroom.FromDataAccess(savedModel));
            }
            catch (DbEntityValidationException ex)
            {
                var errTxt = ex.GetStringRepresentation();
                Logger.WriteError("RestroomHandler.SaveRestroomAsync.DbEntityValidationException -> EntityValidationErrors : \r\n" + errTxt);
                throw;
            }
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="feedbackId"></param>
 /// <returns></returns>
 public bool FeedbackExists(long feedbackId)
 {
     return(RestroomUnitOfWork.Get <entity.Feedback>().Any(f => f.FeedbackId == feedbackId));
 }