tcell_agent 0.2.24 → 0.2.25
Sign up to get free protection for your applications and to get access to all the features.
- 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
|