# Copyright (c) 2015 Sqreen. All Rights Reserved. # Please refer to our terms for more information: https://www.sqreen.com/terms.html module Sqreen module Dependency module Sinatra module_function def required? Sqreen::Dependency.const_exist?('Sinatra::Base') end def insert_sqreen_middlewares(builder, *args, &block) Sqreen.log.debug { 'Inserting Sqreen middlewares for Sinatra' } insert_middleware(builder, Sqreen::ErrorHandlingMiddleware, args, block) do |p, u| if middlewares(builder).include?(::Sinatra::ShowExceptions) Sqreen.log.warn('Sinatra :show_exceptions detected: Sinatra exception handling may prevent the Sqreen error page to display on attacks.') end if (i = middlewares(builder).index(::Rack::Head)) u.insert(i, p) elsif (i = middlewares(builder).index(::Rack::MethodOverride)) u.insert(i + 1, p) elsif (i = middlewares(builder).index(::Sinatra::ExtendedRack)) u.insert(i + 1, p) else u.insert(0, p) end end insert_middleware(builder, Sqreen::Middleware, args, block) do |p, u| if (i = middlewares(builder).index(::Sinatra::ExtendedRack)) u.insert(i, p) else u.insert(0, p) end end insert_middleware(builder, Sqreen::SinatraMiddleware, args, block) do |p, u| if ::Sqreen::Dependency.const_exist?('Rack::PostBodyContentTypeParser') && (i = middlewares(builder).index(::Rack::PostBodyContentTypeParser)) u.insert(i + 1, p) elsif (i = middlewares(builder).index(::Rack::Protection)) u.insert(i + 1, p) else u.append(p) end end end def wrap_middleware(middleware, *args, &block) proc { |app| middleware.new(app, *args, &block) } end def insert_middleware(builder, middleware, args, block) use = builder.instance_variable_get('@use') wrapped = wrap_middleware(middleware, *args, &block) catch(:skip) do throw(:skip) if middlewares(builder).include?(middleware) yield(wrapped, use) end end def inspect_middlewares(builder) Sqreen.log.debug do "Middlewares: " << middlewares(builder).map(&:inspect).inspect end end def middlewares(builder) builder.instance_variable_get(:@use).map do |p| unless p.respond_to?(:binding) && p.binding.local_variable_defined?(:middleware) next :unknown end p.binding.local_variable_get(:middleware) end end end end end