Skip to content

Commit

Permalink
transform Event module into a Class
Browse files Browse the repository at this point in the history
  • Loading branch information
GustavoCaso committed Jul 7, 2023
1 parent 06b7a22 commit 5d8013e
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 50 deletions.
47 changes: 30 additions & 17 deletions lib/datadog/appsec/contrib/devise/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,51 @@ module Datadog
module AppSec
module Contrib
module Devise
# Module to extract event information from the resource
module Event
# Class to extract event information from the resource
class Event
UUID_REGEX = /^\h{8}-\h{4}-\h{4}-\h{4}-\h{12}$/.freeze

SAFE_MODE = 'safe'
EXTENDED_MODE = 'extended'

def self.extract(resource, mode)
event = {}
attr_reader :user_id

return event unless resource
def initialize(resource, mode)
@resource = resource
@mode = mode
@user_id = nil
@email = nil
@username = nil

resource_id = resource.id
extract if @resource
end

case mode
when EXTENDED_MODE
resource_email = resource.email
resource_username = resource.username
def to_h
return @event if defined?(@event)

@event = {}
@event[:email] = @email if @email
@event[:username] = @username if @username
@event
end

event[:id] = resource_id if resource_id
event[:email] = resource_email if resource_email
event[:username] = resource_username if resource_username
private

def extract
@user_id = @resource.id

case @mode
when EXTENDED_MODE
@email = @resource.email
@username = @resource.username
when SAFE_MODE
event[:id] = resource_id if resource_id && resource_id.to_s =~ UUID_REGEX
@user_id = nil unless @user_id && @user_id.to_s =~ UUID_REGEX
else
Datadog.logger.warn(
"Invalid automated user evenst mode: `#{mode}`. "\
"Invalid automated user evenst mode: `#{@mode}`. "\
'Supported modes are: `safe` and `extended`.'
)
end

event
end
end
end
Expand Down
24 changes: 10 additions & 14 deletions lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require_relative '../tracking'
require_relative '../resource'
require_relative '../event_information'
require_relative '../event'

module Datadog
module AppSec
Expand All @@ -28,41 +28,37 @@ def validate(resource, &block)

devise_resource = resource ? Resource.new(resource) : nil

event_information = Event.extract(devise_resource, automated_track_user_events_mode)
event_information = Event.new(devise_resource, automated_track_user_events_mode)

if result
if event_information[:id]
user_id = event_information.delete(:id)

if event_information.user_id
Tracking.track_login_success(
appsec_scope.trace,
appsec_scope.service_entry_span,
user_id: user_id,
**event_information
user_id: event_information.user_id,
**event_information.to_h
)
Datadog.logger.debug { 'User Login Event success' }
else
Tracking.track_login_success(
appsec_scope.trace,
appsec_scope.service_entry_span,
user_id: nil,
**event_information
**event_information.to_h
)
Datadog.logger.debug { 'User Login Event success, but can\'t extract user ID. Tracking empty event' }
end

return result
end

if devise_resource
user_id = event_information.delete(:id)

if event_information.user_id
Tracking.track_login_failure(
appsec_scope.trace,
appsec_scope.service_entry_span,
user_id: user_id,
user_id: event_information.user_id,
user_exists: true,
**event_information
**event_information.to_h
)
Datadog.logger.debug { 'User Login Event failure users exists' }
else
Expand All @@ -71,7 +67,7 @@ def validate(resource, &block)
appsec_scope.service_entry_span,
user_id: nil,
user_exists: false,
**event_information
**event_information.to_h
)
Datadog.logger.debug { 'User Login Event failure user do not exists' }
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require_relative '../tracking'
require_relative '../resource'
require_relative '../event_information'
require_relative '../event'

module Datadog
module AppSec
Expand All @@ -27,24 +27,22 @@ def create
if resource.persisted?
devise_resource = Resource.new(resource)

event_information = Event.extract(devise_resource, automated_track_user_events_mode)

if event_information[:id]
user_id = event_information.delete(:id)
event_information = Event.new(devise_resource, automated_track_user_events_mode)

if event_information.user_id
Tracking.track_signup(
appsec_scope.trace,
appsec_scope.service_entry_span,
user_id: user_id,
**event_information
user_id: event_information.user_id,
**event_information.to_h
)
Datadog.logger.debug { 'User Signup Event' }
else
Tracking.track_signup(
appsec_scope.trace,
appsec_scope.service_entry_span,
user_id: nil,
**event_information
**event_information.to_h
)
Datadog.logger.warn { 'User Signup Event, but can\'t extract user ID. Tracking empty event' }
end
Expand Down
13 changes: 11 additions & 2 deletions sig/datadog/appsec/contrib/devise/event.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@ module Datadog
module AppSec
module Contrib
module Devise
module Event
class Event
UUID_REGEX: ::Regexp

SAFE_MODE: String

EXTENDED_MODE: String

def self.extract: (Devise::Resource? resource, String mode) -> Hash[Symbol, untyped]
attr_reader user_id: untyped

def initialize: (Devise::Resource? resource, String mode) -> void


def to_h: () -> Hash[Symbol, untyped]

private

def extract: () -> void
end
end
end
Expand Down
30 changes: 21 additions & 9 deletions spec/datadog/appsec/contrib/devise/event_spec.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
require 'datadog/appsec/spec_helper'
require 'datadog/appsec/contrib/devise/resource'
require 'datadog/appsec/contrib/devise/event_information'
require 'datadog/appsec/contrib/devise/event'

RSpec.describe Datadog::AppSec::Contrib::Devise::Event do
subject(:event_information) { described_class.extract(resource, mode) }
let(:event) { described_class.new(resource, mode) }
let(:resource) { Datadog::AppSec::Contrib::Devise::Resource.new(object) }

let(:object_class) do
Expand All @@ -23,7 +23,9 @@ def initialize(id: nil, uuid: nil, email: nil, username: nil)
let(:resource) { nil }
let(:mode) { 'safe' }

it { is_expected.to eq({}) }
it do
expect(event.to_h).to eq({})
end
end

context 'safe mode' do
Expand All @@ -32,14 +34,18 @@ def initialize(id: nil, uuid: nil, email: nil, username: nil)
context 'with ID but not UUID' do
let(:object) { object_class.new(id: 1234) }

it { is_expected.to eq({}) }
it do
expect(event.user_id).to be_nil
end
end

context 'with ID as UUID' do
let(:uuid) { '123e4567-e89b-12d3-a456-426655440000' }
let(:object) { object_class.new(uuid: uuid) }

it { is_expected.to eq({ id: uuid }) }
it do
expect(event.user_id).to eq(uuid)
end
end
end

Expand All @@ -50,21 +56,27 @@ def initialize(id: nil, uuid: nil, email: nil, username: nil)
context 'with ID but not UUID' do
let(:object) { object_class.new(id: 1234) }

it { is_expected.to eq({ id: 1234 }) }
it do
expect(event.user_id).to eq(1234)
end
end

context 'with ID as UUID' do
let(:uuid) { '123e4567-e89b-12d3-a456-426655440000' }
let(:object) { object_class.new(uuid: uuid) }

it { is_expected.to eq({ id: uuid }) }
it do
expect(event.user_id).to eq(uuid)
end
end
end

context 'Email and username' do
let(:object) { object_class.new(id: 1234, email: '[email protected]', username: 'John') }

it { is_expected.to eq({ email: '[email protected]', id: 1234, username: 'John' }) }
it do
expect(event.to_h).to eq({ email: '[email protected]', username: 'John' })
end
end
end

Expand All @@ -74,7 +86,7 @@ def initialize(id: nil, uuid: nil, email: nil, username: nil)

it do
expect(Datadog.logger).to receive(:warn)
is_expected.to eq({})
expect(event.to_h).to eq({})
end
end
end

0 comments on commit 5d8013e

Please sign in to comment.