Skip to content

Commit 0ab4de7

Browse files
committed
Fix Devise and API Sampler specs
1 parent f2a6e58 commit 0ab4de7

File tree

3 files changed

+52
-22
lines changed

3 files changed

+52
-22
lines changed

spec/datadog/appsec/integration/api_security/schema_extraction_spec.rb

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,23 @@
99
require 'active_record'
1010
require 'datadog/tracing'
1111
require 'datadog/appsec'
12+
require 'devise'
1213

1314
RSpec.describe 'Schema extraction for API security' do
1415
include Rack::Test::Methods
1516

1617
before do
17-
stub_const('User', Class.new(ActiveRecord::Base)).tap do |klass|
18+
# NOTE: Due to the legacy code in AppSec component we always patch Devise
19+
# and this is a minimalistic workaround to trigger the patching and
20+
# have it configured properly.
21+
Devise.send(:remove_const, :Engine)
22+
load File.join(Gem.loaded_specs['devise'].full_gem_path, 'lib/devise/rails.rb')
23+
Devise.setup { |config| config.parent_controller = 'ActionController::Base' }
24+
25+
stub_const('Product', Class.new(ActiveRecord::Base)).tap do |klass|
1826
klass.establish_connection({adapter: 'sqlite3', database: ':memory:'})
1927

20-
klass.connection.create_table 'users', force: :cascade do |t|
28+
klass.connection.create_table 'products', force: :cascade do |t|
2129
t.string :name, null: false
2230
end
2331

@@ -48,9 +56,10 @@ def initialize(files, dirs = {}, &block)
4856
Datadog.configure do |config|
4957
config.tracing.enabled = true
5058
config.tracing.sampler = sampler
51-
config.apm.tracing.enabled = true
5259
config.tracing.instrument :rails
5360

61+
config.apm.tracing.enabled = true
62+
5463
config.appsec.enabled = true
5564
config.appsec.instrument :rails
5665
config.appsec.instrument :active_record
@@ -85,20 +94,20 @@ def initialize(files, dirs = {}, &block)
8594

8695
app.initialize!
8796
app.routes.draw do
88-
get '/api/users', to: 'api#users'
97+
get '/api/products', to: 'api#products'
8998
get '/api/search', to: 'api#search'
9099
end
91100

92101
stub_const('ApiController', Class.new(ActionController::Base)).class_eval do
93-
def users
94-
render json: {id: 1, name: 'John', email: '[email protected]'}
102+
def products
103+
render json: {id: 1, name: 'Widget', price: 29.99}
95104
end
96105

97106
def search
98-
users = User.find_by_sql(
99-
"SELECT * FROM users WHERE name = '#{params[:name]}'"
107+
products = Product.find_by_sql(
108+
"SELECT * FROM products WHERE name = '#{params[:name]}'"
100109
)
101-
render json: users
110+
render json: products
102111
end
103112
end
104113

@@ -114,6 +123,7 @@ def search
114123

115124
Datadog.configuration.reset!
116125
Datadog.registry[:rack].reset_configuration!
126+
117127
Datadog::AppSec::RateLimiter.reset!
118128
Datadog::AppSec::APISecurity::Sampler.reset!
119129

@@ -146,7 +156,7 @@ def search
146156
config.appsec.api_security.sample_delay = 30
147157
end
148158

149-
get('/api/users')
159+
get('/api/products')
150160
end
151161

152162
it 'extracts schema and adds to span tags' do
@@ -167,7 +177,7 @@ def search
167177
end
168178

169179
context 'when APM sampler rejects the trace' do
170-
before { get('/api/users') }
180+
before { get('/api/products') }
171181

172182
let(:sampler) { instance_double(Datadog::Tracing::Sampling::Sampler, sample!: false) }
173183

@@ -184,7 +194,7 @@ def search
184194
before do
185195
allow_any_instance_of(Datadog::AppSec::APISecurity::Sampler).to receive(:sample?).and_return(false)
186196

187-
get('/api/users')
197+
get('/api/products')
188198
end
189199

190200
let(:sampler) { instance_double(Datadog::Tracing::Sampling::Sampler, sample!: true) }
@@ -206,7 +216,7 @@ def search
206216
config.appsec.api_security.sample_delay = 30
207217
end
208218

209-
get('/api/users')
219+
get('/api/products')
210220
end
211221

212222
it 'does not extract schema' do
@@ -226,7 +236,7 @@ def search
226236
config.appsec.api_security.sample_delay = 30
227237
end
228238

229-
get('/api/users')
239+
get('/api/products')
230240
end
231241

232242
let(:sampler) { instance_double(Datadog::Tracing::Sampling::Sampler, sample!: false) }
@@ -247,7 +257,7 @@ def search
247257
config.appsec.api_security.sample_delay = 30
248258
end
249259

250-
get('/api/search', {'name' => "Bob'; OR 1=1"})
260+
get('/api/search', {'name' => "Widget'; OR 1=1"})
251261
end
252262

253263
it 'blocks the request and extracts only request schema' do

spec/datadog/appsec/integration/contrib/devise/signin_multi_user_tracking_spec.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,11 @@ def index
170170
end
171171

172172
let(:sessions_controller) do
173-
stub_const('TestSessionsController', Class.new(Devise::SessionsController))
173+
stub_const('TestSessionsController', Class.new(Devise::SessionsController)).class_eval do
174+
def new
175+
render plain: '<login-form>'
176+
end
177+
end
174178
end
175179

176180
let(:user_model) do
@@ -351,7 +355,7 @@ def valid_for_authentication?
351355

352356
it 'tracks login failure event' do
353357
expect(response).to be_unprocessable
354-
expect(response.body).to match(%r{<form .* action="/users/sign_in" .*>})
358+
expect(response.body).to match(%r{<login-form>})
355359

356360
expect(http_service_entry_trace.sampling_priority).to eq(Datadog::Tracing::Sampling::Ext::Priority::USER_KEEP)
357361

@@ -401,6 +405,10 @@ def valid_for_authentication?
401405

402406
let(:sessions_controller) do
403407
stub_const('TestSessionsController', Class.new(Devise::SessionsController)).class_eval do
408+
def new
409+
render plain: '<login-form>'
410+
end
411+
404412
def create
405413
Datadog::Kit::AppSec::Events.track_login_failure(
406414
Datadog::Tracing.active_trace,
@@ -417,7 +425,7 @@ def create
417425

418426
it 'tracks login failure event with SDK overrides' do
419427
expect(response).to be_unprocessable
420-
expect(response.body).to match(%r{<form .* action="/users/sign_in" .*>})
428+
expect(response.body).to match(%r{<login-form>})
421429

422430
expect(http_service_entry_trace.sampling_priority).to eq(Datadog::Tracing::Sampling::Ext::Priority::USER_KEEP)
423431

spec/datadog/appsec/integration/contrib/devise/signin_single_user_tracking_spec.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,11 @@ def index
153153
end
154154

155155
let(:sessions_controller) do
156-
stub_const('TestSessionsController', Class.new(Devise::SessionsController))
156+
stub_const('TestSessionsController', Class.new(Devise::SessionsController)).class_eval do
157+
def new
158+
render plain: '<login-form>'
159+
end
160+
end
157161
end
158162

159163
let(:user_model) do
@@ -323,6 +327,10 @@ def index
323327

324328
let(:sessions_controller) do
325329
stub_const('TestSessionsController', Class.new(Devise::SessionsController)).class_eval do
330+
def new
331+
render plain: '<login-form>'
332+
end
333+
326334
def create
327335
Datadog::Kit::AppSec::Events.track_login_success(
328336
Datadog::Tracing.active_trace,
@@ -361,7 +369,7 @@ def create
361369

362370
it 'tracks login failure event' do
363371
expect(response).to be_unprocessable
364-
expect(response.body).to match(%r{<form .* action="/users/sign_in" .*>})
372+
expect(response.body).to match(%r{<login-form>})
365373

366374
expect(http_service_entry_trace.sampling_priority).to eq(Datadog::Tracing::Sampling::Ext::Priority::USER_KEEP)
367375

@@ -409,7 +417,7 @@ def valid_for_authentication?
409417

410418
it 'tracks login failure event' do
411419
expect(response).to be_unprocessable
412-
expect(response.body).to match(%r{<form .* action="/users/sign_in" .*>})
420+
expect(response.body).to match(%r{<login-form>})
413421

414422
expect(http_service_entry_trace.sampling_priority).to eq(Datadog::Tracing::Sampling::Ext::Priority::USER_KEEP)
415423

@@ -459,6 +467,10 @@ def valid_for_authentication?
459467

460468
let(:sessions_controller) do
461469
stub_const('TestSessionsController', Class.new(Devise::SessionsController)).class_eval do
470+
def new
471+
render plain: '<login-form>'
472+
end
473+
462474
def create
463475
Datadog::Kit::AppSec::Events.track_login_failure(
464476
Datadog::Tracing.active_trace,
@@ -475,7 +487,7 @@ def create
475487

476488
it 'tracks login failure event with SDK overrides' do
477489
expect(response).to be_unprocessable
478-
expect(response.body).to match(%r{<form .* action="/users/sign_in" .*>})
490+
expect(response.body).to match(%r{<login-form>})
479491

480492
expect(http_service_entry_trace.sampling_priority).to eq(Datadog::Tracing::Sampling::Ext::Priority::USER_KEEP)
481493

0 commit comments

Comments
 (0)