public bool ResetPassword(Models.Account.User user)
        {
            bool outcome = false;

            if (string.IsNullOrEmpty(user.NewPassword)) return outcome;

            try
            {
                using (var ctx = new AssessmentEntities())
                {
                    string password_hash = ctx.usp_GetHash(user.NewPassword).SingleOrDefault<string>();

                    var userObj = ctx.User.Where(x => x.Email == user.Email).SingleOrDefault();
                    if (userObj != null)
                    {
                        // values used in 'reset password email'
                        user.UserName = userObj.UserName;
                        user.Guid = userObj.Guid;
                        user.FirstName = userObj.FirstName;
                        user.LastName = userObj.LastName;

                        // reset password
                        userObj.Password = password_hash;
                        userObj.StatusId = (int)Models.Account.UserStatus.Unconfirmed;
                        userObj.DateUpdated = DateTime.Now;
                        ctx.SaveChanges();
                        outcome = true;
                    }
                    else
                    {
                        Logger.Log(LogLevel.Error, "Error in ResetPassword [email = " + user.Email + "]: user not found");
                    }
                }
            }
            catch (Exception e)
            {
                outcome = false;
                Logger.Log(LogLevel.Error, "Error in ResetPassword: " + e.Message);
                throw new Exception();
            }

            return outcome;
        }
        public bool ChangePassword(Models.Account.User user)
        {
            bool outcome = false;

            if (string.IsNullOrEmpty(user.Password) || string.IsNullOrEmpty(user.NewPassword)
                || string.IsNullOrEmpty(user.NewPasswordConfirm)) return outcome;

            if (user.NewPassword != user.NewPasswordConfirm) return outcome;
            if (user.NewPassword == user.Password) return outcome;

            try
            {
                using (var ctx = new AssessmentEntities())
                {
                    string password_hash = ctx.usp_GetHash(user.NewPassword).SingleOrDefault<string>();

                    var userObj = ctx.User.Where(x => x.UserName == user.UserName).SingleOrDefault();
                    if (userObj != null)
                    {
                        userObj.Password = password_hash;
                        userObj.StatusId = (int)Models.Account.UserStatus.Active;
                        userObj.DateUpdated = DateTime.Now;
                        ctx.SaveChanges();
                        outcome = true;
                    }
                    else
                    {
                        Logger.Log(LogLevel.Error, "Error in ChangePassword [user name = " + user.UserName + "]: user not found");
                    }
                }
            }
            catch (Exception e)
            {
                outcome = false;
                Logger.Log(LogLevel.Error, "Error in ChangePassword: " + e.Message);
                throw new Exception();
            }

            return outcome;
        }
        public bool AddUser(Models.Account.User user)
        {
            bool outcome = false;
            var now = DateTime.Now;

            if (user != null && string.IsNullOrEmpty(user.Email))
            {
                Logger.Log(LogLevel.Error, "Error in AddUser: email not provided");
                return outcome;
            }

            try
            {
                using (var ctx = new AssessmentEntities())
                {
                    if (ctx.User.Any(x => x.Email == user.Email || x.UserName == user.Email))
                    {
                        Logger.Log(LogLevel.Error, "Error in AddUser [email = " + user.Email + "]: user already exists");
                        return outcome;   // duplicate user
                    }

                    string password_hash = ctx.usp_GetHash(user.Password).SingleOrDefault<string>();

                    // add user
                    var userObj = new User()
                    {
                        Guid = user.Guid,
                        UserName = user.Email,
                        Password = password_hash,
                        Email = user.Email,
                        FirstName = user.FirstName,
                        LastName = user.LastName,
                        StatusId = (int)Models.Account.UserStatus.Unconfirmed,
                        StartDate = now,
                        DateCreated = now,
                        DateUpdated = now
                    };

                    ctx.User.Add(userObj);
                    ctx.SaveChanges();

                    // add Guest role
                    var roleGuestObj = ctx.Role.FirstOrDefault(x => x.Name.Contains("Guest"));

                    if (roleGuestObj != null)
                    {
                        var userRoleObj = new UserRole()
                        {
                            UserId = userObj.Id,
                            RoleId = roleGuestObj.Id
                        };

                        ctx.UserRole.Add(userRoleObj);
                    }

                    // add Admin role
                    if (user.IsAdmin)
                    {
                        var roleAdminObj = ctx.Role.FirstOrDefault(x => x.Name.Contains("Admin"));

                        if (roleAdminObj != null)
                        {
                            var userRoleObj = new UserRole()
                            {
                                UserId = userObj.Id,
                                RoleId = roleAdminObj.Id
                            };

                            ctx.UserRole.Add(userRoleObj);
                        }
                    }

                    ctx.SaveChanges();
                    outcome = true;
                }
            }
            catch (Exception e)
            {
                Logger.Log(LogLevel.Error, "Error in AddUser" + (user != null ? " [email = " + user.Email + "]: " : ": ") + e.Message);
                throw new Exception();
            }

            return outcome;
        }
        public bool Authenticate(string userName, string password, out Models.Account.UserStatus status)
        {
            status = Models.Account.UserStatus.Undefined;
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password)) return false;

            bool result = false;
            string userName_encrypted = _aes.Encrypt(userName.Trim().ToLowerInvariant());
            int status_suspended = (int)Models.Account.UserStatus.Suspended;

            using (var ctx = new AssessmentEntities())
            {
                try
                {
                    string password_hash = ctx.usp_GetHash(password).SingleOrDefault<string>();

                    var userObj = ctx.User.Where(x =>
                           x.UserName == userName_encrypted
                           && x.Password == password_hash
                           && x.StatusId != status_suspended
                           && (x.EndDate.HasValue ? (DateTime)x.EndDate : DateTime.MaxValue) > DateTime.Now
                           && !x.Deleted)
                           .SingleOrDefault();

                    if (userObj != null)
                    {
                        userObj.LastLoginDate = DateTime.Now;
                        status = (Models.Account.UserStatus)userObj.UserStatus.Id;
                        ctx.SaveChanges();
                        result = true;
                    }
                    else
                    {
                        Logger.Log(LogLevel.Info, "Login not allowed [user name = " + userName + "]");
                    }
                }
                catch (Exception e)
                {
                    Logger.Log(LogLevel.Error, "Error in Authenticate: " + e.Message);
                }
            }

            return result;
        }