From 3836849cc1283ec9a93a93a960ab29d22c01ed2a Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Sun, 14 Jan 2024 02:53:28 -0700 Subject: [PATCH 01/13] New branch --- rammerhead/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rammerhead/README.md b/rammerhead/README.md index 4a53ecbe..759e11f3 100644 --- a/rammerhead/README.md +++ b/rammerhead/README.md @@ -1,2 +1,2 @@ -# Rammerhead source files for the browser. Compiled for older browsers via [Esbuild](https://esbuild.github.io/). +# Rammerhead source files for the browser. Compiled for older browsers via [ESBuild](https://esbuild.github.io/). From 5b5b4c8b5d1b94721ac210e3e1e758bc64a96660 Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Sun, 14 Jan 2024 04:47:37 -0700 Subject: [PATCH 02/13] DB auth! --- Gemfile | 3 +++ main.rb | 25 ++++++++++++++++++++----- postgres.yml | 19 +++++++++++++++++++ require.rb | 3 +++ ruby/db.rb | 42 ++++++++++++++++++++++++++++++++++++++++++ ruby/validator.rb | 2 +- 6 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 postgres.yml create mode 100644 ruby/db.rb diff --git a/Gemfile b/Gemfile index 4468198a..42e1e321 100644 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,9 @@ gem 'rack_csrf' gem 'dry-schema' gem 'dry-validation' gem 'yaml' +gem 'sequel' +gem 'pg' +gem 'bcrypt' gem "rack-reverse-proxy", require: "rack/reverse_proxy" group :development, :test do gem "rerun" diff --git a/main.rb b/main.rb index 04ced05e..e06694c4 100644 --- a/main.rb +++ b/main.rb @@ -28,6 +28,10 @@ validateYML() #Validate the ENV variables validateEnv() +#Setup DB when Private is true +if Settings.private == "true" + dbSetup() +end #Encrypted cookies use Rack::Session::EncryptedCookie, cookie_options #csrf @@ -61,11 +65,22 @@ #Auth to login to the site post '/auth' do - if params[:password] == Settings.password && params[:username] == Settings.username - session[:auth] = true - session[:uid] = SecureRandom.alphanumeric(2048) - redirect '/' + if Settings.private == "false" + if params[:password] == Settings.password && params[:username] == Settings.username + session[:auth] = true + session[:uid] = SecureRandom.alphanumeric(2048) + redirect '/' + else + redirect '/' + end else - redirect '/' + loggedIn = login(params[:username], params[:password]) + if loggedIn == true + session[:auth] = true + session[:uid] = SecureRandom.alphanumeric(2048) + redirect '/' + else + redirect '/' + end end end diff --git a/postgres.yml b/postgres.yml new file mode 100644 index 00000000..af5df55b --- /dev/null +++ b/postgres.yml @@ -0,0 +1,19 @@ +version: '3.1' + +services: + + db: + image: postgres + restart: always + environment: + POSTGRES_PASSWORD: example + POSTGRES_USER: example + POSTGRES_DB: example + ports: + - 5432:5432 + + adminer: + image: adminer + restart: always + ports: + - 8099:8080 diff --git a/require.rb b/require.rb index 529b1496..8311ecc8 100644 --- a/require.rb +++ b/require.rb @@ -10,7 +10,10 @@ require 'dry/schema' require 'dry/validation' require 'yaml' +require 'sequel' +require 'bcrypt' require './ruby/utils.rb' require './ruby/uv.rb' require './ruby/auth.rb' require './ruby/validator.rb' +require './ruby/db.rb' diff --git a/ruby/db.rb b/ruby/db.rb new file mode 100644 index 00000000..41350974 --- /dev/null +++ b/ruby/db.rb @@ -0,0 +1,42 @@ +def dbSetup() + puts "Setting up database...".green + db = Sequel.postgres(host: 'localhost', user: 'example', password: 'example', database: 'example') + puts "Creating table 'users' (if it does not exist)...".green + if db.table_exists?(:users) + puts "Table 'users' already exists.".yellow + else + db.create_table :users do + primary_key :id + String :username + String :password + Boolean :admin + end + end + + puts "Adding user admin user: #{Settings.username} (if it does not exist)".green + if db[:users].where(username: Settings.username).count >= 1 + puts "User #{Settings.username} already exists.".yellow + else + password = BCrypt::Password.create(Settings.password) + db[:users].insert(username: Settings.username, password: password, admin: true) + end + db.disconnect + puts "Database setup complete.".green + return +end + +def login(username, password) + username = username.gsub(/[^0-9A-Za-z]/, '') + password = password.gsub(/[^0-9A-Za-z]/, '') + db = Sequel.postgres(host: 'localhost', user: 'example', password: 'example', database: 'example') + ## we need to check for the password but it is hashed so we need to use bcrypt to check it + pass = db[:users].where(username: username).get(:password) + password = BCrypt::Password.new(pass) + if pass == password + db.disconnect + return true + else + db.disconnect + return false + end +end diff --git a/ruby/validator.rb b/ruby/validator.rb index cb5406e8..680fce0d 100644 --- a/ruby/validator.rb +++ b/ruby/validator.rb @@ -21,7 +21,7 @@ class YamlValidator < Dry::Validation::Contract key.failure('must have a url') if value !~ /\A#{URI::regexp(['http', 'https'])}\z/ key.failure('must have a / at the end') if value !~ /\/\z/ else - key.failure('must NOT have a url') if value =~ /\A#{URI::regexp(['http', 'https'])}\z/ + key.failure('must NOT have a url (N/A will work)') if value =~ /\A#{URI::regexp(['http', 'https'])}\z/ end end rule(:username) do From fffa8913f972c5f7c5dd406e1a94dcb1b6ef0de7 Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Sun, 14 Jan 2024 19:27:51 -0700 Subject: [PATCH 03/13] Bug fixes --- main.rb | 4 ++-- ruby/db.rb | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/main.rb b/main.rb index e06694c4..2f541229 100644 --- a/main.rb +++ b/main.rb @@ -29,7 +29,7 @@ #Validate the ENV variables validateEnv() #Setup DB when Private is true -if Settings.private == "true" +if Settings.private == "true" && Settings.multiuser == "false" dbSetup() end #Encrypted cookies @@ -65,7 +65,7 @@ #Auth to login to the site post '/auth' do - if Settings.private == "false" + if Settings.private == "false" && Settings.multiuser == "false" if params[:password] == Settings.password && params[:username] == Settings.username session[:auth] = true session[:uid] = SecureRandom.alphanumeric(2048) diff --git a/ruby/db.rb b/ruby/db.rb index 41350974..dc2c9846 100644 --- a/ruby/db.rb +++ b/ruby/db.rb @@ -29,14 +29,14 @@ def login(username, password) username = username.gsub(/[^0-9A-Za-z]/, '') password = password.gsub(/[^0-9A-Za-z]/, '') db = Sequel.postgres(host: 'localhost', user: 'example', password: 'example', database: 'example') - ## we need to check for the password but it is hashed so we need to use bcrypt to check it - pass = db[:users].where(username: username).get(:password) - password = BCrypt::Password.new(pass) - if pass == password - db.disconnect - return true - else - db.disconnect + hashedPassword = db[:users].where(username: username).get(:password) + begin + if BCrypt::Password.new(hashedPassword) == password + return true + else + return false + end + rescue BCrypt::Errors::InvalidHash return false end end From 9359a56ef6afe716121ef7b289faa669cef9d4ab Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Sun, 14 Jan 2024 21:06:25 -0700 Subject: [PATCH 04/13] CLI! --- Gemfile | 3 ++ cli/cli.rb | 102 ++++++++++++++++++++++++++++++++++++++++++++++ main.rb | 14 ++++--- ruby/db.rb | 21 +++++++--- ruby/validator.rb | 10 +++-- 5 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 cli/cli.rb diff --git a/Gemfile b/Gemfile index 42e1e321..89f93c12 100644 --- a/Gemfile +++ b/Gemfile @@ -17,6 +17,9 @@ gem 'yaml' gem 'sequel' gem 'pg' gem 'bcrypt' +gem 'thor' +gem 'readline' +gem 'readline-ext' gem "rack-reverse-proxy", require: "rack/reverse_proxy" group :development, :test do gem "rerun" diff --git a/cli/cli.rb b/cli/cli.rb new file mode 100644 index 00000000..1e3a0473 --- /dev/null +++ b/cli/cli.rb @@ -0,0 +1,102 @@ +require 'thor' +require 'colorize' +require 'sequel' +require 'bcrypt' +require 'readline' +require_relative '../ruby/db.rb' + +class RubyCLI < Thor + #class_option :verbose, :type => :boolean, :aliases => "-v" + desc "create", "Create a new user" + def create + puts "Creating a new user...".red + username = Readline.readline("Username: ", true) + username = username.gsub(/[^0-9A-Za-z]/, '') + username = username.downcase + while true + password = Readline.readline("Password: ", true) + passwordConfirm = Readline.readline("Retype password: ", true) + if password != passwordConfirm + puts "\e[H\e[2J" + puts "Passwords do not match! Try again.".red + else + break + end + end + + db = connectDB() + hashedPassword = BCrypt::Password.create(password) + if db[:users].where(username: username).count > 0 + puts "User already exists!".red + db.disconnect + exit + else + db[:users].insert(username: username, password: hashedPassword, admin: false) + puts "User created!".blue + db.disconnect + end + + end + desc "delete", "Delete a user" + def delete + puts "Deleting a user...".red + username = Readline.readline("Username: ", true) + username = username.gsub(/[^0-9A-Za-z]/, '') + username = username.downcase + db = connectDB() + while true + usernameConfirm = Readline.readline("Are you sure you want to delete #{username}? (y/n): ", true).downcase + if usernameConfirm == "y" || usernameConfirm == "yes" + if db[:users].where(username: username).count > 0 + db[:users].where(username: username).delete + puts "User deleted!".blue + db.disconnect + else + puts "User does not exist! (use the list command to see all users)".red + db.disconnect + end + exit + elsif usernameConfirm == "n" || usernameConfirm == "no" + puts "Ok, exiting...".blue + db.disconnect + exit + end + end + end + desc "list", "List all users" + def list + db = connectDB() + puts "Listing all users...".red + users = db[:users] + users.each{|user| puts user[:username]} + end + desc "reset", "Reset a user's password" + def reset + puts "Resetting a user's password...".red + username = Readline.readline("Username: ", true) + username = username.gsub(/[^0-9A-Za-z]/, '') + username = username.downcase + db = connectDB() + if db[:users].where(username: username).count > 0 + while true + password = Readline.readline("New Password: ", true) + passwordConfirm = Readline.readline("Retype new password: ", true) + if password != passwordConfirm + puts "\e[H\e[2J" + puts "Passwords do not match! Try again.".red + else + break + end + end + hashedPassword = BCrypt::Password.create(password) + db[:users].where(username: username).update(password: hashedPassword) + puts "Password reset!".blue + db.disconnect + else + puts "User does not exist! (use the list command to see all users)".red + db.disconnect + end + end +end + +RubyCLI.start(ARGV) diff --git a/main.rb b/main.rb index 2f541229..02c87c1c 100644 --- a/main.rb +++ b/main.rb @@ -29,7 +29,7 @@ #Validate the ENV variables validateEnv() #Setup DB when Private is true -if Settings.private == "true" && Settings.multiuser == "false" +if Settings.private == "true" && Settings.multiuser == "true" dbSetup() end #Encrypted cookies @@ -44,8 +44,12 @@ if request.path_info == '/auth' return #any route on the main domain - elsif request.url.include? ENV['DOMAIN'] || Settings.mainURL - return + elsif Settings.private == "false" + if request.url.include? ENV['DOMAIN'] || Settings.mainURL + return + else + auth() + end else auth() end @@ -65,8 +69,8 @@ #Auth to login to the site post '/auth' do - if Settings.private == "false" && Settings.multiuser == "false" - if params[:password] == Settings.password && params[:username] == Settings.username + if Settings.private == "false" || Settings.multiuser == "false" + if params[:password] == Settings.password && params[:username].downcase == Settings.username.downcase session[:auth] = true session[:uid] = SecureRandom.alphanumeric(2048) redirect '/' diff --git a/ruby/db.rb b/ruby/db.rb index dc2c9846..0e7ef062 100644 --- a/ruby/db.rb +++ b/ruby/db.rb @@ -1,6 +1,11 @@ +def connectDB() + db = Sequel.postgres(host: 'localhost', user: 'example', password: 'example', database: 'example') + return db +end + def dbSetup() puts "Setting up database...".green - db = Sequel.postgres(host: 'localhost', user: 'example', password: 'example', database: 'example') + db = connectDB() puts "Creating table 'users' (if it does not exist)...".green if db.table_exists?(:users) puts "Table 'users' already exists.".yellow @@ -13,12 +18,12 @@ def dbSetup() end end - puts "Adding user admin user: #{Settings.username} (if it does not exist)".green - if db[:users].where(username: Settings.username).count >= 1 - puts "User #{Settings.username} already exists.".yellow + puts "Adding user admin user: #{Settings.username.downcase} (if it does not exist)".green + if db[:users].where(username: Settings.username.downcase).count >= 1 + puts "User #{Settings.username.downcase} already exists.".yellow else password = BCrypt::Password.create(Settings.password) - db[:users].insert(username: Settings.username, password: password, admin: true) + db[:users].insert(username: Settings.username.downcase, password: password, admin: true) end db.disconnect puts "Database setup complete.".green @@ -27,16 +32,20 @@ def dbSetup() def login(username, password) username = username.gsub(/[^0-9A-Za-z]/, '') + username = username.downcase password = password.gsub(/[^0-9A-Za-z]/, '') - db = Sequel.postgres(host: 'localhost', user: 'example', password: 'example', database: 'example') + db = connectDB() hashedPassword = db[:users].where(username: username).get(:password) begin if BCrypt::Password.new(hashedPassword) == password + db.disconnect return true else + db.disconnect return false end rescue BCrypt::Errors::InvalidHash + db.disconnect return false end end diff --git a/ruby/validator.rb b/ruby/validator.rb index 680fce0d..6849e027 100644 --- a/ruby/validator.rb +++ b/ruby/validator.rb @@ -5,7 +5,8 @@ class YamlValidator < Dry::Validation::Contract required(:private).filled(:string) required(:username).filled(:string) required(:password).filled(:string) - required(:mainURL).filled(:string) + optional(:multiuser).filled(:string) + optional(:mainURL).filled(:string) end rule(:port) do key.failure('must be greater than 0') if value <= 0 @@ -20,8 +21,6 @@ class YamlValidator < Dry::Validation::Contract if (Settings.private == "false") key.failure('must have a url') if value !~ /\A#{URI::regexp(['http', 'https'])}\z/ key.failure('must have a / at the end') if value !~ /\/\z/ - else - key.failure('must NOT have a url (N/A will work)') if value =~ /\A#{URI::regexp(['http', 'https'])}\z/ end end rule(:username) do @@ -40,6 +39,11 @@ class YamlValidator < Dry::Validation::Contract key.failure('the password must NOT be "ruby"') if value == "ruby" end end + rule(:multiuser) do + if (Settings.private == "true") + key.failure('MUST BE TRUE OR FALSE') if value != "true" && value != "false" + end + end end def validateYML From 5633f881abeb1988a32261975eec3466eedfc715 Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Sun, 14 Jan 2024 22:13:35 -0700 Subject: [PATCH 05/13] DB connection no longer hardcoded --- cli/cli.rb | 16 +++++++++++----- package.json | 3 ++- ruby/db.rb | 16 ++++++++++++---- ruby/validator.rb | 1 + 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/cli/cli.rb b/cli/cli.rb index 1e3a0473..86a1d131 100644 --- a/cli/cli.rb +++ b/cli/cli.rb @@ -3,10 +3,16 @@ require 'sequel' require 'bcrypt' require 'readline' +require 'yaml' require_relative '../ruby/db.rb' +settings = YAML.load_file(File.join(File.dirname(__FILE__), '../config/settings.yml')) +$host = ENV['DB_HOST'] || settings['database']['host'].to_s +$user = ENV['DB_USERNAME'] || settings['database']['username'].to_s +$password = ENV['DB_PASSWORD'] || settings['database']['password'].to_s +$database = ENV['DB_DATABASE'] || settings['database']['dbname'].to_s + class RubyCLI < Thor - #class_option :verbose, :type => :boolean, :aliases => "-v" desc "create", "Create a new user" def create puts "Creating a new user...".red @@ -24,7 +30,7 @@ def create end end - db = connectDB() + db = connectDB($host, $user, $password, $database) hashedPassword = BCrypt::Password.create(password) if db[:users].where(username: username).count > 0 puts "User already exists!".red @@ -43,7 +49,7 @@ def delete username = Readline.readline("Username: ", true) username = username.gsub(/[^0-9A-Za-z]/, '') username = username.downcase - db = connectDB() + db = connectDB($host, $user, $password, $database) while true usernameConfirm = Readline.readline("Are you sure you want to delete #{username}? (y/n): ", true).downcase if usernameConfirm == "y" || usernameConfirm == "yes" @@ -65,7 +71,7 @@ def delete end desc "list", "List all users" def list - db = connectDB() + db = connectDB($host, $user, $password, $database) puts "Listing all users...".red users = db[:users] users.each{|user| puts user[:username]} @@ -76,7 +82,7 @@ def reset username = Readline.readline("Username: ", true) username = username.gsub(/[^0-9A-Za-z]/, '') username = username.downcase - db = connectDB() + db = connectDB($host, $user, $password, $database) if db[:users].where(username: username).count > 0 while true password = Readline.readline("New Password: ", true) diff --git a/package.json b/package.json index 730aca4e..c42d1fb7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "dev": "bundle exec rerun --ignore 'src/public/css/*' --signal 'TERM' -c -w 5 --no-notify -- puma", "start": "bundle exec puma -e production", "install": "bundle install && npm run build", - "build": "node ./build.js" + "build": "node ./build.js", + "cli": "bundle exec ruby ./cli/cli.rb" }, "engines": { "node": ">=18.0.0" diff --git a/ruby/db.rb b/ruby/db.rb index 0e7ef062..a742feb9 100644 --- a/ruby/db.rb +++ b/ruby/db.rb @@ -1,11 +1,19 @@ -def connectDB() - db = Sequel.postgres(host: 'localhost', user: 'example', password: 'example', database: 'example') +def connectDB(host, user, password, database) + db = Sequel.postgres(host: host, user: user, password: password, database: database) return db end +def defineDBVars() + $host = ENV['DB_HOST'] || Settings.database.host + $user = ENV['DB_USERNAME'] || Settings.database.username + $password = ENV['DB_PASSWORD'] || Settings.database.password + $database = ENV['DB_DATABASE'] || Settings.database.dbname +end + def dbSetup() puts "Setting up database...".green - db = connectDB() + defineDBVars() + db = connectDB($host, $user, $password, $database) puts "Creating table 'users' (if it does not exist)...".green if db.table_exists?(:users) puts "Table 'users' already exists.".yellow @@ -34,7 +42,7 @@ def login(username, password) username = username.gsub(/[^0-9A-Za-z]/, '') username = username.downcase password = password.gsub(/[^0-9A-Za-z]/, '') - db = connectDB() + db = connectDB($host, $user, $password, $database) hashedPassword = db[:users].where(username: username).get(:password) begin if BCrypt::Password.new(hashedPassword) == password diff --git a/ruby/validator.rb b/ruby/validator.rb index 6849e027..cc322645 100644 --- a/ruby/validator.rb +++ b/ruby/validator.rb @@ -41,6 +41,7 @@ class YamlValidator < Dry::Validation::Contract end rule(:multiuser) do if (Settings.private == "true") + key.failure('multiuser is required to be used when private mode is enabled') if value == nil key.failure('MUST BE TRUE OR FALSE') if value != "true" && value != "false" end end From a6e398dc61d0828e07e85c187a0f16aec6b93b04 Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Sun, 14 Jan 2024 22:54:06 -0700 Subject: [PATCH 06/13] Update example config --- config/settings.example.yml | 26 ++++++++++++++++++++------ ruby/validator.rb | 8 +++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/config/settings.example.yml b/config/settings.example.yml index d879c4f4..b5c6ff31 100644 --- a/config/settings.example.yml +++ b/config/settings.example.yml @@ -1,6 +1,20 @@ -port: 9293 -verboseLogging: "false" -private: "false" -username: "ruby" -password: "ruby" -mainURL: "http://localhost:3000/browser/" +port: 9293 #currently does nothing, but will be used in the future +verboseLogging: "false" #change this to "true" to enable verbose logging +private: "false" #change this to "true" to enable private mode +username: "ruby" #change this to your username (when using private mode) +password: "ruby" #change this to your password (when using private mode) + +# Everything below this line is optional is some form or another +mainURL: "https://localhost:9293/" # set to a URL to redirect to when the user visits the root of the server (e.g. http://example.com/) WILL be ignored when private mode is enabled + #more info: when using docker this can/is overriden by the environment variable DOMAIN +multiuser: "true" # set to true to enable multiuser mode when using private mode (if not using private mode, this will be ignored) + #more info: when using docker this can/is overriden by the environment variable MULTIUSER + +# Database Settings Only Needed When Using Multiuser Mode is Enabled +# These are ignored when multiuser mode is not enabled +# When using multiuser mode and docker, these will be overriden by the environment variables set in the docker-compose.yml file +database: + username: "ruby" # change this to your database username + password: "ruby" # change this to your database password + host: "postgres" # change this to your database host + dbname: "ruby" # change this to your database name diff --git a/ruby/validator.rb b/ruby/validator.rb index cc322645..26872403 100644 --- a/ruby/validator.rb +++ b/ruby/validator.rb @@ -7,6 +7,12 @@ class YamlValidator < Dry::Validation::Contract required(:password).filled(:string) optional(:multiuser).filled(:string) optional(:mainURL).filled(:string) + optional(:database).filled(:hash).schema do + required(:host).filled(:string) + required(:username).filled(:string) + required(:password).filled(:string) + required(:dbname).filled(:string) + end end rule(:port) do key.failure('must be greater than 0') if value <= 0 @@ -45,7 +51,7 @@ class YamlValidator < Dry::Validation::Contract key.failure('MUST BE TRUE OR FALSE') if value != "true" && value != "false" end end -end + end def validateYML config = YAML.load_file(File.join(settings.root, '/config/settings.yml')) From e038882ed862688705a9b1154801df36bd0dae8e Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Sun, 14 Jan 2024 23:38:27 -0700 Subject: [PATCH 07/13] Update docker to reflect changes --- config/settings.example.yml | 6 ++---- docker/docker-compose.build.yml | 20 ++++++++++++++++---- docker/docker-compose.yml | 27 ++++++++++++++++++++------- main.rb | 1 + 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/config/settings.example.yml b/config/settings.example.yml index b5c6ff31..475a0207 100644 --- a/config/settings.example.yml +++ b/config/settings.example.yml @@ -6,15 +6,13 @@ password: "ruby" #change this to your password (when using private mode) # Everything below this line is optional is some form or another mainURL: "https://localhost:9293/" # set to a URL to redirect to when the user visits the root of the server (e.g. http://example.com/) WILL be ignored when private mode is enabled - #more info: when using docker this can/is overriden by the environment variable DOMAIN multiuser: "true" # set to true to enable multiuser mode when using private mode (if not using private mode, this will be ignored) - #more info: when using docker this can/is overriden by the environment variable MULTIUSER # Database Settings Only Needed When Using Multiuser Mode is Enabled # These are ignored when multiuser mode is not enabled -# When using multiuser mode and docker, these will be overriden by the environment variables set in the docker-compose.yml file +# NOTE: when using docker these values should not be changed database: username: "ruby" # change this to your database username password: "ruby" # change this to your database password - host: "postgres" # change this to your database host + host: "db" # change this to your database host dbname: "ruby" # change this to your database name diff --git a/docker/docker-compose.build.yml b/docker/docker-compose.build.yml index 0451ae21..cebd8e53 100644 --- a/docker/docker-compose.build.yml +++ b/docker/docker-compose.build.yml @@ -10,7 +10,19 @@ services: - your port here:9293 volumes: - ./config.yml:/usr/src/app/config/settings.yml -#networks: -# default: -# external: -# name: default_net + # + # Uncomment the following lines if you want to use a database (mutliuser mode) + #db: + # image: postgres + # restart: always + # environment: + # POSTGRES_PASSWORD: ruby + # POSTGRES_USER: ruby + # POSTGRES_DB: ruby + + # Uncomment the following lines if you want to use adminer (database management) + #adminer: + # image: adminer + # restart: always + # ports: + # - 8099:8080 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 35171840..97fe39a0 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,14 +1,27 @@ -version: '2' +version: '3' services: ruby: restart: unless-stopped - image: 'ghcr.io/ruby-network/ruby:latest' + image: 'motortruck1221/ruby:latest' ports: #DO NOT CHANGE 9293! - - 9293:9293 + - your port here:9293 volumes: - ./config.yml:/usr/src/app/config/settings.yml -#networks: - # default: - # external: - # name: default_net + + # + # Uncomment the following lines if you want to use a database (mutliuser mode) + #db: + # image: postgres + # restart: always + # environment: + # POSTGRES_PASSWORD: ruby + # POSTGRES_USER: ruby + # POSTGRES_DB: ruby + + # Uncomment the following lines if you want to use adminer (database management) + #adminer: + # image: adminer + # restart: always + # ports: + # - 8099:8080 diff --git a/main.rb b/main.rb index 02c87c1c..b8f8a0ae 100644 --- a/main.rb +++ b/main.rb @@ -5,6 +5,7 @@ set :views, File.join(settings.root, 'src', 'views') set :template, File.join(settings.root, 'src', 'templates') register Config + logging = Settings.verboseLogging if logging == "true" puts "Verbose logging is enabled".green From cf0ca9ab47727d7a1da0a9a8dbe2f3e044989682 Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Mon, 15 Jan 2024 00:27:21 -0700 Subject: [PATCH 08/13] Update DOCS --- docs/advanced-config.md | 12 ++++++++-- docs/private.md | 53 ++++++++++++++++++++++++++++++++++++----- main.rb | 9 +++++++ node-server/server.js | 4 ++-- 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/docs/advanced-config.md b/docs/advanced-config.md index e31d3dcc..3df294b9 100644 --- a/docs/advanced-config.md +++ b/docs/advanced-config.md @@ -3,7 +3,7 @@ ##### This provides a list of all the configuration options available to you. ##### The config file can be found [here](../config/settings.example.yml) -`port` - The port the Ruby server will run on. Default is `9293` +`port` - The port the Ruby server will run on. Default is `9293` (does not currently work) `verboseLogging` - Whether or not to log all requests to the console. Default is `false` @@ -13,7 +13,15 @@ `password` - The password for use in either, private instances. If it is a normal instance, password will always be `ruby` -`mainUrl` - The main URL for use in a normal instance. If you are trying to make a private instance set this value to `NA` +`mainUrl` - The main URL for use in a normal instance. If you are trying to make a private instance set this value to anything or delete it. + +`multiuser` - Whether or not to enable multiuser mode. Default is `false` **ONLY WORKS IN PRIVATE MODE** + +`database` - A set of options for the database connection. **ONLY WORKS IN PRIVATE MODE** **Currently only supports Postgresql** + - `host` - The host of the database. Default is `localhost` + - `dbName` - The name of the database. Default is `ruby` + - `username` - The username for the database. Default is `ruby` + - `password` - The password for the database. Default is `ruby` --- #### Options coming soon: diff --git a/docs/private.md b/docs/private.md index e94290b7..498cfac8 100644 --- a/docs/private.md +++ b/docs/private.md @@ -3,7 +3,7 @@ ## Notes - I am expecting you to be using Linux. If you are not the commands should be easily translatable to the shell you are using -## No Docker +## No Docker (one user) #### Prerequisites - Ruby needs to be installed - Don't know how? Follow our [guide](./install-ruby.md) @@ -34,8 +34,6 @@ private: "true" username: "your username" password: "your password" - # DO NOT CHANGE THE VALUE BELOW - mainURL: "NA" ``` 6. Start the server ```bash @@ -43,7 +41,7 @@ ``` 7. You should now be able to access your instance at `http://localhost:9293` -## Docker +## Docker (one user) #### Prerequisites - Docker needs to be installed - Don't know how? Follow our [guide](./docker-install.md) @@ -63,8 +61,6 @@ private: "true" username: "your username" password: "your password" - # DO NOT CHANGE THE VALUE BELOW - mainURL: "NA" ``` 3. Follow the commands in the [docker instance](./docker.md) guide depending on what docker method you used - Docker Compose [here](./docker.md#docker-compose) @@ -72,3 +68,48 @@ - Standalone Docker (not recommended) [here](./docker.md#standalone) 3a. Simply omit the step where it tells you to make a config.yml file (as you have already done that) + +## No Docker (multiuser) - **NOT SUPPORTED** +This is not supported due to the fact that everyones setup is different. +Here is a list of things you will need to do: +- Setup a database (Postgresql) +- Setup ruby to use multiuser mode +- Pray +**Use docker if you want multiuser mode [here](./private.md#docker-multiuser)** + +## Docker (multiuser) + +#### Prerequisites +- Docker needs to be installed - Don't know how? Follow our [guide](./docker-install.md) + +--- + +##### Most of the commands are the same as the ones in a public [docker instance](./docker.md) + +1. Make a config.yml file + ```bash + nano config.yml + ``` + +2. To make a private instance with multiuser the file should look something like this: + ```yml + port: 9293 #currently does nothing, but will be used in the future + verboseLogging: "false" #change this to "true" to enable verbose logging + private: "false" #change this to "true" to enable private mode + username: "ruby" #change this to your username (when using private mode) + password: "ruby" #change this to your password (when using private mode) + + multiuser: "true" # set to true to enable multiuser mode when using private mode (if not using private mode, this will be ignored) + + database: + username: "ruby" # change this to your database username + password: "ruby" # change this to your database password + host: "db" # change this to your database host + dbname: "ruby" # change this to your database name + ``` +3. Follow the commands in the [docker instance](./docker.md) guide depending on what docker method you used + - Docker Compose [here](./docker.md#docker-compose) + - Docker Compose (build) [here](./docker.md#docker-compose-build) + - Standalone Docker (not recommended) [here](./docker.md#standalone) **NOT SUPPORTED** + +3a. Simply omit the step where it tells you to make a config.yml file (as you have already done that) diff --git a/main.rb b/main.rb index b8f8a0ae..8d03a5fd 100644 --- a/main.rb +++ b/main.rb @@ -4,6 +4,15 @@ set :public_folder, File.join(settings.root, 'src', 'public') set :views, File.join(settings.root, 'src', 'views') set :template, File.join(settings.root, 'src', 'templates') + +Config.setup do |config| + config.use_env = true + config.env_prefix = 'SETTINGS' + config.env_separator = '_' + config.env_converter = :downcase + config.env_parse_values = true +end + register Config logging = Settings.verboseLogging diff --git a/node-server/server.js b/node-server/server.js index eeb9e53b..0ae553ff 100644 --- a/node-server/server.js +++ b/node-server/server.js @@ -53,7 +53,7 @@ const proxyHandler = (handler, opts) => { }; const app = Fastify({ logger: false, serverFactory: proxyHandler }) -await app +await app .register(fastifyHttpProxy, { upstream: 'http://localhost:9292', prefix: '/', @@ -82,7 +82,7 @@ app.get('/search=:query', async (req, res) => { reply.code(500).send({ error: "Internal Server Error" }); } }); -app.get('/version', async (req, res) => { +app.get('/version', (req, res) => { res.send({ version: latestRelease }); }); app.get('/health', async (req, res) => { From da3758e215773f8443c9c0dc34b91ba581d3a9bf Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Mon, 15 Jan 2024 01:20:25 -0700 Subject: [PATCH 09/13] Update docs for docker --- docker/docker-compose.build.yml | 6 +++-- docker/docker-compose.yml | 6 +++-- docs/README.md | 3 ++- docs/advanced-config.md | 20 ++++++++-------- docs/docker.md | 41 ++++++++++++++++++++++----------- docs/multiuser.md | 25 ++++++++++++++++++++ docs/private.md | 6 +++-- 7 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 docs/multiuser.md diff --git a/docker/docker-compose.build.yml b/docker/docker-compose.build.yml index cebd8e53..561e3f3a 100644 --- a/docker/docker-compose.build.yml +++ b/docker/docker-compose.build.yml @@ -14,15 +14,17 @@ services: # Uncomment the following lines if you want to use a database (mutliuser mode) #db: # image: postgres - # restart: always + # restart: unless-stopped # environment: # POSTGRES_PASSWORD: ruby # POSTGRES_USER: ruby # POSTGRES_DB: ruby + # volumes: + # - ./db:/var/lib/postgresql/data # Uncomment the following lines if you want to use adminer (database management) #adminer: # image: adminer - # restart: always + # restart: unless-stopped # ports: # - 8099:8080 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 97fe39a0..5b7571fc 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -13,15 +13,17 @@ services: # Uncomment the following lines if you want to use a database (mutliuser mode) #db: # image: postgres - # restart: always + # restart: unless-stopped # environment: # POSTGRES_PASSWORD: ruby # POSTGRES_USER: ruby # POSTGRES_DB: ruby + # volumes: + # - ./db:/var/lib/postgresql/data # Uncomment the following lines if you want to use adminer (database management) #adminer: # image: adminer - # restart: always + # restart: unless-stopped # ports: # - 8099:8080 diff --git a/docs/README.md b/docs/README.md index e69f6d23..fcf444a2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,7 +11,8 @@ ## Getting Started - Local setup (no docker) [here](./terminal.md) - Local setup (with docker)(*recommended*) [here](./docker.md) -- Private instance setup [here](./private.md) (both docker and non-docker) +- Private instance setup [here](./private.md) (both docker and non-docker, including multiuser) +- CLI commands for multiuser mode [here](./multiuser.md) - Ruby and Bundler installation [here](./install-ruby.md) - Docker Installation [here](./docker-install.md) diff --git a/docs/advanced-config.md b/docs/advanced-config.md index 3df294b9..fef90e56 100644 --- a/docs/advanced-config.md +++ b/docs/advanced-config.md @@ -3,21 +3,21 @@ ##### This provides a list of all the configuration options available to you. ##### The config file can be found [here](../config/settings.example.yml) -`port` - The port the Ruby server will run on. Default is `9293` (does not currently work) +- `port` - The port the Ruby server will run on. Default is `9293` (does not currently work) -`verboseLogging` - Whether or not to log all requests to the console. Default is `false` +- `verboseLogging` - Whether or not to log all requests to the console. Default is `false` -`private` - Whether or not to enable private mode. Default is `false` +- `private` - Whether or not to enable private mode. Default is `false` -`username` - The username for use in either, private instances. If it is a normal instance, username will always be `ruby` +- `username` - The username for use in either, private instances. If it is a normal instance, username will always be `ruby` -`password` - The password for use in either, private instances. If it is a normal instance, password will always be `ruby` +- `password` - The password for use in either, private instances. If it is a normal instance, password will always be `ruby` -`mainUrl` - The main URL for use in a normal instance. If you are trying to make a private instance set this value to anything or delete it. +- `mainUrl` - The main URL for use in a normal instance. If you are trying to make a private instance set this value to anything or delete it. -`multiuser` - Whether or not to enable multiuser mode. Default is `false` **ONLY WORKS IN PRIVATE MODE** +- `multiuser` - Whether or not to enable multiuser mode. Default is `false` **ONLY WORKS IN PRIVATE MODE** -`database` - A set of options for the database connection. **ONLY WORKS IN PRIVATE MODE** **Currently only supports Postgresql** +- `database` - A set of options for the database connection. **ONLY WORKS IN PRIVATE MODE AND MULTIUSER IS ENABLED, CURRENTLY ONLY SUPPORTS POSTGRESQL** - `host` - The host of the database. Default is `localhost` - `dbName` - The name of the database. Default is `ruby` - `username` - The username for the database. Default is `ruby` @@ -25,6 +25,6 @@ --- #### Options coming soon: -`port` - Will be switched to `rubyPort` and will be the port the Ruby server will run on. Default is `9292` +- `port` - Will be switched to `rubyPort` and will be the port the Ruby server will run on. Default is `9292` -`nodePort` - Will be the port the Node server will run on. Default is `9293` +- `nodePort` - Will be the port the Node server will run on. Default is `9293` diff --git a/docs/docker.md b/docs/docker.md index c3a00931..54cec3bd 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -31,20 +31,35 @@ Or just copy this config: ```yml - version: '2' + version: "3" services: - ruby: - restart: unless-stopped - image: 'ghcr.io/ruby-network/ruby' - ports: - #DO NOT CHANGE 9293! - - your port here:9293 - volumes: - - ./config.yml:/usr/src/app/config/settings.yml - #networks: - # default: - # external: - # name: default_net + ruby: + image: 'motortruck1221/ruby:latest' + container_name: ruby + restart: unless-stopped + ports: + # DO NOT CHANGE 9293 + - "your port here:9293" + volumes: + - ./config.yml:/usr/src/app/config/settings.yml + + # Uncomment the following lines if you want to use adminer (database management) + #db: + # image: postgres + # restart: unless-stopped + # environment: + # POSTGRES_PASSWORD: ruby + # POSTGRES_USER: ruby + # POSTGRES_DB: ruby + # volumes: + # - ./db:/var/lib/postgresql/data + + # Uncomment the following lines if you want to use adminer (database management) + #adminer: + # image: adminer + # restart: unless-stopped + # ports: + # - 8099:8080 ``` 2. Download our settings.example.yml file [here](https://github.com/ruby-network/ruby/tree/main/config/settings.example.yml) diff --git a/docs/multiuser.md b/docs/multiuser.md new file mode 100644 index 00000000..21b862f7 --- /dev/null +++ b/docs/multiuser.md @@ -0,0 +1,25 @@ +# Multiuser mode + +## Prerequisites +- A setup private instance of Ruby (using Docker Compose, or standalone) with multiuser mode enabled (see [here](./private.md#docker-multiuser) for more info) + +--- + +## How to execute commands + +There are two ways to execute the CLI, either using `yarn cli` or `bundler exec ruby ./cli/cli.rb` + +This tutorial will use `yarn cli` as it is easier to type + +## Commands + +- `yarn cli` is the command to execute the CLI +- `yarn cli help [command]` to get help with a command +- `yarn cli create` - Create a new user +- `yarn cli delete` - Delete a user +- `yarn cli list` - List all users +- `yarn cli reset` - Reset a users password + +## How to use in Docker Compose + +- `docker-compose exec ruby yarn cli [command]` - where `[command]` is one of the commands listed above diff --git a/docs/private.md b/docs/private.md index 498cfac8..eca86aca 100644 --- a/docs/private.md +++ b/docs/private.md @@ -74,7 +74,7 @@ This is not supported due to the fact that everyones setup is different. Here is a list of things you will need to do: - Setup a database (Postgresql) - Setup ruby to use multiuser mode -- Pray + **Use docker if you want multiuser mode [here](./private.md#docker-multiuser)** ## Docker (multiuser) @@ -107,9 +107,11 @@ Here is a list of things you will need to do: host: "db" # change this to your database host dbname: "ruby" # change this to your database name ``` -3. Follow the commands in the [docker instance](./docker.md) guide depending on what docker method you used +3. Follow the commands in the [docker instance](./docker.md) guide depending on what docker method you used. **Make sure you uncomment the database section of the file** - Docker Compose [here](./docker.md#docker-compose) - Docker Compose (build) [here](./docker.md#docker-compose-build) - Standalone Docker (not recommended) [here](./docker.md#standalone) **NOT SUPPORTED** 3a. Simply omit the step where it tells you to make a config.yml file (as you have already done that) + +3b. For multiuser mode, we provide a set of CLI commands to manage users. You can find them [here](./multiuser.md) From c10639759328716905ee51c992f9502abb3be097 Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Mon, 15 Jan 2024 01:22:54 -0700 Subject: [PATCH 10/13] :skull: --- docs/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docker.md b/docs/docker.md index 54cec3bd..d48fa49e 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -43,7 +43,7 @@ volumes: - ./config.yml:/usr/src/app/config/settings.yml - # Uncomment the following lines if you want to use adminer (database management) + # Uncomment the following lines if you want to use a database (multiuser mode) #db: # image: postgres # restart: unless-stopped From 7b1dffcdf0198a3d19bbe25eb9c36c5c8b5381f3 Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Mon, 15 Jan 2024 01:26:20 -0700 Subject: [PATCH 11/13] Make sure to notify about not changing base values when using docker --- docs/private.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/private.md b/docs/private.md index eca86aca..97241724 100644 --- a/docs/private.md +++ b/docs/private.md @@ -102,6 +102,7 @@ Here is a list of things you will need to do: multiuser: "true" # set to true to enable multiuser mode when using private mode (if not using private mode, this will be ignored) database: + #The db defaults should not be changed when using docker username: "ruby" # change this to your database username password: "ruby" # change this to your database password host: "db" # change this to your database host From 2d450d2316c474d72ab2343fb12bdfb53bb5a5aa Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Mon, 15 Jan 2024 01:26:43 -0700 Subject: [PATCH 12/13] Make sure to notify about not changing base values when using docker --- docs/private.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/private.md b/docs/private.md index 97241724..d8ad4180 100644 --- a/docs/private.md +++ b/docs/private.md @@ -102,7 +102,7 @@ Here is a list of things you will need to do: multiuser: "true" # set to true to enable multiuser mode when using private mode (if not using private mode, this will be ignored) database: - #The db defaults should not be changed when using docker + #The db defaults should not be changed when using docker (unless you know what you are doing) username: "ruby" # change this to your database username password: "ruby" # change this to your database password host: "db" # change this to your database host From 2e783c7188454c21658b2e751f5589cecaf85481 Mon Sep 17 00:00:00 2001 From: MotorTruck1221 Date: Mon, 15 Jan 2024 01:29:10 -0700 Subject: [PATCH 13/13] :skull:, :skull: --- docs/private.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/private.md b/docs/private.md index d8ad4180..6440c17b 100644 --- a/docs/private.md +++ b/docs/private.md @@ -34,6 +34,7 @@ private: "true" username: "your username" password: "your password" + multiuser: "false" ``` 6. Start the server ```bash @@ -61,11 +62,12 @@ private: "true" username: "your username" password: "your password" + multiuser: "false" ``` 3. Follow the commands in the [docker instance](./docker.md) guide depending on what docker method you used - Docker Compose [here](./docker.md#docker-compose) - Docker Compose (build) [here](./docker.md#docker-compose-build) - - Standalone Docker (not recommended) [here](./docker.md#standalone) + - Standalone Docker (not recommended) [here](./docker.md#standalone) **NOT RECOMMENDED** 3a. Simply omit the step where it tells you to make a config.yml file (as you have already done that) @@ -95,9 +97,9 @@ Here is a list of things you will need to do: ```yml port: 9293 #currently does nothing, but will be used in the future verboseLogging: "false" #change this to "true" to enable verbose logging - private: "false" #change this to "true" to enable private mode - username: "ruby" #change this to your username (when using private mode) - password: "ruby" #change this to your password (when using private mode) + private: "true" #change this to "true" to enable private mode + username: "yourUsername" #change this to your username (when using private mode) + password: "yourPassword" #change this to your password (when using private mode) multiuser: "true" # set to true to enable multiuser mode when using private mode (if not using private mode, this will be ignored)