tcell_agent 0.4.0 → 1.0.0

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