class SimpleSession::Base
Attributes
request[R]
session[R]
Public Class Methods
new(app, options = {})
click to toggle source
# File lib/simple_session/base.rb, line 11 def initialize app, options = {} @app = app @key = options.fetch :key, 'rack.session' @secret = options.fetch :secret, get_secret_errors(options) @options_key = options.fetch :options_key, 'rack.session.options' @default_opts = DEFAULT_OPTS.merge!(options) end
Public Instance Methods
add_session(headers)
click to toggle source
# File lib/simple_session/base.rb, line 87 def add_session headers cookie = Hash.new cookie.merge!(session.fetch(:options, @default_opts)) cookie[:value] = encrypt session set_cookie_header headers, @key, cookie end
call(env)
click to toggle source
# File lib/simple_session/base.rb, line 43 def call env # Decrypt request session and store it extract_session env # Load session into app env load_environment env # Pass on request status, headers, body = @app.call env # Check session for changes and update update_options if options_changed? update_session if session_changed? # Encrypt and add session to headers add_session headers [status, headers, body] end
cipher_key()
click to toggle source
# File lib/simple_session/base.rb, line 181 def cipher_key hmac("A red, red fox has had three socks but all have holes" + @secret) end
decrypt(data)
click to toggle source
# File lib/simple_session/base.rb, line 133 def decrypt data # Decode Base64 b = data.unpack('m0').first # Parse Signature h1 = b[0, 32] data = b[32..-1] h2 = data.reverse[0, 32].reverse data = data.reverse[32..-1].reverse if h1 == signature.to_s && h2 == signature.to_s # Decipher Marshal.load unload_cipher data else raise SecurityError end end
digest()
click to toggle source
# File lib/simple_session/base.rb, line 151 def digest OpenSSL::Digest.new 'sha256', @secret end
encrypt(data)
click to toggle source
# File lib/simple_session/base.rb, line 119 def encrypt data # Serialize m = Marshal.dump data # Cipher c = load_cipher m # Sign h = signature + c + signature # Encode Base64 [h].pack('m0') end
extract_session(env)
click to toggle source
# File lib/simple_session/base.rb, line 63 def extract_session env begin @request = Rack::Request.new env @session = req_session ? decrypt(req_session) : new_session_hash session.merge!(options_hash) raise ArgumentError, "Unable to decrypt session" unless session rescue Exception => e @session = new_session_hash.merge!(options_hash) print e.message end end
get_secret_errors(options)
click to toggle source
# File lib/simple_session/base.rb, line 19 def get_secret_errors options secret = options[:secret] missing_msg = %[ SimpleSession requires a secret like this: use SimpleSession::Session, secret: 'some secret' ] short_msg = %[ SimpleSession require a secret with a minimum length of 32 use SimpleSession::Session, secret: SecureRandom.hex(32) ] raise ArgumentError, missing_msg unless secret raise ArgumentError, short_msg unless secret.length >= 32 end
hmac(data)
click to toggle source
# File lib/simple_session/base.rb, line 155 def hmac data OpenSSL::HMAC.digest digest, @secret, data end
load_cipher(marshaled_data)
click to toggle source
# File lib/simple_session/base.rb, line 163 def load_cipher marshaled_data cipher = new_cipher cipher.encrypt iv = cipher.random_iv cipher.iv = iv cipher.key = cipher_key iv + cipher.update(marshaled_data) + cipher.final end
load_environment(env)
click to toggle source
# File lib/simple_session/base.rb, line 82 def load_environment env env[@key] = session.dup env[@options_key] = session[:options].dup end
new_cipher()
click to toggle source
# File lib/simple_session/base.rb, line 159 def new_cipher OpenSSL::Cipher::AES.new(256, :CBC) end
new_session_hash()
click to toggle source
# File lib/simple_session/base.rb, line 39 def new_session_hash { session_id: SecureRandom.hex(32) } end
options_changed?()
click to toggle source
# File lib/simple_session/base.rb, line 103 def options_changed? request.session_options != session[:options] end
options_hash()
click to toggle source
# File lib/simple_session/base.rb, line 77 def options_hash o = session[:options] || OptionHash.new(@default_opts).opts { options: o } end
req_session()
click to toggle source
# File lib/simple_session/base.rb, line 35 def req_session request.cookies[@key] if request end
session_changed?()
click to toggle source
# File lib/simple_session/base.rb, line 107 def session_changed? request.session != session end
signature()
click to toggle source
# File lib/simple_session/base.rb, line 115 def signature hmac(cipher_key) end
unload_cipher(data)
click to toggle source
# File lib/simple_session/base.rb, line 173 def unload_cipher data cipher = new_cipher cipher.decrypt cipher.iv = data[0, 16] cipher.key = cipher_key cipher.update(data[16..-1]) + cipher.final end
update_options()
click to toggle source
# File lib/simple_session/base.rb, line 99 def update_options session[:options] = {options: OptionHash.new(request.session_options).opts} end
update_session()
click to toggle source
# File lib/simple_session/base.rb, line 111 def update_session @session = request.session end