wafris 2.1.2 → 2.3.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.
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