Sha256: 46d30dd5f0eb1e1c186b761febd1a957d16671cd6e66054f6905cbfc1350687f

Contents?: true

Size: 1.74 KB

Versions: 1

Compression:

Stored size: 1.74 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)
      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(/-/, '_')
      )

      if header_session_id
        env['rack.session'][::BigSession::RAILS_SESSION_BIG_SESSION_ID_KEY] =
          if @header_secret
            validate_header_session_id(header_session_id, header_signature)
          else
            header_session_id
          end

        SessionId.set(env['rack.session'][::BigSession::RAILS_SESSION_BIG_SESSION_ID_KEY])
      else
        SessionId.set(env['rack.session'][::BigSession::RAILS_SESSION_BIG_SESSION_ID_KEY]) unless SessionId.current
        env['rack.session'][::BigSession::RAILS_SESSION_BIG_SESSION_ID_KEY] = SessionId.current
      end

      @app.call(env)
    end

    private

    def validate_header_session_id(header_session_id, header_signature)
      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

1 entries across 1 versions & 1 rubygems

Version Path
big_session-0.1.0 lib/big_session/rack_middleware.rb