wafris 2.1.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b9b1568fdef719383076bc488ff10f37d62b07aeaf143665e2e766e1d5d61b6
4
- data.tar.gz: d96a46ce2ef95bbe3bfbd4d4d4b08d10a72f8270e1808f8e0f212692249a6634
3
+ metadata.gz: 0fad1d400c6106dc0f2f29b6b46a0ab919f4060ef45a4bde4dbb8607b95c1cae
4
+ data.tar.gz: b3b854a117e0a7021bf3194e339da5f0acdf320439f973226e850249bc445dcd
5
5
  SHA512:
6
- metadata.gz: 3cf48c2b9aee1ac009b1e242490e6512e45e231d4a57d698cb89237a5c83f466cea1ef428feb4550dce39d786a102790257c861ddd4314e5f7865dad1967e32d
7
- data.tar.gz: 29b8543c5dd1236471a60c29f45cd9ce71793db0ae77a349b6666c1862e4bcec90ee5e6ba211b87e719a74584fad142bead0afa04b6643f9999636e928aeb24e
6
+ metadata.gz: bd8e5e8109a7aa1b51c1361d7c288d11e2cca0ea4a5c0e66a198bbde30d9835b57ce2711f2869c575cc604577b4fe927836bfb0e47764f4e08a4c39c2a2e82db
7
+ data.tar.gz: fb171df540399f4a128e9bd28a1f80c3aa41e6a97e3cccc5eae0f2fa13b1de86be516d227bce3582fc9cefb35eb067e1b4ced665e79e5af89672187195eac109
@@ -1,98 +1,66 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "version"
2
4
 
3
5
  module Wafris
4
6
  class Configuration
5
- attr_accessor :api_key
6
- attr_accessor :db_file_path
7
- attr_accessor :db_file_name
8
- attr_accessor :downsync_custom_rules_interval
9
- attr_accessor :downsync_data_subscriptions_interval
10
- attr_accessor :downsync_url
11
- attr_accessor :upsync_url
12
- attr_accessor :upsync_interval
13
- attr_accessor :upsync_queue_limit
14
- attr_accessor :upsync_status
15
- attr_accessor :upsync_queue
16
- attr_accessor :local_only
17
- attr_accessor :last_upsync_timestamp
18
- attr_accessor :max_body_size_mb
19
- attr_accessor :rate_limiters
7
+ attr_accessor :api_key,
8
+ :db_file_path,
9
+ :db_file_name,
10
+ :downsync_custom_rules_interval,
11
+ :downsync_data_subscriptions_interval,
12
+ :downsync_url,
13
+ :upsync_url,
14
+ :upsync_interval,
15
+ :upsync_queue_limit,
16
+ :upsync_status,
17
+ :upsync_queue,
18
+ :local_only,
19
+ :last_upsync_timestamp,
20
+ :max_body_size_mb,
21
+ :rate_limiters
20
22
 
21
23
  def initialize
22
- # API Key - Required
23
- if ENV["WAFRIS_API_KEY"]
24
- @api_key = ENV["WAFRIS_API_KEY"]
25
- else
26
- unless @api_key
27
- LogSuppressor.puts_log("Firewall disabled as neither local only or API key set")
28
- end
29
- end
30
-
31
- # DB FILE PATH LOCATION - Optional
24
+ @api_key = ENV["WAFRIS_API_KEY"]
32
25
  @db_file_path = ENV["WAFRIS_DB_FILE_PATH"] || "./tmp/wafris"
33
-
34
- # Ensure that the db_file_path exists
35
- unless File.directory?(@db_file_path)
36
- LogSuppressor.puts_log("DB File Path does not exist - creating it now.")
37
- FileUtils.mkdir_p(@db_file_path) unless File.exist?(@db_file_path)
38
- end
39
-
40
- # DB FILE NAME - For local
41
26
  @db_file_name = ENV["WAFRIS_DB_FILE_NAME"] || "wafris.db"
42
-
43
- # DOWNSYNC
44
- # Custom Rules are checked often (default 1 minute) - Optional
45
27
  @downsync_custom_rules_interval = ENV["WAFRIS_DOWNSYNC_CUSTOM_RULES_INTERVAL"]&.to_i || 60
46
-
47
- # Data Subscriptions are checked rarely (default 1 day) - Optional
48
28
  @downsync_data_subscriptions_interval = ENV["WAFRIS_DOWNSYNC_DATA_SUBSCRIPTIONS_INTERVAL"]&.to_i || 60
49
-
50
- # Set Downsync URL - Optional
51
- # Used for both DataSubscription and CustomRules
52
29
  @downsync_url = ENV["WAFRIS_DOWNSYNC_URL"] || "https://distributor.wafris.org/v2/downsync"
53
-
54
- # UPSYNC - Optional
55
- # Set Upsync URL
56
30
  @upsync_url = ENV["WAFRIS_UPSYNC_URL"] || "https://collector.wafris.org/v2/upsync"
57
-
58
- # Set Upsync Interval - Optional
59
31
  @upsync_interval = ENV["WAFRIS_UPSYNC_INTERVAL"]&.to_i || 10
60
-
61
- # Set Upsync Queued Request Limit - Optional
62
32
  @upsync_queue_limit = ENV["WAFRIS_UPSYNC_QUEUE_LIMIT"]&.to_i || 250
63
-
64
- # Set Maximium Body Size for Requests - Optional (in Megabytes)
65
- @max_body_size_mb = if ENV["WAFRIS_MAX_BODY_SIZE_MB"] && ENV["WAFRIS_MAX_BODY_SIZE_MB"].to_i > 0
66
- ENV["WAFRIS_MAX_BODY_SIZE_MB"].to_i
67
- else
68
- 10
69
- end
70
-
71
- # Upsync Queue Defaults
33
+ @max_body_size_mb = set_max_body_size
72
34
  @upsync_queue = []
73
35
  @last_upsync_timestamp = Time.now.to_i
74
-
75
- # Memory structure for rate limiting
76
36
  @rate_limiters = {}
77
-
78
- # Disable Upsync if Downsync API Key is invalid
79
- # This prevents the client from sending upsync requests
80
- # if the API key is known bad
81
37
  @upsync_status = "Disabled"
82
38
  end
83
39
 
84
- def current_config
85
- output = {}
86
-
87
- instance_variables.each do |var|
88
- output[var.to_s] = instance_variable_get(var)
40
+ def setup
41
+ if @api_key
42
+ create_db_file_path
43
+ else
44
+ LogSuppressor.puts_log("Firewall disabled as API key is not set.")
89
45
  end
46
+ end
90
47
 
91
- output
48
+ private
49
+
50
+ def set_max_body_size
51
+ if ENV["WAFRIS_MAX_BODY_SIZE_MB"] && ENV["WAFRIS_MAX_BODY_SIZE_MB"].to_i > 0
52
+ ENV["WAFRIS_MAX_BODY_SIZE_MB"].to_i
53
+ else
54
+ 10
55
+ end
92
56
  end
93
57
 
94
- def create_settings
95
- @version = Wafris::VERSION
58
+ def create_db_file_path
59
+ # Ensure that the db_file_path exists
60
+ unless File.directory?(@db_file_path)
61
+ LogSuppressor.puts_log("DB File Path does not exist - creating it now.")
62
+ FileUtils.mkdir_p(@db_file_path) unless File.exist?(@db_file_path)
63
+ end
96
64
  end
97
65
  end
98
66
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wafris
4
- VERSION = "2.1.2"
4
+ VERSION = "2.3.0"
5
5
  end
data/lib/wafris.rb CHANGED
@@ -34,12 +34,18 @@ module Wafris
34
34
 
35
35
  def configure
36
36
  self.configuration ||= Wafris::Configuration.new
37
- yield(configuration)
37
+ if block_given?
38
+ yield(configuration)
39
+ LogSuppressor.puts_log("Configuration settings created with configure block.")
40
+ else
41
+ LogSuppressor.puts_log("Configuration settings created with defaults and ENV vars.")
42
+ end
38
43
 
39
- LogSuppressor.puts_log("[Wafris] Configuration settings created.")
40
- configuration.create_settings
44
+ configuration.setup
45
+
46
+ return configuration
41
47
  rescue => e
42
- puts "[Wafris] firewall disabled due to: #{e.message}. Cannot connect via Wafris.configure. Please check your configuration settings. More info can be found at: https://github.com/Wafris/wafris-rb"
48
+ LogSuppressor.puts_log("Firewall disabled due to: #{e.message}. Please check your configuration settings.")
43
49
  end
44
50
 
45
51
  def zero_pad(number, length)
@@ -181,20 +187,25 @@ module Wafris
181
187
 
182
188
  url_and_api_key = @configuration.upsync_url + "/" + @configuration.api_key
183
189
 
190
+ LogSuppressor.puts_log("[Upsync] Beginning request thread...")
191
+ current_time = Time.now
184
192
  response = HTTParty.post(
185
193
  url_and_api_key,
186
194
  body: body,
187
195
  headers: headers,
188
- timeout: 10
196
+ timeout: 5
189
197
  )
190
198
 
191
199
  if response.code == 200
192
200
  @configuration.upsync_status = "Complete"
193
201
  else
194
- LogSuppressor.puts_log("Upsync Error. HTTP Response: #{response.code}")
202
+ LogSuppressor.puts_log("[Upsync] Error. HTTP Response: #{response.code}")
195
203
  end
196
204
  rescue HTTParty::Error => e
197
- LogSuppressor.puts_log("Upsync Error. Failed to send upsync requests: #{e.message}")
205
+ LogSuppressor.puts_log("[Upsync] Thread Error. Failed to send upsync requests: #{e.message}")
206
+ ensure
207
+ elapsed_time = Time.now - current_time
208
+ LogSuppressor.puts_log("[Upsync] request thread complete in #{elapsed_time.round(2)} seconds.")
198
209
  end
199
210
 
200
211
  # This method is used to queue upsync requests. It takes in several parameters including:
@@ -220,7 +231,7 @@ module Wafris
220
231
  @configuration.upsync_queue = []
221
232
  @configuration.last_upsync_timestamp = Time.now.to_i
222
233
 
223
- send_upsync_requests(requests_array)
234
+ Thread.new { send_upsync_requests(requests_array) }
224
235
  end
225
236
 
226
237
  @configuration.upsync_status = "Enabled"
@@ -249,10 +260,10 @@ module Wafris
249
260
  begin
250
261
  lockfile = File.open(lockfile_path, File::RDWR | File::CREAT | File::EXCL)
251
262
  rescue Errno::EEXIST
252
- LogSuppressor.puts_log("[Wafris][Downsync] Lockfile already exists, skipping downsync.")
263
+ LogSuppressor.puts_log("[Downsync][downsync_db] Lockfile already exists, skipping downsync.")
253
264
  return
254
265
  rescue Exception => e
255
- LogSuppressor.puts_log("[Wafris][Downsync] Error creating lockfile: #{e.message}")
266
+ LogSuppressor.puts_log("[Downsync] Error creating lockfile: #{e.message}")
256
267
  end
257
268
 
258
269
  begin
@@ -274,10 +285,14 @@ module Wafris
274
285
  # puts "Downloading from #{@configuration.downsync_url}/#{db_rule_category}/#{@configuration.api_key}?current_version=#{current_filename}&process_id=#{Process.pid}"
275
286
  uri = "#{@configuration.downsync_url}/#{db_rule_category}/#{@configuration.api_key}?#{data.to_query}"
276
287
 
288
+ LogSuppressor.puts_log("[Downsync] Beginning request thread for #{db_rule_category}...")
289
+ current_time = Time.now
290
+
277
291
  response = HTTParty.get(
278
292
  uri,
279
293
  follow_redirects: true, # Enable following redirects
280
- max_redirects: 2 # Maximum number of redirects to follow
294
+ max_redirects: 2, # Maximum number of redirects to follow
295
+ timeout: 30
281
296
  )
282
297
 
283
298
  # TODO: What to do if timeout
@@ -285,13 +300,12 @@ module Wafris
285
300
 
286
301
  if response.code == 401
287
302
  @configuration.upsync_status = "Disabled"
288
- LogSuppressor.puts_log("[Wafris][Downsync] Unauthorized: Bad or missing API key")
289
- LogSuppressor.puts_log("[Wafris][Downsync] API Key: #{@configuration.api_key}")
303
+ LogSuppressor.puts_log("[Downsync] Unauthorized: Bad or missing API key")
304
+ LogSuppressor.puts_log("[Downsync] API Key: #{@configuration.api_key}")
290
305
  filename = current_filename
291
306
 
292
307
  elsif response.code == 304
293
308
  @configuration.upsync_status = "Enabled"
294
- LogSuppressor.puts_log("[Wafris][Downsync] No new rules to download")
295
309
 
296
310
  filename = current_filename
297
311
 
@@ -326,12 +340,12 @@ module Wafris
326
340
  # DB file is bad or empty so keep using whatever we have now
327
341
  else
328
342
  filename = old_file_name
329
- LogSuppressor.puts_log("[Wafris][Downsync] DB Error - No tables exist in the db file #{@configuration.db_file_path}/#{filename}")
343
+ LogSuppressor.puts_log("[Downsync] DB Error - No tables exist in the db file #{@configuration.db_file_path}/#{filename}")
330
344
  end
331
345
 
332
346
  end
333
347
  rescue => e
334
- LogSuppressor.puts_log("[Wafris][Downsync] Error downloading rules: #{e.message}")
348
+ LogSuppressor.puts_log("[Downsync] Error downloading rules: #{e.message}")
335
349
 
336
350
  # This gets set even if the API key is bad or other issues
337
351
  # to prevent hammering the distribution server on every request
@@ -347,42 +361,47 @@ module Wafris
347
361
  # Ensure the lockfile is removed after operations
348
362
  lockfile.close
349
363
  File.delete(lockfile_path)
364
+
365
+ elapsed_time = Time.now - current_time
366
+ LogSuppressor.puts_log("[Downsync] request thread complete in #{elapsed_time.round(2)} seconds for #{db_rule_category}.")
350
367
  end
351
368
 
352
369
  filename
353
370
  end
354
371
 
372
+ def sync_interval(db_rule_category)
373
+ if db_rule_category == "custom_rules"
374
+ @configuration.downsync_custom_rules_interval
375
+ else
376
+ @configuration.downsync_data_subscriptions_interval
377
+ end
378
+ end
379
+
355
380
  # Returns the current database file,
356
381
  # if the file is older than the interval, it will download the latest db
357
382
  # if the file doesn't exist, it will download the latest db
358
383
  # if the lockfile exists, it will return the current db
359
384
  def current_db(db_rule_category)
360
- interval = if db_rule_category == "custom_rules"
361
- @configuration.downsync_custom_rules_interval
362
- else
363
- @configuration.downsync_data_subscriptions_interval
364
- end
365
-
366
385
  # Checks for existing current modfile, which contains the current db filename
367
386
  if File.exist?("#{@configuration.db_file_path}/#{db_rule_category}.modfile")
368
387
 
369
- LogSuppressor.puts_log("[Wafris][Downsync] Modfile exists, skipping downsync")
388
+ LogSuppressor.puts_log("[Downsync] Modfile exists, skipping downsync")
370
389
 
371
390
  # Get last Modified Time and current database file name
372
391
  last_db_synctime = File.mtime("#{@configuration.db_file_path}/#{db_rule_category}.modfile").to_i
373
392
  returned_db = File.read("#{@configuration.db_file_path}/#{db_rule_category}.modfile").strip
374
393
 
375
- LogSuppressor.puts_log("[Wafris][Downsync] Modfile Last Modified Time: #{last_db_synctime}")
376
- LogSuppressor.puts_log("[Wafris][Downsync] DB in Modfile: #{returned_db}")
394
+ LogSuppressor.puts_log("[Downsync] Modfile Last Modified Time: #{last_db_synctime}")
395
+ LogSuppressor.puts_log("[Downsync] DB in Modfile: #{returned_db}")
377
396
 
378
397
  # Check if the db file is older than the interval
379
- if (Time.now.to_i - last_db_synctime) > interval
398
+ if (Time.now.to_i - last_db_synctime) > sync_interval(db_rule_category)
380
399
 
381
- LogSuppressor.puts_log("[Wafris][Downsync] DB is older than the interval")
400
+ LogSuppressor.puts_log("[Downsync] DB is older than the interval")
382
401
 
383
402
  # Make sure that another process isn't already downloading the rules
384
403
  if !File.exist?("#{@configuration.db_file_path}/#{db_rule_category}.lockfile")
385
- returned_db = downsync_db(db_rule_category, returned_db)
404
+ Thread.new { downsync_db(db_rule_category, returned_db) }
386
405
  end
387
406
 
388
407
  returned_db
@@ -390,7 +409,7 @@ module Wafris
390
409
  # Current db is up to date
391
410
  else
392
411
 
393
- LogSuppressor.puts_log("[Wafris][Downsync] DB is up to date")
412
+ LogSuppressor.puts_log("[Downsync] DB is up to date")
394
413
 
395
414
  returned_db = File.read("#{@configuration.db_file_path}/#{db_rule_category}.modfile").strip
396
415
 
@@ -407,24 +426,18 @@ module Wafris
407
426
  # No modfile exists, so download the latest db
408
427
  else
409
428
 
410
- LogSuppressor.puts_log("[Wafris][Downsync] No modfile exists, downloading latest db")
429
+ LogSuppressor.puts_log("[Downsync] No modfile exists, downloading latest #{db_rule_category} db")
411
430
 
412
431
  # Make sure that another process isn't already downloading the rules
413
432
  if File.exist?("#{@configuration.db_file_path}/#{db_rule_category}.lockfile")
414
- LogSuppressor.puts_log("[Wafris][Downsync] Lockfile exists, skipping downsync")
433
+ LogSuppressor.puts_log("[Downsync][current_db] Lockfile exists, skipping downsync")
415
434
  # Lockfile exists, but no modfile with a db filename
416
435
  nil
417
436
  else
418
-
419
- LogSuppressor.puts_log("[Wafris][Downsync] No modfile exists, downloading latest db")
420
437
  # No modfile exists, so download the latest db
421
- returned_db = downsync_db(db_rule_category, nil)
438
+ Thread.new { downsync_db(db_rule_category, nil) }
422
439
 
423
- if returned_db.nil?
424
- nil
425
- else
426
- returned_db
427
- end
440
+ nil
428
441
  end
429
442
  end
430
443
  end
@@ -432,15 +445,18 @@ module Wafris
432
445
  # This is the main loop that evaluates the request
433
446
  # as well as sorts out when downsync and upsync should be called
434
447
  def evaluate(request)
435
- @configuration ||= Wafris::Configuration.new
448
+ if @configuration.nil?
449
+ configure
450
+ end
436
451
 
437
452
  return "Passed" if @configuration.api_key.nil?
438
453
 
454
+ # Now current_db can return the actual db, nil, or a future object
439
455
  rules_db_filename = current_db("custom_rules")
440
456
  data_subscriptions_db_filename = current_db("data_subscriptions")
441
457
 
442
458
  # Checks to see if the filenames are present before loading the db
443
- if rules_db_filename.to_s.strip != "" && data_subscriptions_db_filename.strip.to_s.strip != ""
459
+ if rules_db_filename.to_s.strip != "" && data_subscriptions_db_filename.to_s.strip != ""
444
460
 
445
461
  rules_db = SQLite3::Database.new "#{@configuration.db_file_path}/#{rules_db_filename}"
446
462
  data_subscriptions_db =
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wafris
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Buckbee
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-11-19 00:00:00.000000000 Z
12
+ date: 2024-11-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack