Class: Stealth::Session

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

Constant Summary collapse

SLUG_SEPARATOR =
'->'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(user_id: nil, previous: false) ⇒ Session

Returns a new instance of Session.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/stealth/session.rb', line 12

def initialize(user_id: nil, previous: false)
  @user_id = user_id
  @previous = previous

  if user_id.present?
    unless defined?($redis) && $redis.present?
      raise(Stealth::Errors::RedisNotConfigured, "Please make sure REDIS_URL is configured before using sessions")
    end

    get
  end

  self
end

Instance Attribute Details

#flowObject (readonly)

Returns the value of attribute flow.



9
10
11
# File 'lib/stealth/session.rb', line 9

def flow
  @flow
end

#previousObject (readonly)

Returns the value of attribute previous.



9
10
11
# File 'lib/stealth/session.rb', line 9

def previous
  @previous
end

#sessionObject

Returns the value of attribute session.



10
11
12
# File 'lib/stealth/session.rb', line 10

def session
  @session
end

#stateObject (readonly)

Returns the value of attribute state.



9
10
11
# File 'lib/stealth/session.rb', line 9

def state
  @state
end

#user_idObject (readonly)

Returns the value of attribute user_id.



9
10
11
# File 'lib/stealth/session.rb', line 9

def user_id
  @user_id
end

Class Method Details

.canonical_session_slug(flow:, state:) ⇒ Object



117
118
119
# File 'lib/stealth/session.rb', line 117

def self.canonical_session_slug(flow:, state:)
  [flow, state].join(SLUG_SEPARATOR)
end

.flow_and_state_from_session_slug(slug:) ⇒ Object



27
28
29
30
31
32
# File 'lib/stealth/session.rb', line 27

def self.flow_and_state_from_session_slug(slug:)
  {
    flow: slug&.split(SLUG_SEPARATOR)&.first,
    state: slug&.split(SLUG_SEPARATOR)&.last
  }
end

.is_a_session_string?(string) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
115
# File 'lib/stealth/session.rb', line 112

def self.is_a_session_string?(string)
  session_regex = /(.+)(#{SLUG_SEPARATOR})(.+)/
  !!string.match(session_regex)
end

Instance Method Details

#+(steps) ⇒ Object



91
92
93
94
95
96
97
98
99
100
# File 'lib/stealth/session.rb', line 91

def +(steps)
  return nil if flow.blank?
  return self if steps.zero?

  new_state = self.state + steps
  new_session = Stealth::Session.new(user_id: self.user_id)
  new_session.session = self.class.canonical_session_slug(flow: self.flow_string, state: new_state)

  new_session
end

#-(steps) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'lib/stealth/session.rb', line 102

def -(steps)
  return nil if flow.blank?

  if steps < 0
    return self + steps.abs
  else
    return self + (-steps)
  end
end

#blank?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/stealth/session.rb', line 83

def blank?
  !present?
end

#flow_stringObject



44
45
46
# File 'lib/stealth/session.rb', line 44

def flow_string
  session&.split(SLUG_SEPARATOR)&.first
end

#getObject



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/stealth/session.rb', line 52

def get
  prev_key = previous_session_key(user_id: user_id)

  @session ||= begin
    if sessions_expire?
      previous? ? getex(prev_key) : getex(user_id)
    else
      previous? ? $redis.get(prev_key) : $redis.get(user_id)
    end
  end
end

#present?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/stealth/session.rb', line 79

def present?
  session.present?
end

#previous?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/stealth/session.rb', line 87

def previous?
  @previous
end

#set(flow:, state:) ⇒ Object



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

def set(flow:, state:)
  store_current_to_previous(flow: flow, state: state)

  @flow = nil
  @session = self.class.canonical_session_slug(flow: flow, state: state)

  Stealth::Logger.l(topic: "session", message: "User #{user_id}: setting session to #{flow}->#{state}")

  if sessions_expire?
    $redis.setex(user_id, Stealth.config.session_ttl, session)
  else
    $redis.set(user_id, session)
  end
end

#state_stringObject



48
49
50
# File 'lib/stealth/session.rb', line 48

def state_string
  session&.split(SLUG_SEPARATOR)&.last
end