tcell_agent 0.2.24 → 0.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/tcell_agent/configuration.rb +34 -0
- data/lib/tcell_agent/devise.rb +0 -46
- data/lib/tcell_agent/instrumentation.rb +1 -1
- data/lib/tcell_agent/rails/auth/authlogic.rb +53 -47
- data/lib/tcell_agent/rails/auth/devise.rb +87 -55
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +72 -0
- data/lib/tcell_agent/rails/auth/hooks.rb +79 -0
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +2 -0
- data/lib/tcell_agent/rails/on_start.rb +2 -0
- data/lib/tcell_agent/rails.rb +2 -0
- data/lib/tcell_agent/sensor_events/appsensor_event.rb +3 -3
- data/lib/tcell_agent/sensor_events/login_fraud.rb +44 -33
- data/lib/tcell_agent/servers/unicorn.rb +7 -7
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/rails/auth/hooks_spec.rb +246 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92307eb548621a9832e41c4966bf2aac64933d43
|
4
|
+
data.tar.gz: b0fb089fcbf1967b74ae58538e37425bdb74f466
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b411099b2c2525530594416c52ef0801eb9e6fa33d7c07dde867b22e381a9edffe00f497512cab7fe2751543264aaa57f7a1629071fedbb65f57f0aafe5bd46
|
7
|
+
data.tar.gz: 18a19efaf4d730e0165521c6c7da3f189adb13ae0975de945e1954bd392157c9441d5c33823f3fcdef3f50cc2f10d177172366bda909e70c5234ba297a24d157
|
data/README.md
CHANGED
@@ -57,6 +57,8 @@ module TCellAgent
|
|
57
57
|
:enable_instrumentation, # false = Do not add instrumentation
|
58
58
|
:enable_intercept_requests # false = Do not insert middleware
|
59
59
|
|
60
|
+
attr_accessor :enabled_instrumentations
|
61
|
+
|
60
62
|
attr_accessor :exp_config_settings
|
61
63
|
|
62
64
|
def should_start_event_manager?
|
@@ -79,6 +81,30 @@ module TCellAgent
|
|
79
81
|
@enabled && @enable_instrumentation && @enable_intercept_requests
|
80
82
|
end
|
81
83
|
|
84
|
+
def should_instrument_doorkeeper?
|
85
|
+
if @enabled_instrumentations.has_key?('doorkeeper') || @enabled_instrumentations.has_key?(:doorkeeper)
|
86
|
+
!!(@enabled_instrumentations['doorkeeper'] || @enabled_instrumentations[:doorkeeper])
|
87
|
+
else
|
88
|
+
true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def should_instrument_devise?
|
93
|
+
if @enabled_instrumentations.has_key?('devise') || @enabled_instrumentations.has_key?(:devise)
|
94
|
+
!!(@enabled_instrumentations['devise'] || @enabled_instrumentations[:devise])
|
95
|
+
else
|
96
|
+
true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def should_instrument_authlogic?
|
101
|
+
if @enabled_instrumentations.has_key?('authlogic') || @enabled_instrumentations.has_key?(:authlogic)
|
102
|
+
!!(@enabled_instrumentations['authlogic'] || @enabled_instrumentations[:authlogic])
|
103
|
+
else
|
104
|
+
true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
82
108
|
def initialize(filename="config/tcell_agent.config", useapp=nil)
|
83
109
|
# These will be set when the agent starts up, to give rails initializers
|
84
110
|
# a chance to run
|
@@ -104,6 +130,11 @@ module TCellAgent
|
|
104
130
|
@enable_instrumentation = true
|
105
131
|
@enable_intercept_requests = true
|
106
132
|
|
133
|
+
@enabled_instrumentations = {
|
134
|
+
doorkeeper: true,
|
135
|
+
devise: true,
|
136
|
+
authlogic: true
|
137
|
+
}
|
107
138
|
|
108
139
|
@agent_home_dir = File.join(Dir.getwd, "tcell")
|
109
140
|
@config_filename = File.join(Dir.getwd, filename)
|
@@ -240,6 +271,8 @@ module TCellAgent
|
|
240
271
|
data_exposure = app_data.fetch('data_exposure', {})
|
241
272
|
@max_data_ex_db_records_per_request = data_exposure.fetch('max_data_ex_db_records_per_request', @max_data_ex_db_records_per_request)
|
242
273
|
|
274
|
+
@enabled_instrumentations = app_data.fetch('enabled_instrumentations', {})
|
275
|
+
|
243
276
|
@reverse_proxy = app_data.fetch('reverse_proxy', @reverse_proxy)
|
244
277
|
@reverse_proxy_ip_address_header = app_data.fetch('reverse_proxy_ip_address_header', @reverse_proxy_ip_address_header)
|
245
278
|
|
@@ -293,6 +326,7 @@ module TCellAgent
|
|
293
326
|
@agent_log_dir ||= File.join(@agent_home_dir, "logs")
|
294
327
|
File.join(@agent_log_dir, "tcell_agent_payloads.log")
|
295
328
|
end
|
329
|
+
|
296
330
|
end # class
|
297
331
|
|
298
332
|
TCellAgent.configuration ||= TCellAgent::Configuration.new
|
data/lib/tcell_agent/devise.rb
CHANGED
@@ -5,12 +5,6 @@ require 'devise/rails'
|
|
5
5
|
require 'devise/strategies/database_authenticatable'
|
6
6
|
require 'tcell_agent/userinfo'
|
7
7
|
require 'tcell_agent/logger'
|
8
|
-
#Warden::Manager.after_authentication do |user,auth,opts|
|
9
|
-
# p "<M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M"
|
10
|
-
# p user
|
11
|
-
# # do something with user
|
12
|
-
#end
|
13
|
-
|
14
8
|
require 'tcell_agent/sensor_events/honeytokens'
|
15
9
|
|
16
10
|
module TCellAgent
|
@@ -39,45 +33,5 @@ module TCellAgent
|
|
39
33
|
end
|
40
34
|
end
|
41
35
|
end
|
42
|
-
# Devise::Strategies::DatabaseAuthenticatable.class_eval do
|
43
|
-
# alias_method :original_authenticate!, :authenticate!
|
44
|
-
# def authenticate!
|
45
|
-
# begin
|
46
|
-
# tcell_background_worker = TCellAgent.thread_agent
|
47
|
-
# # if (tcell_background_worker && tcell_background_worker.honeytokens_policy)
|
48
|
-
# # credstring = ""
|
49
|
-
# # authentication_keys.each do |authentication_key|
|
50
|
-
# # credstring = credstring + authentication_hash[authentication_key] + "::"
|
51
|
-
# # end
|
52
|
-
# # credstring = credstring + password[1..-3] # Chop off first and last 2 characters
|
53
|
-
# # token_id = tcell_background_worker.honeytokens_policy.id_for_credentialstring(credstring)
|
54
|
-
# # if token_id
|
55
|
-
# # begin
|
56
|
-
# # event = TCellAgent::SensorEvents::HoneytokensSensorEvent.new(request, token_id)
|
57
|
-
# # TCellAgent.send_event(event)
|
58
|
-
# # rescue
|
59
|
-
# # #pass
|
60
|
-
# # end
|
61
|
-
# # return
|
62
|
-
# # end
|
63
|
-
# # end
|
64
|
-
# rescue Exception => e
|
65
|
-
# TCellAgent.logger.error("uncaught exception while processing honeytokens: #{e.message}")
|
66
|
-
# end
|
67
|
-
# original_authenticate!
|
68
|
-
# end
|
69
|
-
# end
|
70
36
|
end
|
71
37
|
end
|
72
|
-
# module Devise
|
73
|
-
# module Models
|
74
|
-
# module Recoverable
|
75
|
-
# extend ActiveSupport::Concern
|
76
|
-
# alias_method :original_send_reset_password_instructions, :send_reset_password_instructions
|
77
|
-
# def send_reset_password_instructions
|
78
|
-
# x = original_send_reset_password_instructions
|
79
|
-
# x
|
80
|
-
# end
|
81
|
-
# end
|
82
|
-
# end
|
83
|
-
# end
|
@@ -62,7 +62,7 @@ module TCellAgent
|
|
62
62
|
class TCellData
|
63
63
|
attr_accessor :transaction_id, :session_id, :hmac_session_id, :user_id, :route_id,
|
64
64
|
:uri, :context_filters_by_term, :database_filters, :ip_address, :user_agent, :request_method,
|
65
|
-
:path_parameters, :ip_blocking_triggered, :grape_mount_endpoint
|
65
|
+
:path_parameters, :ip_blocking_triggered, :grape_mount_endpoint, :referrer, :path
|
66
66
|
|
67
67
|
def self.filterx(sanitize_string, event_flag, replace_flag, term)
|
68
68
|
send_event = false
|
@@ -1,57 +1,63 @@
|
|
1
1
|
# See the file "LICENSE" for the full license governing this code.
|
2
2
|
|
3
|
-
|
4
|
-
require 'tcell_agent/configuration'
|
5
|
-
require 'tcell_agent/instrumentation'
|
3
|
+
if TCellAgent.configuration.should_instrument_authlogic?
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require 'tcell_agent/agent'
|
11
|
-
require 'tcell_agent/sensor_events/login_fraud'
|
12
|
-
Authlogic::Session::Base.class_eval do
|
13
|
-
alias_method :original_save, :save
|
14
|
-
def save(&block)
|
15
|
-
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
16
|
-
user_logged_in_before = (user != nil)
|
17
|
-
success = original_save
|
18
|
-
user_logged_in_after = (user != nil)
|
19
|
-
TCellAgent::Instrumentation.safe_block("Authlogic login info") {
|
5
|
+
require 'tcell_agent/logger'
|
6
|
+
require 'tcell_agent/configuration'
|
7
|
+
require 'tcell_agent/instrumentation'
|
20
8
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
9
|
+
module TCellAgent
|
10
|
+
if defined?(Authlogic)
|
11
|
+
TCellAgent.logger.debug("Instrumenting Authlogic")
|
12
|
+
require 'tcell_agent/agent'
|
13
|
+
require 'tcell_agent/sensor_events/login_fraud'
|
14
|
+
Authlogic::Session::Base.class_eval do
|
15
|
+
alias_method :original_save, :save
|
16
|
+
def save(&block)
|
17
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
18
|
+
user_logged_in_before = (user != nil)
|
19
|
+
success = original_save
|
20
|
+
user_logged_in_after = (user != nil)
|
21
|
+
TCellAgent::Instrumentation.safe_block("Authlogic login info") {
|
22
|
+
|
23
|
+
login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
|
24
|
+
if (login_fraud_policy && login_fraud_policy.enabled)
|
25
|
+
user_id = nil
|
26
|
+
TCellAgent::Instrumentation.safe_block("getting userid for login form") {
|
27
|
+
user_id = self.send(self.class.login_field.to_sym)
|
28
|
+
}
|
29
|
+
if (user_logged_in_before && user_logged_in_after)
|
30
|
+
#password changed or logged in as another user
|
31
|
+
elsif (!user_logged_in_before && !user_logged_in_after)
|
32
|
+
if (login_fraud_policy.login_failed_enabled)
|
33
|
+
request = Authlogic::Session::Base.controller.request
|
34
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
35
|
+
if tcell_data
|
36
|
+
event = TCellAgent::SensorEvents::LoginFailure.new(request.env, tcell_data, user_id)
|
37
|
+
TCellAgent.send_event(event)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
elsif (!user_logged_in_before && user_logged_in_after)
|
41
|
+
if (login_fraud_policy.login_success_enabled)
|
42
|
+
request = Authlogic::Session::Base.controller.request
|
43
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
44
|
+
if tcell_data
|
45
|
+
event = TCellAgent::SensorEvents::LoginSuccess.new(request.env, tcell_data, user_id)
|
46
|
+
TCellAgent.send_event(event)
|
47
|
+
end
|
48
|
+
end
|
44
49
|
end
|
45
50
|
end
|
46
|
-
|
47
|
-
}
|
51
|
+
}
|
48
52
|
|
49
|
-
|
53
|
+
success
|
50
54
|
|
51
|
-
|
52
|
-
|
53
|
-
|
55
|
+
else
|
56
|
+
original_save
|
57
|
+
end # if instrument
|
58
|
+
end
|
54
59
|
end
|
55
|
-
end
|
56
|
-
end
|
60
|
+
end # if Authlogic
|
61
|
+
end
|
62
|
+
|
57
63
|
end
|
@@ -1,80 +1,112 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
if TCellAgent.configuration.should_instrument_devise? && defined?(Devise)
|
2
|
+
module TCellAgent
|
3
3
|
|
4
|
+
require 'base64'
|
4
5
|
require 'tcell_agent/agent'
|
5
6
|
require 'tcell_agent/sensor_events/login_fraud'
|
6
7
|
require 'tcell_agent/policies/appsensor_policy'
|
7
8
|
|
8
|
-
|
9
|
+
module DeviseInstrumentation
|
10
|
+
def self.report_login_event(clazz, request_env, user_id)
|
11
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
|
14
|
+
if (login_fraud_policy && login_fraud_policy.enabled && login_fraud_policy.login_failed_enabled)
|
15
|
+
tcell_data = request_env[TCellAgent::Instrumentation::TCELL_ID]
|
16
|
+
if tcell_data
|
17
|
+
TCellAgent.send_event(clazz.new(request_env, tcell_data, user_id))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
18
21
|
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
module TCellFailureAppRespond
|
24
|
+
def respond
|
25
|
+
TCellAgent::Instrumentation.safe_block("Devise Failure App Respond") do
|
26
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
27
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
28
|
+
if tcell_data
|
29
|
+
# in the case of http auth, the user_id is set in
|
30
|
+
# Devise::Strategies::Authenticatable.valid_for_http_auth?
|
31
|
+
user_id = tcell_data.user_id
|
32
|
+
user_id = _get_tcell_username unless user_id
|
33
|
+
TCellAgent::DeviseInstrumentation.report_login_event(
|
34
|
+
TCellAgent::SensorEvents::LoginFailure,
|
35
|
+
request.env,
|
36
|
+
user_id
|
37
|
+
)
|
38
|
+
end
|
23
39
|
|
24
|
-
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
25
|
-
TCellAgent::Instrumentation.safe_block("Devise login successful") {
|
26
|
-
tcell_username = _get_tcell_username
|
27
|
-
login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
|
28
|
-
if (login_fraud_policy && login_fraud_policy.enabled && login_fraud_policy.login_success_enabled)
|
29
|
-
hmac_session_id = request.env[TCellAgent::Instrumentation::TCELL_ID].hmac_session_id
|
30
|
-
request.env[TCellAgent::Instrumentation::TCELL_ID].user_id = TCellAgent::UserInformation.getUserFromRequest(request)
|
31
|
-
user_id = tcell_username || request.env[TCellAgent::Instrumentation::TCELL_ID].user_id
|
32
|
-
event = TCellAgent::SensorEvents::LoginSuccess.new(request, response, user_id, hmac_session_id)
|
33
|
-
TCellAgent.send_event(event)
|
34
40
|
end
|
35
|
-
|
41
|
+
end
|
42
|
+
|
43
|
+
super if defined?(super)
|
36
44
|
end
|
37
45
|
|
38
|
-
|
46
|
+
def _get_tcell_username
|
47
|
+
_tcell_username = nil
|
48
|
+
TCellAgent::Instrumentation.safe_block("Devise Get TCell Username") {
|
49
|
+
keys = scope_class.authentication_keys.dup
|
50
|
+
user_params = request.POST.fetch("user",{})
|
51
|
+
keys.each do |key|
|
52
|
+
next_usename = user_params.fetch(key, nil)
|
53
|
+
if next_usename
|
54
|
+
_tcell_username ||= ""
|
55
|
+
_tcell_username += next_usename
|
56
|
+
end
|
57
|
+
end
|
58
|
+
}
|
59
|
+
_tcell_username
|
60
|
+
end
|
39
61
|
end
|
62
|
+
end
|
40
63
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
64
|
+
# prepend is ruby 2+ feature
|
65
|
+
Devise::FailureApp.send(:prepend, DeviseInstrumentation::TCellFailureAppRespond)
|
66
|
+
|
67
|
+
Devise::Strategies::Authenticatable.class_eval do
|
68
|
+
alias_method :tcell_valid_for_http_auth?, :valid_for_http_auth?
|
69
|
+
def valid_for_http_auth?
|
70
|
+
is_valid = tcell_valid_for_http_auth?
|
71
|
+
|
72
|
+
TCellAgent::Instrumentation.safe_block("Devise set username for http basic auth") do
|
73
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
74
|
+
if http_auth_hash && tcell_data
|
75
|
+
username = http_auth_hash[http_authentication_key]
|
76
|
+
tcell_data.user_id = username if username && !tcell_data.user_id
|
52
77
|
end
|
53
|
-
|
54
|
-
|
78
|
+
end
|
79
|
+
|
80
|
+
is_valid
|
55
81
|
end
|
56
82
|
|
57
|
-
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
83
|
+
alias_method :tcell_validate, :validate
|
84
|
+
def validate(resource, &block)
|
85
|
+
is_valid = tcell_validate(resource, &block)
|
86
|
+
|
87
|
+
TCellAgent::Instrumentation.safe_block("Devise Authenticatable Validate") do
|
88
|
+
if (is_valid && TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
89
|
+
username = nil
|
90
|
+
(authentication_keys || []).each do |auth_key|
|
91
|
+
attr = authentication_hash[auth_key]
|
92
|
+
if attr
|
93
|
+
username ||= ""
|
94
|
+
username += attr
|
68
95
|
end
|
69
96
|
end
|
70
|
-
|
97
|
+
|
98
|
+
TCellAgent::DeviseInstrumentation.report_login_event(
|
99
|
+
TCellAgent::SensorEvents::LoginSuccess,
|
100
|
+
request.env,
|
101
|
+
username
|
102
|
+
)
|
103
|
+
end
|
71
104
|
end
|
72
|
-
end
|
73
105
|
|
74
|
-
|
75
|
-
(options = env["warden.options"]) && options[:action] == "unauthenticated"
|
106
|
+
is_valid
|
76
107
|
end
|
108
|
+
|
77
109
|
end
|
78
110
|
|
79
|
-
end
|
111
|
+
end
|
80
112
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
if TCellAgent.configuration.should_instrument_doorkeeper?
|
2
|
+
|
3
|
+
if defined?(Doorkeeper)
|
4
|
+
require 'tcell_agent/agent'
|
5
|
+
require 'tcell_agent/sensor_events/login_fraud'
|
6
|
+
require 'tcell_agent/policies/appsensor_policy'
|
7
|
+
require 'tcell_agent/sensor_events/login_fraud'
|
8
|
+
|
9
|
+
module TCellAgent
|
10
|
+
module DoorkeeperInstrumentation
|
11
|
+
|
12
|
+
Doorkeeper::TokensController.class_eval do
|
13
|
+
alias_method :tcell_authorize_response, :authorize_response
|
14
|
+
def authorize_response
|
15
|
+
result = tcell_authorize_response
|
16
|
+
|
17
|
+
TCellAgent::Instrumentation.safe_block("Doorkeeper Token Authorize") do
|
18
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
19
|
+
login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
|
20
|
+
if (login_fraud_policy && login_fraud_policy.enabled && login_fraud_policy.login_failed_enabled)
|
21
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
22
|
+
if tcell_data
|
23
|
+
if result.is_a?(Doorkeeper::OAuth::TokenResponse)
|
24
|
+
TCellAgent.send_event(
|
25
|
+
TCellAgent::SensorEvents::LoginSuccess.new(request.env, tcell_data, result.token.resource_owner_id)
|
26
|
+
)
|
27
|
+
elsif result.is_a?(Doorkeeper::OAuth::ErrorResponse)
|
28
|
+
TCellAgent.send_event(
|
29
|
+
TCellAgent::SensorEvents::LoginFailure.new(request.env, tcell_data, request.POST['client_id'])
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module TCellAuthorizationsNew
|
43
|
+
def new
|
44
|
+
super if defined?(super)
|
45
|
+
|
46
|
+
TCellAgent::Instrumentation.safe_block("Doorkeeper Token Authorize") do
|
47
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
48
|
+
if pre_auth.error
|
49
|
+
login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
|
50
|
+
if (login_fraud_policy && login_fraud_policy.enabled && login_fraud_policy.login_failed_enabled)
|
51
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
52
|
+
if tcell_data && pre_auth.error
|
53
|
+
TCellAgent.send_event(
|
54
|
+
TCellAgent::SensorEvents::LoginFailure.new(request.env, tcell_data, current_resource_owner.id)
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# prepend is ruby 2+ feature
|
65
|
+
Doorkeeper::AuthorizationsController.send(:prepend, TCellAuthorizationsNew)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'tcell_agent/agent'
|
2
|
+
require 'tcell_agent/sensor_events/login_fraud'
|
3
|
+
require 'tcell_agent/policies/appsensor_policy'
|
4
|
+
require 'tcell_agent/sensor_events/login_fraud'
|
5
|
+
|
6
|
+
if defined?(TCellAgent::Hooks::V1::Frameworks::Rails::Login)
|
7
|
+
TCellAgent::Hooks::V1::Frameworks::Rails::Login.module_eval do
|
8
|
+
class << self
|
9
|
+
alias_method :tcell_register_login_event, :register_login_event
|
10
|
+
def register_login_event(status, rails_request, user_id, user_valid=nil)
|
11
|
+
TCellAgent::Instrumentation.safe_block("Rails Auth Hooks") do
|
12
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
13
|
+
login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
|
14
|
+
if (login_fraud_policy && login_fraud_policy.enabled && login_fraud_policy.login_failed_enabled)
|
15
|
+
tcell_data = rails_request.env[TCellAgent::Instrumentation::TCELL_ID]
|
16
|
+
if tcell_data
|
17
|
+
if status == TCellAgent::Hooks::V1::Login::LOGIN_FAILURE
|
18
|
+
TCellAgent.send_event(
|
19
|
+
TCellAgent::SensorEvents::LoginFailure.new(rails_request.env, tcell_data, user_id)
|
20
|
+
)
|
21
|
+
elsif status == TCellAgent::Hooks::V1::Login::LOGIN_SUCCESS
|
22
|
+
TCellAgent.send_event(
|
23
|
+
TCellAgent::SensorEvents::LoginSuccess.new(rails_request.env, tcell_data, user_id)
|
24
|
+
)
|
25
|
+
else
|
26
|
+
TCellAgent.logger.error("Unkown login status: #{status}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if defined?(TCellAgent::Hooks::V1::Login)
|
38
|
+
TCellAgent::Hooks::V1::Login.module_eval do
|
39
|
+
class << self
|
40
|
+
alias_method :tcell_register_login_event, :register_login_event
|
41
|
+
def register_login_event(
|
42
|
+
status,
|
43
|
+
session_id,
|
44
|
+
user_agent,
|
45
|
+
referrer,
|
46
|
+
remote_address,
|
47
|
+
header_keys,
|
48
|
+
user_id,
|
49
|
+
document_uri,
|
50
|
+
user_valid=nil)
|
51
|
+
TCellAgent::Instrumentation.safe_block("Login Auth Hooks") do
|
52
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
53
|
+
login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
|
54
|
+
if (login_fraud_policy && login_fraud_policy.enabled && login_fraud_policy.login_failed_enabled)
|
55
|
+
tcell_data = TCellAgent::Instrumentation::TCellData.new
|
56
|
+
tcell_data.user_agent = user_agent
|
57
|
+
tcell_data.referrer = referrer
|
58
|
+
tcell_data.ip_address = remote_address
|
59
|
+
tcell_data.path = document_uri
|
60
|
+
tcell_data.hmac_session_id = TCellAgent::SensorEvents::Util.hmac(session_id)
|
61
|
+
|
62
|
+
if status == TCellAgent::Hooks::V1::Login::LOGIN_FAILURE
|
63
|
+
TCellAgent.send_event(
|
64
|
+
TCellAgent::SensorEvents::LoginFailure.new(header_keys, tcell_data, user_id)
|
65
|
+
)
|
66
|
+
elsif status == TCellAgent::Hooks::V1::Login::LOGIN_SUCCESS
|
67
|
+
TCellAgent.send_event(
|
68
|
+
TCellAgent::SensorEvents::LoginSuccess.new(header_keys, tcell_data, user_id)
|
69
|
+
)
|
70
|
+
else
|
71
|
+
TCellAgent.logger.error("Unkown login status: #{status}")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -47,6 +47,8 @@ module TCellAgent
|
|
47
47
|
TCellAgent::Instrumentation.safe_block("Setting and ip address user agent") {
|
48
48
|
env[TCellAgent::Instrumentation::TCELL_ID].ip_address = TCellAgent::Utils::Rails.better_ip(request)
|
49
49
|
env[TCellAgent::Instrumentation::TCELL_ID].user_agent = request.user_agent
|
50
|
+
env[TCellAgent::Instrumentation::TCELL_ID].path = request.path
|
51
|
+
env[TCellAgent::Instrumentation::TCELL_ID].referrer = request.referrer
|
50
52
|
}
|
51
53
|
end
|
52
54
|
|
@@ -26,6 +26,8 @@ else
|
|
26
26
|
require 'tcell_agent/rails/auth/devise' if defined?(Devise)
|
27
27
|
require 'tcell_agent/authlogic' if defined?(Authlogic)
|
28
28
|
require 'tcell_agent/rails/auth/authlogic' if defined?(Authlogic)
|
29
|
+
require 'tcell_agent/rails/auth/doorkeeper'
|
30
|
+
require 'tcell_agent/rails/auth/hooks'
|
29
31
|
end
|
30
32
|
|
31
33
|
# TODO: will this get run ever?
|
data/lib/tcell_agent/rails.rb
CHANGED
@@ -31,6 +31,8 @@ module TCellAgent
|
|
31
31
|
require 'tcell_agent/rails/auth/devise' if defined?(Devise)
|
32
32
|
require 'tcell_agent/authlogic' if defined?(Authlogic)
|
33
33
|
require 'tcell_agent/rails/auth/authlogic' if defined?(Authlogic)
|
34
|
+
require 'tcell_agent/rails/auth/doorkeeper'
|
35
|
+
require 'tcell_agent/rails/auth/hooks'
|
34
36
|
end
|
35
37
|
app.config.middleware.insert_before(0, TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware)
|
36
38
|
app.config.middleware.insert_after(0, TCellAgent::Instrumentation::Rails::Middleware::HeadersMiddleware)
|
@@ -19,9 +19,9 @@ module TCellAgent
|
|
19
19
|
pattern=nil)
|
20
20
|
super("as")
|
21
21
|
self["dp"] = detection_point
|
22
|
-
self["param"] = param if param
|
23
|
-
self["remote_addr"] = remote_addr if remote_addr
|
24
|
-
self["m"] = method if method
|
22
|
+
self["param"] = param.to_s if param
|
23
|
+
self["remote_addr"] = remote_addr.to_s if remote_addr
|
24
|
+
self["m"] = method.to_s if method
|
25
25
|
@raw_location = location
|
26
26
|
@user_id = user_id
|
27
27
|
@hmac_session_id = hmac_session_id
|
@@ -3,41 +3,52 @@
|
|
3
3
|
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
4
4
|
require 'tcell_agent/sensor_events/sensor'
|
5
5
|
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
6
|
+
|
6
7
|
module TCellAgent
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
headers = request.env.select {|k,v| k.start_with? 'HTTP_'}
|
13
|
-
.collect {|k,v| k.sub(/^HTTP_/, '') }
|
14
|
-
self["event_name"] = "login-failure"
|
15
|
-
self["user_agent"] = request.env['HTTP_USER_AGENT']
|
16
|
-
self["referrer"] = request.referer
|
17
|
-
self["remote_addr"] = request.remote_ip
|
18
|
-
self["header_keys"] = headers
|
19
|
-
self["user_id"] = user_id
|
20
|
-
self["document_uri"] = TCellAgent::SensorEvents::Util.strip_uri_values(request.path)
|
21
|
-
self["session"] = hmac_session_id
|
22
|
-
end
|
23
|
-
end
|
8
|
+
module SensorEvents
|
9
|
+
|
10
|
+
class LoginEvent < TCellSensorEvent
|
11
|
+
def initialize(header_keys, tcell_data, user_id, user_valid)
|
12
|
+
super("login")
|
24
13
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
14
|
+
self["header_keys"] = header_keys
|
15
|
+
|
16
|
+
self["user_agent"] = tcell_data.user_agent.to_s if tcell_data.user_agent
|
17
|
+
self["referrer"] = tcell_data.referrer.to_s if tcell_data.referrer
|
18
|
+
self["remote_addr"] = tcell_data.ip_address.to_s if tcell_data.ip_address
|
19
|
+
self["user_id"] = user_id.to_s if user_id
|
20
|
+
self["document_uri"] = TCellAgent::SensorEvents::Util.strip_uri_values(tcell_data.path) if tcell_data.path
|
21
|
+
self["session"] = tcell_data.hmac_session_id if tcell_data.hmac_session_id
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
def clean_header_keys(request_env_or_header_keys)
|
26
|
+
if request_env_or_header_keys.is_a?(Hash)
|
27
|
+
request_env_or_header_keys.select {|k,v| k.start_with? 'HTTP_'}.collect {|k,v| k.sub(/^HTTP_/, '') }
|
28
|
+
else
|
29
|
+
request_env_or_header_keys.map { |k| k.sub(/^HTTP_/, '') }
|
30
|
+
end
|
40
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class LoginFailure < LoginEvent
|
35
|
+
def initialize(request_env_or_header_keys, tcell_data, user_id, user_valid=nil)
|
36
|
+
header_keys = clean_header_keys(request_env_or_header_keys)
|
37
|
+
|
38
|
+
super(header_keys, tcell_data, user_id, user_valid)
|
39
|
+
|
40
|
+
self["event_name"] = "login-failure"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class LoginSuccess < LoginEvent
|
45
|
+
def initialize(request_env_or_header_keys, tcell_data, user_id, user_valid=nil)
|
46
|
+
header_keys = clean_header_keys(request_env_or_header_keys)
|
47
|
+
|
48
|
+
super(header_keys, tcell_data, user_id, user_valid)
|
41
49
|
|
50
|
+
self["event_name"] = "login-success"
|
51
|
+
end
|
42
52
|
end
|
43
|
-
end
|
53
|
+
end
|
54
|
+
end
|
@@ -10,19 +10,19 @@ Unicorn::HttpServer.class_eval do
|
|
10
10
|
# this only runs when preload_app=true because when preload_app=false
|
11
11
|
# the gems aren't loaded early enough for tcell to override
|
12
12
|
# the class definitions
|
13
|
-
alias_method :
|
14
|
-
def
|
13
|
+
alias_method :tcell_bind_new_listeners!, :bind_new_listeners!
|
14
|
+
def bind_new_listeners!
|
15
15
|
TCellAgent.run_instrumentation("Unicorn")
|
16
16
|
|
17
|
-
|
17
|
+
tcell_bind_new_listeners!
|
18
18
|
end
|
19
19
|
|
20
20
|
# This gets called when unicorn receives the HUP signal to reload its config.
|
21
21
|
# Tcell also needs to ensure its config is reloaded and services are started
|
22
22
|
# or stopped accordingly
|
23
|
-
alias_method :
|
23
|
+
alias_method :tcell_load_config!, :load_config!
|
24
24
|
def load_config!
|
25
|
-
|
25
|
+
tcell_load_config!
|
26
26
|
|
27
27
|
TCellAgent::Instrumentation.safe_block("Reloading Tcell Config") do
|
28
28
|
new_config = TCellAgent::Configuration.new
|
@@ -94,9 +94,9 @@ Unicorn::HttpServer.class_eval do
|
|
94
94
|
# this only runs when preload_app=true because when preload_app=false
|
95
95
|
# the gems aren't loaded early enough for tcell to override
|
96
96
|
# the class definitions
|
97
|
-
alias
|
97
|
+
alias tcell_init_worker_process init_worker_process
|
98
98
|
def init_worker_process(work)
|
99
|
-
start_process =
|
99
|
+
start_process = tcell_init_worker_process(work)
|
100
100
|
|
101
101
|
if TCellAgent.configuration.enabled && TCellAgent.configuration.should_instrument?
|
102
102
|
begin
|
data/lib/tcell_agent/version.rb
CHANGED
@@ -0,0 +1,246 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module TCellAgent
|
4
|
+
|
5
|
+
module Hooks
|
6
|
+
module V1
|
7
|
+
module Frameworks
|
8
|
+
module Rails
|
9
|
+
module Login
|
10
|
+
def self.register_login_event(status, rails_request, user_id, user_valid=nil)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Hooks
|
19
|
+
module V1
|
20
|
+
module Login
|
21
|
+
LOGIN_SUCCESS = "success"
|
22
|
+
LOGIN_FAILURE = "failure"
|
23
|
+
def self.register_login_event(status, session_id, user_agent, referrer, remote_addr, header_keys, user_id, document_uri, user_valid=nil)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "manually requiring auth hooks" do
|
30
|
+
before(:all) do
|
31
|
+
require 'tcell_agent/rails/auth/hooks'
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "Using generic interface" do
|
35
|
+
context "with a login failure" do
|
36
|
+
it "should report the login failure" do
|
37
|
+
login_fraud = double("login_fraud", enabled: true, login_failed_enabled: true)
|
38
|
+
|
39
|
+
expect(TCellAgent).to receive(:policy).with(TCellAgent::PolicyTypes::LoginFraud).and_return(
|
40
|
+
login_fraud
|
41
|
+
)
|
42
|
+
expect(TCellAgent).to receive(:send_event).with(
|
43
|
+
{
|
44
|
+
"event_type" => "login",
|
45
|
+
"header_keys" => ["USER_AGENT", "X_FORWARDED_FOR"],
|
46
|
+
"user_agent" => "user_agent",
|
47
|
+
"referrer" => "referrer",
|
48
|
+
"remote_addr" => "1.1.1.1",
|
49
|
+
"user_id" => "user_id",
|
50
|
+
"document_uri" => "http://tcell.tcell.io/login?param_name=",
|
51
|
+
"session" => "48c0ce7961d8d5d4bd57bd77976b3d38",
|
52
|
+
"event_name" => "login-failure"
|
53
|
+
}
|
54
|
+
)
|
55
|
+
|
56
|
+
status = Hooks::V1::Login::LOGIN_FAILURE
|
57
|
+
header_keys = ["HTTP_USER_AGENT", "HTTP_X_FORWARDED_FOR"]
|
58
|
+
document_uri = "http://tcell.tcell.io/login?param_name=param_value"
|
59
|
+
|
60
|
+
Hooks::V1::Login.register_login_event(
|
61
|
+
status, "session_id", "user_agent", "referrer", "1.1.1.1", header_keys, "user_id", document_uri
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "with a login success" do
|
67
|
+
it "should report the login success" do
|
68
|
+
login_fraud = double("login_fraud", enabled: true, login_failed_enabled: true)
|
69
|
+
|
70
|
+
expect(TCellAgent).to receive(:policy).with(TCellAgent::PolicyTypes::LoginFraud).and_return(
|
71
|
+
login_fraud
|
72
|
+
)
|
73
|
+
expect(TCellAgent).to receive(:send_event).with(
|
74
|
+
{
|
75
|
+
"event_type" => "login",
|
76
|
+
"header_keys" => ["USER_AGENT", "X_FORWARDED_FOR"],
|
77
|
+
"user_agent" => "user_agent",
|
78
|
+
"referrer" => "referrer",
|
79
|
+
"remote_addr" => "1.1.1.1",
|
80
|
+
"user_id" => "user_id",
|
81
|
+
"document_uri" => "http://tcell.tcell.io/login?param_name=",
|
82
|
+
"session" => "48c0ce7961d8d5d4bd57bd77976b3d38",
|
83
|
+
"event_name" => "login-success"
|
84
|
+
}
|
85
|
+
)
|
86
|
+
|
87
|
+
status = Hooks::V1::Login::LOGIN_SUCCESS
|
88
|
+
header_keys = ["HTTP_USER_AGENT", "HTTP_X_FORWARDED_FOR"]
|
89
|
+
document_uri = "http://tcell.tcell.io/login?param_name=param_value"
|
90
|
+
|
91
|
+
Hooks::V1::Login.register_login_event(
|
92
|
+
status, "session_id", "user_agent", "referrer", "1.1.1.1", header_keys, "user_id", document_uri
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "with an unknown status" do
|
98
|
+
it "should log the error" do
|
99
|
+
login_fraud = double("login_fraud", enabled: true, login_failed_enabled: true)
|
100
|
+
logger = double("logger")
|
101
|
+
|
102
|
+
expect(TCellAgent).to receive(:policy).with(TCellAgent::PolicyTypes::LoginFraud).and_return(
|
103
|
+
login_fraud
|
104
|
+
)
|
105
|
+
expect(TCellAgent).to_not receive(:send_event)
|
106
|
+
expect(TCellAgent).to receive(:logger).and_return(logger)
|
107
|
+
expect(logger).to receive(:error).with("Unkown login status: mumbo-jumbo")
|
108
|
+
|
109
|
+
status = "mumbo-jumbo"
|
110
|
+
header_keys = ["HTTP_USER_AGENT", "HTTP_X_FORWARDED_FOR"]
|
111
|
+
document_uri = "http://tcell.tcell.io/login?param_name=param_value"
|
112
|
+
|
113
|
+
Hooks::V1::Login.register_login_event(
|
114
|
+
status, "session_id", "user_agent", "referrer", "1.1.1.1", header_keys, "user_id", document_uri
|
115
|
+
)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "Using rails interface" do
|
121
|
+
context "with a login failure" do
|
122
|
+
it "should report the login failure" do
|
123
|
+
login_fraud = double("login_fraud", enabled: true, login_failed_enabled: true)
|
124
|
+
rails_request = double("rails_request")
|
125
|
+
tcell_data = TCellAgent::Instrumentation::TCellData.new
|
126
|
+
tcell_data.user_agent = "user_agent"
|
127
|
+
tcell_data.referrer = "referrer"
|
128
|
+
tcell_data.ip_address = "1.1.1.1"
|
129
|
+
tcell_data.path = "http://tcell.tcell.io/login?param_name=param_value"
|
130
|
+
tcell_data.hmac_session_id = TCellAgent::SensorEvents::Util.hmac("session_id")
|
131
|
+
request_env = {
|
132
|
+
TCellAgent::Instrumentation::TCELL_ID => tcell_data,
|
133
|
+
"HTTP_USER_AGENT" => true,
|
134
|
+
"HTTP_X_FORWARDED_FOR" => true
|
135
|
+
}
|
136
|
+
|
137
|
+
|
138
|
+
expect(TCellAgent).to receive(:policy).with(TCellAgent::PolicyTypes::LoginFraud).and_return(
|
139
|
+
login_fraud
|
140
|
+
)
|
141
|
+
expect(rails_request).to receive(:env).and_return(request_env)
|
142
|
+
expect(rails_request).to receive(:env).and_return(request_env)
|
143
|
+
expect(TCellAgent).to receive(:send_event).with(
|
144
|
+
{
|
145
|
+
"event_type" => "login",
|
146
|
+
"header_keys" => ["USER_AGENT", "X_FORWARDED_FOR"],
|
147
|
+
"user_agent" => "user_agent",
|
148
|
+
"referrer" => "referrer",
|
149
|
+
"remote_addr" => "1.1.1.1",
|
150
|
+
"user_id" => "user_id",
|
151
|
+
"document_uri" => "http://tcell.tcell.io/login?param_name=",
|
152
|
+
"session" => "48c0ce7961d8d5d4bd57bd77976b3d38",
|
153
|
+
"event_name" => "login-failure"
|
154
|
+
}
|
155
|
+
)
|
156
|
+
|
157
|
+
status = Hooks::V1::Login::LOGIN_FAILURE
|
158
|
+
|
159
|
+
Hooks::V1::Frameworks::Rails::Login.register_login_event(
|
160
|
+
status, rails_request, "user_id"
|
161
|
+
)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "with a login success" do
|
166
|
+
it "should report the login success" do
|
167
|
+
login_fraud = double("login_fraud", enabled: true, login_failed_enabled: true)
|
168
|
+
rails_request = double("rails_request")
|
169
|
+
tcell_data = TCellAgent::Instrumentation::TCellData.new
|
170
|
+
tcell_data.user_agent = "user_agent"
|
171
|
+
tcell_data.referrer = "referrer"
|
172
|
+
tcell_data.ip_address = "1.1.1.1"
|
173
|
+
tcell_data.path = "http://tcell.tcell.io/login?param_name=param_value"
|
174
|
+
tcell_data.hmac_session_id = TCellAgent::SensorEvents::Util.hmac("session_id")
|
175
|
+
request_env = {
|
176
|
+
TCellAgent::Instrumentation::TCELL_ID => tcell_data,
|
177
|
+
"HTTP_USER_AGENT" => true,
|
178
|
+
"HTTP_X_FORWARDED_FOR" => true
|
179
|
+
}
|
180
|
+
|
181
|
+
|
182
|
+
expect(TCellAgent).to receive(:policy).with(TCellAgent::PolicyTypes::LoginFraud).and_return(
|
183
|
+
login_fraud
|
184
|
+
)
|
185
|
+
expect(rails_request).to receive(:env).and_return(request_env)
|
186
|
+
expect(rails_request).to receive(:env).and_return(request_env)
|
187
|
+
expect(TCellAgent).to receive(:send_event).with(
|
188
|
+
{
|
189
|
+
"event_type" => "login",
|
190
|
+
"header_keys" => ["USER_AGENT", "X_FORWARDED_FOR"],
|
191
|
+
"user_agent" => "user_agent",
|
192
|
+
"referrer" => "referrer",
|
193
|
+
"remote_addr" => "1.1.1.1",
|
194
|
+
"user_id" => "user_id",
|
195
|
+
"document_uri" => "http://tcell.tcell.io/login?param_name=",
|
196
|
+
"session" => "48c0ce7961d8d5d4bd57bd77976b3d38",
|
197
|
+
"event_name" => "login-success"
|
198
|
+
}
|
199
|
+
)
|
200
|
+
|
201
|
+
status = Hooks::V1::Login::LOGIN_SUCCESS
|
202
|
+
|
203
|
+
Hooks::V1::Frameworks::Rails::Login.register_login_event(
|
204
|
+
status, rails_request, "user_id"
|
205
|
+
)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "with an unknown status" do
|
210
|
+
it "should log the error" do
|
211
|
+
login_fraud = double("login_fraud", enabled: true, login_failed_enabled: true)
|
212
|
+
logger = double("logger")
|
213
|
+
rails_request = double("rails_request")
|
214
|
+
tcell_data = TCellAgent::Instrumentation::TCellData.new
|
215
|
+
tcell_data.user_agent = "user_agent"
|
216
|
+
tcell_data.referrer = "referrer"
|
217
|
+
tcell_data.ip_address = "1.1.1.1"
|
218
|
+
tcell_data.path = "http://tcell.tcell.io/login?param_name=param_value"
|
219
|
+
tcell_data.hmac_session_id = TCellAgent::SensorEvents::Util.hmac("session_id")
|
220
|
+
request_env = {
|
221
|
+
TCellAgent::Instrumentation::TCELL_ID => tcell_data,
|
222
|
+
"HTTP_USER_AGENT" => true,
|
223
|
+
"HTTP_X_FORWARDED_FOR" => true
|
224
|
+
}
|
225
|
+
|
226
|
+
|
227
|
+
expect(TCellAgent).to receive(:policy).with(TCellAgent::PolicyTypes::LoginFraud).and_return(
|
228
|
+
login_fraud
|
229
|
+
)
|
230
|
+
expect(rails_request).to receive(:env).and_return(request_env)
|
231
|
+
expect(TCellAgent).to_not receive(:send_event)
|
232
|
+
expect(TCellAgent).to receive(:logger).and_return(logger)
|
233
|
+
expect(logger).to receive(:error).with("Unkown login status: mumbo-jumbo")
|
234
|
+
|
235
|
+
status = "mumbo-jumbo"
|
236
|
+
|
237
|
+
Hooks::V1::Frameworks::Rails::Login.register_login_event(
|
238
|
+
status, rails_request, "user_id"
|
239
|
+
)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tcell_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garrett
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -185,6 +185,8 @@ files:
|
|
185
185
|
- lib/tcell_agent/policies/secure_headers_policy.rb
|
186
186
|
- lib/tcell_agent/rails/auth/authlogic.rb
|
187
187
|
- lib/tcell_agent/rails/auth/devise.rb
|
188
|
+
- lib/tcell_agent/rails/auth/doorkeeper.rb
|
189
|
+
- lib/tcell_agent/rails/auth/hooks.rb
|
188
190
|
- lib/tcell_agent/rails/better_ip.rb
|
189
191
|
- lib/tcell_agent/rails/csrf_exception.rb
|
190
192
|
- lib/tcell_agent/rails/dlp/process_request.rb
|
@@ -311,6 +313,7 @@ files:
|
|
311
313
|
- spec/lib/tcell_agent/policies/login_policy_spec.rb
|
312
314
|
- spec/lib/tcell_agent/policies/patches_policy_spec.rb
|
313
315
|
- spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb
|
316
|
+
- spec/lib/tcell_agent/rails/auth/hooks_spec.rb
|
314
317
|
- spec/lib/tcell_agent/rails/better_ip_spec.rb
|
315
318
|
- spec/lib/tcell_agent/rails/logger_spec.rb
|
316
319
|
- spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb
|
@@ -460,6 +463,7 @@ test_files:
|
|
460
463
|
- spec/lib/tcell_agent/policies/login_policy_spec.rb
|
461
464
|
- spec/lib/tcell_agent/policies/patches_policy_spec.rb
|
462
465
|
- spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb
|
466
|
+
- spec/lib/tcell_agent/rails/auth/hooks_spec.rb
|
463
467
|
- spec/lib/tcell_agent/rails/better_ip_spec.rb
|
464
468
|
- spec/lib/tcell_agent/rails/logger_spec.rb
|
465
469
|
- spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb
|