From f66f7bd9d9bc540caa259cb9351033b11c75566a Mon Sep 17 00:00:00 2001 From: josephroy99 Date: Mon, 11 Dec 2023 00:31:30 +0000 Subject: [PATCH 1/5] added ruby files --- .gitignore | 3 ++ auth/Gemfile | 10 ++++++ auth/Gemfile.lock | 33 +++++++++++++++++++ auth/README.md | 7 +++++ auth/auth.rb | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 .gitignore create mode 100644 auth/Gemfile create mode 100644 auth/Gemfile.lock create mode 100644 auth/README.md create mode 100644 auth/auth.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85ffe74 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin/ + +*.db diff --git a/auth/Gemfile b/auth/Gemfile new file mode 100644 index 0000000..ae64a56 --- /dev/null +++ b/auth/Gemfile @@ -0,0 +1,10 @@ +# Gemfile + +source "https://rubygems.org" + +ruby '3.2.2' + +gem 'sinatra' +gem 'webrick' +gem 'jwt' +gem 'sqlite3' \ No newline at end of file diff --git a/auth/Gemfile.lock b/auth/Gemfile.lock new file mode 100644 index 0000000..034e13d --- /dev/null +++ b/auth/Gemfile.lock @@ -0,0 +1,33 @@ +GEM + remote: https://rubygems.org/ + specs: + jwt (2.7.1) + mustermann (3.0.0) + ruby2_keywords (~> 0.0.1) + rack (2.2.8) + rack-protection (3.1.0) + rack (~> 2.2, >= 2.2.4) + ruby2_keywords (0.0.5) + sinatra (3.1.0) + mustermann (~> 3.0) + rack (~> 2.2, >= 2.2.4) + rack-protection (= 3.1.0) + tilt (~> 2.0) + sqlite3 (1.6.9-x64-mingw-ucrt) + tilt (2.3.0) + webrick (1.8.1) + +PLATFORMS + x64-mingw-ucrt + +DEPENDENCIES + jwt + sinatra + sqlite3 + webrick + +RUBY VERSION + ruby 3.2.2p53 + +BUNDLED WITH + 2.4.22 diff --git a/auth/README.md b/auth/README.md new file mode 100644 index 0000000..69c483c --- /dev/null +++ b/auth/README.md @@ -0,0 +1,7 @@ +Install dependancies + +gem install sinatra webrick +ruby ./auth -p 4567 + +To use the Gemfile: +bundle installd \ No newline at end of file diff --git a/auth/auth.rb b/auth/auth.rb new file mode 100644 index 0000000..4ff9c7f --- /dev/null +++ b/auth/auth.rb @@ -0,0 +1,80 @@ +# Install Sinatra: gem install sinatra + +require 'sinatra' +require 'json' +require 'sqlite3' +require 'jwt' + +payload = { data: 'test', test: 'hello' } +hmac_secret = 'my$ecretK3y' +token = JWT.encode payload, hmac_secret, 'HS256' +puts token + +decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' } +puts decoded_token + +######### + +# Check if the directory exists +directory_path = './database' + +unless File.directory?(directory_path) + # If not, create the directory + Dir.mkdir(directory_path) + puts "Directory '#{directory_path}' created successfully." +end + +db = SQLite3::Database.new('./database/auth.db') + +db.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, hashed_password TEXT)') +db.execute('CREATE TABLE IF NOT EXISTS claims (id INTEGER PRIMARY KEY, claim TEXT)') +db.execute('CREATE TABLE IF NOT EXISTS user_claims (id INTEGER PRIMARY KEY, user_id INTEGER, claim_id INTEGER)') + +db.execute('INSERT INTO claims (claim) VALUES (?)', 'add_user') +db.execute('INSERT INTO claims (claim) VALUES (?)', 'remove_user') + +# Check if the users table is empty +result = db.get_first_value('SELECT COUNT(*) FROM users') + +if result == 0 + db.execute('INSERT INTO users (username, hashed_password) VALUES (?, ?)', ['admin', 'password']) + puts 'Default admin user added.' +else + puts 'Table already contains data. Skipping default user creation.' +end + +results = db.execute('SELECT * FROM users') +results.each do |row| + puts "ID: #{row[0]}, Username: #{row[1]}, Hashed Password: #{row[2]}" +end + +############## + + +# Define a simple API endpoint +get '/api/greeting' do + content_type :json + { greeting: 'Hello, World!' }.to_json +end + +get '/api/greeting/:name' do + content_type :json + { greeting: "Hello, #{params[:name]}!" }.to_json +end + +post '/auth' do + content_type :json + { jwt: } +end + +def get_jwt (username, expiry_time) + claims = [] +end + +def get_claims (username) + db = SQLite3::Database.new('./database/auth.db') + db.execute('') +end + +# Run the application +# ruby your_file_name.rb -- 2.40.1 From 3b2d359705aab84c6f2a85ae47043ffd3a3504e6 Mon Sep 17 00:00:00 2001 From: josephroy99 Date: Mon, 11 Dec 2023 20:56:09 +0000 Subject: [PATCH 2/5] add more functionality --- auth/Gemfile | 5 ++- auth/auth.rb | 87 +++++++++++++++++++------------------ auth/cryptography.rb | 7 +++ auth/database_queries.rb | 40 +++++++++++++++++ auth/initialize_database.rb | 49 +++++++++++++++++++++ auth/post.rb | 27 ++++++++++++ 6 files changed, 171 insertions(+), 44 deletions(-) create mode 100644 auth/cryptography.rb create mode 100644 auth/database_queries.rb create mode 100644 auth/initialize_database.rb create mode 100644 auth/post.rb diff --git a/auth/Gemfile b/auth/Gemfile index ae64a56..8a35825 100644 --- a/auth/Gemfile +++ b/auth/Gemfile @@ -7,4 +7,7 @@ ruby '3.2.2' gem 'sinatra' gem 'webrick' gem 'jwt' -gem 'sqlite3' \ No newline at end of file +gem 'sqlite3' +gem 'bcrypt' + +# bundle install \ No newline at end of file diff --git a/auth/auth.rb b/auth/auth.rb index 4ff9c7f..7b9ddc4 100644 --- a/auth/auth.rb +++ b/auth/auth.rb @@ -1,4 +1,8 @@ # Install Sinatra: gem install sinatra +require_relative "initialize_database" +require_relative "database_queries" +require_relative "cryptography" + require 'sinatra' require 'json' @@ -8,48 +12,12 @@ require 'jwt' payload = { data: 'test', test: 'hello' } hmac_secret = 'my$ecretK3y' token = JWT.encode payload, hmac_secret, 'HS256' -puts token +#puts token decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' } -puts decoded_token - -######### - -# Check if the directory exists -directory_path = './database' - -unless File.directory?(directory_path) - # If not, create the directory - Dir.mkdir(directory_path) - puts "Directory '#{directory_path}' created successfully." -end - -db = SQLite3::Database.new('./database/auth.db') - -db.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, hashed_password TEXT)') -db.execute('CREATE TABLE IF NOT EXISTS claims (id INTEGER PRIMARY KEY, claim TEXT)') -db.execute('CREATE TABLE IF NOT EXISTS user_claims (id INTEGER PRIMARY KEY, user_id INTEGER, claim_id INTEGER)') - -db.execute('INSERT INTO claims (claim) VALUES (?)', 'add_user') -db.execute('INSERT INTO claims (claim) VALUES (?)', 'remove_user') - -# Check if the users table is empty -result = db.get_first_value('SELECT COUNT(*) FROM users') - -if result == 0 - db.execute('INSERT INTO users (username, hashed_password) VALUES (?, ?)', ['admin', 'password']) - puts 'Default admin user added.' -else - puts 'Table already contains data. Skipping default user creation.' -end - -results = db.execute('SELECT * FROM users') -results.each do |row| - puts "ID: #{row[0]}, Username: #{row[1]}, Hashed Password: #{row[2]}" -end - -############## +#puts decoded_token +initialize_database # Define a simple API endpoint get '/api/greeting' do @@ -58,22 +26,55 @@ get '/api/greeting' do end get '/api/greeting/:name' do + get_claims params[:name] content_type :json { greeting: "Hello, #{params[:name]}!" }.to_json end -post '/auth' do +post '/auth/login' do + username = params[:username] + password = params[:password] + request_hashed_password = hash_password password + + user_id = get_user_id username + hashed_password = get_user_hashed_password user_id + + puts hashed_password + puts request_hashed_password + unless hashed_password == request_hashed_password + status 401 + 'Unauthorized Access' + end + content_type :json - { jwt: } + { jwt: "Logged in" }.to_json end def get_jwt (username, expiry_time) - claims = [] + get_claims username end def get_claims (username) + puts "Getting claims for #{username}" db = SQLite3::Database.new('./database/auth.db') - db.execute('') + results = db.execute(' + SELECT C.claim + FROM users U + INNER JOIN user_claims UC ON U.id = UC.user_id + INNER JOIN claims C ON UC.claim_id = U.id + WHERE u.username = ? + ', username) + + + if results.empty? + puts 'No claims found.' + else + results.each do |column| + puts "#{column[0]}" + end + end + + return results end # Run the application diff --git a/auth/cryptography.rb b/auth/cryptography.rb new file mode 100644 index 0000000..91862eb --- /dev/null +++ b/auth/cryptography.rb @@ -0,0 +1,7 @@ +require 'bcrypt' + +def hash_password(password) + # Hash the password without using a salt + hashed_password = BCrypt::Password.create(password, salt: 'hello') + return hashed_password + end \ No newline at end of file diff --git a/auth/database_queries.rb b/auth/database_queries.rb new file mode 100644 index 0000000..4153f23 --- /dev/null +++ b/auth/database_queries.rb @@ -0,0 +1,40 @@ +require 'sqlite3' + +def get_user_id(username) + db = SQLite3::Database.new('./database/auth.db') + + user_id = db.get_first_value(' + SELECT id + FROM users U + WHERE U.username = ? + + ', [username]) + + return user_id +end + +def get_user_hashed_password(user_id) + db = SQLite3::Database.new('./database/auth.db') + + password_hash = db.get_first_value(' + SELECT hashed_password + FROM users U + WHERE U.id = ? + + ', [user_id]) + + return password_hash +end + +def get_user_salt(user_id) + db = SQLite3::Database.new('./database/auth.db') + + salt = db.get_first_value(' + SELECT salt + FROM users U + WHERE U.id = ? + + ', [user_id]) + + return salt +end \ No newline at end of file diff --git a/auth/initialize_database.rb b/auth/initialize_database.rb new file mode 100644 index 0000000..7227898 --- /dev/null +++ b/auth/initialize_database.rb @@ -0,0 +1,49 @@ +require_relative "cryptography" + +require 'sqlite3' + +def initialize_database + puts 'Checking if database needs initializing.' + + directory_path = './database' + + unless File.directory?(directory_path) + # If not, create the directory + Dir.mkdir(directory_path) + puts "Directory '#{directory_path}' created successfully." + end + + db = SQLite3::Database.new('./database/auth.db') + + puts 'Creating tables if necessary.' + db.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, hashed_password TEXT, salt TEXT)') + db.execute('CREATE TABLE IF NOT EXISTS claims (id INTEGER PRIMARY KEY, claim TEXT)') + db.execute('CREATE TABLE IF NOT EXISTS user_claims (id INTEGER PRIMARY KEY, user_id INTEGER, claim_id INTEGER)') + + result = db.get_first_value('SELECT COUNT(*) FROM users') + + if result == 0 + hashed_password = hash_password 'pass123' + puts 'Default admin user added.' + db.execute('INSERT INTO users (username, hashed_password) VALUES (?, ?)', ['admin', hashed_password]) + else + puts 'Table already contains data. Skipping default user creation.' + end + + result = db.get_first_value('SELECT COUNT(*) FROM claims') + + if result == 0 + db.execute('INSERT INTO claims (claim) VALUES (?)', ['add_user']) + db.execute('INSERT INTO claims (claim) VALUES (?)', ['remove_user']) + db.execute('INSERT INTO claims (claim) VALUES (?)', ['add_claim_to_user']) + db.execute('INSERT INTO claims (claim) VALUES (?)', ['remove_claim_from_user']) + end + + admin_user_id = db.get_first_value('SELECT id FROM users WHERE username = ?', ['admin']) + claim_ids = db.execute('SELECT id FROM claims') + + claim_ids.each do |claim_id| + db.execute('INSERT INTO user_claims (user_id, claim_id) VALUES (?, ?)', [admin_user_id, claim_id]) + end +end + diff --git a/auth/post.rb b/auth/post.rb new file mode 100644 index 0000000..b79cf3a --- /dev/null +++ b/auth/post.rb @@ -0,0 +1,27 @@ +require 'net/http' +require 'uri' + +# The URL you want to send the POST request to +url = URI.parse('http://localhost:4567/auth/login') + +# Create a new Net::HTTP object with the target server +http = Net::HTTP.new(url.host, url.port) + +# If your server uses HTTPS, you might need to enable SSL +# http.use_ssl = true + +# Create a new Net::HTTP::Post request with the desired path +request = Net::HTTP::Post.new(url.path) + +# Set the request body with the data you want to send +request.body = 'username=admin&password=pass123' + +# Set the 'Content-Type' header if needed +request['Content-Type'] = 'application/x-www-form-urlencoded' + +# Send the request and get the response +response = http.request(request) + +# Output the response +puts "Response Code: #{response.code}" +puts "Response Body: #{response.body}" -- 2.40.1 From 67aaee9a7291863930453f48614ba3ce5e89dca8 Mon Sep 17 00:00:00 2001 From: Joseph Roy Date: Mon, 11 Dec 2023 22:35:31 +0000 Subject: [PATCH 3/5] add docker files --- auth/Gemfile | 3 ++- auth/docker_compose.yml | 12 ++++++++++++ auth/dockerfile | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 auth/docker_compose.yml create mode 100644 auth/dockerfile diff --git a/auth/Gemfile b/auth/Gemfile index 8a35825..65576fa 100644 --- a/auth/Gemfile +++ b/auth/Gemfile @@ -2,7 +2,8 @@ source "https://rubygems.org" -ruby '3.2.2' +#ruby '3.2.2' +ruby '2.6.10' gem 'sinatra' gem 'webrick' diff --git a/auth/docker_compose.yml b/auth/docker_compose.yml new file mode 100644 index 0000000..2f75842 --- /dev/null +++ b/auth/docker_compose.yml @@ -0,0 +1,12 @@ +version: "3" + +services: + app: + build: + context: . + dockerfile: Dockerfile + ports: + - "4567:4567" + volumes: + - ./auth:/app # Adjust the path accordingly + command: ["./auth.rb"] diff --git a/auth/dockerfile b/auth/dockerfile new file mode 100644 index 0000000..d93b2ba --- /dev/null +++ b/auth/dockerfile @@ -0,0 +1,22 @@ +# Stage 1: Build stage with git +FROM ubuntu:jammy AS GITCOPY + +WORKDIR /roysathome + +RUN apt-get update && apt-get install -y git + +RUN git clone https://git.roysathome.net/joseph/roysathome.net.git . + +# Stage 2: Final image with Ruby +FROM ruby:3.2.2 + +# Copy files from the first stage +COPY --from=GITCOPY /roysathome/auth /app + +WORKDIR /app + +# Gemfile and Gemfile.lock are already in /usr/src/app/roysathome/auth due to the previous COPY command + +RUN bundle install + +CMD ["./auth.rb"] -- 2.40.1 From 5f97a8d20c90078f366b66c56011946bfcabcd38 Mon Sep 17 00:00:00 2001 From: joseph Date: Tue, 12 Dec 2023 08:52:27 +0000 Subject: [PATCH 4/5] change ruby version in gemfile --- auth/Gemfile | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/auth/Gemfile b/auth/Gemfile index 65576fa..ede6601 100644 --- a/auth/Gemfile +++ b/auth/Gemfile @@ -1,14 +1,14 @@ -# Gemfile - -source "https://rubygems.org" - -#ruby '3.2.2' -ruby '2.6.10' - -gem 'sinatra' -gem 'webrick' -gem 'jwt' -gem 'sqlite3' -gem 'bcrypt' - +# Gemfile + +source "https://rubygems.org" + +ruby '3.2.2' +#ruby '2.6.10' + +gem 'sinatra' +gem 'webrick' +gem 'jwt' +gem 'sqlite3' +gem 'bcrypt' + # bundle install \ No newline at end of file -- 2.40.1 From b3b38dd5a0ba07bf2995a154123a2abbf2bae53d Mon Sep 17 00:00:00 2001 From: josephroy99 Date: Tue, 12 Dec 2023 22:52:36 +0000 Subject: [PATCH 5/5] make login code work --- auth/auth.rb | 24 +++++------------------- auth/cryptography.rb | 18 +++++++++++++----- auth/database_queries.rb | 27 ++++++++++++++++++--------- auth/initialize_database.rb | 4 ++-- auth/post.rb | 2 +- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/auth/auth.rb b/auth/auth.rb index 7b9ddc4..fbd4d0f 100644 --- a/auth/auth.rb +++ b/auth/auth.rb @@ -19,34 +19,20 @@ decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' } initialize_database -# Define a simple API endpoint -get '/api/greeting' do - content_type :json - { greeting: 'Hello, World!' }.to_json -end - -get '/api/greeting/:name' do - get_claims params[:name] - content_type :json - { greeting: "Hello, #{params[:name]}!" }.to_json -end - post '/auth/login' do + content_type :json + username = params[:username] password = params[:password] - request_hashed_password = hash_password password user_id = get_user_id username - hashed_password = get_user_hashed_password user_id - puts hashed_password - puts request_hashed_password - unless hashed_password == request_hashed_password + unless check_password_for_user(user_id, password) status 401 - 'Unauthorized Access' + + return { jwt: "Unuthorized Access" }.to_json end - content_type :json { jwt: "Logged in" }.to_json end diff --git a/auth/cryptography.rb b/auth/cryptography.rb index 91862eb..e3f87db 100644 --- a/auth/cryptography.rb +++ b/auth/cryptography.rb @@ -1,7 +1,15 @@ require 'bcrypt' -def hash_password(password) - # Hash the password without using a salt - hashed_password = BCrypt::Password.create(password, salt: 'hello') - return hashed_password - end \ No newline at end of file +def create_password_for_user(password) + return BCrypt::Password.create(password) +end + +def check_password_for_user(user_id, entered_password) + hashed_password = get_user_hashed_password(user_id) + + if BCrypt::Password.new(hashed_password) == entered_password + return true + else + return false + end +end \ No newline at end of file diff --git a/auth/database_queries.rb b/auth/database_queries.rb index 4153f23..19ea04e 100644 --- a/auth/database_queries.rb +++ b/auth/database_queries.rb @@ -1,5 +1,17 @@ require 'sqlite3' + +def create_new_user(username, password) + db = SQLite3::Database.new('./database/auth.db') + + db.execute(' + INSERT INTO users (username, hashed_password) + VALUES (?, ?) + ', [username, create_password_for_user(password)]) +end + + + def get_user_id(username) db = SQLite3::Database.new('./database/auth.db') @@ -26,15 +38,12 @@ def get_user_hashed_password(user_id) return password_hash end -def get_user_salt(user_id) +def update_user_password(user_id, password) db = SQLite3::Database.new('./database/auth.db') - salt = db.get_first_value(' - SELECT salt - FROM users U - WHERE U.id = ? - - ', [user_id]) - - return salt + db.execute(' + UPDATE users + SET hashed_password = ?, salt = ? + WHERE id = ? + ', [hash_password, salt, user_id]) end \ No newline at end of file diff --git a/auth/initialize_database.rb b/auth/initialize_database.rb index 7227898..63c9c89 100644 --- a/auth/initialize_database.rb +++ b/auth/initialize_database.rb @@ -23,9 +23,9 @@ def initialize_database result = db.get_first_value('SELECT COUNT(*) FROM users') if result == 0 - hashed_password = hash_password 'pass123' puts 'Default admin user added.' - db.execute('INSERT INTO users (username, hashed_password) VALUES (?, ?)', ['admin', hashed_password]) + + create_new_user('admin', 'pass123') else puts 'Table already contains data. Skipping default user creation.' end diff --git a/auth/post.rb b/auth/post.rb index b79cf3a..9391862 100644 --- a/auth/post.rb +++ b/auth/post.rb @@ -14,7 +14,7 @@ http = Net::HTTP.new(url.host, url.port) request = Net::HTTP::Post.new(url.path) # Set the request body with the data you want to send -request.body = 'username=admin&password=pass123' +request.body = 'username=admin&password=pass1re23' # Set the 'Content-Type' header if needed request['Content-Type'] = 'application/x-www-form-urlencoded' -- 2.40.1