Sha256: 7e2e696224794d42472878e1263e45bdae15dd999edac0b68c84646f2eba844f

Contents?: true

Size: 1.59 KB

Versions: 13

Compression:

Stored size: 1.59 KB

Contents

# frozen_string_literal: true

require "digest"
require "base64"

##
# Used **specifically** for compatibility with Sidekiq's Web interface.
# Remove once we have real sessions or once Sidekiq's author decides they
# don't need cookie sessions to protect against CSRF.
#
class Rage::SidekiqSession
  KEY = Digest::SHA2.hexdigest(ENV["SECRET_KEY_BASE"] || File.read("Gemfile.lock") + File.read("config/routes.rb"))
  SESSION_KEY = "rage.sidekiq.session"

  def self.with_session(env)
    env["rack.session"] = session = self.new(env)
    response = yield

    if session.changed
      Rack::Utils.set_cookie_header!(
        response[1],
        SESSION_KEY,
        { path: env["SCRIPT_NAME"], httponly: true, same_site: true, value: session.dump }
      )
    end

    response
  end

  attr_reader :changed

  def initialize(env)
    @env = env
    session = Rack::Utils.parse_cookies(@env)[SESSION_KEY]
    @data = decode_session(session)
  end

  def [](key)
    @data[key]
  end

  def[]=(key, value)
    @changed = true
    @data[key] = value
  end

  def to_hash
    @data
  end

  def dump
    encoded_data = Marshal.dump(@data)
    signature = OpenSSL::HMAC.hexdigest("SHA256", KEY, encoded_data)

    Base64.urlsafe_encode64("#{encoded_data}--#{signature}")
  end

  private

  def decode_session(session)
    return {} unless session

    encoded_data, signature = Base64.urlsafe_decode64(session).split("--")
    ref_signature = OpenSSL::HMAC.hexdigest("SHA256", KEY, encoded_data)

    if Rack::Utils.secure_compare(signature, ref_signature)
      Marshal.load(encoded_data)
    else
      {}
    end
  end
end

Version data entries

13 entries across 13 versions & 1 rubygems

Version Path
rage-rb-1.6.0 lib/rage/sidekiq_session.rb
rage-rb-1.4.0 lib/rage/sidekiq_session.rb
rage-rb-1.3.0 lib/rage/sidekiq_session.rb
rage-rb-1.2.2 lib/rage/sidekiq_session.rb
rage-rb-1.2.1 lib/rage/sidekiq_session.rb
rage-rb-1.2.0 lib/rage/sidekiq_session.rb
rage-rb-1.1.0 lib/rage/sidekiq_session.rb
rage-rb-1.0.0 lib/rage/sidekiq_session.rb
rage-rb-0.7.0 lib/rage/sidekiq_session.rb
rage-rb-0.6.0 lib/rage/sidekiq_session.rb
rage-rb-0.5.2 lib/rage/sidekiq_session.rb
rage-rb-0.5.1 lib/rage/sidekiq_session.rb
rage-rb-0.5.0 lib/rage/sidekiq_session.rb