module Roda::RodaPlugins::Sessions

def self.configure(app, opts=OPTS)

Configure the plugin, see Sessions for details on options.
def self.configure(app, opts=OPTS)
  plugin_opts = opts
  opts = (app.opts[:sessions] || DEFAULT_OPTIONS).merge(opts)
  co = opts[:cookie_options] = DEFAULT_COOKIE_OPTIONS.merge(opts[:cookie_options] || OPTS).freeze
  opts[:parser] ||= app.opts[:json_parser] || JSON.method(:parse)
  opts[:serializer] ||= app.opts[:json_serializer] || :to_json.to_proc
  if opts[:upgrade_from_rack_session_cookie_secret]
    opts[:upgrade_from_rack_session_cookie_key] ||= 'rack.session'
    rsco = opts[:upgrade_from_rack_session_cookie_options] = Hash[opts[:upgrade_from_rack_session_cookie_options] || OPTS]
    rsco[:path] ||= co[:path]
    rsco[:domain] ||= co[:domain]
  end
  opts[:cipher_secret], opts[:hmac_secret] = split_secret(:secret, opts[:secret])
  opts[:old_cipher_secret], opts[:old_hmac_secret] = (split_secret(:old_secret, opts[:old_secret]) if opts[:old_secret])
  case opts[:pad_size]
  when nil
    # no changes
  when Integer
    raise RodaError, "invalid :pad_size: #{opts[:pad_size]}, must be >=2, < 4096" unless opts[:pad_size] >= 2 && opts[:pad_size] < 4096
  else
    raise RodaError, "invalid :pad_size option: #{opts[:pad_size].inspect}, must be Integer or nil"
  end
  
  app.opts[:sessions] = opts.freeze
  app.opts[:sessions_convert_symbols] = true unless app.opts.has_key?(:sessions_convert_symbols)
end

def self.split_secret(name, secret)

Split given secret into a cipher secret and an hmac secret.
def self.split_secret(name, secret)
  raise RodaError, "sessions plugin :#{name} option must be a String" unless secret.is_a?(String)
  raise RodaError, "invalid sessions plugin :#{name} option length: #{secret.bytesize}, must be >=64" unless secret.bytesize >= 64
  hmac_secret = secret = secret.dup.force_encoding('BINARY')
  cipher_secret = secret.slice!(0, 32)
  [cipher_secret.freeze, hmac_secret.freeze]
end