tcell_agent 2.0.0 → 2.5.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 (112) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/bin/tcell_agent +41 -150
  4. data/lib/tcell_agent/agent.rb +87 -52
  5. data/lib/tcell_agent/config_initializer.rb +63 -0
  6. data/lib/tcell_agent/configuration.rb +72 -267
  7. data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
  8. data/lib/tcell_agent/instrument_servers.rb +14 -18
  9. data/lib/tcell_agent/instrumentation/cmdi.rb +47 -15
  10. data/lib/tcell_agent/instrumentation/lfi.rb +72 -15
  11. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
  12. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
  13. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
  17. data/lib/tcell_agent/instrumentation.rb +14 -6
  18. data/lib/tcell_agent/logger.rb +3 -4
  19. data/lib/tcell_agent/policies/command_injection_policy.rb +1 -1
  20. data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
  21. data/lib/tcell_agent/policies/headers_policy.rb +2 -2
  22. data/lib/tcell_agent/policies/patches_policy.rb +8 -4
  23. data/lib/tcell_agent/policies/policies_manager.rb +1 -0
  24. data/lib/tcell_agent/policies/policy_polling.rb +4 -3
  25. data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
  26. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  27. data/lib/tcell_agent/rails/auth/devise.rb +103 -102
  28. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  29. data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -57
  30. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  31. data/lib/tcell_agent/rails/better_ip.rb +7 -19
  32. data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
  33. data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
  34. data/lib/tcell_agent/rails/dlp.rb +58 -56
  35. data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
  36. data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
  37. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
  38. data/lib/tcell_agent/rails/middleware/global_middleware.rb +3 -4
  39. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
  40. data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
  41. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  42. data/lib/tcell_agent/rails/routes/grape.rb +5 -12
  43. data/lib/tcell_agent/rails/routes.rb +6 -9
  44. data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
  45. data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
  46. data/lib/tcell_agent/routes/table.rb +3 -0
  47. data/lib/tcell_agent/rust/agent_config.rb +62 -33
  48. data/lib/tcell_agent/rust/{libtcellagent-4.14.0.so → libtcellagent-alpine.so} +0 -0
  49. data/lib/tcell_agent/rust/{libtcellagent-4.14.0.dylib → libtcellagent-x64.dll} +0 -0
  50. data/lib/tcell_agent/rust/{libtcellagent-alpine-4.14.0.so → libtcellagent.dylib} +0 -0
  51. data/lib/tcell_agent/rust/libtcellagent.so +0 -0
  52. data/lib/tcell_agent/rust/models.rb +9 -0
  53. data/lib/tcell_agent/rust/native_agent.rb +61 -51
  54. data/lib/tcell_agent/rust/native_library.rb +8 -10
  55. data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
  56. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
  57. data/lib/tcell_agent/servers/puma.rb +30 -13
  58. data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -0
  59. data/lib/tcell_agent/servers/rails_server.rb +4 -4
  60. data/lib/tcell_agent/servers/unicorn.rb +1 -1
  61. data/lib/tcell_agent/servers/webrick.rb +12 -3
  62. data/lib/tcell_agent/settings_reporter.rb +0 -93
  63. data/lib/tcell_agent/sinatra.rb +1 -0
  64. data/lib/tcell_agent/tcell_context.rb +16 -7
  65. data/lib/tcell_agent/utils/headers.rb +0 -1
  66. data/lib/tcell_agent/utils/strings.rb +2 -2
  67. data/lib/tcell_agent/version.rb +1 -1
  68. data/lib/tcell_agent.rb +8 -16
  69. data/spec/cruby_spec_helper.rb +26 -0
  70. data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
  71. data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
  72. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
  73. data/spec/lib/tcell_agent/{cmdi_spec.rb → instrumentation/cmdi_spec.rb} +50 -0
  74. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
  75. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +213 -223
  76. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +95 -61
  77. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +120 -2
  78. data/spec/lib/tcell_agent/patches_spec.rb +2 -1
  79. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
  80. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
  81. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
  82. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
  83. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +13 -8
  84. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
  85. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
  86. data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
  87. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
  88. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
  89. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
  90. data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
  91. data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
  92. data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
  93. data/spec/spec_helper.rb +9 -1
  94. data/spec/support/builders.rb +8 -7
  95. data/spec/support/server_mocks/passenger_mock.rb +7 -0
  96. data/spec/support/server_mocks/puma_mock.rb +21 -0
  97. data/spec/support/server_mocks/rails_mock.rb +7 -0
  98. data/spec/support/server_mocks/thin_mock.rb +7 -0
  99. data/spec/support/server_mocks/unicorn_mock.rb +11 -0
  100. data/spec/support/shared_spec.rb +29 -0
  101. data/tcell_agent.gemspec +14 -14
  102. metadata +46 -29
  103. data/Rakefile +0 -18
  104. data/lib/tcell_agent/authlogic.rb +0 -23
  105. data/lib/tcell_agent/config/unknown_options.rb +0 -119
  106. data/lib/tcell_agent/devise.rb +0 -33
  107. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
  108. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -123
  109. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -159
  110. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
  111. data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
  112. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -1,6 +1,9 @@
1
+ # rubocop:disable Style/HashSyntax
2
+
1
3
  require 'spec_helper'
2
4
  require 'securerandom'
3
5
 
6
+ FILE_CONTENTS = "This is line one.\nThis is line two.\n".freeze
4
7
  describe 'IO' do
5
8
  before do
6
9
  native_agent = double('native_agent')
@@ -17,8 +20,9 @@ describe 'IO' do
17
20
  @file_contents = "This is line one.\nThis is line two.\n"
18
21
  @file_length = @file_contents.length
19
22
 
20
- @new_file_name = '/tmp/' + SecureRandom.uuid
23
+ @new_file_name = NEW_FILE_NAME
21
24
  @new_file_contents_offset = "This OFFSETe one.\nThis is line two.\n"
25
+ @new_file_contents_offset_bytes = "\x00\x00\x00\x00\x00OFFSET"
22
26
  end
23
27
 
24
28
  describe '.binread' do
@@ -42,6 +46,7 @@ describe 'IO' do
42
46
  TCellAgent::PolicyTypes::LFI
43
47
  ).and_return(@local_files_policy)
44
48
  expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
49
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
45
50
  end
46
51
  end
47
52
 
@@ -49,23 +54,20 @@ describe 'IO' do
49
54
  result = IO.binread('|echo test')
50
55
  expect(result).to eq "test\n"
51
56
  end
52
- context 'with a filename' do
53
- it 'should still be able to read file' do
54
- result = IO.binread(@filename)
55
- expect(result).to eq @file_contents
56
- end
57
+
58
+ it 'should read the file normally' do
59
+ result = IO.binread(@filename)
60
+ expect(result).to eq @file_contents
57
61
  end
58
- context 'with a filename and a length of 20' do
59
- it 'should read 20 bytes of the file' do
60
- result = IO.binread(@filename, 20)
61
- expect(result).to eq @file_contents[0..19]
62
- end
62
+
63
+ it 'should read 20 bytes of the file' do
64
+ result = IO.binread(@filename, 20)
65
+ expect(result).to eq @file_contents[0..19]
63
66
  end
64
- context 'with a filename and a length of 20 and an offset of 5' do
65
- it 'should read 20 bytes starting from the 5th byte' do
66
- result = IO.binread(@filename, 20, 5)
67
- expect(result).to eq @file_contents[5..24]
68
- end
67
+
68
+ it 'should read 20 bytes starting from the 5th byte' do
69
+ result = IO.binread(@filename, 20, 5)
70
+ expect(result).to eq @file_contents[5..24]
69
71
  end
70
72
  end
71
73
  context 'with a file blocked for read/write' do
@@ -75,33 +77,31 @@ describe 'IO' do
75
77
  TCellAgent::PolicyTypes::LFI
76
78
  ).and_return(@local_files_policy)
77
79
  expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
80
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
78
81
  end
79
82
  end
80
83
 
81
- it 'should still be able to execute OS commands', :skip_before do
84
+ it 'should execute shell commands', :skip_before do
82
85
  result = IO.binread('|echo test')
83
86
  expect(result).to eq "test\n"
84
87
  end
85
- context 'with a filename' do
86
- it 'should not be able to read the file' do
87
- expect do
88
- IO.binread(@filename)
89
- end.to raise_error(IOError)
90
- end
88
+
89
+ it 'should receive an IOError' do
90
+ expect do
91
+ IO.binread(@filename)
92
+ end.to raise_error(IOError)
91
93
  end
92
- context 'with a filename and a length of 20' do
93
- it 'should not be able to read the file' do
94
- expect do
95
- IO.binread(@filename, 20)
96
- end.to raise_error(IOError)
97
- end
94
+
95
+ it 'should receive an IOError' do
96
+ expect do
97
+ IO.binread(@filename, 20)
98
+ end.to raise_error(IOError)
98
99
  end
99
- context 'with a filename and a length of 20 and an offset of 5' do
100
- it 'should not be able to read the file' do
101
- expect do
102
- IO.binread(@filename, 20, 5)
103
- end.to raise_error(IOError)
104
- end
100
+
101
+ it 'should receive an IOError' do
102
+ expect do
103
+ IO.binread(@filename, 20, 5)
104
+ end.to raise_error(IOError)
105
105
  end
106
106
  end
107
107
  end
@@ -120,6 +120,7 @@ describe 'IO' do
120
120
  end.to raise_error(ArgumentError)
121
121
  end
122
122
  end
123
+
123
124
  context 'with a file not blocked for read/write' do
124
125
  before do
125
126
  expect(TCellAgent).to receive(:policy).with(
@@ -128,28 +129,36 @@ describe 'IO' do
128
129
  expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
129
130
  end
130
131
 
131
- context 'with a nonexistent filename and string' do
132
+ after(:each) do
133
+ File.delete(@new_file_name)
134
+ end
135
+
136
+ context 'with a non-existent file' do
132
137
  it 'should create the file' do
133
138
  IO.binwrite(@new_file_name, '')
134
139
  expect(File.exist?(@new_file_name)).to be_truthy
135
- File.delete(@new_file_name)
136
140
  end
141
+
137
142
  it 'should write to the file' do
138
143
  expect(IO.binwrite(@new_file_name, @file_contents)).to eq @file_length
139
- File.delete(@new_file_name)
140
144
  end
141
- end
142
- context 'with a nonexistent filename and string and offset' do
143
- it 'should write to the file at the offset value 5' do
144
- expect(TCellAgent).to receive(:policy).with(
145
- TCellAgent::PolicyTypes::LFI
146
- ).and_return(@local_files_policy, @local_files_policy)
147
- expect(@local_files_policy).to receive(:block_file_access?).and_return(false, false)
148
145
 
149
- IO.binwrite(@new_file_name, @file_contents)
150
- IO.binwrite(@new_file_name, 'OFFSET', 5)
151
- expect(IO.binread(@new_file_name)).to eq @new_file_contents_offset
152
- File.delete(@new_file_name)
146
+ context 'using offset, perm' do
147
+ after :each do
148
+ expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('444')
149
+
150
+ expect(TCellAgent).to receive(:policy).with(
151
+ TCellAgent::PolicyTypes::LFI
152
+ ).and_return(@local_files_policy)
153
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
154
+ expect(File.open(@new_file_name).read).to eq @new_file_contents_offset_bytes
155
+ end
156
+
157
+ test_ruby2_ruby3_keywords(IO,
158
+ 'binwrite',
159
+ [NEW_FILE_NAME, 'OFFSET', 5],
160
+ { perm: 0o444 },
161
+ 6)
153
162
  end
154
163
  end
155
164
  end
@@ -161,19 +170,10 @@ describe 'IO' do
161
170
  expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
162
171
  end
163
172
 
164
- context 'with a nonexistent filename and a string' do
165
- it 'should not be able to write to the file' do
166
- expect do
167
- IO.binwrite(@new_file_name, @file_contents)
168
- end.to raise_error(IOError)
169
- end
170
- end
171
- context 'with a nonexistent filename and a string and an offset' do
172
- it 'should not be able to write to the file' do
173
- expect do
174
- IO.binwrite(@new_file_name, @file_contents)
175
- end.to raise_error(IOError)
176
- end
173
+ it 'should not be able to create and write to a file' do
174
+ expect do
175
+ IO.binwrite(@new_file_name, @file_contents)
176
+ end.to raise_error(IOError)
177
177
  end
178
178
  end
179
179
  end
@@ -194,20 +194,18 @@ describe 'IO' do
194
194
  expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
195
195
  end
196
196
 
197
- context 'with a filename' do
198
- it 'should be able to read the file' do
199
- result = ''
200
- IO.foreach(@filename) { |line| result << line }
201
- expect(result).to eq @file_contents
202
- end
197
+ it 'should be able to read the file' do
198
+ result = ''
199
+ IO.foreach(@filename) { |line| result << line }
200
+ expect(result).to eq @file_contents
203
201
  end
204
- context 'with a filename and a limit 16' do
205
- it 'should split each line to a max length of 16' do
206
- result = ''
207
- IO.foreach(@filename, 16) { |line| result << line }
208
- expect(result).to eq @file_contents
209
- end
202
+
203
+ it 'should split each line to a max length of 16' do
204
+ result = ''
205
+ IO.foreach(@filename, 16) { |line| result << line }
206
+ expect(result).to eq @file_contents
210
207
  end
208
+
211
209
  context 'with a filename and sep' do
212
210
  # TODO: no documentation on how to use sep
213
211
  end
@@ -223,14 +221,18 @@ describe 'IO' do
223
221
  expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
224
222
  end
225
223
 
226
- context 'with a filename' do
227
- it 'should not be able to read the file' do
228
- expect do
229
- result = ''
230
- IO.foreach(@filename) { |line| result << line }
231
- expect(result).to eq @file_contents
232
- end.to raise_error(IOError)
233
- end
224
+ it 'returns an IOError' do
225
+ expect do
226
+ result = ''
227
+ IO.foreach(@filename) { |line| result << line }
228
+ end.to raise_error(IOError)
229
+ end
230
+
231
+ it 'returns an IOError if it is non-existent' do
232
+ expect do
233
+ result = ''
234
+ IO.foreach('/tmp/bad-file-name') { |line| result << line }
235
+ end.to raise_error(IOError)
234
236
  end
235
237
  end
236
238
  end
@@ -254,30 +256,26 @@ describe 'IO' do
254
256
  ).and_return(@local_files_policy)
255
257
 
256
258
  expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
259
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
257
260
  end
258
261
  end
259
262
 
260
- it 'should still be able to execute OS commands', :skip_before do
263
+ it 'executes OS commands', :skip_before do
261
264
  result = IO.read('|echo test')
262
265
  expect(result).to eq "test\n"
263
266
  end
264
- context 'with a filename' do
265
- it 'should read the file' do
266
- result = IO.read(@filename)
267
- expect(result).to eq @file_contents
268
- end
269
- end
270
- context 'with a filename and a length of 20' do
271
- it 'should read 20 bytes of the file' do
272
- result = IO.read(@filename, 20)
273
- expect(result).to eq @file_contents[0..19]
274
- end
267
+
268
+ it 'returns the file contents' do
269
+ result = IO.read(@filename)
270
+ expect(result).to eq @file_contents
275
271
  end
276
- context 'with a filename and a length of 20 and an offset of 5' do
277
- it 'should read 20 bytes starting from the 5th byte' do
278
- result = IO.read(@filename, 20, 5)
279
- expect(result).to eq @file_contents[5..24]
280
- end
272
+
273
+ context 'using length, offset, mode' do
274
+ test_ruby2_ruby3_keywords(IO,
275
+ 'read',
276
+ [get_test_resource_path('lfi_sample_file.txt'), 20, 5],
277
+ { mode: 'rb' },
278
+ FILE_CONTENTS[5..24])
281
279
  end
282
280
  end
283
281
  context 'with a file blocked for read/write' do
@@ -288,33 +286,28 @@ describe 'IO' do
288
286
  ).and_return(@local_files_policy)
289
287
 
290
288
  expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
289
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
291
290
  end
292
291
  end
293
292
 
294
- it 'should still be able to execute OS commands', :skip_before do
293
+ it 'executes OS commands', :skip_before do
295
294
  result = IO.read('|echo test')
296
295
  expect(result).to eq "test\n"
297
296
  end
298
- context 'with a filename' do
299
- it 'should not be able to read the file' do
300
- expect do
301
- IO.read(@filename)
302
- end.to raise_error(IOError)
303
- end
297
+ it 'receeive an IOError' do
298
+ expect do
299
+ IO.read(@filename)
300
+ end.to raise_error(IOError)
304
301
  end
305
- context 'with a filename and a length 20' do
306
- it 'should not be able to read the file' do
307
- expect do
308
- IO.read(@filename, 20)
309
- end.to raise_error(IOError)
310
- end
302
+ it 'receeive an IOError' do
303
+ expect do
304
+ IO.read(@filename, 20)
305
+ end.to raise_error(IOError)
311
306
  end
312
- context 'with a filename and a length and an offset 5' do
313
- it 'should not be able to read the file' do
314
- expect do
315
- IO.read(@filename, 20, 5)
316
- end.to raise_error(IOError)
317
- end
307
+ it 'receeive an IOError' do
308
+ expect do
309
+ IO.read(@filename, 20, 5)
310
+ end.to raise_error(IOError)
318
311
  end
319
312
  end
320
313
  end
@@ -338,24 +331,34 @@ describe 'IO' do
338
331
  ).and_return(@local_files_policy)
339
332
 
340
333
  expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
334
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
341
335
  end
342
336
  end
343
337
 
344
- context 'with a filename' do
345
- it 'should read the file' do
346
- result = IO.readlines(@filename)
347
- expect(result[0] + result[1]).to eq @file_contents
348
- end
338
+ it 'reads the file normally' do
339
+ result = IO.readlines(@filename)
340
+ expect(result[0] + result[1]).to eq @file_contents
349
341
  end
350
- context 'with a filename and a limit 20' do
351
- it 'should read 20 bytes of the file' do
342
+
343
+ context 'using limit, separator' do
344
+ it 'splits the file and splits it into 5 char chunks' do
352
345
  exp_result = ['This ', 'is li', 'ne on', "e.\n", 'This ', 'is li', 'ne tw', "o.\n"]
353
346
  result = IO.readlines(@filename, 5)
354
347
  expect(result).to eq exp_result
355
348
  end
356
- end
357
- context 'with a filename and a limit of 20 and sep' do
358
- # TODO
349
+
350
+ it 'splits the file based on the sep and limit' do
351
+ exp_result = ['This ', 'is ', 'line ', "one.\n", 'This ', 'is ', 'line ', "two.\n"]
352
+ result = IO.readlines(@filename, ' ', 5)
353
+ expect(result).to eq exp_result
354
+ end
355
+
356
+ test_ruby2_ruby3_keywords(IO,
357
+ 'readlines',
358
+ [get_test_resource_path('lfi_sample_file.txt'), ' ', 5],
359
+ { chomp: true },
360
+ ['This', 'is', 'line', "one.\n", 'This', 'is', 'line', "two.\n"],
361
+ '2.4.0')
359
362
  end
360
363
  end
361
364
  context 'with a file blocked for read/write' do
@@ -366,6 +369,7 @@ describe 'IO' do
366
369
  ).and_return(@local_files_policy)
367
370
 
368
371
  expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
372
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
369
373
  end
370
374
  end
371
375
 
@@ -373,12 +377,11 @@ describe 'IO' do
373
377
  result = IO.readlines('|echo test')[0]
374
378
  expect(result).to eq "test\n"
375
379
  end
376
- context 'with a filename' do
377
- it 'should not be able to read the file' do
378
- expect do
379
- IO.readlines(@filename)
380
- end.to raise_error(IOError)
381
- end
380
+
381
+ it 'should not be able to read the file' do
382
+ expect do
383
+ IO.readlines(@filename)
384
+ end.to raise_error(IOError)
382
385
  end
383
386
  end
384
387
  end
@@ -397,16 +400,7 @@ describe 'IO' do
397
400
  end.to raise_error(Errno::ENOENT)
398
401
  end
399
402
  end
400
- context 'with a nonexistent file' do
401
- context 'with mode r' do
402
- it 'should raise an error' do
403
- end
404
- end
405
- context 'with mode w' do
406
- it 'should return an integer' do
407
- end
408
- end
409
- end
403
+
410
404
  context 'with a file not blocked for read/write' do
411
405
  before do
412
406
  expect(TCellAgent).to receive(:policy).with(
@@ -415,27 +409,27 @@ describe 'IO' do
415
409
  expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
416
410
  end
417
411
 
418
- context 'with a filename' do
419
- it 'should return an integer' do
420
- fd = IO.sysopen(@filename)
421
- expect(fd).to be_a(Integer)
422
- end
423
- it 'should open the file for read' do
424
- fd = IO.sysopen(@filename)
425
- expect(IO.new(fd).read).to eq @file_contents
426
- end
412
+ it 'returns an integer' do
413
+ fd = IO.sysopen(@filename)
414
+ expect(fd).to be_a(Integer)
427
415
  end
428
- context 'with a filename and mode w' do
429
- it 'should return an integer' do
430
- fd = IO.sysopen(@new_file_name, 'w')
431
- expect(fd).to be_a(Integer)
432
- end
433
- it 'should open the file for write' do
434
- fd = IO.sysopen(@new_file_name, 'w')
435
- file = IO.new(fd, 'w')
436
- file.puts @file_contents
437
- file.rewind
438
- end
416
+ it 'opens the file for read' do
417
+ fd = IO.sysopen(@filename)
418
+ expect(IO.new(fd).read).to eq @file_contents
419
+ end
420
+ it 'uses the mode when set' do
421
+ fd = IO.sysopen(@new_file_name, 'w')
422
+ expect(fd).to be_a(Integer)
423
+
424
+ file = IO.new(fd, 'w')
425
+ file.puts @file_contents
426
+ file.rewind
427
+ end
428
+ it 'should open the file for write' do
429
+ fd = IO.sysopen(@new_file_name, 'w')
430
+ file = IO.new(fd, 'w')
431
+ file.puts @file_contents
432
+ file.rewind
439
433
  end
440
434
  end
441
435
  context 'with a file blocked for read/write' do
@@ -446,19 +440,16 @@ describe 'IO' do
446
440
  expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
447
441
  end
448
442
 
449
- context 'with a filename' do
450
- it 'should not be able to open the file for read' do
451
- expect do
452
- IO.sysopen(@filename)
453
- end.to raise_error(IOError)
454
- end
443
+ it 'should not be able to open the file for read' do
444
+ expect do
445
+ IO.sysopen(@filename)
446
+ end.to raise_error(IOError)
455
447
  end
456
- context 'with a filename and mode' do
457
- it 'should not be able to open the file for read' do
458
- expect do
459
- IO.sysopen(@filename, 'r')
460
- end.to raise_error(IOError)
461
- end
448
+
449
+ it 'should not be able to open the file for read' do
450
+ expect do
451
+ IO.sysopen(@filename, 'r')
452
+ end.to raise_error(IOError)
462
453
  end
463
454
  end
464
455
  end
@@ -485,48 +476,49 @@ describe 'IO' do
485
476
  expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
486
477
  end
487
478
 
488
- context 'with a filename that doe not exist' do
489
- it 'should create the file' do
490
- IO.write(@new_file_name, @file_contents)
491
- expect(File.exist?(@new_file_name)).to be_truthy
492
- File.delete(@new_file_name)
493
- end
494
- it 'should write to the file' do
495
- expect(TCellAgent).to receive(:policy).with(
496
- TCellAgent::PolicyTypes::LFI
497
- ).and_return(@local_files_policy)
498
- expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
479
+ after :each do
480
+ File.delete(@new_file_name)
481
+ end
482
+ it 'creates the file' do
483
+ IO.write(@new_file_name, @file_contents)
484
+ expect(File.exist?(@new_file_name)).to be_truthy
485
+ end
486
+ it 'writes to the file' do
487
+ expect(TCellAgent).to receive(:policy).with(
488
+ TCellAgent::PolicyTypes::LFI
489
+ ).and_return(@local_files_policy)
490
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
499
491
 
500
- IO.write(@new_file_name, @file_contents)
501
- expect(IO.read(@new_file_name)).to eq @file_contents
502
- File.delete(@new_file_name)
503
- end
492
+ IO.write(@new_file_name, @file_contents)
493
+ expect(File.open(@new_file_name).read).to eq @file_contents
504
494
  end
505
- context 'with a filename that does exist' do
506
- it 'should overwrite the file' do
507
- expect(TCellAgent).to receive(:policy).with(
508
- TCellAgent::PolicyTypes::LFI
509
- ).and_return(@local_files_policy)
510
- expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
511
495
 
512
- IO.write(@new_file_name, @file_contents)
513
- expect(IO.read(@new_file_name)).to eq @file_contents
514
- File.delete(@new_file_name)
515
- end
496
+ it 'writes over the file' do
497
+ expect(TCellAgent).to receive(:policy).with(
498
+ TCellAgent::PolicyTypes::LFI
499
+ ).and_return(@local_files_policy)
500
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
501
+
502
+ IO.write(@new_file_name, @file_contents)
503
+ expect(File.open(@new_file_name).read).to eq @file_contents
516
504
  end
517
- context 'with a filename that does exist and an offset 5' do
518
- it 'should overwrite the file starting at the offset value' do
505
+
506
+ context 'using offset, perm' do
507
+ after :each do
508
+ expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('444')
509
+
519
510
  expect(TCellAgent).to receive(:policy).with(
520
511
  TCellAgent::PolicyTypes::LFI
521
- ).and_return(@local_files_policy, @local_files_policy)
522
- expect(@local_files_policy).to receive(:block_file_access?).and_return(false, false)
523
-
524
- exp_results = @file_contents.dup
525
- exp_results[1..6] = 'OFFSET'
526
- IO.write(@new_file_name, @file_contents)
527
- IO.write(@new_file_name, 'OFFSET', 1)
528
- expect(IO.read(@new_file_name)).to eq exp_results
512
+ ).and_return(@local_files_policy)
513
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
514
+ expect(File.open(@new_file_name).read).to eq @new_file_contents_offset_bytes
529
515
  end
516
+
517
+ test_ruby2_ruby3_keywords(IO,
518
+ 'write',
519
+ [NEW_FILE_NAME, 'OFFSET', 5],
520
+ { perm: 0o444 },
521
+ 6)
530
522
  end
531
523
  end
532
524
  context 'with a file blocked for read/write' do
@@ -537,20 +529,18 @@ describe 'IO' do
537
529
  expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
538
530
  end
539
531
 
540
- context 'with a filename that does not exist' do
541
- it 'should not be able to write to the file' do
542
- expect do
543
- IO.write(@new_file_name, '')
544
- end.to raise_error(IOError)
545
- end
532
+ it 'raises an IOError' do
533
+ expect do
534
+ IO.write(@new_file_name, '')
535
+ end.to raise_error(IOError)
546
536
  end
547
- context 'with a filename that does exist' do
548
- it 'should not be able to write to the file' do
549
- expect do
550
- IO.write(@filename, @file_contents)
551
- end.to raise_error(IOError)
552
- end
537
+ it 'should not be able to create and write to the file' do
538
+ expect do
539
+ IO.write(@filename, @file_contents)
540
+ end.to raise_error(IOError)
553
541
  end
554
542
  end
555
543
  end
556
544
  end
545
+
546
+ # rubocop:enable Style/HashSyntax