Module: Datadog::AppSec::Contrib::Rails::Patcher
- Defined in:
- lib/datadog/appsec/contrib/rails/patcher.rb
Overview
Patcher for AppSec on Rails
Constant Summary collapse
- GUARD_ACTION_CONTROLLER_ONCE_PER_APP =
Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
- BEFORE_INITIALIZE_ONLY_ONCE_PER_APP =
Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
- AFTER_INITIALIZE_ONLY_ONCE_PER_APP =
Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
Class Method Summary collapse
- .add_middleware(app) ⇒ Object
- .after_initialize(app) ⇒ Object
- .before_initialize(app) ⇒ Object
- .include_middleware?(middleware, app) ⇒ Boolean
- .inspect_middlewares(app) ⇒ Object
- .patch ⇒ Object
- .patch_action_controller ⇒ Object
- .patch_after_initialize ⇒ Object
- .patch_before_initialize ⇒ Object
- .patched? ⇒ Boolean
- .setup_security ⇒ Object
- .target_version ⇒ Object
Class Method Details
.add_middleware(app) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 61 def add_middleware(app) # Add trace middleware if include_middleware?(Datadog::Tracing::Contrib::Rack::TraceMiddleware, app) app.middleware.insert_after( Datadog::Tracing::Contrib::Rack::TraceMiddleware, Datadog::AppSec::Contrib::Rack::RequestMiddleware ) else app.middleware.insert_before(0, Datadog::AppSec::Contrib::Rack::RequestMiddleware) end end |
.after_initialize(app) ⇒ Object
117 118 119 120 121 122 123 124 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 117 def after_initialize(app) AFTER_INITIALIZE_ONLY_ONCE_PER_APP[app].run do # Finish configuring the tracer after the application is initialized. # We need to wait for some things, like application name, middleware stack, etc. setup_security inspect_middlewares(app) end end |
.before_initialize(app) ⇒ Object
51 52 53 54 55 56 57 58 59 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 51 def before_initialize(app) BEFORE_INITIALIZE_ONLY_ONCE_PER_APP[app].run do # Middleware must be added before the application is initialized. # Otherwise the middleware stack will be frozen. add_middleware(app) if Datadog.configuration.tracing[:rails][:middleware] ::ActionController::Metal.prepend(Patches::ProcessActionPatch) end end |
.include_middleware?(middleware, app) ⇒ Boolean
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 73 def include_middleware?(middleware, app) found = false # find tracer middleware reference in Rails::Configuration::MiddlewareStackProxy app.middleware.instance_variable_get(:@operations).each do |operation| args = case operation when Array # rails 5.2 _op, args = operation args when Proc if operation.binding.local_variables.include?(:args) # rails 6.0, 6.1 operation.binding.local_variable_get(:args) else # rails 7.0 uses ... to pass args args_getter = Class.new do def method_missing(_op, *args) # standard:disable Style/MissingRespondToMissing args end end.new operation.call(args_getter) end else # unknown, pass through [] end found = true if args.include?(middleware) end found end |
.inspect_middlewares(app) ⇒ Object
107 108 109 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 107 def inspect_middlewares(app) Datadog.logger.debug { +'Rails middlewares: ' << app.middleware.map(&:inspect).inspect } end |
.patch ⇒ Object
36 37 38 39 40 41 42 43 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 36 def patch Gateway::Watcher.watch patch_before_initialize patch_after_initialize patch_action_controller Patcher.instance_variable_set(:@patched, true) end |
.patch_action_controller ⇒ Object
126 127 128 129 130 131 132 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 126 def patch_action_controller ::ActiveSupport.on_load(:action_controller) do GUARD_ACTION_CONTROLLER_ONCE_PER_APP[self].run do ::ActionController::Base.prepend(Patches::RenderToBodyPatch) end end end |
.patch_after_initialize ⇒ Object
111 112 113 114 115 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 111 def patch_after_initialize ::ActiveSupport.on_load(:after_initialize) do Datadog::AppSec::Contrib::Rails::Patcher.after_initialize(self) end end |
.patch_before_initialize ⇒ Object
45 46 47 48 49 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 45 def patch_before_initialize ::ActiveSupport.on_load(:before_initialize) do Datadog::AppSec::Contrib::Rails::Patcher.before_initialize(self) end end |
.patched? ⇒ Boolean
28 29 30 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 28 def patched? Patcher.instance_variable_get(:@patched) end |
.setup_security ⇒ Object
134 135 136 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 134 def setup_security Datadog::AppSec::Contrib::Rails::Framework.setup end |
.target_version ⇒ Object
32 33 34 |
# File 'lib/datadog/appsec/contrib/rails/patcher.rb', line 32 def target_version Integration.version end |