add new features for JWT

This commit is contained in:
Joseph.Roy 2023-12-13 16:02:09 +00:00
parent 35440e6b43
commit e925905a4a
6 changed files with 71 additions and 30 deletions

View File

@ -10,5 +10,6 @@ gem 'webrick'
gem 'jwt' gem 'jwt'
gem 'sqlite3' gem 'sqlite3'
gem 'bcrypt' gem 'bcrypt'
gem 'securerandom'
# bundle install # bundle install

View File

@ -9,6 +9,7 @@ GEM
rack-protection (3.1.0) rack-protection (3.1.0)
rack (~> 2.2, >= 2.2.4) rack (~> 2.2, >= 2.2.4)
ruby2_keywords (0.0.5) ruby2_keywords (0.0.5)
securerandom (0.3.0)
sinatra (3.1.0) sinatra (3.1.0)
mustermann (~> 3.0) mustermann (~> 3.0)
rack (~> 2.2, >= 2.2.4) rack (~> 2.2, >= 2.2.4)
@ -24,6 +25,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
bcrypt bcrypt
jwt jwt
securerandom
sinatra sinatra
sqlite3 sqlite3
webrick webrick

View File

@ -9,21 +9,23 @@ require 'json'
require 'sqlite3' require 'sqlite3'
require 'jwt' require 'jwt'
payload = { data: {time: 'now', help: 'no'}.to_json, test: 'hello' } #puts generate_random_string(256)
hmac_secret = 'my$ecretK3y'
token = JWT.encode payload, hmac_secret, 'HS256'
#puts token
begin
decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' }
puts "Token is valid!"
puts "Decoded token: #{decoded_token}"
puts data_value = decoded_token.first['data'] #
puts test_value = decoded_token.first['test'] #token = JWT.encode payload, hmac_secret, 'HS256'
rescue JWT::DecodeError ##puts token
puts "Invalid token or signature!" #
end #begin
# decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' }
# puts "Token is valid!"
# puts "Decoded token: #{decoded_token}"
#
# puts data_value = decoded_token.first['data']
# puts test_value = decoded_token.first['test']
#rescue JWT::DecodeError
# puts "Invalid token or signature!"
#end
#puts decoded_token #puts decoded_token
@ -38,7 +40,7 @@ post '/auth/login' do
unless check_if_user_exists username unless check_if_user_exists username
status 401 status 401
return { jwt: "Unuthorized Access" }.to_json return { reply: "Unuthorized Access" }.to_json
end end
user_id = get_user_id username user_id = get_user_id username
@ -46,26 +48,41 @@ post '/auth/login' do
unless check_password_for_user(user_id, password) unless check_password_for_user(user_id, password)
status 401 status 401
return { jwt: "Unuthorized Access" }.to_json return { reply: "Unuthorized Access" }.to_json
end end
{ jwt: "Logged in" }.to_json reauthJWT = get_reauth_jwt user_id
return reauthJWT.to_json
end end
def get_jwt (username, expiry_time) def get_reauth_jwt (user_id)
get_claims username #claims = get_claims user_id
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
}
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 end
def get_claims (username) def get_claims (user_id)
puts "Getting claims for #{username}" puts "Getting claims for #{user_id}"
db = SQLite3::Database.new('./database/auth.db') db = SQLite3::Database.new('./database/auth.db')
results = db.execute(' results = db.execute('
SELECT C.claim SELECT C.claim
FROM users U FROM users U
INNER JOIN user_claims UC ON U.id = UC.user_id INNER JOIN user_claims UC ON U.id = UC.user_id
INNER JOIN claims C ON UC.claim_id = U.id INNER JOIN claims C ON UC.claim_id = U.id
WHERE u.username = ? WHERE u.id = ?
', username) ', user_id)
if results.empty? if results.empty?

View File

@ -1,4 +1,5 @@
require 'bcrypt' require 'bcrypt'
require 'securerandom'
def create_password_for_user(password) def create_password_for_user(password)
return BCrypt::Password.create(password) return BCrypt::Password.create(password)
@ -13,3 +14,7 @@ def check_password_for_user(user_id, entered_password)
return false return false
end end
end end
def generate_random_string(length)
SecureRandom.urlsafe_base64(length)
end

View File

@ -1,13 +1,12 @@
require 'sqlite3' require 'sqlite3'
def create_new_user(username, password, is_admin)
def create_new_user(username, password)
db = SQLite3::Database.new('./database/auth.db') db = SQLite3::Database.new('./database/auth.db')
db.execute(' db.execute('
INSERT INTO users (username, hashed_password) INSERT INTO users (username, hashed_password, is_admin)
VALUES (?, ?) VALUES (?, ?, ?)
', [username.downcase, create_password_for_user(password)]) ', [username.downcase, create_password_for_user(password), is_admin])
end end
def check_if_user_exists(username) def check_if_user_exists(username)
@ -22,6 +21,19 @@ def check_if_user_exists(username)
end end
end end
def check_if_user_is_admin(user_id)
db = SQLite3::Database.new('./database/auth.db')
result = db.get_first_value('SELECT is_admin FROM users WHERE id = ?', user_id)
if result == 1
return true
else
return false
end
end
def get_user_id(username) def get_user_id(username)
db = SQLite3::Database.new('./database/auth.db') db = SQLite3::Database.new('./database/auth.db')

View File

@ -16,7 +16,7 @@ def initialize_database
db = SQLite3::Database.new('./database/auth.db') db = SQLite3::Database.new('./database/auth.db')
puts 'Creating tables if necessary.' 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 users (id INTEGER PRIMARY KEY, username TEXT, hashed_password TEXT, is_admin INTEGER)')
db.execute('CREATE TABLE IF NOT EXISTS claims (id INTEGER PRIMARY KEY, claim 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('CREATE TABLE IF NOT EXISTS user_claims (id INTEGER PRIMARY KEY, user_id INTEGER, claim_id INTEGER)')
@ -25,7 +25,7 @@ def initialize_database
if result == 0 if result == 0
puts 'Default admin user added.' puts 'Default admin user added.'
create_new_user('admin', 'pass123') create_new_user('admin', 'pass123', 1)
else else
puts 'Table already contains data. Skipping default user creation.' puts 'Table already contains data. Skipping default user creation.'
end end
@ -36,6 +36,10 @@ def initialize_database
db.execute('INSERT INTO claims (claim) VALUES (?)', ['add_user']) 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 (?)', ['remove_user'])
db.execute('INSERT INTO claims (claim) VALUES (?)', ['add_claim_to_user']) db.execute('INSERT INTO claims (claim) VALUES (?)', ['add_claim_to_user'])
db.execute('INSERT INTO claims (claim) VALUES (?)', ['is_machine'])
db.execute('INSERT INTO claims (claim) VALUES (?)', ['is_user'])
db.execute('INSERT INTO claims (claim) VALUES (?)', ['remove_claim_from_user'])
db.execute('INSERT INTO claims (claim) VALUES (?)', ['remove_claim_from_user'])
db.execute('INSERT INTO claims (claim) VALUES (?)', ['remove_claim_from_user']) db.execute('INSERT INTO claims (claim) VALUES (?)', ['remove_claim_from_user'])
end end