Compare commits
3 Commits
cca1aa4604
...
fde1dd14b5
Author | SHA1 | Date | |
---|---|---|---|
fde1dd14b5
|
|||
a4955d35fa
|
|||
aa907dfa5f
|
38
app.rb
38
app.rb
@ -13,9 +13,14 @@ require "anyflake"
|
||||
|
||||
require "jwt"
|
||||
|
||||
SESSION_SECRET_HEX_LENGTH = 64
|
||||
$LOAD_PATH.unshift File.dirname(__FILE__) + "/lib"
|
||||
|
||||
set :session_secret, ENV.fetch("SESSION_SECRET") { SecureRandom.hex(SESSION_SECRET_HEX_LENGTH) }
|
||||
require "config"
|
||||
|
||||
SESSION_SECRET_HEX_LENGTH = 64
|
||||
JWT_SECRET_HEX_LENGTH = 64
|
||||
|
||||
ENV_PREFIX = "KIPUNJI"
|
||||
|
||||
CLK_TCK = 100
|
||||
PID_FILE_PATH = "/run/app/pid".freeze
|
||||
@ -38,7 +43,9 @@ DURATION_PARTS = [
|
||||
[1, "second", "s"]
|
||||
].freeze
|
||||
|
||||
JWT_SECRET = SecureRandom.bytes(64).freeze
|
||||
config = Config.new
|
||||
|
||||
set :session_secret, config.session_secret.unwrap
|
||||
|
||||
module Sinatra
|
||||
module RequestHeadersHelper
|
||||
@ -209,12 +216,13 @@ before do
|
||||
end
|
||||
|
||||
helpers do
|
||||
def json(obj, opts: nil, pretty: false)
|
||||
if pretty
|
||||
def jsonify(obj, opts: nil, pretty: false)
|
||||
buf = if pretty
|
||||
JSON.pretty_generate obj, opts:
|
||||
else
|
||||
JSON.generate(obj, opts:)
|
||||
end
|
||||
"#{buf}\n"
|
||||
end
|
||||
|
||||
def protected! hidden = false
|
||||
@ -244,14 +252,14 @@ end
|
||||
get "/env", provides: "json" do
|
||||
pretty = params.key? :pretty
|
||||
|
||||
json ENV.sort.to_h, pretty:
|
||||
jsonify ENV.sort.to_h, pretty:
|
||||
end
|
||||
|
||||
get "/headers", provides: "json" do
|
||||
pretty = params.key? :pretty
|
||||
h = req_headers
|
||||
|
||||
json h, pretty:
|
||||
jsonify h, pretty:
|
||||
end
|
||||
|
||||
get "/livez" do
|
||||
@ -266,7 +274,7 @@ get "/livez/uptime" do
|
||||
tt = TickTock.new
|
||||
x = {started_at: tt.started_at, seconds: tt.uptime.to_i, human: human_time(tt.uptime.to_i)}
|
||||
|
||||
json x
|
||||
jsonify x
|
||||
end
|
||||
|
||||
post "/livez/toggle" do
|
||||
@ -330,7 +338,7 @@ end
|
||||
get "/pid" do
|
||||
pretty = params.key? :pretty
|
||||
|
||||
json({puma: master_pid, pid: Process.pid}, pretty:)
|
||||
jsonify({puma: master_pid, pid: Process.pid}, pretty:)
|
||||
end
|
||||
|
||||
get "/token" do
|
||||
@ -340,31 +348,31 @@ get "/token" do
|
||||
token = JWT.encode payload, JWT_SECRET, "HS256"
|
||||
x = {token: token, expires_at: expires_at}
|
||||
|
||||
json x
|
||||
jsonify x
|
||||
end
|
||||
|
||||
get "/token/validate" do
|
||||
token = req_headers["authorization"].split[1]
|
||||
payload = JWT.decode token, JWT_SECRET, true, algorithm: "HS256"
|
||||
|
||||
json payload
|
||||
jsonify payload
|
||||
end
|
||||
|
||||
post "/session" do
|
||||
session.merge! params
|
||||
|
||||
json session.to_hash
|
||||
jsonify session.to_hash
|
||||
end
|
||||
|
||||
get "/session" do
|
||||
j = session.to_hash
|
||||
j[:hostname] = ENV["HOSTNAME"]
|
||||
|
||||
json j
|
||||
jsonify j
|
||||
end
|
||||
|
||||
get "/cookies" do
|
||||
json response.headers
|
||||
jsonify response.headers
|
||||
end
|
||||
|
||||
get "/_cat/headers" do
|
||||
@ -415,5 +423,5 @@ route :delete, :get, :patch, :post, :put, "/auth/basic", provides: "json" do
|
||||
protected!
|
||||
end
|
||||
|
||||
json({authenticated: true, user: @auth.username}, pretty:)
|
||||
jsonify({authenticated: true, user: @auth.username}, pretty:)
|
||||
end
|
||||
|
50
lib/config.rb
Normal file
50
lib/config.rb
Normal file
@ -0,0 +1,50 @@
|
||||
require "sensitive"
|
||||
|
||||
class Config
|
||||
attr_accessor :cat
|
||||
|
||||
attr_reader :jwt_secret, :session_secret
|
||||
|
||||
def initialize(prefix = ENV_PREFIX, jwt_secret = nil, session_secret = nil, cat = nil)
|
||||
@prefix = prefix
|
||||
@cat = cat
|
||||
|
||||
session_secret ||= ENV.fetch "SESSION_SECRET" do
|
||||
SecureRandom.hex SESSION_SECRET_HEX_LENGTH
|
||||
end
|
||||
|
||||
jwt_secret ||= fetch_env "JWT_SECRET" do
|
||||
SecureRandom.hex JWT_SECRET_HEX_LENGTH
|
||||
end
|
||||
|
||||
@session_secret = Sensitive.new session_secret
|
||||
@jwt_secret = Sensitive.new jwt_secret
|
||||
@cat ||= ENV.fetch "#{@prefix}_CAT", nil
|
||||
end
|
||||
|
||||
def fetch_env(name, &)
|
||||
ENV.fetch "#{@prefix}_#{name}", &
|
||||
end
|
||||
|
||||
def as_json(options = nil)
|
||||
{jwt_secret: jwt_secret, session_secret: @session_secret, cat: @cat}
|
||||
end
|
||||
|
||||
def to_json(options = nil)
|
||||
if options &&
|
||||
options.key?(:pretty) &&
|
||||
options[:pretty] == true
|
||||
JSON.pretty_generate as_json(options)
|
||||
else
|
||||
JSON.generate as_json(options)
|
||||
end
|
||||
end
|
||||
|
||||
def session_secret=(v)
|
||||
@session_secret = Sensitive.new v
|
||||
end
|
||||
|
||||
def jwt_secret=(v)
|
||||
@jwt_secret = Sensitive.new v
|
||||
end
|
||||
end
|
39
lib/sensitive.rb
Normal file
39
lib/sensitive.rb
Normal file
@ -0,0 +1,39 @@
|
||||
class Sensitive
|
||||
alias_method :eql?, :==
|
||||
alias_method :equal?, :==
|
||||
|
||||
def initialize(v, ch: "*", head: 2, tail: 2)
|
||||
@v = v
|
||||
@ch = ch
|
||||
@head = head
|
||||
@tail = tail
|
||||
end
|
||||
|
||||
def mask(v)
|
||||
"".concat(v[0, @head], @ch * (v.length - (@head + @tail)), v[-@tail, @tail])
|
||||
end
|
||||
|
||||
def unwrap
|
||||
@v
|
||||
end
|
||||
|
||||
def length
|
||||
@v.length
|
||||
end
|
||||
|
||||
def to_s
|
||||
mask @v
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#<#{self.class.name} @v=#{wrap}>"
|
||||
end
|
||||
|
||||
def hash
|
||||
@v.hash
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
other.is_a?(Sensitive) && other.hash == hash
|
||||
end
|
||||
end
|
26
spec/sensitive_spec.rb
Normal file
26
spec/sensitive_spec.rb
Normal file
@ -0,0 +1,26 @@
|
||||
require "minitest/autorun"
|
||||
|
||||
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
|
||||
|
||||
require "sensitive"
|
||||
|
||||
ALPHABET = ('a' .. 'z').reduce(:concat)
|
||||
|
||||
describe "Sensitive" do
|
||||
before do
|
||||
@s = Sensitive.new ALPHABET
|
||||
end
|
||||
|
||||
it "test initialize" do
|
||||
_(@s.to_s).must_equal "ab" + "*" * 22 + "yz"
|
||||
end
|
||||
|
||||
it "test initialize" do
|
||||
_(@s.unwrap).must_equal ALPHABET
|
||||
end
|
||||
|
||||
it "test using different mask character" do
|
||||
s = Sensitive.new ALPHABET, ch: "x"
|
||||
_(s.to_s).must_equal "x"
|
||||
end
|
||||
end
|
26
test/test_sensitive.rb
Normal file
26
test/test_sensitive.rb
Normal file
@ -0,0 +1,26 @@
|
||||
require "minitest/autorun"
|
||||
|
||||
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
|
||||
|
||||
require "sensitive"
|
||||
|
||||
ALPHABET = ("a".."z").reduce(:concat)
|
||||
|
||||
class TestSensitive < Minitest::Test
|
||||
def setup
|
||||
@s = Sensitive.new ALPHABET
|
||||
end
|
||||
|
||||
def test_initialize
|
||||
assert_equal @s.to_s, "ab" + "*" * 22 + "yz"
|
||||
end
|
||||
|
||||
def test_unwrap
|
||||
assert_equal @s.unwrap, ALPHABET
|
||||
end
|
||||
|
||||
def test_using_a_different_mask_character
|
||||
s = Sensitive.new ALPHABET, ch: "x"
|
||||
assert_equal s.to_s, "ab" + "x" * 22 + "yz"
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user