public User ValidLogin(int id, string password, out string message)
        {
            User user = null;

            message = this.GetUser(out user, id);
            if (!String.IsNullOrWhiteSpace(message))
            {
                return(null);
            }
            return(DBUserShared.ValidLogin(password, user));
        }
        private string CreateUserDB()
        {
            SqliteConnection conn = null;

            try
            {
                if (File.Exists(this.UsersFile))
                {
                    return("");
                }

                conn = new SqliteConnection(@"data source=" + this.UsersFile);
                conn.Open();

                SqliteCommand cmd = new SqliteCommand(conn);

                cmd.CommandText = DBUserShared.GetDBSQL();
                cmd.ExecuteNonQuery();

                return("");
            }
            catch (Exception ex)
            {
                try
                {
                    File.Delete(this.UsersFile);
                }
                catch
                {
                    return("Please manually remove: " + this.UsersFile + ", " + ex.Message);//should not get in here
                }
                return("Error creating user database: " + ex.Message);
            }
            finally
            {
                if (conn != null)
                {
                    conn.Close();
                    conn = null;
                }
            }
        }
        private string LoadUserBase(out List <User> users, bool single, int id)
        {
            users = new List <User>();
            SqliteConnection conn   = null;
            SqliteDataReader reader = null;

            try
            {
                conn = new SqliteConnection(@"data source=" + this.UsersFile);
                conn.Open();
                SqliteCommand cmd = new SqliteCommand(conn);

                cmd.CommandText = "SELECT id, description, fullname, password, securityLevel";
                for (int i = 0; i < DBUserShared.FingerCount; ++i)
                {
                    cmd.CommandText += String.Format(", fingerprint{0}", i);
                }
                cmd.CommandText += " FROM User WHERE deleted = 0";
                if (single)
                {
                    cmd.CommandText += " AND id = " + id;
                }

                reader = cmd.ExecuteReader();

                while (reader.Read())
                {
                    Dictionary <int, byte[]> lstFingerPrints = new Dictionary <int, byte[]>();

                    for (int i = 0; i < DBUserShared.FingerCount; ++i)
                    {
                        byte[] bytes = null;
                        int    index = 5 + i;
                        if (!reader.IsDBNull(index))
                        {
                            try
                            {
                                bytes = DBUserShared.AES_Decrypt((byte[])reader[index]);
                                lstFingerPrints.Add(i, bytes);
                            }
                            catch
                            {
                                //ignore but should not get in here
                                continue;
                            }
                        }
                    }
                    byte[] password = null;
                    if (reader[3] != System.DBNull.Value)
                    {
                        password = (byte[])reader[3];
                    }
                    User user = new User(int.Parse(reader[0].ToString()),
                                         reader[1].ToString(),
                                         reader[2].ToString(),
                                         password,
                                         byte.Parse(reader[4].ToString()),
                                         lstFingerPrints);
                    users.Add(user);
                }
                return("");
            }
            catch (Exception ex)
            {
                return("Error reading user database: " + ex.Message);
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader = null;
                }

                if (conn != null)
                {
                    conn.Close();
                    conn = null;
                }
            }
        }
        public string AddEditUser(User user, bool customTransaction, bool updateUserLastUpdated, bool customID)
        {
            if (user == null)
            {
                return("User cannot be null.");
            }

            if (String.IsNullOrWhiteSpace(user.FullName))
            {
                return("The user's fullname cannot be empty.");
            }

            if (DefaultUser.DefaultUserName.ToUpper().Equals(user.FullName.ToUpper()))
            {
                return(String.Format("The user's name cannot be {0}.", DefaultUser.DefaultUserName));
            }

            if (user.PasswordChanged && (String.IsNullOrWhiteSpace(user.NewPassword) || user.NewPassword.Length > VARCHAR_StandardSize))
            {
                return("The user's password cannot be empty.");
            }


            if (user.Description != null && user.Description.Length > VARCHAR_StandardSize)
            {
                return("The user's description is too long.");
            }

            SqliteDataReader reader = null;
            SqliteConnection conn   = null;

            try
            {
                SqliteTransaction transaction = null;
                if (customTransaction)
                {
                    if (_tempConn == null)
                    {
                        _tempConn = new SqliteConnection(@"data source=" + this.UsersFile);
                        _tempConn.Open();
                        _customTransaction = _tempConn.BeginTransaction();
                    }
                    conn = _tempConn;
                }
                else
                {
                    conn = new SqliteConnection(@"data source=" + this.UsersFile);
                    conn.Open();
                    transaction = conn.BeginTransaction();
                }

                SqliteCommand cmd = new SqliteCommand(conn);
                cmd.Parameters.Add(new SqliteParameter("@userID", user.ID));

                string description   = user.Description;
                string fullName      = user.FullName;
                byte   securityLevel = user.SecurityLevel;
                if (user.ID > 0)
                {
                    if (!customID)
                    {
                        cmd.CommandText = "SELECT id FROM User WHERE id = @userID";
                        reader          = cmd.ExecuteReader();
                        if (!reader.HasRows)
                        {
                            return("Couldn't find a user with the ID " + user.ID);
                        }
                        reader.Close();
                    }

                    cmd.Parameters.Add(new SqliteParameter("@id", user.ID));
                    //force the admin properties to stay the same
                    if (user.ID == DefaultAdminUser.DefaultAdminID)
                    {
                        description   = DefaultAdminUser.DefaultAdminDescription;
                        fullName      = DefaultAdminUser.DefaultAdminName;
                        securityLevel = DefaultAdminUser.DefaultAdminSecurityLevel;
                    }
                }
                cmd.Parameters.Add(new SqliteParameter("@description", description));

                cmd.Parameters.Add(new SqliteParameter("@fullname", fullName));

                byte[] password = user.Password;
                if (!customID && user.PasswordChanged)
                {
                    if (String.IsNullOrWhiteSpace(user.NewPassword))
                    {
                        return("The password cannot be blank.");
                    }
                    password = User.GenerateSHA256(user.NewPassword);
                    cmd.Parameters.Add(new SqliteParameter("password", password));
                }
                else if (customID)
                {
                    cmd.Parameters.Add(new SqliteParameter("password", user.Password));
                }
                cmd.Parameters.Add(new SqliteParameter("@securityLevel", securityLevel));

                if (user.ID > 0 && !customID)
                {
                    cmd.CommandText = "UPDATE User SET description = @description, fullname = @fullname, securityLevel = @securityLevel";
                    if (user.PasswordChanged)
                    {
                        cmd.CommandText += ", password = @password";
                    }
                }
                else
                {
                    cmd.CommandText = "INSERT INTO User(";
                    if (customID)
                    {
                        cmd.CommandText += "id,";
                    }
                    cmd.CommandText += "description, fullname, password, securityLevel";
                }

                for (int i = 0; i < DBUserShared.FingerCount; ++i)
                {
                    if (user.ID > 0 && !customID)
                    {
                        cmd.CommandText += String.Format(" ,fingerprint{0} = @fingerprint{0}", i);
                    }
                    else
                    {
                        cmd.CommandText += String.Format(" ,fingerprint{0}", i);
                    }
                    cmd.Parameters.Add(new SqliteParameter(String.Format("@fingerprint{0}", i), DBNull.Value));
                }

                foreach (FingerPrint fingerprint in user.FingerPrints)
                {
                    string fp = String.Format("@fingerprint{0}", fingerprint.PrintNumber);
                    if (cmd.Parameters.Contains(fp) && fingerprint.Print != null && fingerprint.Print.Length != 0)
                    {
                        cmd.Parameters[fp].Value = DBUserShared.AES_Encrypt(fingerprint.Print);
                    }
                }

                if (user.ID > 0 && !customID)
                {
                    cmd.CommandText += " WHERE ID = @id";
                }
                else
                {
                    cmd.CommandText += ") VALUES(";
                    if (customID)
                    {
                        cmd.CommandText += "@userID,";
                    }
                    cmd.CommandText += "@description, @fullname, @password, @securityLevel";

                    for (int i = 0; i < DBUserShared.FingerCount; ++i)
                    {
                        cmd.CommandText += String.Format(" ,@fingerprint{0}", i);
                    }
                    cmd.CommandText += ")";
                }

                cmd.ExecuteNonQuery();

                if (user.ID < 0 && !customID)
                {
                    cmd.CommandText = "SELECT last_insert_rowid()";
                    reader          = cmd.ExecuteReader();
                    while (reader.Read())
                    {
                        user.ID = int.Parse(reader[0].ToString());
                        cmd.Parameters["@userID"].Value = user.ID;
                    }
                    reader.Close();
                }

                if (updateUserLastUpdated)
                {
                    cmd.CommandText = "DELETE FROM UserLastUpdated";
                    cmd.ExecuteNonQuery();
                    cmd.CommandText = "INSERT INTO UserLastUpdated(Value) VALUES(@value)";
                    cmd.Parameters.Add(new SqliteParameter("@value", DateTime.Now));
                    cmd.ExecuteNonQuery();
                }

                if (!customTransaction)
                {
                    transaction.Commit();
                }
                return("");
            }
            catch (Exception ex)
            {
                return("Failed to add or edit user: " + ex.Message);
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader = null;
                }
                if (!customTransaction)
                {
                    if (conn != null)
                    {
                        conn.Close();
                        conn = null;
                    }
                }
            }
        }