Sha256: 156f906c24d4989c7bc72b42f368503320dc272a67e1257f2b96bb272a4c6a96

Contents?: true

Size: 1.71 KB

Versions: 2

Compression:

Stored size: 1.71 KB

Contents

# frozen_string_literal: true

require 'securerandom'
require 'openssl'
require 'logger'

module BigSession
  # This middleware reads BigSession headers from the request and sets/creates a
  # SessionId usable by the rest of the app
  class RackMiddleware
    class << self
      def activate(header_secret = nil)
        Rails.application.config.middleware.use ::BigSession::RackMiddleware, header_secret
      end
    end

    def initialize(app, header_secret = nil)
      @app = app
      @header_secret = header_secret
    end

    def call(env)
      session_id = retrieve_or_generate_session_id(env)
      env['rack.session'][::BigSession::RAILS_SESSION_BIG_SESSION_ID_KEY] = session_id
      SessionId.with_session_id(session_id) do
        @app.call(env)
      end
    end

    private

    def retrieve_or_generate_session_id(env)
      header_session_id, header_signature = env.values_at(
        'HTTP_' + ::BigSession::BIG_SESSION_HEADER_NAME.upcase.gsub(/-/, '_'),
        'HTTP_' + ::BigSession::BIG_SESSION_SIGNATURE_HEADER_NAME
          .upcase.gsub(/-/, '_')
      )

      return validate_header_session_id(header_session_id, header_signature) \
        if header_session_id

      SessionId.current ||
        env['rack.session'][::BigSession::RAILS_SESSION_BIG_SESSION_ID_KEY] ||
        SessionId.new_session_id
    end

    def validate_header_session_id(header_session_id, header_signature)
      return header_session_id unless @header_secret

      digest = OpenSSL::HMAC.hexdigest('sha256', @header_secret, header_session_id)
      return header_session_id if digest == header_signature

      logger = Logger.new(STDOUT)
      logger.warn('Failed to validate big session header signature.')
      nil
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
big_session-0.1.2 lib/big_session/rack_middleware.rb
big_session-0.1.1 lib/big_session/rack_middleware.rb