/usr/lib/ruby/vendor_ruby/merb-core/dispatch/session.rb is in ruby-merb-core 1.1.3+dfsg-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 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 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | require 'merb-core/dispatch/session/container'
require 'merb-core/dispatch/session/store_container'
# Try to require SecureRandom from the Ruby 1.9.x
begin
require 'securerandom'
rescue LoadError
end
module Merb
class Config
# Returns stores list constructed from
# configured session stores (:session_stores config option)
# or default one (:session_store config option).
#
# :api: private
def self.session_stores
@session_stores ||= begin
config_stores = Array(
Merb::Config[:session_stores] || Merb::Config[:session_store]
)
config_stores.map { |name| name.to_sym }
end
end
end # Config
# The Merb::Session module gets mixed into Merb::SessionContainer to allow
# app-level functionality (usually found in ./merb/session/session.rb) for
# session.
#
# You can use this module to implement additional methods to simplify
# building wizard-like application components,
# authentication frameworks, etc.
#
# Session configuration options:
#
# :session_id_key The key by which a session value/id is
# retrieved; defaults to _session_id
#
# :session_expiry When to expire the session cookie;
# by defaults session expires when browser quits.
#
# :session_secret_key A secret string which is used to sign/validate
# session data; min. 16 chars
#
# :default_cookie_domain The default domain to write cookies for.
module Session
end
# This is mixed into Merb::Controller on framework boot.
module SessionMixin
# Raised when no suitable session store has been setup.
class NoSessionContainer < StandardError; end
# Raised when storing more data than the available space reserved.
class SessionOverflow < StandardError; end
# :api: private
def self.included(base)
# Register a callback to finalize sessions - needs to run before the cookie
# callback extracts Set-Cookie headers from request.cookies.
base._after_dispatch_callbacks.unshift lambda { |c| c.request.finalize_session }
end
# ==== Parameters
# session_store<String>:: The type of session store to access.
#
# ==== Returns
# SessionContainer:: The session that was extracted from the request object.
#
# :api: public
def session(session_store = nil)
request.session(session_store)
end
# Module methods
# ==== Returns
# String:: A random 32 character string for use as a unique session ID.
#
# :api: private
def rand_uuid
if defined?(SecureRandom)
SecureRandom.hex(16)
else
values = [
rand(0x0010000),
rand(0x0010000),
rand(0x0010000),
rand(0x0010000),
rand(0x0010000),
rand(0x1000000),
rand(0x1000000),
]
"%04x%04x%04x%04x%04x%06x%06x" % values
end
end
# Marks this session as needing a new cookie.
#
# :api: private
def needs_new_cookie!
@_new_cookie = true
end
# Does session need new cookie?
#
# ==== Returns
# Boolean:: true if a new cookie is needed, false otherwise.
#
# :api: private
def needs_new_cookie?
@_new_cookie
end
module_function :rand_uuid, :needs_new_cookie!, :needs_new_cookie?
module RequestMixin
# Adds class methods to Merb::Request object.
# Sets up repository of session store types.
# Sets the session ID key and expiry values.
#
# :api: private
def self.included(base)
base.extend ClassMethods
# Keep track of all known session store types.
base.cattr_accessor :registered_session_types
base.registered_session_types = Dictionary.new
base.class_inheritable_accessor :_session_id_key, :_session_secret_key,
:_session_expiry, :_session_secure,
:_session_http_only, :_default_cookie_domain
base._session_id_key = Merb::Config[:session_id_key] || '_session_id'
base._session_expiry = Merb::Config[:session_expiry] || 0
base._session_secret_key = Merb::Config[:session_secret_key]
base._session_secure = Merb::Config[:session_secure] || false
base._session_http_only = Merb::Config[:session_http_only] || false
base._default_cookie_domain = Merb::Config[:default_cookie_domain]
end
module ClassMethods
# ==== Parameters
# name<~to_sym>:: Name of the session type to register.
# class_name<String>:: The corresponding class name.
#
# === Notres
# This is automatically called when Merb::SessionContainer is subclassed.
#
# :api: private
def register_session_type(name, class_name)
self.registered_session_types[name.to_sym] = class_name
end
end
# The default session store type.
#
# :api: private
def default_session_store
Merb::Config[:session_store] && Merb::Config[:session_store].to_sym
end
# ==== Returns
# Hash:: All active session stores by type.
#
# :api: private
def session_stores
@session_stores ||= {}
end
# Returns session container. Merb is able to handle multiple session
# stores, hence a parameter to pick it.
#
# ==== Parameters
# session_store<String>:: The type of session store to access,
# defaults to default_session_store.
#
# === Notes
# If no suitable session store type is given, it defaults to
# cookie-based sessions.
#
# ==== Returns
# SessionContainer::
# an instance of a session store extending Merb::SessionContainer.
#
# :api: public
def session(session_store = nil)
session_store ||= default_session_store
if class_name = self.class.registered_session_types[session_store]
session_stores[session_store] ||= Object.full_const_get(class_name).setup(self)
elsif fallback = self.class.registered_session_types.keys.first
Merb.logger.warn "Session store '#{session_store}' not found. Check your configuration in init file."
Merb.logger.warn "Falling back to #{fallback} session store."
session(fallback)
else
msg = "No session store set. Set it in init file like this: c[:session_store] = 'activerecord'"
Merb.logger.error!(msg)
raise NoSessionContainer, msg
end
end
# ==== Parameters
# new_session<Merb::SessionContainer>:: A session store instance.
#
# === Notes
# The session is assigned internally by its session_store_type key.
#
# :api: private
def session=(new_session)
if self.session?(new_session.class.session_store_type)
original_session_id = self.session(new_session.class.session_store_type).session_id
if new_session.session_id != original_session_id
set_session_id_cookie(new_session.session_id)
end
end
session_stores[new_session.class.session_store_type] = new_session
end
# Whether a session has been setup
#
# ==== Returns
# Boolean:: true if the session is part of the session stores configured.
#
# :api: private
def session?(session_store = nil)
(session_store ? [session_store] : session_stores).any? do |type, store|
store.is_a?(Merb::SessionContainer)
end
end
# Teardown and/or persist the current sessions.
#
# :api: private
def finalize_session
session_stores.each { |name, store| store.finalize(self) }
end
alias :finalize_sessions :finalize_session
# Assign default cookie values
#
# :api: private
def default_cookies
defaults = {}
if route && route.allow_fixation? && params.key?(_session_id_key)
Merb.logger.info("Fixated session id: #{_session_id_key}")
defaults[_session_id_key] = params[_session_id_key]
end
defaults
end
# Sets session cookie value.
#
# ==== Parameters
# value<String>:: The value of the session cookie; either the session id or the actual encoded data.
# options<Hash>:: Cookie options like domain, path and expired.
#
# :api: private
def set_session_cookie_value(value, options = {})
defaults = {}
defaults[:expires] = Time.now + _session_expiry if _session_expiry > 0
defaults[:domain] = _default_cookie_domain if _default_cookie_domain
defaults[:secure] = _session_secure
defaults[:http_only] = _session_http_only
cookies.set_cookie(_session_id_key, value, defaults.merge(options))
end
alias :set_session_id_cookie :set_session_cookie_value
# ==== Returns
# String:: The value of the session cookie; either the session id or the actual encoded data.
#
# :api: private
def session_cookie_value
cookies[_session_id_key]
end
alias :session_id :session_cookie_value
# Destroy the session cookie.
#
# :api: private
def destroy_session_cookie
cookies.delete(_session_id_key)
end
end
end
end
|