Class: Rack::Session::Encookie

Inherits:
Object
  • Object
show all
Defined in:
lib/encookie/cookie.rb

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ Encookie

Returns a new instance of Encookie.



4
5
6
7
8
9
10
# File 'lib/encookie/cookie.rb', line 4

def initialize(app, options={})
  @app = app
  @name = options[:name] || 'rack.session'
  @key = options[:key]
  @default_options = { domain: nil, path: '/'}.merge(options)
  fail 'A secret is required' unless @key
end

Instance Method Details

#call(env) ⇒ Object



12
13
14
15
16
# File 'lib/encookie/cookie.rb', line 12

def call(env)
  load_session env
  status, headers, body = @app.call env
  commit_session env, status, headers, body
end

#commit_session(env, status, headers, body) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/encookie/cookie.rb', line 32

def commit_session(env, status, headers, body)
  options = env['rack.session.options']

  session_data = env['rack.session']
  json = MultiJson.dump session_data
  enc = ::Encookie::Cryptor.encrypt plaintext: json, key: @key
  cookieval = encrypted_to_cookieval enc

  if session_data.size > (4096 - @name.size)
    env['rack.errors'].puts 'Warning! Rack::Session::Cookie data size exceeds 4K. Content dropped.'
  else
    cookie = Hash.new
    cookie[:value] = cookieval
    cookie[:expires] = Time.now + options[:expire_after] unless options[:expire_after].nil?
    Utils.set_cookie_header! headers, @name, cookie.merge(options)
  end

  [status, headers, body]
end

#cookieval_to_encrypted(cookieval) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/encookie/cookie.rb', line 57

def cookieval_to_encrypted(cookieval)
  combined = Base64.urlsafe_decode64 cookieval
  iv = combined[0..11]
  auth_tag = combined[12..27]
  ciphertext = combined[28..-1]
  ::Encookie::Cryptor::Encrypted.new ciphertext, iv, auth_tag
end

#encrypted_to_cookieval(encrypted) ⇒ Object



52
53
54
55
# File 'lib/encookie/cookie.rb', line 52

def encrypted_to_cookieval(encrypted)
  combined = encrypted.iv + encrypted.auth_tag + encrypted.ciphertext
  Base64.urlsafe_encode64 combined
end

#load_session(env) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/encookie/cookie.rb', line 18

def load_session(env)
  request = Rack::Request.new env
  env['rack.session.options'] = @default_options.dup

  cookieval = request.cookies[@name]
  enc = cookieval_to_encrypted cookieval
  json = ::Encookie::Cryptor.decrypt ciphertext: enc.ciphertext, key: @key, iv: enc.iv, auth_tag: enc.auth_tag
  session_data = MultiJson.load json, symbolize_keys: true

  env['rack.session'] = session_data
rescue
  env['rack.session'] = Hash.new
end