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}"