Class: Rack::GlobalSessions::GlobalSession

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

Overview

Global session middleware. Note: this class relies on Rack::Cookies being used higher up in the chain.

Instance Method Summary collapse

Constructor Details

#initialize(app, configuration, &block) ⇒ GlobalSession

Make a new global session.

The optional block here controls an alternate ticket retrieval method. If no ticket is stored in the cookie jar, this function is called. If it returns a non-nil value, that value is the ticket.

Parameters

app(Rack client): application to run configuration(String or HasGlobalSession::Configuration): has_global_session configuration.

If a string, is interpreted as a
filename to load the config from.

block: optional alternate ticket retrieval function


51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rack_global_session.rb', line 51

def initialize(app, configuration, &block)
  @app = app
  if configuration.instance_of?(String)
    @configuration = Configuration.new(configuration, ENV['RACK_ENV'] || 'development')
  else
    @configuration = configuration
  end
  @cookie_retrieval = block
  @directory = Directory.new(@configuration, @configuration['directory'])
  @cookie_name = @configuration['cookie']['name']
end

Instance Method Details

#call(env) ⇒ Object

Rack request chain. Sets up the global session ticket from the environment and passes it up the chain.


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/rack_global_session.rb', line 133

def call(env)
  env['rack.cookies'] = {} unless env['rack.cookies']
  begin
    read_cookie(env)
    renew_ticket(env)
  rescue Exception => e
    wipe_cookie(env)
    $stderr.puts "Error while reading cookies: #{e.class} #{e} #{e.backtrace}"
    if env['rack.logger']
      env['rack.logger'].error("Error while reading cookies: #{e.class} #{e} #{e.backtrace}")
    end
    return [403, {'Content-Type' => 'text/plain'}, "Invalid cookie"]
  else
    begin
      tuple = @app.call(env)
    rescue HasGlobalSession::NoAuthority => e
      wipe_cookie(env)
      $stderr.puts "Error during request: #{e.class} #{e} #{e.backtrace}"
      if env['rack.logger']
        env['rack.logger'].error("Error during request: #{e.class} #{e} #{e.backtrace}")
      end
      return [500, {'Content-Type' => 'text/plain'}, "Error"]
    rescue Exception => e
      wipe_cookie(env)
      raise e
    else
      update_cookie(env)
      return tuple
    end
  end
end

Read a cookie from the Rack environment.

Parameters

env(Hash): Rack environment.


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rack_global_session.rb', line 67

def read_cookie(env)
  begin
    if env['rack.cookies'].key?(@cookie_name)
      env['global_session'] = Session.new(@directory,
                                          env['rack.cookies'][@cookie_name])
    elsif @cookie_retrieval && cookie = @cookie_retrieval.call(env)
      env['global_session'] = Session.new(@directory, cookie)
    else
      env['global_session'] = Session.new(@directory)
    end
    true
  rescue Exception => e
    # Reinitialize global session cookie
    env['global_session'] = Session.new(@directory)
    update_cookie(env)
    raise e
  end
end

#renew_ticket(env) ⇒ Object

Renew the session ticket.

Parameters

env(Hash): Rack environment


90
91
92
93
94
95
96
# File 'lib/rack_global_session.rb', line 90

def renew_ticket(env)
  if @configuration['renew'] && env['global_session'] &&
      env['global_session'].directory.local_authority_name &&
      env['global_session'].expired_at < renew.to_i.minutes.from_now.utc
    env['global_session'].renew!
  end
end

Update the cookie jar with the revised ticket.

Parameters

env(Hash): Rack environment


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/rack_global_session.rb', line 102

def update_cookie(env)
  begin
    domain = @configuration['cookie']['domain'] || ENV['SERVER_NAME']
    if env['global_session'] && env['global_session'].valid?
      value = env['global_session'].to_s
      expires = @configuration['ephemeral'] ? nil : env['global_session'].expired_at
      unless env['rack.cookies'].key?(@cookie_name) &&
          env['rack.cookies'][@cookie_name] == value
        env['rack.cookies'][@cookie_name] = {:value => value, :domain => domain, :expires => expires}
      end
    else
      # write an empty cookie
      env['rack.cookies'][@cookie_name] = {:value => nil, :domain => domain, :expires => Time.at(0)}
    end
  rescue Exception => e
    wipe_cookie(env)
    raise e
  end
end

Delete the ticket from the cookie jar.

Parameters

env(Hash): Rack environment


126
127
128
129
# File 'lib/rack_global_session.rb', line 126

def wipe_cookie(env)
  domain = @configuration['cookie']['domain'] || ENV['SERVER_NAME']
  env['rack.cookies'][@cookie_name] = {:value => nil, :domain => domain, :expires => Time.at(0)}
end