|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +require 'datadog/tracing/contrib/support/spec_helper' |
| 4 | +require 'datadog/appsec/spec_helper' |
| 5 | +require 'rack/test' |
| 6 | + |
| 7 | +require 'datadog/tracing' |
| 8 | +require 'datadog/appsec' |
| 9 | + |
| 10 | +RSpec.describe 'Rack-request headers collection for identity.set_user' do |
| 11 | + include Rack::Test::Methods |
| 12 | + |
| 13 | + before do |
| 14 | + Datadog.configure do |c| |
| 15 | + c.tracing.enabled = true |
| 16 | + |
| 17 | + c.appsec.enabled = true |
| 18 | + c.appsec.instrument :rack |
| 19 | + |
| 20 | + c.appsec.standalone.enabled = false |
| 21 | + c.appsec.waf_timeout = 10_000_000 # in us |
| 22 | + c.appsec.ip_passlist = [] |
| 23 | + c.appsec.ip_denylist = [] |
| 24 | + c.appsec.user_id_denylist = [] |
| 25 | + c.appsec.ruleset = :recommended |
| 26 | + c.appsec.api_security.enabled = false |
| 27 | + c.appsec.api_security.sample_rate = 0.0 |
| 28 | + |
| 29 | + c.remote.enabled = false |
| 30 | + end |
| 31 | + |
| 32 | + allow(Datadog::AppSec::Instrumentation).to receive(:gateway).and_return(gateway) |
| 33 | + |
| 34 | + # NOTE: Don't reach the agent in any way |
| 35 | + allow_any_instance_of(Datadog::Tracing::Transport::HTTP::Client).to receive(:send_request) |
| 36 | + allow_any_instance_of(Datadog::Tracing::Transport::Traces::Transport).to receive(:native_events_supported?) |
| 37 | + .and_return(true) |
| 38 | + |
| 39 | + Datadog::AppSec::Contrib::Rack::Gateway::Watcher.watch_request_finish |
| 40 | + end |
| 41 | + |
| 42 | + after do |
| 43 | + Datadog.configuration.reset! |
| 44 | + Datadog.registry[:rack].reset_configuration! |
| 45 | + end |
| 46 | + |
| 47 | + let(:gateway) { Datadog::AppSec::Instrumentation::Gateway.new } |
| 48 | + |
| 49 | + let(:http_service_entry_span) do |
| 50 | + Datadog::Tracing::Transport::TraceFormatter.format!(trace) |
| 51 | + spans.find { |s| s.name == 'rack.request' } |
| 52 | + end |
| 53 | + |
| 54 | + let(:app) do |
| 55 | + stack = Rack::Builder.new do |
| 56 | + use Datadog::Tracing::Contrib::Rack::TraceMiddleware |
| 57 | + use Datadog::AppSec::Contrib::Rack::RequestMiddleware |
| 58 | + |
| 59 | + map '/with-identity-set-user' do |
| 60 | + run( |
| 61 | + lambda do |_env| |
| 62 | + Datadog::Kit::Identity.set_user( |
| 63 | + Datadog::Tracing.active_trace, Datadog::Tracing.active_span, id: '42' |
| 64 | + ) |
| 65 | + |
| 66 | + [200, { 'Content-Type' => 'text/html' }, ['OK']] |
| 67 | + end |
| 68 | + ) |
| 69 | + end |
| 70 | + |
| 71 | + map '/without-identity-set-user' do |
| 72 | + run ->(_env) { [200, { 'Content-Type' => 'text/html' }, ['OK']] } |
| 73 | + end |
| 74 | + end |
| 75 | + |
| 76 | + stack.to_app |
| 77 | + end |
| 78 | + |
| 79 | + subject(:response) { last_response } |
| 80 | + |
| 81 | + context 'when identity.set_user event was pushed' do |
| 82 | + before do |
| 83 | + headers = { |
| 84 | + 'HTTP_CF_RAY' => '230b030023ae2822-SJC', |
| 85 | + 'HTTP_CF_CONNECTING_IPV6' => '2001:db8:3333:4444:5555:6666:1.2.3.4' |
| 86 | + } |
| 87 | + get('/with-identity-set-user', {}, headers) |
| 88 | + end |
| 89 | + |
| 90 | + it 'collects identity related request headers' do |
| 91 | + expect(response).to be_ok |
| 92 | + |
| 93 | + expect(http_service_entry_span.tags['http.request.headers.cf-connecting-ipv6']) |
| 94 | + .to eq('2001:db8:3333:4444:5555:6666:1.2.3.4') |
| 95 | + end |
| 96 | + end |
| 97 | + |
| 98 | + context 'when identity.set_user event was not pushed' do |
| 99 | + before do |
| 100 | + headers = { |
| 101 | + 'HTTP_CF_RAY' => '230b030023ae2822-SJC', |
| 102 | + 'HTTP_CF_CONNECTING_IPV6' => '2001:db8:3333:4444:5555:6666:1.2.3.4' |
| 103 | + } |
| 104 | + get('/without-identity-set-user', {}, headers) |
| 105 | + end |
| 106 | + |
| 107 | + it 'does not collect identity related request headers' do |
| 108 | + expect(response).to be_ok |
| 109 | + |
| 110 | + expect(http_service_entry_span.tags).not_to have_key('http.request.headers.cf-connecting-ipv6') |
| 111 | + end |
| 112 | + end |
| 113 | +end |
0 commit comments