NETRAVE/lib/utils/first_run_init.rb
VetheonGames 281d5f6ebf Implement Encryption for Sensitive Data and Switch to .env for Configuration Storage
This commit introduces several significant changes to improve the security and configuration management of the application.

    Encryption of Sensitive Data: We've introduced encryption for sensitive data such as database passwords. This is done using the Blowfish algorithm. The encryption and decryption methods are added to the Utilities module. The encryption is applied when the user enters their database password during the first run setup. The encrypted password is then stored in the .env file. When the application needs to use the password, it is decrypted using the key that was generated during encryption.

    Switch from YAML to .env for Configuration Storage: The application now uses a .env file for storing configuration data instead of a YAML file. This change was made to take advantage of the .env file's ability to store environment variables, which can be easily accessed by the application. The .env file stores the database username, encrypted password, encryption key, and database name.

    First Run Setup Changes: The FirstRunInit class has been updated to ask the user for their database details, encrypt the password, and store these details in the .env file. It also checks if any of the necessary details are missing and runs the first run setup if they are.

    Database Connection Testing: The DatabaseManager class now decrypts the password before using it to test the database connection. It also checks if the password or key are nil before attempting to decrypt the password.

    Logging: A new LoggMan class has been added to handle logging. This class provides a simple method for logging messages, which can be used throughout the application to log errors or other important information.

    Bug Fixes and Error Handling: Several bugs were fixed and error handling was improved. For example, a bug that caused the application to crash if the .env file was missing has been fixed. Also, the application now checks if the .env file exists and creates it if it doesn't.

These changes significantly improve the security, reliability, and usability of the application.
2023-06-11 15:46:53 -06:00

117 lines
3.2 KiB
Ruby

# frozen_string_literal: true
require 'curses'
require 'dynamic_curses_input'
require 'dotenv'
require_relative 'database_manager'
require_relative 'system_information_gather'
require_relative 'utilities'
require_relative 'logg_man'
# first run class
class FirstRunInit
include Utilities
include Curses
def initialize(db_manager = nil)
@db_manager = db_manager || DatabaseManager.new
@info_gatherer = SystemInformationGather.new(@db_manager)
@loggman = LoggMan.new
end
def run
first_run_setup
end
def first_run_setup # rubocop:disable Metrics/MethodLength
db_details = ask_for_db_details
until @db_manager.test_db_connection(db_details)
Curses.setpos(4, 0)
Curses.addstr("Whoops! We couldn't connect to the database with the details you provided. Please try again!")
Curses.refresh
db_details = ask_for_db_details
end
@db_manager.create_system_info_table
@db_manager.create_services_table
uplink_speed = @info_gatherer.ask_for_uplink_speed
downlink_speed = @info_gatherer.ask_for_downlink_speed
total_bandwidth = calculate_total_bandwidth(uplink_speed, downlink_speed)
services = @info_gatherer.ask_for_services
system_info = {
uplink_speed:,
downlink_speed:,
total_bandwidth:
}
@db_manager.store_system_info(system_info)
@db_manager.store_services(services)
end
def ask_for_db_details # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
Curses.clear
Curses.setpos(1, 0)
Curses.addstr('Please enter your database username: ')
Curses.refresh
username = DCI.catch_input(true)
Curses.setpos(2, 0)
Curses.addstr('Please enter your database password: ')
Curses.refresh
Curses.noecho
password = DCI.catch_input(false)
Curses.echo
Curses.setpos(3, 0)
Curses.addstr('Please enter your database name: ')
Curses.refresh
database = DCI.catch_input(true)
# Generate a secret key
key = generate_key
# Encrypt the password
encrypted_password = encrypt_string_chacha20(password, key)
db_details = { username:, password: encrypted_password, key:, database: }
write_db_details_to_config_file(db_details)
end
def write_db_details_to_config_file(db_details)
# Write the database details to the .env file
File.open('.env', 'w') do |file|
file.puts %(DB_USERNAME="#{db_details[:username]}")
file.puts %(DB_PASSWORD="#{db_details[:password]}")
file.puts %(DB_SECRET_KEY="#{db_details[:key]}")
file.puts %(DB_DATABASE="#{db_details[:database]}")
end
# Load the .env file using dotenv
Dotenv.load
rescue StandardError => e
@loggman.log_error("Failed to write to .env file: #{e.message}")
end
def ask_for_default_mode
loop do
Curses.setpos(8, 0)
Curses.addstr('Please enter the default mode (TUI, GUI, or WebApp): ')
Curses.refresh
mode = Curses.getstr.strip.downcase
return mode if valid_mode?(mode)
Curses.setpos(9, 0)
Curses.addstr("Whoops! That didn't appear to be a valid mode. Please try again!")
Curses.refresh
end
end
def valid_mode?(mode)
%w[tui gui webapp].include?(mode)
end
end