tcell_agent 0.4.0 → 1.0.0

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 (199) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +9 -22
  3. data/bin/tcell_agent +127 -132
  4. data/lib/tcell_agent/agent/event_processor.rb +23 -22
  5. data/lib/tcell_agent/agent/fork_pipe_manager.rb +7 -7
  6. data/lib/tcell_agent/agent/policy_manager.rb +20 -15
  7. data/lib/tcell_agent/agent/policy_types.rb +5 -11
  8. data/lib/tcell_agent/agent/static_agent.rb +5 -1
  9. data/lib/tcell_agent/agent.rb +6 -4
  10. data/lib/tcell_agent/api.rb +7 -9
  11. data/lib/tcell_agent/appsensor/meta_data.rb +11 -4
  12. data/lib/tcell_agent/authlogic.rb +3 -3
  13. data/lib/tcell_agent/cmdi.rb +6 -4
  14. data/lib/tcell_agent/config/unknown_options.rb +3 -1
  15. data/lib/tcell_agent/configuration.rb +47 -49
  16. data/lib/tcell_agent/devise.rb +2 -2
  17. data/lib/tcell_agent/hooks/login_fraud.rb +58 -29
  18. data/lib/tcell_agent/instrumentation.rb +11 -10
  19. data/lib/tcell_agent/logger.rb +2 -2
  20. data/lib/tcell_agent/patches/meta_data.rb +9 -13
  21. data/lib/tcell_agent/patches.rb +7 -10
  22. data/lib/tcell_agent/policies/clickjacking_policy.rb +4 -5
  23. data/lib/tcell_agent/policies/content_security_policy.rb +6 -12
  24. data/lib/tcell_agent/policies/dataloss_policy.rb +2 -2
  25. data/lib/tcell_agent/policies/http_redirect_policy.rb +2 -2
  26. data/lib/tcell_agent/policies/policy.rb +0 -2
  27. data/lib/tcell_agent/policies/rust_policies.rb +90 -0
  28. data/lib/tcell_agent/policies/secure_headers_policy.rb +2 -2
  29. data/lib/tcell_agent/rails/auth/authlogic.rb +42 -24
  30. data/lib/tcell_agent/rails/auth/devise.rb +44 -23
  31. data/lib/tcell_agent/rails/auth/doorkeeper.rb +33 -15
  32. data/lib/tcell_agent/rails/better_ip.rb +1 -1
  33. data/lib/tcell_agent/rails/csrf_exception.rb +2 -2
  34. data/lib/tcell_agent/rails/dlp/process_request.rb +1 -1
  35. data/lib/tcell_agent/rails/dlp.rb +6 -6
  36. data/lib/tcell_agent/rails/dlp_handler.rb +1 -1
  37. data/lib/tcell_agent/rails/js_agent_insert.rb +1 -1
  38. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +1 -1
  39. data/lib/tcell_agent/rails/middleware/context_middleware.rb +3 -2
  40. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +10 -9
  41. data/lib/tcell_agent/rails/routes/grape.rb +6 -6
  42. data/lib/tcell_agent/rails/routes.rb +8 -11
  43. data/lib/tcell_agent/rust/libtcellagent-0.11.1.dylib +0 -0
  44. data/lib/tcell_agent/rust/{libtcellagent-0.6.1.so → libtcellagent-0.11.1.so} +0 -0
  45. data/lib/tcell_agent/rust/models.rb +16 -0
  46. data/lib/tcell_agent/rust/tcellagent-0.11.1.dll +0 -0
  47. data/lib/tcell_agent/rust/whisperer.rb +119 -48
  48. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +17 -20
  49. data/lib/tcell_agent/sensor_events/command_injection.rb +50 -5
  50. data/lib/tcell_agent/sensor_events/login_fraud.rb +34 -18
  51. data/lib/tcell_agent/sensor_events/patches.rb +21 -0
  52. data/lib/tcell_agent/sensor_events/server_agent.rb +3 -3
  53. data/lib/tcell_agent/sensor_events/util/utils.rb +4 -3
  54. data/lib/tcell_agent/servers/puma.rb +2 -2
  55. data/lib/tcell_agent/servers/unicorn.rb +1 -1
  56. data/lib/tcell_agent/utils/passwords.rb +28 -0
  57. data/lib/tcell_agent/version.rb +1 -1
  58. data/lib/tcell_agent.rb +1 -5
  59. data/spec/apps/rails-3.2/config/tcell_agent.config +15 -0
  60. data/spec/apps/rails-3.2/log/development.log +0 -0
  61. data/spec/apps/rails-3.2/log/test.log +12 -0
  62. data/spec/apps/rails-4.1/log/test.log +0 -0
  63. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +46 -45
  64. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +276 -164
  65. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +44 -47
  66. data/spec/lib/tcell_agent/api/api_spec.rb +16 -16
  67. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +131 -116
  68. data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +55 -51
  69. data/spec/lib/tcell_agent/cmdi_spec.rb +413 -436
  70. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +145 -128
  71. data/spec/lib/tcell_agent/configuration_spec.rb +165 -169
  72. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +144 -153
  73. data/spec/lib/tcell_agent/instrumentation_spec.rb +84 -85
  74. data/spec/lib/tcell_agent/patches_spec.rb +70 -111
  75. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +313 -244
  76. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +28 -28
  77. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +643 -513
  78. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +55 -102
  79. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +111 -134
  80. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +141 -146
  81. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +8 -8
  82. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +15 -17
  83. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +231 -559
  84. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +27 -27
  85. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +30 -34
  86. data/spec/lib/tcell_agent/rails/logger_spec.rb +50 -49
  87. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +182 -199
  88. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +110 -84
  89. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +107 -85
  90. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +68 -40
  91. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +81 -67
  92. data/spec/lib/tcell_agent/rails/responses_spec.rb +33 -37
  93. data/spec/lib/tcell_agent/rails/routes/grape_spec.rb +116 -121
  94. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +25 -28
  95. data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +87 -85
  96. data/spec/lib/tcell_agent/rails_spec.rb +1 -6
  97. data/spec/lib/tcell_agent/rust/models_spec.rb +112 -0
  98. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +502 -179
  99. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +44 -33
  100. data/spec/lib/tcell_agent/sensor_events/dlp_spec.rb +4 -4
  101. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +183 -169
  102. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +25 -25
  103. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +17 -20
  104. data/spec/lib/tcell_agent/utils/params_spec.rb +28 -28
  105. data/spec/lib/tcell_agent/utils/passwords_spec.rb +143 -0
  106. data/spec/lib/tcell_agent/utils/strings_spec.rb +35 -35
  107. data/spec/lib/tcell_agent_spec.rb +8 -8
  108. data/spec/spec_helper.rb +4 -4
  109. data/spec/support/middleware_helper.rb +10 -10
  110. data/spec/support/static_agent_overrides.rb +16 -12
  111. data/tcell_agent.gemspec +17 -33
  112. metadata +43 -198
  113. data/LICENSE_libinjection +0 -32
  114. data/Readme.txt +0 -7
  115. data/ext/libinjection/extconf.rb +0 -3
  116. data/ext/libinjection/libinjection.h +0 -65
  117. data/ext/libinjection/libinjection_html5.c +0 -847
  118. data/ext/libinjection/libinjection_html5.h +0 -54
  119. data/ext/libinjection/libinjection_sqli.c +0 -2317
  120. data/ext/libinjection/libinjection_sqli.h +0 -295
  121. data/ext/libinjection/libinjection_sqli_data.h +0 -9004
  122. data/ext/libinjection/libinjection_wrap.c +0 -3525
  123. data/ext/libinjection/libinjection_xss.c +0 -531
  124. data/ext/libinjection/libinjection_xss.h +0 -21
  125. data/lib/tcell_agent/appsensor/injections_matcher.rb +0 -155
  126. data/lib/tcell_agent/appsensor/rules/appsensor_rule_manager.rb +0 -49
  127. data/lib/tcell_agent/appsensor/rules/appsensor_rule_set.rb +0 -67
  128. data/lib/tcell_agent/appsensor/rules/baserules.json +0 -467
  129. data/lib/tcell_agent/patches/block_rule.rb +0 -93
  130. data/lib/tcell_agent/patches/sensors_matcher.rb +0 -31
  131. data/lib/tcell_agent/policies/appsensor/cmdi_sensor.rb +0 -23
  132. data/lib/tcell_agent/policies/appsensor/fpt_sensor.rb +0 -23
  133. data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +0 -117
  134. data/lib/tcell_agent/policies/appsensor/nullbyte_sensor.rb +0 -26
  135. data/lib/tcell_agent/policies/appsensor/retr_sensor.rb +0 -22
  136. data/lib/tcell_agent/policies/appsensor/sqli_sensor.rb +0 -34
  137. data/lib/tcell_agent/policies/appsensor/xss_sensor.rb +0 -34
  138. data/lib/tcell_agent/policies/appsensor_policy.rb +0 -49
  139. data/lib/tcell_agent/policies/command_injection_policy.rb +0 -196
  140. data/lib/tcell_agent/policies/honeytokens_policy.rb +0 -69
  141. data/lib/tcell_agent/policies/patches_policy.rb +0 -84
  142. data/lib/tcell_agent/rust/libtcellagent-0.6.1.dylib +0 -0
  143. data/lib/tcell_agent/rust/tcellagent-0.6.1.dll +0 -0
  144. data/spec/apps/rails-3.2/Gemfile +0 -25
  145. data/spec/apps/rails-3.2/Gemfile.lock +0 -126
  146. data/spec/apps/rails-3.2/Rakefile +0 -7
  147. data/spec/apps/rails-3.2/app/assets/images/rails.png +0 -0
  148. data/spec/apps/rails-3.2/app/assets/javascripts/application.js +0 -15
  149. data/spec/apps/rails-3.2/app/assets/stylesheets/application.css +0 -13
  150. data/spec/apps/rails-3.2/app/controllers/application_controller.rb +0 -3
  151. data/spec/apps/rails-3.2/app/controllers/t_cell_app_controller.rb +0 -5
  152. data/spec/apps/rails-3.2/app/helpers/application_helper.rb +0 -2
  153. data/spec/apps/rails-3.2/app/views/layouts/application.html.erb +0 -14
  154. data/spec/apps/rails-3.2/app/views/t_cell_app/index.html.erb +0 -1
  155. data/spec/apps/rails-3.2/config/application.rb +0 -63
  156. data/spec/apps/rails-3.2/config/boot.rb +0 -6
  157. data/spec/apps/rails-3.2/config/environment.rb +0 -5
  158. data/spec/apps/rails-3.2/config/environments/test.rb +0 -37
  159. data/spec/apps/rails-3.2/config/routes.rb +0 -11
  160. data/spec/apps/rails-3.2/config.ru +0 -4
  161. data/spec/apps/rails-4.1/Gemfile +0 -7
  162. data/spec/apps/rails-4.1/Gemfile.lock +0 -114
  163. data/spec/apps/rails-4.1/Rakefile +0 -6
  164. data/spec/apps/rails-4.1/app/assets/javascripts/application.js +0 -16
  165. data/spec/apps/rails-4.1/app/assets/stylesheets/application.css +0 -15
  166. data/spec/apps/rails-4.1/app/controllers/application_controller.rb +0 -5
  167. data/spec/apps/rails-4.1/app/controllers/t_cell_app_controller.rb +0 -5
  168. data/spec/apps/rails-4.1/app/helpers/application_helper.rb +0 -2
  169. data/spec/apps/rails-4.1/app/views/layouts/application.html.erb +0 -14
  170. data/spec/apps/rails-4.1/app/views/t_cell_app/index.html.erb +0 -1
  171. data/spec/apps/rails-4.1/config/application.rb +0 -24
  172. data/spec/apps/rails-4.1/config/boot.rb +0 -4
  173. data/spec/apps/rails-4.1/config/environment.rb +0 -5
  174. data/spec/apps/rails-4.1/config/environments/test.rb +0 -41
  175. data/spec/apps/rails-4.1/config/initializers/assets.rb +0 -8
  176. data/spec/apps/rails-4.1/config/initializers/backtrace_silencers.rb +0 -7
  177. data/spec/apps/rails-4.1/config/initializers/cookies_serializer.rb +0 -3
  178. data/spec/apps/rails-4.1/config/initializers/filter_parameter_logging.rb +0 -4
  179. data/spec/apps/rails-4.1/config/initializers/inflections.rb +0 -16
  180. data/spec/apps/rails-4.1/config/initializers/mime_types.rb +0 -4
  181. data/spec/apps/rails-4.1/config/initializers/session_store.rb +0 -3
  182. data/spec/apps/rails-4.1/config/initializers/wrap_parameters.rb +0 -14
  183. data/spec/apps/rails-4.1/config/locales/en.yml +0 -23
  184. data/spec/apps/rails-4.1/config/routes.rb +0 -12
  185. data/spec/apps/rails-4.1/config/secrets.yml +0 -22
  186. data/spec/apps/rails-4.1/config.ru +0 -4
  187. data/spec/controllers/application_controller.rb +0 -12
  188. data/spec/lib/tcell_agent/appsensor/injections_matcher_spec.rb +0 -522
  189. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_manager_spec.rb +0 -23
  190. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_set_spec.rb +0 -159
  191. data/spec/lib/tcell_agent/patches/block_rule_spec.rb +0 -458
  192. data/spec/lib/tcell_agent/patches/sensors_matcher_spec.rb +0 -35
  193. data/spec/lib/tcell_agent/policies/appsensor/cmdi_sensor_spec.rb +0 -139
  194. data/spec/lib/tcell_agent/policies/appsensor/fpt_sensor_spec.rb +0 -139
  195. data/spec/lib/tcell_agent/policies/appsensor/nullbyte_sensor_spec.rb +0 -167
  196. data/spec/lib/tcell_agent/policies/appsensor/retr_sensor_spec.rb +0 -139
  197. data/spec/lib/tcell_agent/policies/appsensor/sqli_sensor_spec.rb +0 -246
  198. data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +0 -882
  199. data/spec/lib/tcell_agent/policies/honeytokens_policy_spec.rb +0 -22
@@ -2,24 +2,23 @@ require 'spec_helper'
2
2
 
3
3
  module TCellAgent
4
4
  module SensorEvents
5
-
6
5
  describe Agent do
7
-
8
- describe "#start_policy_polling_loop" do
9
- context "should_start_policy_poll disabled" do
10
- it "should not start the policy polling loop" do
6
+ describe '#start_policy_polling_loop' do
7
+ context 'should_start_policy_poll disabled' do
8
+ it 'should not start the policy polling loop' do
11
9
  configuration = double(
12
- "configuration",
10
+ 'configuration',
13
11
  {
14
- should_start_policy_poll?: false,
15
- event_time_limit_seconds: nil,
16
- event_batch_size_limit: nil,
17
- preload_policy_filename: nil,
18
- cache_filename_with_app_id: "cache-file.app_id"
12
+ :should_start_policy_poll? => false,
13
+ :event_time_limit_seconds => nil,
14
+ :event_batch_size_limit => nil,
15
+ :preload_policy_filename => nil,
16
+ :cache_filename_with_app_id => 'cache-file.app_id'
19
17
  }
20
18
  )
21
19
 
22
20
  expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
21
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
23
22
  agent = TCellAgent::Agent.new
24
23
 
25
24
  expect(Thread).to_not receive(:new)
@@ -27,164 +26,170 @@ module TCellAgent
27
26
  end
28
27
  end
29
28
 
30
- context "should_start_policy_poll enabled" do
31
- context "tcell_api_url" do
32
- context "is nil " do
33
- it "should not start the policy polling loop" do
29
+ context 'should_start_policy_poll enabled' do
30
+ context 'tcell_api_url' do
31
+ context 'is nil ' do
32
+ it 'should not start the policy polling loop' do
34
33
  configuration = double(
35
- "configuration",
34
+ 'configuration',
36
35
  {
37
- tcell_api_url: nil,
38
- should_start_policy_poll?: true,
39
- event_time_limit_seconds: nil,
40
- event_batch_size_limit: nil,
41
- preload_policy_filename: nil,
42
- cache_filename_with_app_id: "cache-file.app_id"
36
+ :tcell_api_url => nil,
37
+ :should_start_policy_poll? => true,
38
+ :event_time_limit_seconds => nil,
39
+ :event_batch_size_limit => nil,
40
+ :preload_policy_filename => nil,
41
+ :cache_filename_with_app_id => 'cache-file.app_id'
43
42
  }
44
43
  )
45
44
 
45
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
46
46
  expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
47
47
  agent = TCellAgent::Agent.new
48
48
 
49
- logger = double("logger")
49
+ logger = double('logger')
50
50
 
51
51
  expect(TCellAgent).to receive(:logger).and_return(logger)
52
- expect(logger).to receive(:error).with("tCell.io tcell_api_url is missing. Disabling policy polling.")
52
+ expect(logger).to receive(:error).with('tCell.io tcell_api_url is missing. Disabling policy polling.')
53
53
  expect(Thread).to_not receive(:new)
54
54
  agent.start_policy_polling_loop
55
55
  end
56
56
  end
57
57
 
58
- context "is empty" do
59
- it "should not start the policy polling loop" do
58
+ context 'is empty' do
59
+ it 'should not start the policy polling loop' do
60
60
  configuration = double(
61
- "configuration",
61
+ 'configuration',
62
62
  {
63
- tcell_api_url: "",
64
- should_start_policy_poll?: true,
65
- event_time_limit_seconds: nil,
66
- event_batch_size_limit: nil,
67
- preload_policy_filename: nil,
68
- cache_filename_with_app_id: "cache-file.app_id"
63
+ :tcell_api_url => '',
64
+ :should_start_policy_poll? => true,
65
+ :event_time_limit_seconds => nil,
66
+ :event_batch_size_limit => nil,
67
+ :preload_policy_filename => nil,
68
+ :cache_filename_with_app_id => 'cache-file.app_id'
69
69
  }
70
70
  )
71
71
 
72
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
72
73
  expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
73
74
  agent = TCellAgent::Agent.new
74
75
 
75
- logger = double("logger")
76
+ logger = double('logger')
76
77
 
77
78
  expect(TCellAgent).to receive(:logger).and_return(logger)
78
- expect(logger).to receive(:error).with("tCell.io tcell_api_url is missing. Disabling policy polling.")
79
+ expect(logger).to receive(:error).with('tCell.io tcell_api_url is missing. Disabling policy polling.')
79
80
  expect(Thread).to_not receive(:new)
80
81
  agent.start_policy_polling_loop
81
82
  end
82
83
  end
83
84
 
84
- context "is blank space" do
85
- it "should not start the policy polling loop" do
85
+ context 'is blank space' do
86
+ it 'should not start the policy polling loop' do
86
87
  configuration = double(
87
- "configuration",
88
+ 'configuration',
88
89
  {
89
- tcell_api_url: " ",
90
- should_start_policy_poll?: true,
91
- event_time_limit_seconds: nil,
92
- event_batch_size_limit: nil,
93
- preload_policy_filename: nil,
94
- cache_filename_with_app_id: "cache-file.app_id"
90
+ :tcell_api_url => ' ',
91
+ :should_start_policy_poll? => true,
92
+ :event_time_limit_seconds => nil,
93
+ :event_batch_size_limit => nil,
94
+ :preload_policy_filename => nil,
95
+ :cache_filename_with_app_id => 'cache-file.app_id'
95
96
  }
96
97
  )
97
98
 
99
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
98
100
  expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
99
101
  agent = TCellAgent::Agent.new
100
102
 
101
- logger = double("logger")
103
+ logger = double('logger')
102
104
 
103
105
  expect(TCellAgent).to receive(:logger).and_return(logger)
104
- expect(logger).to receive(:error).with("tCell.io tcell_api_url is missing. Disabling policy polling.")
106
+ expect(logger).to receive(:error).with('tCell.io tcell_api_url is missing. Disabling policy polling.')
105
107
  expect(Thread).to_not receive(:new)
106
108
  agent.start_policy_polling_loop
107
109
  end
108
110
  end
109
111
  end
110
112
 
111
- context "app_id" do
112
- context "is nil " do
113
- it "should not start the policy polling loop" do
113
+ context 'app_id' do
114
+ context 'is nil ' do
115
+ it 'should not start the policy polling loop' do
114
116
  configuration = double(
115
- "configuration",
117
+ 'configuration',
116
118
  {
117
- tcell_api_url: "present",
118
- app_id: nil,
119
- should_start_policy_poll?: true,
120
- event_time_limit_seconds: nil,
121
- event_batch_size_limit: nil,
122
- preload_policy_filename: nil,
123
- cache_filename_with_app_id: "cache-file.app_id"
119
+ :tcell_api_url => 'present',
120
+ :app_id => nil,
121
+ :should_start_policy_poll? => true,
122
+ :event_time_limit_seconds => nil,
123
+ :event_batch_size_limit => nil,
124
+ :preload_policy_filename => nil,
125
+ :cache_filename_with_app_id => 'cache-file.app_id'
124
126
  }
125
127
  )
126
128
 
129
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
127
130
  expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
128
131
  agent = TCellAgent::Agent.new
129
132
 
130
- logger = double("logger")
133
+ logger = double('logger')
131
134
 
132
135
  expect(TCellAgent).to receive(:logger).and_return(logger)
133
- expect(logger).to receive(:error).with("tCell.io app_id is missing. Disabling policy polling.")
136
+ expect(logger).to receive(:error).with('tCell.io app_id is missing. Disabling policy polling.')
134
137
  expect(Thread).to_not receive(:new)
135
138
  agent.start_policy_polling_loop
136
139
  end
137
140
  end
138
141
 
139
- context "is empty" do
140
- it "should not start the policy polling loop" do
142
+ context 'is empty' do
143
+ it 'should not start the policy polling loop' do
141
144
  configuration = double(
142
- "configuration",
145
+ 'configuration',
143
146
  {
144
- tcell_api_url: "present",
145
- app_id: "",
146
- should_start_policy_poll?: true,
147
- event_time_limit_seconds: nil,
148
- event_batch_size_limit: nil,
149
- preload_policy_filename: nil,
150
- cache_filename_with_app_id: "cache-file.app_id"
147
+ :tcell_api_url => 'present',
148
+ :app_id => '',
149
+ :should_start_policy_poll? => true,
150
+ :event_time_limit_seconds => nil,
151
+ :event_batch_size_limit => nil,
152
+ :preload_policy_filename => nil,
153
+ :cache_filename_with_app_id => 'cache-file.app_id'
151
154
  }
152
155
  )
153
156
 
157
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
154
158
  expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
155
159
  agent = TCellAgent::Agent.new
156
160
 
157
- logger = double("logger")
161
+ logger = double('logger')
158
162
 
159
163
  expect(TCellAgent).to receive(:logger).and_return(logger)
160
- expect(logger).to receive(:error).with("tCell.io app_id is missing. Disabling policy polling.")
164
+ expect(logger).to receive(:error).with('tCell.io app_id is missing. Disabling policy polling.')
161
165
  expect(Thread).to_not receive(:new)
162
166
  agent.start_policy_polling_loop
163
167
  end
164
168
  end
165
169
 
166
- context "is blank space" do
167
- it "should not start the policy polling loop" do
170
+ context 'is blank space' do
171
+ it 'should not start the policy polling loop' do
168
172
  configuration = double(
169
- "configuration",
173
+ 'configuration',
170
174
  {
171
- tcell_api_url: "present",
172
- app_id: " ",
173
- should_start_policy_poll?: true,
174
- event_time_limit_seconds: nil,
175
- event_batch_size_limit: nil,
176
- preload_policy_filename: nil,
177
- cache_filename_with_app_id: "cache-file.app_id"
175
+ :tcell_api_url => 'present',
176
+ :app_id => ' ',
177
+ :should_start_policy_poll? => true,
178
+ :event_time_limit_seconds => nil,
179
+ :event_batch_size_limit => nil,
180
+ :preload_policy_filename => nil,
181
+ :cache_filename_with_app_id => 'cache-file.app_id'
178
182
  }
179
183
  )
180
184
 
185
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
181
186
  expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
182
187
  agent = TCellAgent::Agent.new
183
188
 
184
- logger = double("logger")
189
+ logger = double('logger')
185
190
 
186
191
  expect(TCellAgent).to receive(:logger).and_return(logger)
187
- expect(logger).to receive(:error).with("tCell.io app_id is missing. Disabling policy polling.")
192
+ expect(logger).to receive(:error).with('tCell.io app_id is missing. Disabling policy polling.')
188
193
  expect(Thread).to_not receive(:new)
189
194
  agent.start_policy_polling_loop
190
195
  end
@@ -193,29 +198,27 @@ module TCellAgent
193
198
  end
194
199
  end
195
200
 
196
- describe "#cache" do
197
- context "with an existing cached file" do
198
-
199
- context "with two processes" do
200
- context "while one process is writing to the cached file" do
201
+ describe '#cache' do
202
+ context 'with an existing cached file' do
203
+ context 'with two processes' do
204
+ context 'while one process is writing to the cached file' do
201
205
  before(:each) do
202
206
  TCellAgent.thread_agent.cache(
203
- "http-redirect",
207
+ 'http-redirect',
204
208
  {
205
- "app_id"=>"raftest-EyJZR",
206
- "policy_id"=>"363b8b60-a9a8-11e5-bb10-a9372a56b8a7",
207
- "data"=> {
208
- "enabled"=>true,
209
- "block"=>false,
210
- "whitelist"=>[]
209
+ 'app_id' => 'raftest-EyJZR',
210
+ 'policy_id' => '363b8b60-a9a8-11e5-bb10-a9372a56b8a7',
211
+ 'data' => {
212
+ 'enabled' => true,
213
+ 'block' => false,
214
+ 'whitelist' => []
211
215
  }
212
216
  }
213
217
  )
214
218
  end
215
219
 
216
- it "should raise a timeout exception when the other process tries to write to it" do
220
+ it 'should raise a timeout exception when the other process tries to write to it' do
217
221
  file_lock_holder = ForkBreak::Process.new do |breakpoints|
218
-
219
222
  original_dump = JSON.method(:dump)
220
223
  JSON.stub(:dump) do |*args|
221
224
  breakpoints << :before_dump
@@ -223,14 +226,14 @@ module TCellAgent
223
226
  end
224
227
 
225
228
  TCellAgent.thread_agent.cache(
226
- "http-redirect",
229
+ 'http-redirect',
227
230
  {
228
- "app_id"=>"raftest-EyJZR",
229
- "policy_id"=>"363b8b60-a9a8-11e5-bb10-a9372a56b8a7",
230
- "data"=> {
231
- "enabled"=>true,
232
- "block"=>false,
233
- "whitelist"=>[]
231
+ 'app_id' => 'raftest-EyJZR',
232
+ 'policy_id' => '363b8b60-a9a8-11e5-bb10-a9372a56b8a7',
233
+ 'data' => {
234
+ 'enabled' => true,
235
+ 'block' => false,
236
+ 'whitelist' => []
234
237
  }
235
238
  }
236
239
  )
@@ -238,19 +241,19 @@ module TCellAgent
238
241
 
239
242
  file_lock_holder.run_until(:before_dump).wait
240
243
 
241
- logger = double("logger")
244
+ logger = double('logger')
242
245
  expect(TCellAgent).to receive(:logger).and_return(logger)
243
- expect(logger).to receive(:warn).with("execution expired")
246
+ expect(logger).to receive(:warn).with('execution expired')
244
247
 
245
248
  TCellAgent.thread_agent.cache(
246
- "http-redirect",
249
+ 'http-redirect',
247
250
  {
248
- "app_id"=>"raftest-EyJZR",
249
- "policy_id"=>"363b8b60-a9a8-11e5-bb10-a9372a56b8a7",
250
- "data"=> {
251
- "enabled"=>true,
252
- "block"=>false,
253
- "whitelist"=>[]
251
+ 'app_id' => 'raftest-EyJZR',
252
+ 'policy_id' => '363b8b60-a9a8-11e5-bb10-a9372a56b8a7',
253
+ 'data' => {
254
+ 'enabled' => true,
255
+ 'block' => false,
256
+ 'whitelist' => []
254
257
  }
255
258
  }
256
259
  )
@@ -258,7 +261,6 @@ module TCellAgent
258
261
  file_lock_holder.finish.wait
259
262
  end
260
263
 
261
-
262
264
  after(:each) do
263
265
  File.delete(TCellAgent.configuration.cache_filename_with_app_id)
264
266
  end
@@ -266,9 +268,9 @@ module TCellAgent
266
268
  end
267
269
  end
268
270
 
269
- context "with 10 processes updating the cached file" do
270
- xit "should update the cached file with all updates" do
271
- processes = 5.times.map do |process_number|
271
+ context 'with 10 processes updating the cached file' do
272
+ xit 'should update the cached file with all updates' do
273
+ processes = Array.new(5).each do |process_number|
272
274
  ForkBreak::Process.new do |breakpoints|
273
275
  original_dump = JSON.method(:dump)
274
276
  JSON.stub(:dump) do |*args|
@@ -279,120 +281,141 @@ module TCellAgent
279
281
  TCellAgent.thread_agent.cache(
280
282
  "process_#{process_number}",
281
283
  {
282
- "app_id"=>"raftest-EyJZR",
283
- "policy_id"=>"policy_id",
284
- "data"=> { "enabled"=>true }
284
+ 'app_id' => 'raftest-EyJZR',
285
+ 'policy_id' => 'policy_id',
286
+ 'data' => { 'enabled' => true }
285
287
  }
286
288
  )
287
-
288
289
  end
289
290
  end
290
291
 
291
292
  processes.map(&:finish).map(&:wait)
292
293
 
293
- policies = JSON.parse(open(TCellAgent.configuration.cache_filename_with_app_id).read)
294
+ policies = JSON.parse(File.open(TCellAgent.configuration.cache_filename_with_app_id).read)
294
295
 
295
296
  File.delete(TCellAgent.configuration.cache_filename_with_app_id)
296
297
 
297
- expect(policies).to eq({
298
- "process_0"=>{"app_id"=>"raftest-EyJZR", "policy_id"=>"policy_id", "data"=>{"enabled"=>true}},
299
- "process_1"=>{"app_id"=>"raftest-EyJZR", "policy_id"=>"policy_id", "data"=>{"enabled"=>true}},
300
- "process_2"=>{"app_id"=>"raftest-EyJZR", "policy_id"=>"policy_id", "data"=>{"enabled"=>true}},
301
- "process_3"=>{"app_id"=>"raftest-EyJZR", "policy_id"=>"policy_id", "data"=>{"enabled"=>true}},
302
- "process_4"=>{"app_id"=>"raftest-EyJZR", "policy_id"=>"policy_id", "data"=>{"enabled"=>true}}
303
- })
298
+ expect(policies).to eq(
299
+ {
300
+ 'process_0' => { 'app_id' => 'raftest-EyJZR', 'policy_id' => 'policy_id', 'data' => { 'enabled' => true } },
301
+ 'process_1' => { 'app_id' => 'raftest-EyJZR', 'policy_id' => 'policy_id', 'data' => { 'enabled' => true } },
302
+ 'process_2' => { 'app_id' => 'raftest-EyJZR', 'policy_id' => 'policy_id', 'data' => { 'enabled' => true } },
303
+ 'process_3' => { 'app_id' => 'raftest-EyJZR', 'policy_id' => 'policy_id', 'data' => { 'enabled' => true } },
304
+ 'process_4' => { 'app_id' => 'raftest-EyJZR', 'policy_id' => 'policy_id', 'data' => { 'enabled' => true } }
305
+ }
306
+ )
304
307
  end
305
308
  end
306
309
  end
307
310
 
308
- describe "#policies_from_cachefile" do
309
- context "with no cache file" do
310
- it "should return nil" do
311
+ describe '#policies_from_cachefile' do
312
+ context 'with no cache file' do
313
+ it 'should return nil' do
314
+ rust_policies = double('rust_policies')
311
315
 
312
- expect(File).to receive(:exist?).with(/tcell\/cache\/tcell_agent.cache/).and_return(false)
316
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(rust_policies)
317
+ expect(File).to receive(:exist?).with(%r{tcell/cache/tcell_agent.cache}).and_return(false)
313
318
  expect_any_instance_of(TCellAgent::Agent).to_not receive(:processPolicyJson)
314
319
  agent = TCellAgent::Agent.new(Process.pid)
315
320
 
316
- expect(agent.policies).to eq({})
321
+ expect(agent.policies).to eq({ 'rust' => rust_policies })
317
322
  end
318
323
  end
319
324
 
320
- context "with a cache file present" do
321
- context "that is empty" do
322
- it "should raise a json error" do
323
- cache_file = double("cache_file")
324
- expect(File).to receive(:exist?).with(/tcell\/cache\/tcell_agent.cache/).and_return(true)
325
+ context 'with a cache file present' do
326
+ context 'that is empty' do
327
+ it 'should raise a json error' do
328
+ cache_file = double('cache_file')
329
+ expect(File).to receive(:exist?).with(%r{tcell/cache/tcell_agent.cache}).and_return(true)
325
330
  expect(File).to receive(:open).and_return(cache_file)
326
331
  expect(cache_file).to receive(:flock).and_return(true)
327
- expect(cache_file).to receive(:read).and_return("")
332
+ expect(cache_file).to receive(:read).and_return('')
328
333
  expect(cache_file).to receive(:close)
329
334
 
330
- logger = double("logger")
335
+ logger = double('logger')
331
336
  expect(TCellAgent).to receive(:logger).and_return(logger)
332
- expect(logger).to receive(:warn).with("A JSON text must at least contain two octets!")
337
+ expect(logger).to receive(:warn).with('A JSON text must at least contain two octets!')
338
+
339
+ rust_policies = double('rust_policies')
340
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(rust_policies)
333
341
 
334
342
  expect_any_instance_of(TCellAgent::Agent).to_not receive(:processPolicyJson)
335
343
 
336
344
  agent = TCellAgent::Agent.new(Process.pid)
337
345
 
338
- expect(agent.policies).to eq({})
346
+ expect(agent.policies).to eq({ 'rust' => rust_policies })
339
347
  end
340
348
  end
341
349
 
342
- context "that has content" do
343
- context "that is malformed" do
344
- it "should raise a json error" do
345
- cache_file = double("cache_file")
346
- expect(File).to receive(:exist?).with(/tcell\/cache\/tcell_agent.cache/).and_return(true)
350
+ context 'that has content' do
351
+ context 'that is malformed' do
352
+ it 'should raise a json error' do
353
+ cache_file = double('cache_file')
354
+ expect(File).to receive(:exist?).with(%r{tcell/cache/tcell_agent.cache}).and_return(true)
347
355
  expect(File).to receive(:open).and_return(cache_file)
348
356
  expect(cache_file).to receive(:flock).and_return(true)
349
- expect(cache_file).to receive(:read).and_return("bad_json")
357
+ expect(cache_file).to receive(:read).and_return('bad_json')
350
358
  expect(cache_file).to receive(:close)
351
359
 
352
- logger = double("logger")
360
+ logger = double('logger')
353
361
  expect(TCellAgent).to receive(:logger).and_return(logger)
354
362
  expect(logger).to receive(:warn).with(/unexpected token at 'bad_json'/)
355
363
  expect_any_instance_of(TCellAgent::Agent).to_not receive(:processPolicyJson)
356
364
 
365
+ rust_policies = double('rust_policies')
366
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(rust_policies)
367
+
357
368
  agent = TCellAgent::Agent.new(Process.pid)
358
369
 
359
- expect(agent.policies).to eq({})
370
+ expect(agent.policies).to eq({ 'rust' => rust_policies })
360
371
  end
361
372
  end
362
373
 
363
- context "that is an empty json object" do
364
- it "should raise a json error" do
365
- cache_file = double("cache_file")
366
- expect(File).to receive(:exist?).with(/tcell\/cache\/tcell_agent.cache/).and_return(true)
374
+ context 'that is an empty json object' do
375
+ it 'should raise a json error' do
376
+ cache_file = double('cache_file')
377
+ expect(File).to receive(:exist?).with(%r{tcell/cache/tcell_agent.cache}).and_return(true)
367
378
  expect(File).to receive(:open).and_return(cache_file)
368
379
  expect(cache_file).to receive(:flock).and_return(true)
369
- expect(cache_file).to receive(:read).and_return("{}")
380
+ expect(cache_file).to receive(:read).and_return('{}')
370
381
  expect(cache_file).to receive(:close)
371
382
 
372
383
  expect(TCellAgent).to_not receive(:logger)
373
384
 
385
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
374
386
  expect_any_instance_of(TCellAgent::Agent).to receive(:processPolicyJson).with({}, false)
375
387
 
376
- agent = TCellAgent::Agent.new(Process.pid)
388
+ TCellAgent::Agent.new(Process.pid)
377
389
  end
378
390
  end
379
391
 
380
- context "that is a valid policy" do
381
- it "should set the policies" do
382
- cache_file = double("cache_file")
383
- expect(File).to receive(:exist?).with(/tcell\/cache\/tcell_agent.cache/).and_return(true)
392
+ context 'that is a valid policy' do
393
+ it 'should set the policies' do
394
+ cache_file = double('cache_file')
395
+ expect(File).to receive(:exist?).with(%r{tcell/cache/tcell_agent.cache}).and_return(true)
384
396
  expect(File).to receive(:open).and_return(cache_file)
385
397
  expect(cache_file).to receive(:flock).and_return(true)
386
398
  expect(cache_file).to receive(:read).and_return(
387
399
  {
388
- process_0: {app_id: "raftest-EyJZR", policy_id: "policy_id", data: {enabled: true}}
400
+ :process_0 => {
401
+ :app_id => 'raftest-EyJZR',
402
+ :policy_id => 'policy_id',
403
+ :data => { :enabled => true }
404
+ }
389
405
  }.to_json
390
406
  )
391
407
  expect(cache_file).to receive(:close)
392
408
  expect_any_instance_of(TCellAgent::Agent).to receive(:processPolicyJson).with(
393
- {"process_0"=>{"app_id"=>"raftest-EyJZR", "policy_id"=>"policy_id", "data"=>{"enabled"=>true}}},
409
+ {
410
+ 'process_0' => {
411
+ 'app_id' => 'raftest-EyJZR',
412
+ 'policy_id' => 'policy_id',
413
+ 'data' => { 'enabled' => true }
414
+ }
415
+ },
394
416
  false
395
417
  )
418
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
396
419
 
397
420
  TCellAgent::Agent.new(Process.pid)
398
421
  end
@@ -400,7 +423,96 @@ module TCellAgent
400
423
  end
401
424
  end
402
425
  end
403
- end
404
426
 
427
+ describe '#policy_polling_iteration' do
428
+ context 'with policy polling errors' do
429
+ it 'should extend failure sleep time after each failure' do
430
+ configuration = double(
431
+ 'configuration',
432
+ {
433
+ :should_start_policy_poll? => false,
434
+ :event_time_limit_seconds => nil,
435
+ :event_batch_size_limit => nil,
436
+ :preload_policy_filename => nil,
437
+ :cache_filename_with_app_id => 'cache-file.app_id'
438
+ }
439
+ )
440
+
441
+ api = double('api')
442
+ logger = double('logger')
443
+
444
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
445
+ expect(TCellAgent::TCellApi).to receive(:new).and_return(api)
446
+ expect(TCellAgent::Policies::RustPolicies).to receive(:new).and_return(nil)
447
+ agent = TCellAgent::Agent.new
448
+
449
+ # failure sleep time should double after each failed attempt to retrieve policies
450
+ # until it reaches 480 seconds
451
+ failure_sleep_time = 30
452
+ last_poll_time = 0
453
+
454
+ # 1st attempt
455
+ expect(api).to receive(:poll_api).with(0).and_return(nil)
456
+ expect(TCellAgent).to receive(:logger).and_return(logger)
457
+ expect(logger).to receive(:error).with(
458
+ "Policy was nil. Sleeping for #{failure_sleep_time}"
459
+ )
460
+ expect(agent).to receive(:sleep).with(failure_sleep_time)
461
+ failure_sleep_time, last_poll_time = agent.policy_polling_iteration(failure_sleep_time, last_poll_time)
462
+
463
+ expect(failure_sleep_time).to eq(60)
464
+ expect(last_poll_time).to eq(0)
465
+
466
+ # 2nd attempt
467
+ expect(api).to receive(:poll_api).with(0).and_return(nil)
468
+ expect(TCellAgent).to receive(:logger).and_return(logger)
469
+ expect(logger).to receive(:error).with(
470
+ "Policy was nil. Sleeping for #{failure_sleep_time}"
471
+ )
472
+ expect(agent).to receive(:sleep).with(failure_sleep_time)
473
+ failure_sleep_time, last_poll_time = agent.policy_polling_iteration(failure_sleep_time, last_poll_time)
474
+
475
+ expect(failure_sleep_time).to eq(120)
476
+ expect(last_poll_time).to eq(0)
477
+
478
+ # 3rd attempt
479
+ expect(api).to receive(:poll_api).with(0).and_return(nil)
480
+ expect(TCellAgent).to receive(:logger).and_return(logger)
481
+ expect(logger).to receive(:error).with(
482
+ "Policy was nil. Sleeping for #{failure_sleep_time}"
483
+ )
484
+ expect(agent).to receive(:sleep).with(failure_sleep_time)
485
+ failure_sleep_time, last_poll_time = agent.policy_polling_iteration(failure_sleep_time, last_poll_time)
486
+
487
+ expect(failure_sleep_time).to eq(240)
488
+ expect(last_poll_time).to eq(0)
489
+
490
+ # 4th attempt
491
+ expect(api).to receive(:poll_api).with(0).and_return(nil)
492
+ expect(TCellAgent).to receive(:logger).and_return(logger)
493
+ expect(logger).to receive(:error).with(
494
+ "Policy was nil. Sleeping for #{failure_sleep_time}"
495
+ )
496
+ expect(agent).to receive(:sleep).with(failure_sleep_time)
497
+ failure_sleep_time, last_poll_time = agent.policy_polling_iteration(failure_sleep_time, last_poll_time)
498
+
499
+ expect(failure_sleep_time).to eq(480)
500
+ expect(last_poll_time).to eq(0)
501
+
502
+ # 5th attempt
503
+ expect(api).to receive(:poll_api).with(0).and_return(nil)
504
+ expect(TCellAgent).to receive(:logger).and_return(logger)
505
+ expect(logger).to receive(:error).with(
506
+ "Policy was nil. Sleeping for #{failure_sleep_time}"
507
+ )
508
+ expect(agent).to receive(:sleep).with(failure_sleep_time)
509
+ failure_sleep_time, last_poll_time = agent.policy_polling_iteration(failure_sleep_time, last_poll_time)
510
+
511
+ expect(failure_sleep_time).to eq(480)
512
+ expect(last_poll_time).to eq(0)
513
+ end
514
+ end
515
+ end
516
+ end
405
517
  end
406
518
  end