Class: Tep::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/tep/session.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSession

Returns a new instance of Session.



15
16
17
18
# File 'lib/tep/session.rb', line 15

def initialize
  @data  = Tep.str_hash
  @dirty = false
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.



13
14
15
# File 'lib/tep/session.rb', line 13

def data
  @data
end

#dirtyObject

Returns the value of attribute dirty.



13
14
15
# File 'lib/tep/session.rb', line 13

def dirty
  @dirty
end

Instance Method Details

#clearObject



39
# File 'lib/tep/session.rb', line 39

def clear;     @data = Tep.str_hash; @dirty = true; end

#get(k) ⇒ Object

Spinel doesn't dispatch user-defined [] / []= on user classes -- and emitting them at all forces those methods to default-typed mrb_int params for callers we don't have, which mismatches the underlying String/String slots. So Session exposes only named methods; the translator rewrites session[k] = v to session.set(k, v) and session[k] to session.get(k) for source compatibility with Sinatra. A missing key reads as "" -- the documented session[k] DSL contract (test_sessions pins it; a deliberate divergence from sinatra's nil-on-miss, ledgered in docs/mirrors/sinatra.md). The raw @data hash reads nil for a miss.



31
32
33
34
35
# File 'lib/tep/session.rb', line 31

def get(k)
  v = @data[k]
  v = "" if v.nil?
  v
end

#has?(k) ⇒ Boolean

Returns:

  • (Boolean)


37
# File 'lib/tep/session.rb', line 37

def has?(k);   @data.key?(k);                     end

#lengthObject



38
# File 'lib/tep/session.rb', line 38

def length;    @data.length;                      end

#load_from(cookie_value, secret) ⇒ Object

Verify + decode an inbound cookie value. Returns true on success (data populated), false on missing / tampered.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/tep/session.rb', line 43

def load_from(cookie_value, secret)
  if cookie_value.length == 0 || secret.length == 0
    return false
  end
  dot = cookie_value.rindex(".")
  if dot.nil?
    return false
  end
  payload = cookie_value[0, dot]
  sig     = cookie_value[dot + 1, cookie_value.length - dot - 1]
  expect  = Crypto.sp_crypto_hmac_sha256_hex(secret, payload)
  if !Tep.timing_safe_eq(sig, expect)
    return false
  end
  SpinelKit::Url.parse_query(payload).each do |k, v|
    @data[k] = v
  end
  true
end

#set(k, v) ⇒ Object



36
# File 'lib/tep/session.rb', line 36

def set(k, v); @data[k] = v; @dirty = true;       end

Serialize + sign for the response cookie. Caller decides when to call this (typically only when @dirty).



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/tep/session.rb', line 65

def to_cookie_value(secret)
  payload = ""
  first = true
  @data.each do |k, v|
    if !first
      payload = payload + "&"
    end
    payload = payload + SpinelKit::Url.escape(k) + "=" + SpinelKit::Url.escape(v)
    first = false
  end
  payload + "." + Crypto.sp_crypto_hmac_sha256_hex(secret, payload)
end