add file transfer feature and add more jwt functionality
This commit is contained in:
parent
894b2af373
commit
29c8bb368f
|
@ -12,5 +12,7 @@ gem 'sqlite3'
|
|||
gem 'bcrypt'
|
||||
gem 'securerandom'
|
||||
gem 'json'
|
||||
gem 'multipart-post'
|
||||
|
||||
|
||||
# bundle install
|
97
auth/auth.rb
97
auth/auth.rb
|
@ -2,6 +2,7 @@
|
|||
require_relative "initialize_database"
|
||||
require_relative "database_queries"
|
||||
require_relative "cryptography"
|
||||
require_relative "tokens"
|
||||
|
||||
|
||||
require 'sinatra'
|
||||
|
@ -9,6 +10,10 @@ require 'json'
|
|||
require 'sqlite3'
|
||||
require 'jwt'
|
||||
|
||||
TOKEN_SECRET = 'WChX-tQWbGbj_pGJQREoFAZGC9JWh58KSk8O7KPj-P8Nd-J88g3eSFDVuNe6zddj0ZB3yxjm_IuPNPyLhiSnxlWHImqXR6ajh3OzrzYm0bNb3f5C4IAScphyEdAfYGMcM-HvYOXxxxp5u5mryfiV3JH1CTqL1CzGyO8df7zUpRKXEXZ5SKmUvhfLU0XKCR_28FAZUgPCAi3GywkDDsH0by68j33BU5cnMT8KiEkHOX4wVUVDQc85_AuE7fN3ji_WkhnDCSLXU9dBCcXM3ziFFeX0RbvIRDG0vKdzwt4TOr4Jws7NP9w11GrUGDFKARZqvT7FTxwxO3MM-mmjb2xyGg'
|
||||
|
||||
set :public_folder, DATA_LOCATION + FILE_STORAGE_LOCATION
|
||||
|
||||
#puts generate_random_string(256)
|
||||
|
||||
|
||||
|
@ -68,85 +73,59 @@ post '/auth/reauthenticate' do
|
|||
|
||||
reauth_token = Regexp.last_match(1)
|
||||
|
||||
hmac_secret = 'WChX-tQWbGbj_pGJQREoFAZGC9JWh58KSk8O7KPj-P8Nd-J88g3eSFDVuNe6zddj0ZB3yxjm_IuPNPyLhiSnxlWHImqXR6ajh3OzrzYm0bNb3f5C4IAScphyEdAfYGMcM-HvYOXxxxp5u5mryfiV3JH1CTqL1CzGyO8df7zUpRKXEXZ5SKmUvhfLU0XKCR_28FAZUgPCAi3GywkDDsH0by68j33BU5cnMT8KiEkHOX4wVUVDQc85_AuE7fN3ji_WkhnDCSLXU9dBCcXM3ziFFeX0RbvIRDG0vKdzwt4TOr4Jws7NP9w11GrUGDFKARZqvT7FTxwxO3MM-mmjb2xyGg'
|
||||
|
||||
begin
|
||||
# Verify the token using the secret key
|
||||
decoded_token = JWT.decode(reauth_token, hmac_secret, true, algorithm: 'HS256')
|
||||
decoded_token = JWT.decode(reauth_token, TOKEN_SECRET, true, algorithm: 'HS256')
|
||||
|
||||
# At this point, the token is valid
|
||||
# You can access the claims inside the 'decoded_token' variable
|
||||
|
||||
uid = decoded_token.first['uid']
|
||||
|
||||
|
||||
# Your reauthentication logic here...
|
||||
|
||||
# Return a response (replace with your own logic)
|
||||
{ reply: get_jwt(uid) }.to_json
|
||||
{ jwt: get_jwt(uid) }.to_json
|
||||
rescue JWT::DecodeError
|
||||
status 401
|
||||
return { reply: 'Unauthorized Access. Invalid token.' }.to_json
|
||||
end
|
||||
end
|
||||
|
||||
def get_reauth_jwt (user_id)
|
||||
#claims = get_claims user_id
|
||||
post '/upload' do
|
||||
|
||||
payload = {
|
||||
sub: 'reauthentication' ,
|
||||
admin: check_if_user_is_admin(user_id),
|
||||
iss: 'roysathome.net',
|
||||
uid: user_id, #Example id
|
||||
iat: Time.now.to_i,
|
||||
exp: Time.now.to_i + 3600
|
||||
}
|
||||
authorization_header = request.env['HTTP_AUTHORIZATION']
|
||||
|
||||
hmac_secret = 'WChX-tQWbGbj_pGJQREoFAZGC9JWh58KSk8O7KPj-P8Nd-J88g3eSFDVuNe6zddj0ZB3yxjm_IuPNPyLhiSnxlWHImqXR6ajh3OzrzYm0bNb3f5C4IAScphyEdAfYGMcM-HvYOXxxxp5u5mryfiV3JH1CTqL1CzGyO8df7zUpRKXEXZ5SKmUvhfLU0XKCR_28FAZUgPCAi3GywkDDsH0by68j33BU5cnMT8KiEkHOX4wVUVDQc85_AuE7fN3ji_WkhnDCSLXU9dBCcXM3ziFFeX0RbvIRDG0vKdzwt4TOr4Jws7NP9w11GrUGDFKARZqvT7FTxwxO3MM-mmjb2xyGg'
|
||||
return JWT.encode payload, hmac_secret, 'HS256'
|
||||
#data: {time: 'now', help: 'no'}.to_json
|
||||
end
|
||||
|
||||
def get_jwt (user_id)
|
||||
claims = get_claims user_id
|
||||
|
||||
payload = {
|
||||
sub: 'authentication' ,
|
||||
admin: check_if_user_is_admin(user_id),
|
||||
iss: 'roysathome.net',
|
||||
uid: user_id, #Example id
|
||||
iat: Time.now.to_i,
|
||||
exp: Time.now.to_i + 60,
|
||||
claims: claims
|
||||
}
|
||||
|
||||
hmac_secret = 'WChX-tQWbGbj_pGJQREoFAZGC9JWh58KSk8O7KPj-P8Nd-J88g3eSFDVuNe6zddj0ZB3yxjm_IuPNPyLhiSnxlWHImqXR6ajh3OzrzYm0bNb3f5C4IAScphyEdAfYGMcM-HvYOXxxxp5u5mryfiV3JH1CTqL1CzGyO8df7zUpRKXEXZ5SKmUvhfLU0XKCR_28FAZUgPCAi3GywkDDsH0by68j33BU5cnMT8KiEkHOX4wVUVDQc85_AuE7fN3ji_WkhnDCSLXU9dBCcXM3ziFFeX0RbvIRDG0vKdzwt4TOr4Jws7NP9w11GrUGDFKARZqvT7FTxwxO3MM-mmjb2xyGg'
|
||||
return JWT.encode payload, hmac_secret, 'HS256'
|
||||
end
|
||||
|
||||
def get_claims (user_id)
|
||||
puts "Getting claims for #{user_id}"
|
||||
db = SQLite3::Database.new('./database/auth.db')
|
||||
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.id = ?
|
||||
', user_id)
|
||||
|
||||
|
||||
claims_list = []
|
||||
|
||||
if results.empty?
|
||||
puts 'No claims found.'
|
||||
else
|
||||
results.each do |column|
|
||||
claim = column[0]
|
||||
claims_list << claim
|
||||
end
|
||||
unless authorization_header && authorization_header.match(/^Bearer (.+)/)
|
||||
status 401
|
||||
return { reply: 'Unauthorized Access. Token missing or invalid.' }.to_json
|
||||
end
|
||||
|
||||
return claims_list
|
||||
token = Regexp.last_match(1)
|
||||
|
||||
begin
|
||||
# Verify the token using the secret key
|
||||
decoded_token = JWT.decode(token, TOKEN_SECRET, true, algorithm: 'HS256')
|
||||
|
||||
unless decoded_token.first['claims'].include? 'is_machine'
|
||||
status 401
|
||||
return { reply: 'Unauthorized Access.' }.to_json
|
||||
end
|
||||
|
||||
# Access the uploaded file through the params hash
|
||||
file = params[:file]
|
||||
|
||||
# Save the file to the 'uploads' folder
|
||||
path = "#{DATA_LOCATION}#{FILE_STORAGE_LOCATION}/example.txt"
|
||||
File.open(path, 'wb') do |f|
|
||||
f.write(file[:tempfile].read)
|
||||
end
|
||||
|
||||
"File uploaded successfully: #{file[:filename]}"
|
||||
rescue JWT::DecodeError
|
||||
status 401
|
||||
return { reply: 'Unauthorized Access. Invalid token.' }.to_json
|
||||
end
|
||||
end
|
||||
|
||||
# Run the application
|
||||
|
|
|
@ -17,4 +17,5 @@ end
|
|||
|
||||
def generate_random_string(length)
|
||||
SecureRandom.urlsafe_base64(length)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
require 'sqlite3'
|
||||
|
||||
DATA_LOCATION = './data'
|
||||
DATABASE_SUBPATH = '/database'
|
||||
DATABASE_NAME = '/auth.db'
|
||||
FILE_STORAGE_LOCATION = '/files'
|
||||
|
||||
def create_new_user(username, password, is_admin)
|
||||
db = SQLite3::Database.new('./database/auth.db')
|
||||
db = SQLite3::Database.new( DATA_LOCATION + DATABASE_SUBPATH + DATABASE_NAME )
|
||||
|
||||
db.execute('
|
||||
INSERT INTO users (username, hashed_password, is_admin)
|
||||
|
@ -10,7 +15,7 @@ def create_new_user(username, password, is_admin)
|
|||
end
|
||||
|
||||
def check_if_user_exists(username)
|
||||
db = SQLite3::Database.new('./database/auth.db')
|
||||
db = SQLite3::Database.new( DATA_LOCATION + DATABASE_SUBPATH + DATABASE_NAME )
|
||||
|
||||
result = db.get_first_value('SELECT COUNT(*) FROM users WHERE username = ?', username.downcase)
|
||||
|
||||
|
@ -22,7 +27,7 @@ def check_if_user_exists(username)
|
|||
end
|
||||
|
||||
def check_if_user_is_admin(user_id)
|
||||
db = SQLite3::Database.new('./database/auth.db')
|
||||
db = SQLite3::Database.new( DATA_LOCATION + DATABASE_SUBPATH + DATABASE_NAME )
|
||||
|
||||
result = db.get_first_value('SELECT is_admin FROM users WHERE id = ?', user_id)
|
||||
|
||||
|
@ -35,7 +40,7 @@ end
|
|||
|
||||
|
||||
def get_user_id(username)
|
||||
db = SQLite3::Database.new('./database/auth.db')
|
||||
db = SQLite3::Database.new( DATA_LOCATION + DATABASE_SUBPATH + DATABASE_NAME )
|
||||
|
||||
user_id = db.get_first_value('
|
||||
SELECT id
|
||||
|
@ -48,7 +53,7 @@ def get_user_id(username)
|
|||
end
|
||||
|
||||
def get_user_hashed_password(user_id)
|
||||
db = SQLite3::Database.new('./database/auth.db')
|
||||
db = SQLite3::Database.new( DATA_LOCATION + DATABASE_SUBPATH + DATABASE_NAME )
|
||||
|
||||
password_hash = db.get_first_value('
|
||||
SELECT hashed_password
|
||||
|
@ -61,11 +66,37 @@ def get_user_hashed_password(user_id)
|
|||
end
|
||||
|
||||
def update_user_password(user_id, password)
|
||||
db = SQLite3::Database.new('./database/auth.db')
|
||||
db = SQLite3::Database.new( DATA_LOCATION + DATABASE_SUBPATH + DATABASE_NAME )
|
||||
|
||||
db.execute('
|
||||
UPDATE users
|
||||
SET hashed_password = ?, salt = ?
|
||||
WHERE id = ?
|
||||
', [hash_password, salt, user_id])
|
||||
end
|
||||
end
|
||||
|
||||
def get_claims (user_id)
|
||||
puts "Getting claims for #{user_id}"
|
||||
db = SQLite3::Database.new( DATA_LOCATION + DATABASE_SUBPATH + DATABASE_NAME )
|
||||
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.id = ?
|
||||
', user_id)
|
||||
|
||||
|
||||
claims_list = []
|
||||
|
||||
if results.empty?
|
||||
puts 'No claims found.'
|
||||
else
|
||||
results.each do |column|
|
||||
claim = column[0]
|
||||
claims_list << claim
|
||||
end
|
||||
end
|
||||
|
||||
return claims_list
|
||||
end
|
|
@ -5,15 +5,25 @@ require 'sqlite3'
|
|||
def initialize_database
|
||||
puts 'Checking if database needs initializing.'
|
||||
|
||||
directory_path = './database'
|
||||
database_path = DATA_LOCATION + DATABASE_SUBPATH
|
||||
file_path = DATA_LOCATION + FILE_STORAGE_LOCATION
|
||||
puts database_path
|
||||
|
||||
unless File.directory?(directory_path)
|
||||
# If not, create the directory
|
||||
Dir.mkdir(directory_path)
|
||||
puts "Directory '#{directory_path}' created successfully."
|
||||
unless File.directory?(DATA_LOCATION)
|
||||
Dir.mkdir(DATA_LOCATION)
|
||||
|
||||
unless File.directory?(database_path)
|
||||
Dir.mkdir(database_path)
|
||||
puts "Directory '#{database_path}' created successfully."
|
||||
end
|
||||
|
||||
unless File.directory?(file_path)
|
||||
Dir.mkdir(file_path)
|
||||
puts "Directory '#{file_path}' created successfully."
|
||||
end
|
||||
end
|
||||
|
||||
db = SQLite3::Database.new('./database/auth.db')
|
||||
|
||||
db = SQLite3::Database.new( DATA_LOCATION + DATABASE_SUBPATH + DATABASE_NAME )#'./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, is_admin INTEGER)')
|
||||
|
|
61
auth/post.rb
61
auth/post.rb
|
@ -1,4 +1,5 @@
|
|||
require 'net/http'
|
||||
require 'net/http/post/multipart'
|
||||
require 'uri'
|
||||
require 'json'
|
||||
|
||||
|
@ -41,19 +42,55 @@ puts 'Reauthentication token stored.'
|
|||
response_data = JSON.parse(response.body)
|
||||
reauthentication_token = response_data['token']
|
||||
|
||||
url = URI.parse('http://localhost:4567/auth/reauthenticate')
|
||||
request = Net::HTTP::Post.new(url.path)
|
||||
#while true
|
||||
url = URI.parse('http://localhost:4567/auth/reauthenticate')
|
||||
request = Net::HTTP::Post.new(url.path)
|
||||
|
||||
request['Authorization'] = "Bearer #{reauthentication_token}"
|
||||
request['Authorization'] = "Bearer #{reauthentication_token}"
|
||||
|
||||
response = http.request(request)
|
||||
response = http.request(request)
|
||||
|
||||
unless response.code == '200'
|
||||
puts "Response Code: #{response.code}. Aborting."
|
||||
puts "Response Body: #{response.body}"
|
||||
puts "Aborting."
|
||||
exit
|
||||
end
|
||||
|
||||
#puts response.body
|
||||
|
||||
response_data = JSON.parse(response.body)
|
||||
authentication_token = response_data['jwt']
|
||||
|
||||
#end
|
||||
|
||||
############# Do Files Test
|
||||
#sleep(2)
|
||||
|
||||
# Read the file contents
|
||||
file_content = File.read('./example.txt')
|
||||
|
||||
# Create a URI object for the API endpoint
|
||||
uri = URI.parse('http://localhost:4567/upload')
|
||||
|
||||
# Create a Net::HTTP object
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
|
||||
request = Net::HTTP::Post::Multipart.new(
|
||||
uri.path,
|
||||
'file' => UploadIO.new(StringIO.new(file_content), 'application/octet-stream', 'example.txt')
|
||||
)
|
||||
|
||||
request['Authorization'] = "Bearer #{authentication_token}"
|
||||
|
||||
# Send the request
|
||||
puts "Sending file of size #{(File.size('./example.txt') / 2**20).round(2)} MB"
|
||||
response = http.request(request)
|
||||
|
||||
#puts response.code
|
||||
|
||||
unless response.code == '200'
|
||||
puts "Response Code: #{response.code}. Aborting."
|
||||
puts "Response Body: #{response.body}"
|
||||
puts "Aborting."
|
||||
exit
|
||||
end
|
||||
|
||||
|
||||
puts response.body
|
||||
puts response.code
|
||||
else
|
||||
puts response.body
|
||||
end
|
Loading…
Reference in New Issue