diff --git a/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb b/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb index 68a1c5acf11..4520e05b111 100644 --- a/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +++ b/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb @@ -2,8 +2,8 @@ require 'json' require_relative '../../../instrumentation/gateway' +require_relative '../../../reactive/engine' require_relative '../reactive/multiplex' -require_relative '../../../reactive/operation' module Datadog module AppSec @@ -24,26 +24,24 @@ def watch_multiplex(gateway = Instrumentation.gateway) gateway.watch('graphql.multiplex', :appsec) do |stack, gateway_multiplex| block = false event = nil - scope = AppSec::Scope.active_scope + engine = AppSec::Reactive::Engine.new if scope - AppSec::Reactive::Operation.new('graphql.multiplex') do |op| - GraphQL::Reactive::Multiplex.subscribe(op, scope.processor_context) do |result| - event = { - waf_result: result, - trace: scope.trace, - span: scope.service_entry_span, - multiplex: gateway_multiplex, - actions: result.actions - } - - Datadog::AppSec::Event.tag_and_keep!(scope, result) - scope.processor_context.events << event - end + GraphQL::Reactive::Multiplex.subscribe(engine, scope.processor_context) do |result| + event = { + waf_result: result, + trace: scope.trace, + span: scope.service_entry_span, + multiplex: gateway_multiplex, + actions: result.actions + } - block = GraphQL::Reactive::Multiplex.publish(op, gateway_multiplex) + Datadog::AppSec::Event.tag_and_keep!(scope, result) + scope.processor_context.events << event end + + block = GraphQL::Reactive::Multiplex.publish(engine, gateway_multiplex) end next [nil, [[:block, event]]] if block diff --git a/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb b/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb index 4d08c60b861..cfbf31dc1b8 100644 --- a/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +++ b/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb @@ -12,16 +12,16 @@ module Multiplex ].freeze private_constant :ADDRESSES - def self.publish(op, gateway_multiplex) + def self.publish(engine, gateway_multiplex) catch(:block) do - op.publish('graphql.server.all_resolvers', gateway_multiplex.arguments) + engine.publish('graphql.server.all_resolvers', gateway_multiplex.arguments) nil end end - def self.subscribe(op, waf_context) - op.subscribe(*ADDRESSES) do |*values| + def self.subscribe(engine, waf_context) + engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } arguments = values[0] diff --git a/lib/datadog/appsec/contrib/rack/gateway/watcher.rb b/lib/datadog/appsec/contrib/rack/gateway/watcher.rb index a66387329c3..fb7e095f834 100644 --- a/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +++ b/lib/datadog/appsec/contrib/rack/gateway/watcher.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require_relative '../../../instrumentation/gateway' -require_relative '../../../reactive/operation' +require_relative '../../../reactive/engine' require_relative '../reactive/request' require_relative '../reactive/request_body' require_relative '../reactive/response' @@ -25,32 +25,29 @@ def watch def watch_request(gateway = Instrumentation.gateway) gateway.watch('rack.request', :appsec) do |stack, gateway_request| - block = false event = nil scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY] - - AppSec::Reactive::Operation.new('rack.request') do |op| - Rack::Reactive::Request.subscribe(op, scope.processor_context) do |result| - if result.status == :match - # TODO: should this hash be an Event instance instead? - event = { - waf_result: result, - trace: scope.trace, - span: scope.service_entry_span, - request: gateway_request, - actions: result.actions - } - - # We want to keep the trace in case of security event - scope.trace.keep! if scope.trace - Datadog::AppSec::Event.tag_and_keep!(scope, result) - scope.processor_context.events << event - end + engine = AppSec::Reactive::Engine.new + + Rack::Reactive::Request.subscribe(engine, scope.processor_context) do |result| + if result.status == :match + # TODO: should this hash be an Event instance instead? + event = { + waf_result: result, + trace: scope.trace, + span: scope.service_entry_span, + request: gateway_request, + actions: result.actions + } + + # We want to keep the trace in case of security event + scope.trace.keep! if scope.trace + Datadog::AppSec::Event.tag_and_keep!(scope, result) + scope.processor_context.events << event end - - block = Rack::Reactive::Request.publish(op, gateway_request) end + block = Rack::Reactive::Request.publish(engine, gateway_request) next [nil, [[:block, event]]] if block ret, res = stack.call(gateway_request.request) @@ -66,33 +63,29 @@ def watch_request(gateway = Instrumentation.gateway) def watch_response(gateway = Instrumentation.gateway) gateway.watch('rack.response', :appsec) do |stack, gateway_response| - block = false - event = nil scope = gateway_response.scope - - AppSec::Reactive::Operation.new('rack.response') do |op| - Rack::Reactive::Response.subscribe(op, scope.processor_context) do |result| - if result.status == :match - # TODO: should this hash be an Event instance instead? - event = { - waf_result: result, - trace: scope.trace, - span: scope.service_entry_span, - response: gateway_response, - actions: result.actions - } - - # We want to keep the trace in case of security event - scope.trace.keep! if scope.trace - Datadog::AppSec::Event.tag_and_keep!(scope, result) - scope.processor_context.events << event - end + engine = AppSec::Reactive::Engine.new + + Rack::Reactive::Response.subscribe(engine, scope.processor_context) do |result| + if result.status == :match + # TODO: should this hash be an Event instance instead? + event = { + waf_result: result, + trace: scope.trace, + span: scope.service_entry_span, + response: gateway_response, + actions: result.actions + } + + # We want to keep the trace in case of security event + scope.trace.keep! if scope.trace + Datadog::AppSec::Event.tag_and_keep!(scope, result) + scope.processor_context.events << event end - - block = Rack::Reactive::Response.publish(op, gateway_response) end + block = Rack::Reactive::Response.publish(engine, gateway_response) next [nil, [[:block, event]]] if block ret, res = stack.call(gateway_response.response) @@ -108,33 +101,29 @@ def watch_response(gateway = Instrumentation.gateway) def watch_request_body(gateway = Instrumentation.gateway) gateway.watch('rack.request.body', :appsec) do |stack, gateway_request| - block = false - event = nil scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY] - - AppSec::Reactive::Operation.new('rack.request.body') do |op| - Rack::Reactive::RequestBody.subscribe(op, scope.processor_context) do |result| - if result.status == :match - # TODO: should this hash be an Event instance instead? - event = { - waf_result: result, - trace: scope.trace, - span: scope.service_entry_span, - request: gateway_request, - actions: result.actions - } - - # We want to keep the trace in case of security event - scope.trace.keep! if scope.trace - Datadog::AppSec::Event.tag_and_keep!(scope, result) - scope.processor_context.events << event - end + engine = AppSec::Reactive::Engine.new + + Rack::Reactive::RequestBody.subscribe(engine, scope.processor_context) do |result| + if result.status == :match + # TODO: should this hash be an Event instance instead? + event = { + waf_result: result, + trace: scope.trace, + span: scope.service_entry_span, + request: gateway_request, + actions: result.actions + } + + # We want to keep the trace in case of security event + scope.trace.keep! if scope.trace + Datadog::AppSec::Event.tag_and_keep!(scope, result) + scope.processor_context.events << event end - - block = Rack::Reactive::RequestBody.publish(op, gateway_request) end + block = Rack::Reactive::RequestBody.publish(engine, gateway_request) next [nil, [[:block, event]]] if block ret, res = stack.call(gateway_request.request) diff --git a/lib/datadog/appsec/contrib/rack/reactive/request.rb b/lib/datadog/appsec/contrib/rack/reactive/request.rb index 4f88a8aa989..78074268af6 100644 --- a/lib/datadog/appsec/contrib/rack/reactive/request.rb +++ b/lib/datadog/appsec/contrib/rack/reactive/request.rb @@ -17,21 +17,21 @@ module Request ].freeze private_constant :ADDRESSES - def self.publish(op, gateway_request) + def self.publish(engine, gateway_request) catch(:block) do - op.publish('request.query', gateway_request.query) - op.publish('request.headers', gateway_request.headers) - op.publish('request.uri.raw', gateway_request.fullpath) - op.publish('request.cookies', gateway_request.cookies) - op.publish('request.client_ip', gateway_request.client_ip) - op.publish('server.request.method', gateway_request.method) + engine.publish('request.query', gateway_request.query) + engine.publish('request.headers', gateway_request.headers) + engine.publish('request.uri.raw', gateway_request.fullpath) + engine.publish('request.cookies', gateway_request.cookies) + engine.publish('request.client_ip', gateway_request.client_ip) + engine.publish('server.request.method', gateway_request.method) nil end end - def self.subscribe(op, waf_context) - op.subscribe(*ADDRESSES) do |*values| + def self.subscribe(engine, waf_context) + engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } headers = values[0] diff --git a/lib/datadog/appsec/contrib/rack/reactive/request_body.rb b/lib/datadog/appsec/contrib/rack/reactive/request_body.rb index 1cf98518077..57395ac83b8 100644 --- a/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +++ b/lib/datadog/appsec/contrib/rack/reactive/request_body.rb @@ -12,17 +12,17 @@ module RequestBody ].freeze private_constant :ADDRESSES - def self.publish(op, gateway_request) + def self.publish(engine, gateway_request) catch(:block) do # params have been parsed from the request body - op.publish('request.body', gateway_request.form_hash) + engine.publish('request.body', gateway_request.form_hash) nil end end - def self.subscribe(op, waf_context) - op.subscribe(*ADDRESSES) do |*values| + def self.subscribe(engine, waf_context) + engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } body = values[0] diff --git a/lib/datadog/appsec/contrib/rack/reactive/response.rb b/lib/datadog/appsec/contrib/rack/reactive/response.rb index 850e3c022f8..8c0cd706d26 100644 --- a/lib/datadog/appsec/contrib/rack/reactive/response.rb +++ b/lib/datadog/appsec/contrib/rack/reactive/response.rb @@ -13,17 +13,17 @@ module Response ].freeze private_constant :ADDRESSES - def self.publish(op, gateway_response) + def self.publish(engine, gateway_response) catch(:block) do - op.publish('response.status', gateway_response.status) - op.publish('response.headers', gateway_response.headers) + engine.publish('response.status', gateway_response.status) + engine.publish('response.headers', gateway_response.headers) nil end end - def self.subscribe(op, waf_context) - op.subscribe(*ADDRESSES) do |*values| + def self.subscribe(engine, waf_context) + engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } response_status = values[0] diff --git a/lib/datadog/appsec/contrib/rails/gateway/watcher.rb b/lib/datadog/appsec/contrib/rails/gateway/watcher.rb index ab1bfe612ec..6fb24027f61 100644 --- a/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +++ b/lib/datadog/appsec/contrib/rails/gateway/watcher.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require_relative '../../../instrumentation/gateway' -require_relative '../../../reactive/operation' +require_relative '../../../reactive/engine' require_relative '../reactive/action' require_relative '../../../event' @@ -21,33 +21,29 @@ def watch def watch_request_action(gateway = Instrumentation.gateway) gateway.watch('rails.request.action', :appsec) do |stack, gateway_request| - block = false - event = nil scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY] + engine = AppSec::Reactive::Engine.new - AppSec::Reactive::Operation.new('rails.request.action') do |op| - Rails::Reactive::Action.subscribe(op, scope.processor_context) do |result| - if result.status == :match - # TODO: should this hash be an Event instance instead? - event = { - waf_result: result, - trace: scope.trace, - span: scope.service_entry_span, - request: gateway_request, - actions: result.actions - } + Rails::Reactive::Action.subscribe(engine, scope.processor_context) do |result| + if result.status == :match + # TODO: should this hash be an Event instance instead? + event = { + waf_result: result, + trace: scope.trace, + span: scope.service_entry_span, + request: gateway_request, + actions: result.actions + } - # We want to keep the trace in case of security event - scope.trace.keep! if scope.trace - Datadog::AppSec::Event.tag_and_keep!(scope, result) - scope.processor_context.events << event - end + # We want to keep the trace in case of security event + scope.trace.keep! if scope.trace + Datadog::AppSec::Event.tag_and_keep!(scope, result) + scope.processor_context.events << event end - - block = Rails::Reactive::Action.publish(op, gateway_request) end + block = Rails::Reactive::Action.publish(engine, gateway_request) next [nil, [[:block, event]]] if block ret, res = stack.call(gateway_request.request) diff --git a/lib/datadog/appsec/contrib/rails/reactive/action.rb b/lib/datadog/appsec/contrib/rails/reactive/action.rb index eb28c9983c0..9dbe8697e51 100644 --- a/lib/datadog/appsec/contrib/rails/reactive/action.rb +++ b/lib/datadog/appsec/contrib/rails/reactive/action.rb @@ -15,18 +15,18 @@ module Action ].freeze private_constant :ADDRESSES - def self.publish(op, gateway_request) + def self.publish(engine, gateway_request) catch(:block) do # params have been parsed from the request body - op.publish('rails.request.body', gateway_request.parsed_body) - op.publish('rails.request.route_params', gateway_request.route_params) + engine.publish('rails.request.body', gateway_request.parsed_body) + engine.publish('rails.request.route_params', gateway_request.route_params) nil end end - def self.subscribe(op, waf_context) - op.subscribe(*ADDRESSES) do |*values| + def self.subscribe(engine, waf_context) + engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } body = values[0] path_params = values[1] diff --git a/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb b/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb index 91383478c29..442d829cd34 100644 --- a/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +++ b/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require_relative '../../../instrumentation/gateway' -require_relative '../../../reactive/operation' +require_relative '../../../reactive/engine' require_relative '../../rack/reactive/request_body' require_relative '../reactive/routed' require_relative '../../../event' @@ -23,33 +23,29 @@ def watch def watch_request_dispatch(gateway = Instrumentation.gateway) gateway.watch('sinatra.request.dispatch', :appsec) do |stack, gateway_request| - block = false - event = nil scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY] - - AppSec::Reactive::Operation.new('sinatra.request.dispatch') do |op| - Rack::Reactive::RequestBody.subscribe(op, scope.processor_context) do |result| - if result.status == :match - # TODO: should this hash be an Event instance instead? - event = { - waf_result: result, - trace: scope.trace, - span: scope.service_entry_span, - request: gateway_request, - actions: result.actions - } - - # We want to keep the trace in case of security event - scope.trace.keep! if scope.trace - Datadog::AppSec::Event.tag_and_keep!(scope, result) - scope.processor_context.events << event - end + engine = AppSec::Reactive::Engine.new + + Rack::Reactive::RequestBody.subscribe(engine, scope.processor_context) do |result| + if result.status == :match + # TODO: should this hash be an Event instance instead? + event = { + waf_result: result, + trace: scope.trace, + span: scope.service_entry_span, + request: gateway_request, + actions: result.actions + } + + # We want to keep the trace in case of security event + scope.trace.keep! if scope.trace + Datadog::AppSec::Event.tag_and_keep!(scope, result) + scope.processor_context.events << event end - - block = Rack::Reactive::RequestBody.publish(op, gateway_request) end + block = Rack::Reactive::RequestBody.publish(engine, gateway_request) next [nil, [[:block, event]]] if block ret, res = stack.call(gateway_request.request) @@ -65,33 +61,29 @@ def watch_request_dispatch(gateway = Instrumentation.gateway) def watch_request_routed(gateway = Instrumentation.gateway) gateway.watch('sinatra.request.routed', :appsec) do |stack, (gateway_request, gateway_route_params)| - block = false - event = nil scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY] - - AppSec::Reactive::Operation.new('sinatra.request.routed') do |op| - Sinatra::Reactive::Routed.subscribe(op, scope.processor_context) do |result| - if result.status == :match - # TODO: should this hash be an Event instance instead? - event = { - waf_result: result, - trace: scope.trace, - span: scope.service_entry_span, - request: gateway_request, - actions: result.actions - } - - # We want to keep the trace in case of security event - scope.trace.keep! if scope.trace - Datadog::AppSec::Event.tag_and_keep!(scope, result) - scope.processor_context.events << event - end + engine = AppSec::Reactive::Engine.new + + Sinatra::Reactive::Routed.subscribe(engine, scope.processor_context) do |result| + if result.status == :match + # TODO: should this hash be an Event instance instead? + event = { + waf_result: result, + trace: scope.trace, + span: scope.service_entry_span, + request: gateway_request, + actions: result.actions + } + + # We want to keep the trace in case of security event + scope.trace.keep! if scope.trace + Datadog::AppSec::Event.tag_and_keep!(scope, result) + scope.processor_context.events << event end - - block = Sinatra::Reactive::Routed.publish(op, [gateway_request, gateway_route_params]) end + block = Sinatra::Reactive::Routed.publish(engine, [gateway_request, gateway_route_params]) next [nil, [[:block, event]]] if block ret, res = stack.call(gateway_request.request) diff --git a/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb b/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb index 60e0f7e6301..e34dfb4ccb3 100644 --- a/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +++ b/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb @@ -12,18 +12,18 @@ module Routed ].freeze private_constant :ADDRESSES - def self.publish(op, data) + def self.publish(engine, data) _request, route_params = data catch(:block) do - op.publish('sinatra.request.route_params', route_params.params) + engine.publish('sinatra.request.route_params', route_params.params) nil end end - def self.subscribe(op, waf_context) - op.subscribe(*ADDRESSES) do |*values| + def self.subscribe(engine, waf_context) + engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } path_params = values[0] diff --git a/lib/datadog/appsec/monitor/gateway/watcher.rb b/lib/datadog/appsec/monitor/gateway/watcher.rb index 74fc4d3fd60..e8beb102e52 100644 --- a/lib/datadog/appsec/monitor/gateway/watcher.rb +++ b/lib/datadog/appsec/monitor/gateway/watcher.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require_relative '../../instrumentation/gateway' -require_relative '../../reactive/operation' +require_relative '../../reactive/engine' require_relative '../reactive/set_user' module Datadog @@ -19,32 +19,29 @@ def watch def watch_user_id(gateway = Instrumentation.gateway) gateway.watch('identity.set_user', :appsec) do |stack, user| - block = false event = nil scope = Datadog::AppSec.active_scope - - AppSec::Reactive::Operation.new('identity.set_user') do |op| - Monitor::Reactive::SetUser.subscribe(op, scope.processor_context) do |result| - if result.status == :match - # TODO: should this hash be an Event instance instead? - event = { - waf_result: result, - trace: scope.trace, - span: scope.service_entry_span, - user: user, - actions: result.actions - } - - # We want to keep the trace in case of security event - scope.trace.keep! if scope.trace - Datadog::AppSec::Event.tag_and_keep!(scope, result) - scope.processor_context.events << event - end + engine = AppSec::Reactive::Engine.new + + Monitor::Reactive::SetUser.subscribe(engine, scope.processor_context) do |result| + if result.status == :match + # TODO: should this hash be an Event instance instead? + event = { + waf_result: result, + trace: scope.trace, + span: scope.service_entry_span, + user: user, + actions: result.actions + } + + # We want to keep the trace in case of security event + scope.trace.keep! if scope.trace + Datadog::AppSec::Event.tag_and_keep!(scope, result) + scope.processor_context.events << event end - - block = Monitor::Reactive::SetUser.publish(op, user) end + block = Monitor::Reactive::SetUser.publish(engine, user) throw(Datadog::AppSec::Ext::INTERRUPT, [nil, [[:block, event]]]) if block ret, res = stack.call(user) diff --git a/lib/datadog/appsec/monitor/reactive/set_user.rb b/lib/datadog/appsec/monitor/reactive/set_user.rb index f3c43883bd5..ea3128c6031 100644 --- a/lib/datadog/appsec/monitor/reactive/set_user.rb +++ b/lib/datadog/appsec/monitor/reactive/set_user.rb @@ -11,16 +11,16 @@ module SetUser ].freeze private_constant :ADDRESSES - def self.publish(op, user) + def self.publish(engine, user) catch(:block) do - op.publish('usr.id', user.id) + engine.publish('usr.id', user.id) nil end end - def self.subscribe(op, waf_context) - op.subscribe(*ADDRESSES) do |*values| + def self.subscribe(engine, waf_context) + engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } user_id = values[0] diff --git a/lib/datadog/appsec/reactive/operation.rb b/lib/datadog/appsec/reactive/operation.rb deleted file mode 100644 index f7696cdbcec..00000000000 --- a/lib/datadog/appsec/reactive/operation.rb +++ /dev/null @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -require_relative 'engine' - -module Datadog - module AppSec - module Reactive - # Reactive Engine nested operation tracking - class Operation - attr_reader :reactive, - :parent, - :name - - def initialize(name, parent = nil, reactive_engine = nil) - Datadog.logger.debug { "operation: #{name} initialize" } - @name = name - @parent = parent - @reactive = select_reactive_engine(reactive_engine, parent) - - # TODO: concurrent store - # TODO: constant - Thread.current[:datadog_security_active_operation] = self - - yield self if block_given? - ensure - finalize - end - - # TODO: use structs instead of an arg splat - def subscribe(*addresses, &block) - reactive.subscribe(*addresses, &block) - end - - def publish(address, data) - reactive.publish(address, data) - end - - def finalize - Datadog.logger.debug { "operation: #{name} finalize" } - Thread.current[:datadog_security_active_operation] = parent - end - - private - - def select_reactive_engine(reactive, parent) - return reactive if reactive - - return parent.reactive unless parent.nil? - - Reactive::Engine.new - end - - class << self - def active - Thread.current[:datadog_security_active_operation] - end - - private - - # For testing only. - def reset! - Thread.current[:datadog_security_active_operation] = nil - end - end - end - end - end -end diff --git a/sig/datadog/appsec/contrib/graphql/reactive/multiplex.rbs b/sig/datadog/appsec/contrib/graphql/reactive/multiplex.rbs index 7095e94da50..d0cbad649d8 100644 --- a/sig/datadog/appsec/contrib/graphql/reactive/multiplex.rbs +++ b/sig/datadog/appsec/contrib/graphql/reactive/multiplex.rbs @@ -4,11 +4,11 @@ module Datadog module GraphQL module Reactive module Multiplex - ADDRESSES: ::Array[String] + ADDRESSES: ::Array[::String] - def self.publish: (Datadog::AppSec::Reactive::Operation op, Datadog::AppSec::Contrib::GraphQL::Gateway::Multiplex gateway_multiplex) -> boolish + def self.publish: (AppSec::Reactive::Engine engine, AppSec::Contrib::GraphQL::Gateway::Multiplex gateway_multiplex) -> boolish - def self.subscribe: (Datadog::AppSec::Reactive::Operation op, Datadog::AppSec::Contrib::GraphQL::Gateway::Multiplex waf_context) -> void + def self.subscribe: (AppSec::Reactive::Engine engine, AppSec::Contrib::GraphQL::Gateway::Multiplex waf_context) -> void end end end diff --git a/sig/datadog/appsec/contrib/rack/reactive/request.rbs b/sig/datadog/appsec/contrib/rack/reactive/request.rbs index 7163eff15e3..d55f00a447a 100644 --- a/sig/datadog/appsec/contrib/rack/reactive/request.rbs +++ b/sig/datadog/appsec/contrib/rack/reactive/request.rbs @@ -6,9 +6,9 @@ module Datadog module Request ADDRESSES: ::Array[::String] - def self.publish: (untyped op, Datadog::AppSec::Contrib::Rack::Gateway::Request request) -> untyped + def self.publish: (AppSec::Reactive::Engine engine, AppSec::Contrib::Rack::Gateway::Request request) -> untyped - def self.subscribe: (untyped op, untyped waf_context) { (untyped) -> untyped } -> untyped + def self.subscribe: (AppSec::Reactive::Engine engine, untyped waf_context) { (untyped) -> untyped } -> untyped end end end diff --git a/sig/datadog/appsec/contrib/rack/reactive/request_body.rbs b/sig/datadog/appsec/contrib/rack/reactive/request_body.rbs index 3d04cb7c5ed..7747040eb6a 100644 --- a/sig/datadog/appsec/contrib/rack/reactive/request_body.rbs +++ b/sig/datadog/appsec/contrib/rack/reactive/request_body.rbs @@ -6,9 +6,9 @@ module Datadog module RequestBody ADDRESSES: ::Array[::String] - def self.publish: (untyped op, Datadog::AppSec::Contrib::Rack::Gateway::Response request) -> untyped + def self.publish: (AppSec::Reactive::Engine engine, AppSec::Contrib::Rack::Gateway::Response request) -> untyped - def self.subscribe: (untyped op, untyped waf_context) { (untyped) -> untyped } -> untyped + def self.subscribe: (AppSec::Reactive::Engine engine, untyped waf_context) { (untyped) -> untyped } -> untyped end end end diff --git a/sig/datadog/appsec/contrib/rack/reactive/response.rbs b/sig/datadog/appsec/contrib/rack/reactive/response.rbs index 2d2a9edddc1..a79a98b0da6 100644 --- a/sig/datadog/appsec/contrib/rack/reactive/response.rbs +++ b/sig/datadog/appsec/contrib/rack/reactive/response.rbs @@ -6,9 +6,9 @@ module Datadog module Response ADDRESSES: ::Array[::String] - def self.publish: (untyped op, Datadog::AppSec::Contrib::Rack::Gateway::Response response) -> untyped + def self.publish: (AppSec::Reactive::Engine engine, AppSec::Contrib::Rack::Gateway::Response response) -> untyped - def self.subscribe: (untyped op, untyped waf_context) { (untyped) -> untyped } -> untyped + def self.subscribe: (AppSec::Reactive::Engine engine, untyped waf_context) { (untyped) -> untyped } -> untyped end end end diff --git a/sig/datadog/appsec/contrib/rails/reactive/action.rbs b/sig/datadog/appsec/contrib/rails/reactive/action.rbs index f24f3c62ff5..e442469cb1b 100644 --- a/sig/datadog/appsec/contrib/rails/reactive/action.rbs +++ b/sig/datadog/appsec/contrib/rails/reactive/action.rbs @@ -6,9 +6,9 @@ module Datadog module Action ADDRESSES: ::Array[::String] - def self.publish: (untyped op, Datadog::AppSec::Contrib::Rails::Gateway::Request request) -> untyped + def self.publish: (AppSec::Reactive::Engine engine, AppSec::Contrib::Rails::Gateway::Request request) -> untyped - def self.subscribe: (untyped op, untyped waf_context) { (untyped) -> untyped } -> untyped + def self.subscribe: (AppSec::Reactive::Engine engine, untyped waf_context) { (untyped) -> untyped } -> untyped end end end diff --git a/sig/datadog/appsec/contrib/sinatra/reactive/routed.rbs b/sig/datadog/appsec/contrib/sinatra/reactive/routed.rbs index de3fa0a0919..a711268f7d4 100644 --- a/sig/datadog/appsec/contrib/sinatra/reactive/routed.rbs +++ b/sig/datadog/appsec/contrib/sinatra/reactive/routed.rbs @@ -6,9 +6,9 @@ module Datadog module Routed ADDRESSES: ::Array[::String] - def self.publish: (untyped op, ::Array[Datadog::AppSec::Instrumentation::Gateway::Argument] data) -> untyped + def self.publish: (AppSec::Reactive::Engine engine, ::Array[AppSec::Instrumentation::Gateway::Argument] data) -> untyped - def self.subscribe: (untyped op, untyped waf_context) { (untyped) -> untyped } -> untyped + def self.subscribe: (AppSec::Reactive::Engine engine, untyped waf_context) { (untyped) -> untyped } -> untyped end end end diff --git a/sig/datadog/appsec/monitor/reactive/set_user.rbs b/sig/datadog/appsec/monitor/reactive/set_user.rbs index 49fa18ff860..1efd5ff8277 100644 --- a/sig/datadog/appsec/monitor/reactive/set_user.rbs +++ b/sig/datadog/appsec/monitor/reactive/set_user.rbs @@ -5,9 +5,9 @@ module Datadog module SetUser ADDRESSES: ::Array[::String] - def self.publish: (untyped op, Datadog::AppSec::Instrumentation::Gateway::User user) -> untyped + def self.publish: (AppSec::Reactive::Engine engine, AppSec::Instrumentation::Gateway::User user) -> untyped - def self.subscribe: (untyped op, untyped waf_context) { (untyped) -> untyped } -> untyped + def self.subscribe: (AppSec::Reactive::Engine engine, untyped waf_context) { (untyped) -> untyped } -> untyped end end end diff --git a/sig/datadog/appsec/reactive/operation.rbs b/sig/datadog/appsec/reactive/operation.rbs deleted file mode 100644 index 854e7c9dc6b..00000000000 --- a/sig/datadog/appsec/reactive/operation.rbs +++ /dev/null @@ -1,25 +0,0 @@ -module Datadog - module AppSec - module Reactive - class Operation - attr_reader reactive: Engine - attr_reader parent: Operation? - attr_reader name: ::String - - def initialize: (::String name, ?Operation? parent, ?Engine? reactive_engine) ?{ (Operation) -> void } -> void - def logger: () -> ::Logger - def subscribe: (*::String addresses) { (*untyped values) -> void } -> void - def publish: (::String address, untyped data) -> untyped - def finalize: () -> void - - private - - def select_reactive_engine: (Engine? reactive, Operation? parent) -> Engine - - def self.active: () -> Operation? - - def self.reset!: () -> untyped - end - end - end -end diff --git a/spec/datadog/appsec/contrib/graphql/reactive/multiplex_spec.rb b/spec/datadog/appsec/contrib/graphql/reactive/multiplex_spec.rb index 519904cfc5d..21df7b7b6d5 100644 --- a/spec/datadog/appsec/contrib/graphql/reactive/multiplex_spec.rb +++ b/spec/datadog/appsec/contrib/graphql/reactive/multiplex_spec.rb @@ -4,14 +4,15 @@ require 'datadog/tracing/contrib/graphql/support/application' require 'datadog/appsec/spec_helper' -require 'datadog/appsec/reactive/operation' require 'datadog/appsec/contrib/graphql/gateway/multiplex' require 'datadog/appsec/contrib/graphql/reactive/multiplex' +require 'datadog/appsec/reactive/engine' require 'datadog/appsec/reactive/shared_examples' RSpec.describe Datadog::AppSec::Contrib::GraphQL::Reactive::Multiplex do include_context 'with GraphQL multiplex' + let(:engine) { Datadog::AppSec::Reactive::Engine.new } let(:expected_arguments) do { 'user' => [{ 'id' => 1 }, { 'id' => 10 }], @@ -20,10 +21,10 @@ end describe '.publish' do - it 'propagates multiplex attributes to the operation' do - expect(operation).to receive(:publish).with('graphql.server.all_resolvers', expected_arguments) + it 'propagates multiplex attributes to the engine' do + expect(engine).to receive(:publish).with('graphql.server.all_resolvers', expected_arguments) gateway_multiplex = Datadog::AppSec::Contrib::GraphQL::Gateway::Multiplex.new(multiplex) - described_class.publish(operation, gateway_multiplex) + described_class.publish(engine, gateway_multiplex) end end @@ -32,17 +33,17 @@ context 'not all addresses have been published' do it 'does not call the waf context' do - expect(operation).to receive(:subscribe).with( + expect(engine).to receive(:subscribe).with( 'graphql.server.all_resolvers' ).and_call_original expect(waf_context).to_not receive(:run) - described_class.subscribe(operation, waf_context) + described_class.subscribe(engine, waf_context) end end context 'all addresses have been published' do it 'does call the waf context with the right arguments' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :ok, timeout: false) expect(waf_context).to receive(:run).with( @@ -50,9 +51,9 @@ {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(operation, waf_context) + described_class.subscribe(engine, waf_context) gateway_multiplex = Datadog::AppSec::Contrib::GraphQL::Gateway::Multiplex.new(multiplex) - result = described_class.publish(operation, gateway_multiplex) + result = described_class.publish(engine, gateway_multiplex) expect(result).to be_nil end end diff --git a/spec/datadog/appsec/contrib/rack/reactive/request_body_spec.rb b/spec/datadog/appsec/contrib/rack/reactive/request_body_spec.rb index 7b5ce95a3a2..75cf9aae480 100644 --- a/spec/datadog/appsec/contrib/rack/reactive/request_body_spec.rb +++ b/spec/datadog/appsec/contrib/rack/reactive/request_body_spec.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true require 'datadog/appsec/spec_helper' -require 'datadog/appsec/reactive/operation' require 'datadog/appsec/contrib/rack/gateway/request' require 'datadog/appsec/contrib/rack/reactive/request_body' +require 'datadog/appsec/reactive/engine' require 'datadog/appsec/reactive/shared_examples' require 'rack' RSpec.describe Datadog::AppSec::Contrib::Rack::Reactive::RequestBody do - let(:operation) { Datadog::AppSec::Reactive::Operation.new('test') } + let(:engine) { Datadog::AppSec::Reactive::Engine.new } let(:request) do Datadog::AppSec::Contrib::Rack::Gateway::Request.new( Rack::MockRequest.env_for( @@ -20,10 +20,10 @@ end describe '.publish' do - it 'propagates request body attributes to the operation' do - expect(operation).to receive(:publish).with('request.body', { 'foo' => 'bar' }) + it 'propagates request body attributes to the engine' do + expect(engine).to receive(:publish).with('request.body', { 'foo' => 'bar' }) - described_class.publish(operation, request) + described_class.publish(engine, request) end end @@ -32,15 +32,15 @@ context 'not all addresses have been published' do it 'does not call the waf context' do - expect(operation).to receive(:subscribe).with('request.body').and_call_original + expect(engine).to receive(:subscribe).with('request.body').and_call_original expect(waf_context).to_not receive(:run) - described_class.subscribe(operation, waf_context) + described_class.subscribe(engine, waf_context) end end context 'all addresses have been published' do it 'does call the waf context with the right arguments' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original expected_waf_arguments = { 'server.request.body' => { 'foo' => 'bar' } } @@ -50,8 +50,8 @@ {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(operation, waf_context) - result = described_class.publish(operation, request) + described_class.subscribe(engine, waf_context) + result = described_class.publish(engine, request) expect(result).to be_nil end end diff --git a/spec/datadog/appsec/contrib/rack/reactive/request_spec.rb b/spec/datadog/appsec/contrib/rack/reactive/request_spec.rb index b9927ce8f87..f22a3964b1d 100644 --- a/spec/datadog/appsec/contrib/rack/reactive/request_spec.rb +++ b/spec/datadog/appsec/contrib/rack/reactive/request_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'datadog/appsec/spec_helper' -require 'datadog/appsec/reactive/operation' +require 'datadog/appsec/reactive/engine' require 'datadog/appsec/contrib/rack/gateway/request' require 'datadog/appsec/contrib/rack/reactive/request' require 'datadog/appsec/reactive/shared_examples' @@ -9,7 +9,7 @@ require 'rack' RSpec.describe Datadog::AppSec::Contrib::Rack::Reactive::Request do - let(:operation) { Datadog::AppSec::Reactive::Operation.new('test') } + let(:engine) { Datadog::AppSec::Reactive::Engine.new } let(:request) do Datadog::AppSec::Contrib::Rack::Gateway::Request.new( Rack::MockRequest.env_for( @@ -34,15 +34,15 @@ end describe '.publish' do - it 'propagates request attributes to the operation' do - expect(operation).to receive(:publish).with('server.request.method', 'GET') - expect(operation).to receive(:publish).with('request.query', { 'a' => ['foo'] }) - expect(operation).to receive(:publish).with('request.headers', expected_headers_with_cookies) - expect(operation).to receive(:publish).with('request.uri.raw', '/?a=foo') - expect(operation).to receive(:publish).with('request.cookies', { 'foo' => 'bar' }) - expect(operation).to receive(:publish).with('request.client_ip', '10.10.10.10') + it 'propagates request attributes to the engine' do + expect(engine).to receive(:publish).with('server.request.method', 'GET') + expect(engine).to receive(:publish).with('request.query', { 'a' => ['foo'] }) + expect(engine).to receive(:publish).with('request.headers', expected_headers_with_cookies) + expect(engine).to receive(:publish).with('request.uri.raw', '/?a=foo') + expect(engine).to receive(:publish).with('request.cookies', { 'foo' => 'bar' }) + expect(engine).to receive(:publish).with('request.client_ip', '10.10.10.10') - described_class.publish(operation, request) + described_class.publish(engine, request) end end @@ -51,7 +51,7 @@ context 'not all addresses have been published' do it 'does not call the waf context' do - expect(operation).to receive(:subscribe).with( + expect(engine).to receive(:subscribe).with( 'request.headers', 'request.uri.raw', 'request.query', @@ -60,13 +60,13 @@ 'server.request.method', ).and_call_original expect(waf_context).to_not receive(:run) - described_class.subscribe(operation, waf_context) + described_class.subscribe(engine, waf_context) end end context 'all addresses have been published' do it 'does call the waf context with the right arguments' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original expected_waf_arguments = { 'server.request.cookies' => { 'foo' => 'bar' }, @@ -84,8 +84,8 @@ {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(operation, waf_context) - result = described_class.publish(operation, request) + described_class.subscribe(engine, waf_context) + result = described_class.publish(engine, request) expect(result).to be_nil end end diff --git a/spec/datadog/appsec/contrib/rack/reactive/response_spec.rb b/spec/datadog/appsec/contrib/rack/reactive/response_spec.rb index 8ea92c75e78..ca51117f5e1 100644 --- a/spec/datadog/appsec/contrib/rack/reactive/response_spec.rb +++ b/spec/datadog/appsec/contrib/rack/reactive/response_spec.rb @@ -2,13 +2,13 @@ require 'datadog/appsec/spec_helper' require 'datadog/appsec/scope' -require 'datadog/appsec/reactive/operation' require 'datadog/appsec/contrib/rack/gateway/response' require 'datadog/appsec/contrib/rack/reactive/response' +require 'datadog/appsec/reactive/engine' require 'datadog/appsec/reactive/shared_examples' RSpec.describe Datadog::AppSec::Contrib::Rack::Reactive::Response do - let(:operation) { Datadog::AppSec::Reactive::Operation.new('test') } + let(:engine) { Datadog::AppSec::Reactive::Engine.new } let(:processor_context) { instance_double(Datadog::AppSec::Processor::Context) } let(:scope) { instance_double(Datadog::AppSec::Scope, processor_context: processor_context) } let(:body) { ['Ok'] } @@ -24,31 +24,31 @@ end describe '.publish' do - it 'propagates response attributes to the operation' do - expect(operation).to receive(:publish).with('response.status', 200) - expect(operation).to receive(:publish).with( + it 'propagates response attributes to the engine' do + expect(engine).to receive(:publish).with('response.status', 200) + expect(engine).to receive(:publish).with( 'response.headers', headers, ) - described_class.publish(operation, response) + described_class.publish(engine, response) end end describe '.subscribe' do context 'not all addresses have been published' do it 'does not call the waf context' do - expect(operation).to receive(:subscribe).with( + expect(engine).to receive(:subscribe).with( 'response.status', 'response.headers', ).and_call_original expect(processor_context).to_not receive(:run) - described_class.subscribe(operation, processor_context) + described_class.subscribe(engine, processor_context) end end context 'waf arguments' do before do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original end let(:waf_result) { double(:waf_result, status: :ok, timeout: false) } @@ -73,8 +73,8 @@ {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(operation, processor_context) - result = described_class.publish(operation, response) + described_class.subscribe(engine, processor_context) + result = described_class.publish(engine, response) expect(result).to be_nil end end diff --git a/spec/datadog/appsec/contrib/rails/integration_test_spec.rb b/spec/datadog/appsec/contrib/rails/integration_test_spec.rb index b564e477c9f..1c1b7eecaad 100644 --- a/spec/datadog/appsec/contrib/rails/integration_test_spec.rb +++ b/spec/datadog/appsec/contrib/rails/integration_test_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'datadog/tracing/contrib/rails/rails_helper' require 'datadog/appsec/contrib/support/integration/shared_examples' require 'datadog/appsec/spec_helper' diff --git a/spec/datadog/appsec/contrib/rails/reactive/action_spec.rb b/spec/datadog/appsec/contrib/rails/reactive/action_spec.rb index 75c302e2751..fad066ef7cf 100644 --- a/spec/datadog/appsec/contrib/rails/reactive/action_spec.rb +++ b/spec/datadog/appsec/contrib/rails/reactive/action_spec.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require 'datadog/appsec/spec_helper' -require 'datadog/appsec/reactive/operation' require 'datadog/appsec/contrib/rails/reactive/action' require 'datadog/appsec/contrib/rails/gateway/request' +require 'datadog/appsec/reactive/engine' require 'datadog/appsec/reactive/shared_examples' require 'action_dispatch' RSpec.describe Datadog::AppSec::Contrib::Rails::Reactive::Action do - let(:operation) { Datadog::AppSec::Reactive::Operation.new('test') } + let(:engine) { Datadog::AppSec::Reactive::Engine.new } let(:request) do request_env = Rack::MockRequest.env_for( 'http://example.com:8080/?a=foo', @@ -24,11 +26,11 @@ end describe '.publish' do - it 'propagates request attributes to the operation' do - expect(operation).to receive(:publish).with('rails.request.body', { 'foo' => 'bar' }) - expect(operation).to receive(:publish).with('rails.request.route_params', { id: '1234' }) + it 'propagates request attributes to the engine' do + expect(engine).to receive(:publish).with('rails.request.body', { 'foo' => 'bar' }) + expect(engine).to receive(:publish).with('rails.request.route_params', { id: '1234' }) - described_class.publish(operation, request) + described_class.publish(engine, request) end end @@ -37,15 +39,15 @@ context 'not all addresses have been published' do it 'does not call the waf context' do - expect(operation).to receive(:subscribe).with('rails.request.body', 'rails.request.route_params').and_call_original + expect(engine).to receive(:subscribe).with('rails.request.body', 'rails.request.route_params').and_call_original expect(waf_context).to_not receive(:run) - described_class.subscribe(operation, waf_context) + described_class.subscribe(engine, waf_context) end end context 'all addresses have been published' do it 'does call the waf context with the right arguments' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original expected_waf_arguments = { 'server.request.body' => { 'foo' => 'bar' }, @@ -58,8 +60,8 @@ {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(operation, waf_context) - result = described_class.publish(operation, request) + described_class.subscribe(engine, waf_context) + result = described_class.publish(engine, request) expect(result).to be_nil end end diff --git a/spec/datadog/appsec/contrib/sinatra/reactive/routed_spec.rb b/spec/datadog/appsec/contrib/sinatra/reactive/routed_spec.rb index b30ca74c3f6..690d1609ecb 100644 --- a/spec/datadog/appsec/contrib/sinatra/reactive/routed_spec.rb +++ b/spec/datadog/appsec/contrib/sinatra/reactive/routed_spec.rb @@ -1,16 +1,16 @@ # frozen_string_literal: true require 'datadog/appsec/spec_helper' -require 'datadog/appsec/reactive/operation' require 'datadog/appsec/contrib/sinatra/reactive/routed' require 'datadog/appsec/contrib/rack/gateway/request' require 'datadog/appsec/contrib/sinatra/gateway/route_params' +require 'datadog/appsec/reactive/engine' require 'datadog/appsec/reactive/shared_examples' require 'rack' RSpec.describe Datadog::AppSec::Contrib::Sinatra::Reactive::Routed do - let(:operation) { Datadog::AppSec::Reactive::Operation.new('test') } + let(:engine) { Datadog::AppSec::Reactive::Engine.new } let(:request) do Datadog::AppSec::Contrib::Rack::Gateway::Request.new( Rack::MockRequest.env_for( @@ -22,10 +22,10 @@ let(:routed_params) { Datadog::AppSec::Contrib::Sinatra::Gateway::RouteParams.new({ id: '1234' }) } describe '.publish' do - it 'propagates routed params attributes to the operation' do - expect(operation).to receive(:publish).with('sinatra.request.route_params', { id: '1234' }) + it 'propagates routed params attributes to the engine' do + expect(engine).to receive(:publish).with('sinatra.request.route_params', { id: '1234' }) - described_class.publish(operation, [request, routed_params]) + described_class.publish(engine, [request, routed_params]) end end @@ -34,15 +34,15 @@ context 'not all addresses have been published' do it 'does not call the waf context' do - expect(operation).to receive(:subscribe).with('sinatra.request.route_params').and_call_original + expect(engine).to receive(:subscribe).with('sinatra.request.route_params').and_call_original expect(waf_context).to_not receive(:run) - described_class.subscribe(operation, waf_context) + described_class.subscribe(engine, waf_context) end end context 'all addresses have been published' do it 'does call the waf context with the right arguments' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original expected_waf_arguments = { 'server.request.path_params' => { id: '1234' } @@ -54,8 +54,8 @@ {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(operation, waf_context) - result = described_class.publish(operation, [request, routed_params]) + described_class.subscribe(engine, waf_context) + result = described_class.publish(engine, [request, routed_params]) expect(result).to be_nil end end diff --git a/spec/datadog/appsec/monitor/reactive/set_user_spec.rb b/spec/datadog/appsec/monitor/reactive/set_user_spec.rb index e29b076ffa0..5e5472f6b2a 100644 --- a/spec/datadog/appsec/monitor/reactive/set_user_spec.rb +++ b/spec/datadog/appsec/monitor/reactive/set_user_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true require 'datadog/appsec/spec_helper' -require 'datadog/appsec/reactive/operation' +require 'datadog/appsec/reactive/engine' require 'datadog/appsec/monitor/reactive/set_user' require 'datadog/appsec/reactive/shared_examples' RSpec.describe Datadog::AppSec::Monitor::Reactive::SetUser do - let(:operation) { Datadog::AppSec::Reactive::Operation.new('test') } + let(:engine) { Datadog::AppSec::Reactive::Engine.new } let(:user) { double(:user, id: 1) } describe '.publish' do - it 'propagates request body attributes to the operation' do - expect(operation).to receive(:publish).with('usr.id', 1) + it 'propagates request body attributes to the engine' do + expect(engine).to receive(:publish).with('usr.id', 1) - described_class.publish(operation, user) + described_class.publish(engine, user) end end @@ -22,15 +22,15 @@ context 'not all addresses have been published' do it 'does not call the waf context' do - expect(operation).to receive(:subscribe).with('usr.id').and_call_original + expect(engine).to receive(:subscribe).with('usr.id').and_call_original expect(waf_context).to_not receive(:run) - described_class.subscribe(operation, waf_context) + described_class.subscribe(engine, waf_context) end end context 'all addresses have been published' do it 'does call the waf context with the right arguments' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original expected_waf_persisted_data = { 'usr.id' => 1 } @@ -40,8 +40,8 @@ {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(operation, waf_context) - result = described_class.publish(operation, user) + described_class.subscribe(engine, waf_context) + result = described_class.publish(engine, user) expect(result).to be_nil end end diff --git a/spec/datadog/appsec/reactive/operation_spec.rb b/spec/datadog/appsec/reactive/operation_spec.rb deleted file mode 100644 index 81c0aff0f04..00000000000 --- a/spec/datadog/appsec/reactive/operation_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -require 'datadog/appsec/spec_helper' -require 'datadog/appsec/reactive/operation' - -RSpec.describe Datadog::AppSec::Reactive::Operation do - after do - described_class.send(:reset!) - end - - describe '#initialize' do - it 'sets active to yield operation for the duration of the block' do - active_operation = described_class.active - expect(active_operation).to be_nil - described_class.new('test') do |op| - expect(described_class.active).to eq(op) - end - expect(described_class.active).to be_nil - end - - it 'sets active to parent' do - parent_operation = described_class.new('parent_test') - described_class.new('test', parent_operation) do |op| - expect(described_class.active).to eq(op) - end - expect(described_class.active).to eq(parent_operation) - end - - it 'creates a new Reactive instance when no reactive instance provided' do - described_class.new('test') do |op| - expect(op.reactive).to be_a Datadog::AppSec::Reactive::Engine - end - end - - it 'uses provided reactive instance' do - reactive_instance = Datadog::AppSec::Reactive::Engine.new - described_class.new('test', nil, reactive_instance) do |op| - expect(op.reactive).to eq(reactive_instance) - end - end - - it 'uses reactive instance from parent' do - parent_operation = described_class.new('parent_test') - described_class.new('test', parent_operation) do |op| - expect(op.reactive).to eq(parent_operation.reactive) - end - end - - it 'uses reactive instance over parent engine' do - reactive_instance = Datadog::AppSec::Reactive::Engine.new - parent_operation = described_class.new('parent_test') - described_class.new('test', parent_operation, reactive_instance) do |op| - expect(op.reactive).to eq(reactive_instance) - end - end - end - - describe '#subscribe' do - it 'delegates to reactive engine' do - operation = described_class.new('test') - expect(operation.reactive).to receive(:subscribe).with([:a, :b, :c]) - operation.subscribe([:a, :b, :c]) do - 1 + 1 - end - end - end - - describe '#publish' do - it 'delegates to reactive engine' do - operation = described_class.new('test') - expect(operation.reactive).to receive(:publish).with(:a, 'hello world') - operation.publish(:a, 'hello world') - end - end - - describe '#finalize' do - it 'sets active to parent' do - parent_operation = described_class.new('parent_test') - described_class.new('test', parent_operation) - expect(described_class.active).to eq(parent_operation) - parent_operation.finalize - # The parent of parent_operation is nil because is the top operation - expect(described_class.active).to be_nil - end - end -end diff --git a/spec/datadog/appsec/reactive/shared_examples.rb b/spec/datadog/appsec/reactive/shared_examples.rb index 84715c3b95f..352ae336781 100644 --- a/spec/datadog/appsec/reactive/shared_examples.rb +++ b/spec/datadog/appsec/reactive/shared_examples.rb @@ -3,98 +3,98 @@ RSpec.shared_examples 'waf result' do context 'is a match' do it 'yields result and no blocking action' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :match, timeout: false, actions: []) expect(waf_context).to receive(:run).and_return(waf_result) - described_class.subscribe(operation, waf_context) do |result| + described_class.subscribe(engine, waf_context) do |result| expect(result).to eq(waf_result) end - result = described_class.publish(operation, gateway) + result = described_class.publish(engine, gateway) expect(result).to be_nil end it 'yields result and blocking action. The publish method catches the resul as well' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :match, timeout: false, actions: ['block']) expect(waf_context).to receive(:run).and_return(waf_result) - described_class.subscribe(operation, waf_context) do |result| + described_class.subscribe(engine, waf_context) do |result| expect(result).to eq(waf_result) end - block = described_class.publish(operation, gateway) + block = described_class.publish(engine, gateway) expect(block).to eq(true) end end context 'is ok' do it 'does not yield' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :ok, timeout: false) expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(operation, waf_context, &b) }.not_to yield_control - result = described_class.publish(operation, gateway) + expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + result = described_class.publish(engine, gateway) expect(result).to be_nil end end context 'is invalid_call' do it 'does not yield' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :invalid_call, timeout: false) expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(operation, waf_context, &b) }.not_to yield_control - result = described_class.publish(operation, gateway) + expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + result = described_class.publish(engine, gateway) expect(result).to be_nil end end context 'is invalid_rule' do it 'does not yield' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :invalid_rule, timeout: false) expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(operation, waf_context, &b) }.not_to yield_control - result = described_class.publish(operation, gateway) + expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + result = described_class.publish(engine, gateway) expect(result).to be_nil end end context 'is invalid_flow' do it 'does not yield' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :invalid_flow, timeout: false) expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(operation, waf_context, &b) }.not_to yield_control - result = described_class.publish(operation, gateway) + expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + result = described_class.publish(engine, gateway) expect(result).to be_nil end end context 'is no_rule' do it 'does not yield' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :no_rule, timeout: false) expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(operation, waf_context, &b) }.not_to yield_control - result = described_class.publish(operation, gateway) + expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + result = described_class.publish(engine, gateway) expect(result).to be_nil end end context 'is unknown' do it 'does not yield' do - expect(operation).to receive(:subscribe).and_call_original + expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :foo, timeout: false) expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(operation, waf_context, &b) }.not_to yield_control - result = described_class.publish(operation, gateway) + expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + result = described_class.publish(engine, gateway) expect(result).to be_nil end end diff --git a/spec/datadog/tracing/contrib/graphql/support/application.rb b/spec/datadog/tracing/contrib/graphql/support/application.rb index 88ab68a45fc..ba403ada0d4 100644 --- a/spec/datadog/tracing/contrib/graphql/support/application.rb +++ b/spec/datadog/tracing/contrib/graphql/support/application.rb @@ -39,7 +39,6 @@ TestGraphQL.send(:remove_const, :UserType) if defined?(TestGraphQL::UserType) load 'spec/datadog/tracing/contrib/graphql/support/application_schema.rb' end - let(:operation) { Datadog::AppSec::Reactive::Operation.new('test') } let(:schema) { TestGraphQL::Schema } end