tcell_agent 0.2.2 → 0.2.4

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/bin/tcell_agent +97 -32
  3. data/lib/tcell_agent.rb +4 -4
  4. data/lib/tcell_agent/agent.rb +68 -13
  5. data/lib/tcell_agent/agent/event_processor.rb +256 -79
  6. data/lib/tcell_agent/agent/fork_pipe_manager.rb +114 -0
  7. data/lib/tcell_agent/agent/policy_manager.rb +28 -16
  8. data/lib/tcell_agent/agent/policy_types.rb +3 -4
  9. data/lib/tcell_agent/agent/route_manager.rb +45 -0
  10. data/lib/tcell_agent/agent/static_agent.rb +48 -10
  11. data/lib/tcell_agent/api.rb +0 -2
  12. data/lib/tcell_agent/appsensor/path_traversal.rb +1 -1
  13. data/lib/tcell_agent/configuration.rb +19 -6
  14. data/lib/tcell_agent/instrumentation.rb +123 -0
  15. data/lib/tcell_agent/logger.rb +4 -1
  16. data/lib/tcell_agent/policies/content_security_policy.rb +44 -8
  17. data/lib/tcell_agent/policies/dataloss_policy.rb +122 -65
  18. data/lib/tcell_agent/rails.rb +19 -10
  19. data/{config/initializers/authlogic_auth.rb → lib/tcell_agent/rails/auth/authlogic.rb} +1 -0
  20. data/{config/initializers/devise_auth.rb → lib/tcell_agent/rails/auth/devise.rb} +2 -81
  21. data/lib/tcell_agent/rails/dlp.rb +40 -36
  22. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +2 -2
  23. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +8 -2
  24. data/lib/tcell_agent/rails/routes.rb +15 -19
  25. data/lib/tcell_agent/routes/table.rb +35 -0
  26. data/lib/tcell_agent/sensor_events/app_sensor.rb +22 -33
  27. data/lib/tcell_agent/sensor_events/discovery.rb +30 -0
  28. data/lib/tcell_agent/sensor_events/dlp.rb +9 -4
  29. data/lib/tcell_agent/sensor_events/sensor.rb +3 -0
  30. data/lib/tcell_agent/sensor_events/server_agent.rb +30 -6
  31. data/lib/tcell_agent/sensor_events/util/utils.rb +5 -1
  32. data/lib/tcell_agent/start_background_thread.rb +27 -22
  33. data/lib/tcell_agent/utils/queue_with_timeout.rb +65 -1
  34. data/lib/tcell_agent/version.rb +1 -1
  35. data/spec/lib/tcell_agent/instrumentation_spec.rb +198 -0
  36. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +37 -2
  37. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +81 -8
  38. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +3 -3
  39. data/spec/spec_helper.rb +16 -0
  40. metadata +11 -11
  41. data/config/initializers/init.rb +0 -8
  42. data/lib/tcell_agent/dataloss.rb +0 -0
  43. data/lib/tcell_agent/policies/add_script_tag_policy.rb +0 -47
  44. data/lib/tcell_agent/rails/devise.rb +0 -0
  45. data/spec/lib/tcell_agent/policies/add_script_tag_policy_spec.rb +0 -37
@@ -0,0 +1,30 @@
1
+ require 'tcell_agent/sensor_events/sensor'
2
+
3
+ module TCellAgent
4
+ module SensorEvents
5
+ class DiscoveryEvent < TCellSensorEvent
6
+ DATABASE_TYPE = "db"
7
+ def initialize(route_id=nil)
8
+ super("discovery")
9
+ if route_id
10
+ self["rid"] = route_id
11
+ end
12
+ end
13
+ def for_database(database, schema, table, field)
14
+ self["type"] = "db"
15
+ self["db"] = database
16
+ self["schema"] = schema
17
+ self["table"] = table
18
+ self["field"] = field
19
+ end
20
+ def for_database_fields(database, schema, table, fields)
21
+ self["type"] = "db"
22
+ self["db"] = database
23
+ self["schema"] = schema
24
+ self["table"] = table
25
+ self["fields"] = fields
26
+ return self
27
+ end
28
+ end #/DiscoveryEvent
29
+ end #/SensorEvents
30
+ end #/TCellAgent
@@ -16,9 +16,11 @@ module TCellAgent
16
16
  REQUEST_CONTEXT_COOKIE = "cookie"
17
17
  REQUEST_CONTEXT_HEADER = "header"
18
18
 
19
- def initialize(route_id, raw_uri, found_in, hmac_session_id=nil, user_id=nil)
19
+ def initialize(route_id, raw_uri, found_in, id=nil, hmac_session_id=nil, user_id=nil)
20
20
  super("dlp")
21
- self["rid"] = route_id
21
+ if route_id
22
+ self["rid"] = route_id
23
+ end
22
24
  self["found_in"] = found_in
23
25
  @raw_uri = raw_uri
24
26
  if hmac_session_id
@@ -27,6 +29,9 @@ module TCellAgent
27
29
  if user_id
28
30
  self["uid"] = user_id
29
31
  end
32
+ if id
33
+ self["id"] = id
34
+ end
30
35
  end
31
36
  def for_database(database, schema, table, field)
32
37
  self["type"] = "db"
@@ -37,13 +42,13 @@ module TCellAgent
37
42
  return self
38
43
  end
39
44
  def for_framework(variable)
40
- self["type"] = "framework"
45
+ self["type"] = "fw"
41
46
  self["context"] = "framework"
42
47
  self["variable"] = variable
43
48
  return self
44
49
  end
45
50
  def for_request(variable_context, variable)
46
- self["type"] = "request"
51
+ self["type"] = "req"
47
52
  self["context"] = variable_context
48
53
  self["variable"] = variable
49
54
  return self
@@ -24,6 +24,9 @@ module TCellAgent
24
24
  # This is called in the background thread, so any
25
25
  # santization, analysis, etc doesn't get in the way
26
26
  end
27
+ def bucket_key
28
+ return nil
29
+ end
27
30
  end
28
31
  class TCellHttpTxSensorEvent < TCellSensorEvent
29
32
  def initialize(request, response)
@@ -1,5 +1,6 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
 
3
+ require 'tcell_agent/logger'
3
4
  require 'tcell_agent/sensor_events/util/sanitizer_utilities'
4
5
  require 'tcell_agent/sensor_events/sensor'
5
6
  require 'tcell_agent/sensor_events/util/utils'
@@ -12,10 +13,25 @@ module TCellAgent
12
13
  super("server_agent_details")
13
14
  @flush = true
14
15
  @ensure = true
15
- login = Etc.getlogin
16
- self["user"] = Etc.getlogin
17
- info = Etc.getpwnam(login)
18
- self["group"] = info.gid.to_s
16
+ begin
17
+ login = Etc.getlogin
18
+ self["user"] = login
19
+ TCellAgent.logger.debug("User #{login}")
20
+ begin
21
+ info = Etc.getpwnam(login)
22
+ self["group"] = info.gid.to_s
23
+ TCellAgent.logger.debug("Group #{info.gid.to_s}")
24
+ rescue Exception => te
25
+ TCellAgent.logger.warn("Exception finding group id: #{te.message}")
26
+ TCellAgent.logger.debug(te.backtrace)
27
+ self["group"] = "unknown"
28
+ end
29
+ rescue Exception => to
30
+ self["user"] = "unknown"
31
+ self["group"] = "unknown"
32
+ TCellAgent.logger.warn("Exception finding user & group: #{to.message}")
33
+ TCellAgent.logger.debug(te.backtrace)
34
+ end
19
35
  end
20
36
  end
21
37
  class ServerAgentAppFrameworkEvent < TCellSensorEvent
@@ -34,8 +50,16 @@ module TCellAgent
34
50
  @ensure = true
35
51
  packages = []
36
52
  Gem.loaded_specs.values.map { |x|
37
- package = {"n"=>x.name, "v"=>x.version.version}
38
- packages.push(package)
53
+ begin
54
+ if x.name
55
+ package = {"n"=>x.name, "v"=>x.version.version}
56
+ packages.push(package)
57
+ TCellAgent.logger.debug("Adding packages #{x.name}")
58
+ end
59
+ rescue Exception => te
60
+ TCellAgent.logger.error("Exception adding package: #{te.message}")
61
+ TCellAgent.logger.debug(te.backtrace)
62
+ end
39
63
  }
40
64
  self["packages"] = packages
41
65
  end
@@ -14,7 +14,11 @@ module TCellAgent
14
14
  end
15
15
  end
16
16
  def self.calculateRouteId(method, path, params=nil)
17
- jhash("#{method}|#{path}")
17
+ route_id = jhash("#{method}|#{path}")
18
+ if (route_id)
19
+ route_id = route_id.to_s
20
+ end
21
+ route_id
18
22
  end
19
23
  end
20
24
  end
@@ -3,9 +3,9 @@
3
3
  require 'tcell_agent/logger'
4
4
  require 'tcell_agent/agent'
5
5
  require 'tcell_agent/configuration'
6
+ require 'thread'
6
7
 
7
- agent = ::TCellAgent::Agent.new(Process.pid)
8
- TCellAgent.thread_agent = agent
8
+ TCellAgent.thread_agent.start
9
9
 
10
10
  # creates a fork and pipes a string from parent to child
11
11
  if File.basename($0) != 'rake'
@@ -14,8 +14,8 @@ if File.basename($0) != 'rake'
14
14
  (defined?(WEBrick) && (Rack::Handler.default == Rack::Handler::WEBrick))))
15
15
  TCellAgent.logger.debug("Initializing background thread: Thin")
16
16
  begin
17
- TCellAgent.thread_agent = agent
18
- agent.start
17
+ TCellAgent.thread_agent.start
18
+ #TCellAgent.ensure_event_processor_running
19
19
  rescue Exception => e
20
20
  TCellAgent.logger.error("Could not start worker.", e.message)
21
21
  end
@@ -25,38 +25,43 @@ if File.basename($0) != 'rake'
25
25
  TCellAgent.logger.debug("Initializing background thread: Puma Preload")
26
26
  puma_worker_start = Proc.new do
27
27
  begin
28
- agent = TCellAgent::Agent.new(Process.pid)
29
- TCellAgent.thread_agent = agent
30
- agent.start
28
+ TCellAgent.thread_agent.start
29
+ #TCellAgent.ensure_event_processor_running
31
30
  rescue Exception => e
32
- TCellAgent.logger.error("Could not start worker.", e.message)
31
+ TCellAgent.logger.error("Could not start worker." + e.message)
33
32
  end
34
33
  end
35
34
  Puma.cli_config.options[:before_worker_boot].push(puma_worker_start)
36
- elsif defined?(Unicorn) && Unicorn::HttpServer::LISTENERS.length == 0
37
- agent.start_event_processor(false)
35
+ elsif defined?(Unicorn)
38
36
  TCellAgent.logger.debug("Initializing background thread: Unicorn Preload")
39
37
  class Unicorn::HttpServer
38
+ alias _tcell_start spawn_missing_workers
39
+ def spawn_missing_workers
40
+ TCellAgent.logger.debug("Stopping (pre-spawn) agent " + Process.pid.to_s)
41
+ return _tcell_start
42
+ end
40
43
  alias old_init_worker_process init_worker_process
41
44
  def init_worker_process(work)
45
+ start_process = old_init_worker_process(work)
42
46
  begin
43
- agent = TCellAgent::Agent.new(Process.pid)
44
- TCellAgent.thread_agent = agent
45
- agent.start
47
+ TCellAgent.logger.debug("Starting (post-spawn) agent " + Process.pid.to_s)
48
+ TCellAgent.thread_agent.policy_polling_worker_mutex = Mutex.new
49
+ TCellAgent.thread_agent.policy_polling_thread = nil
50
+ TCellAgent.thread_agent.start
51
+ #TCellAgent.ensure_event_processor_running
46
52
  rescue Exception => e
47
- TCellAgent.logger.error("Could not start worker.", e.message)
53
+ TCellAgent.logger.error("Could not start worker.")
48
54
  end
49
- return old_init_worker_process(work)
55
+ start_process
50
56
  end
51
57
  end
52
58
  else
53
- TCellAgent.logger.debug("Initializing background thread (no-preload).")
54
- begin
55
- TCellAgent.thread_agent = agent
56
- agent.start
57
- rescue Exception => e
58
- TCellAgent.logger.error("Could not start worker.", e.message)
59
- end
59
+ TCellAgent.logger.debug("Initializing background thread (no-preload).")
60
+ begin
61
+ TCellAgent.thread_agent.start
62
+ rescue Exception => e
63
+ TCellAgent.logger.error("Could not start worker.")
64
+ end
60
65
  end
61
66
  end
62
67
 
@@ -5,6 +5,69 @@ require 'thread'
5
5
  require 'logger'
6
6
 
7
7
  module TCellAgent
8
+ class BoundedQueue
9
+ def initialize(max_size = :infinite)
10
+ @lock = Mutex.new
11
+ @items = []
12
+ @item_available = ConditionVariable.new
13
+ @max_size = max_size
14
+ @space_available = ConditionVariable.new
15
+ end
16
+
17
+ def push(obj, timeout=:never, &timeout_policy)
18
+ timeout_policy ||= -> do
19
+ raise "Push timed out"
20
+ end
21
+ wait_for_condition(
22
+ @space_available,
23
+ ->{!full?},
24
+ timeout,
25
+ timeout_policy) do
26
+
27
+ @items.push(obj)
28
+ @item_available.signal
29
+ end
30
+ end
31
+
32
+ def pop(timeout = :never, &timeout_policy)
33
+ timeout_policy ||= ->{nil}
34
+ wait_for_condition(
35
+ @item_available,
36
+ ->{@items.any?},
37
+ timeout,
38
+ timeout_policy) do
39
+ @items.shift
40
+ end
41
+ end
42
+
43
+ def full?
44
+ return false if @max_size == :infinite
45
+ @max_size <= @items.size
46
+ end
47
+
48
+ private
49
+
50
+ def wait_for_condition(
51
+ cv, condition_predicate, timeout=:never, timeout_policy=->{nil})
52
+ deadline = timeout == :never ? :never : Time.now + timeout
53
+ @lock.synchronize do
54
+ loop do
55
+ cv_timeout = timeout == :never ? nil : deadline - Time.now
56
+ if !condition_predicate.call && cv_timeout.to_f >= 0
57
+ cv.wait(@lock, cv_timeout)
58
+ end
59
+ if condition_predicate.call
60
+ return yield
61
+ elsif deadline == :never || deadline > Time.now
62
+ next
63
+ else
64
+ return timeout_policy.call
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+
8
71
  class QueueWithTimeout
9
72
  def initialize
10
73
  @mutex = Mutex.new
@@ -51,7 +114,8 @@ module TCellAgent
51
114
  if @queue.empty?
52
115
  @recieved.wait(@mutex, timeout) if timeout != 0
53
116
  #if we're still empty after the timeout, raise exception
54
- raise ThreadError, "queue empty" if @queue.empty?
117
+ return nil if @queue.empty?
118
+ #raise ThreadError, "queue empty" if @queue.empty?
55
119
  end
56
120
  @queue.shift
57
121
  end
@@ -1,5 +1,5 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
 
3
3
  module TCellAgent
4
- VERSION = "0.2.2"
4
+ VERSION = "0.2.4"
5
5
  end
@@ -0,0 +1,198 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+ class MockAgent < Agent
5
+ end
6
+ end
7
+
8
+
9
+ module TCellAgent
10
+ module Instrumentation
11
+ describe Instrumentation do
12
+ context "Body - SessionId Filters" do
13
+ it "Tests Redaction and Events in Body" do
14
+ action = TCellAgent::Policies::DataLossPolicy::FilterActions.new
15
+ action.body_redact = true
16
+ action.action_id = 5
17
+ policy_json_two = {
18
+ "policy_id"=>"x1a1",
19
+ "data"=>{
20
+ "session_id_protection"=>{"body"=>["redact"], "log"=>["event"]}
21
+ }
22
+ }
23
+ session_id_policy = TCellAgent::Policies::DataLossPolicy.fromJson(policy_json_two)
24
+ mock_agent = MockAgent.new(-1)
25
+ mock_agent.policies[TCellAgent::PolicyTypes::DataLoss] = session_id_policy
26
+ TCellAgent.set_thread_agent(mock_agent)
27
+
28
+ context = TCellData.new
29
+ context.session_id = "tim123123my"
30
+
31
+ body = "this is about tim123123my 3123123."
32
+ TCellAgent.empty_event_queue
33
+ context.filter_body(body)
34
+ expect(body).to eq("this is about [redacted] 3123123.")
35
+ expect(TCellAgent.event_queue.length).to eq(1)
36
+ TCellAgent.set_thread_agent(nil)
37
+ end
38
+ it "Tests Events in Body" do
39
+ action = TCellAgent::Policies::DataLossPolicy::FilterActions.new
40
+ action.body_redact = true
41
+ action.action_id = 5
42
+ policy_json_two = {
43
+ "policy_id"=>"x1a1",
44
+ "data"=>{
45
+ "session_id_protection"=>{"body"=>["event"], "log"=>["redact"]}
46
+ }
47
+ }
48
+ session_id_policy = TCellAgent::Policies::DataLossPolicy.fromJson(policy_json_two)
49
+ mock_agent = MockAgent.new(-1)
50
+ mock_agent.policies[TCellAgent::PolicyTypes::DataLoss] = session_id_policy
51
+ TCellAgent.set_thread_agent(mock_agent)
52
+
53
+ context = TCellData.new
54
+ context.session_id = "tim123123my"
55
+
56
+ body = "this is about tim123123my 3123123."
57
+ TCellAgent.empty_event_queue
58
+ context.filter_body(body)
59
+ expect(body).to eq("this is about tim123123my 3123123.")
60
+ expect(TCellAgent.event_queue.length).to eq(1)
61
+ TCellAgent.set_thread_agent(nil)
62
+ end
63
+ end
64
+ context "Log - SessionId Filters" do
65
+ it "Tests Redaction and Events in Body" do
66
+ action = TCellAgent::Policies::DataLossPolicy::FilterActions.new
67
+ action.body_redact = true
68
+ action.action_id = 5
69
+ policy_json_two = {
70
+ "policy_id"=>"x1a1",
71
+ "data"=>{
72
+ "session_id_protection"=>{"body"=>["redact"], "log"=>["redact"]}
73
+ }
74
+ }
75
+ session_id_policy = TCellAgent::Policies::DataLossPolicy.fromJson(policy_json_two)
76
+ mock_agent = MockAgent.new(-1)
77
+ mock_agent.policies[TCellAgent::PolicyTypes::DataLoss] = session_id_policy
78
+ TCellAgent.set_thread_agent(mock_agent)
79
+
80
+ context = TCellData.new
81
+ context.session_id = "tim123123my"
82
+
83
+ body = "this is about tim123123my 3123123."
84
+ TCellAgent.empty_event_queue
85
+ context.filter_log(body)
86
+ expect(body).to eq("this is about [redacted] 3123123.")
87
+ expect(TCellAgent.event_queue.length).to eq(1)
88
+ TCellAgent.set_thread_agent(nil)
89
+ end
90
+ it "Tests Events Only" do
91
+ action = TCellAgent::Policies::DataLossPolicy::FilterActions.new
92
+ action.body_redact = true
93
+ action.action_id = 5
94
+ policy_json_two = {
95
+ "policy_id"=>"x1a1",
96
+ "data"=>{
97
+ "session_id_protection"=>{"body"=>["redact"], "log"=>["event"]}
98
+ }
99
+ }
100
+ session_id_policy = TCellAgent::Policies::DataLossPolicy.fromJson(policy_json_two)
101
+ mock_agent = MockAgent.new(-1)
102
+ mock_agent.policies[TCellAgent::PolicyTypes::DataLoss] = session_id_policy
103
+ TCellAgent.set_thread_agent(mock_agent)
104
+
105
+ context = TCellData.new
106
+ context.session_id = "tim123123my"
107
+
108
+ body = "this is about tim123123my 3123123."
109
+ TCellAgent.empty_event_queue
110
+ context.filter_log(body)
111
+ expect(body).to eq("this is about tim123123my 3123123.")
112
+ expect(TCellAgent.event_queue.length).to eq(1)
113
+ TCellAgent.set_thread_agent(nil)
114
+ end
115
+ end
116
+ context "Body - Database Filters" do
117
+ it "Tests Redaction and Events in Body" do
118
+ action = TCellAgent::Policies::DataLossPolicy::FilterActions.new
119
+ action.body_redact = true
120
+ action.action_id = 5
121
+ context = TCellData.new
122
+ context.add_response_db_filter("timmy", action, "don", "sam", "tim", "fred")
123
+ context.add_response_db_filter("timmy23", action, "don", "sam", "tim", "fred")
124
+ context.add_response_db_filter("3123123", action, "don", "sam", "tim", "fred")
125
+ context.add_response_db_filter("tim123my", action, "don", "sam", "tim", "fred")
126
+ context.add_response_db_filter("timmy1", action, "don", "sam", "tim", "fred")
127
+ context.add_response_db_filter("tim123123my", action, "don", "sam", "tim", "fred")
128
+ context.add_response_db_filter("ti21312mmy", action, "don", "sam", "tim", "fred")
129
+ context.add_response_db_filter("ti123123mmy", action, "don", "sam", "tim", "fred")
130
+ body = "this is about timmy1 3123123."
131
+ TCellAgent.empty_event_queue
132
+ context.filter_body(body)
133
+ expect(body).to eq("this is about [redacted] [redacted].")
134
+ expect(TCellAgent.event_queue.length).to eq(2)
135
+ end
136
+ it "Tests Event Only Match in Body" do
137
+ action = TCellAgent::Policies::DataLossPolicy::FilterActions.new
138
+ action.body_event = true
139
+ action.action_id = 5
140
+ context = TCellData.new
141
+ context.add_response_db_filter("timmy", action, "don", "sam", "tim", "fred")
142
+ context.add_response_db_filter("timmy23", action, "don", "sam", "tim", "fred")
143
+ context.add_response_db_filter("3123123", action, "don", "sam", "tim", "fred")
144
+ context.add_response_db_filter("tim123my", action, "don", "sam", "tim", "fred")
145
+ context.add_response_db_filter("timmy1", action, "don", "sam", "tim", "fred")
146
+ context.add_response_db_filter("tim123123my", action, "don", "sam", "tim", "fred")
147
+ context.add_response_db_filter("ti21312mmy", action, "don", "sam", "tim", "fred")
148
+ context.add_response_db_filter("ti123123mmy", action, "don", "sam", "tim", "fred")
149
+ body = "this is about timmy1 3123123."
150
+ TCellAgent.empty_event_queue
151
+ context.filter_body(body)
152
+ expect(body).to eq("this is about timmy1 3123123.")
153
+ expect(TCellAgent.event_queue.length).to eq(3) # timmy, timmy1, 3123123
154
+ end
155
+ end
156
+ context "Log - Database Filters" do
157
+ it "Tests Redaction and Events" do
158
+ action = TCellAgent::Policies::DataLossPolicy::FilterActions.new
159
+ action.log_redact = true
160
+ action.action_id = 5
161
+ context = TCellData.new
162
+ context.add_response_db_filter("timmy", action, "don", "sam", "tim", "fred")
163
+ context.add_response_db_filter("timmy23", action, "don", "sam", "tim", "fred")
164
+ context.add_response_db_filter("3123123", action, "don", "sam", "tim", "fred")
165
+ context.add_response_db_filter("tim123my", action, "don", "sam", "tim", "fred")
166
+ context.add_response_db_filter("timmy1", action, "don", "sam", "tim", "fred")
167
+ context.add_response_db_filter("tim123123my", action, "don", "sam", "tim", "fred")
168
+ context.add_response_db_filter("ti21312mmy", action, "don", "sam", "tim", "fred")
169
+ context.add_response_db_filter("ti123123mmy", action, "don", "sam", "tim", "fred")
170
+ body = "this is about timmy1 3123123."
171
+ TCellAgent.empty_event_queue
172
+ context.filter_log(body)
173
+ expect(body).to eq("this is about [redacted] [redacted].")
174
+ expect(TCellAgent.event_queue.length).to eq(2)
175
+ end
176
+ it "Tests Report-Only and Events" do
177
+ action = TCellAgent::Policies::DataLossPolicy::FilterActions.new
178
+ action.log_event = true
179
+ action.action_id = 5
180
+ context = TCellData.new
181
+ context.add_response_db_filter("timmy", action, "don", "sam", "tim", "fred")
182
+ context.add_response_db_filter("timmy23", action, "don", "sam", "tim", "fred")
183
+ context.add_response_db_filter("3123123", action, "don", "sam", "tim", "fred")
184
+ context.add_response_db_filter("tim123my", action, "don", "sam", "tim", "fred")
185
+ context.add_response_db_filter("timmy1", action, "don", "sam", "tim", "fred")
186
+ context.add_response_db_filter("tim123123my", action, "don", "sam", "tim", "fred")
187
+ context.add_response_db_filter("ti21312mmy", action, "don", "sam", "tim", "fred")
188
+ context.add_response_db_filter("ti123123mmy", action, "don", "sam", "tim", "fred")
189
+ body = "this is about timmy1 3123123."
190
+ TCellAgent.empty_event_queue
191
+ context.filter_log(body)
192
+ expect(body).to eq("this is about timmy1 3123123.")
193
+ expect(TCellAgent.event_queue.length).to eq(3) # timmy, timmy1, 3123123
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end