ddr-antivirus 1.0.2 → 1.1.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
  SHA1:
3
- metadata.gz: 0e09e6bc593db830915157ce7ed38e9c05702ec8
4
- data.tar.gz: 66f916b33a1e8e336d5b3172a145007eeba312dd
3
+ metadata.gz: 9424fb9fcce9fd87db0354060b80873112d923bb
4
+ data.tar.gz: 4e190d50edeba08eec311c2ed6e38189fec3eb29
5
5
  SHA512:
6
- metadata.gz: dc8b5c988bb1e6f1b3b50e9439611a965b2291526586ea18670265f6ac4282a6556966b7ac4c1667f107007c8fee198a0fef745fe2fd5328f79413e2d71987d6
7
- data.tar.gz: 91c7a1a590026094a67255a253939ec779a46689637adf813a28e0c728139b58fc1cfe85f881c73e4e8eb98cf3c05fb4c4e035b5f01f66b7313f5fca749003f7
6
+ metadata.gz: 6f2dc02d2c56c5f5e4d0d2669517578b6905b6e300ca6b9afef71243c44540f89cdd630549e386ed15d9b7911a53d05d9030a2801c11503e2b5dd549de02fc84
7
+ data.tar.gz: b32e01dc33aba340e8ac87f7030c431518d24d387992fc42addbe1131c5355c8eef8e35e2ac38b67ef2b223686647bceb09fca26d0a47fbb5c38e5b382d69b76
data/.travis.yml CHANGED
@@ -1,8 +1,10 @@
1
1
  language: ruby
2
2
  before_install:
3
3
  - sudo apt-get update -qq
4
- - sudo apt-get install -y libclamav-dev clamav clamav-freshclam
4
+ - sudo apt-get install -y libclamav-dev clamav clamav-daemon clamav-freshclam
5
+ before_script:
5
6
  - sudo freshclam
7
+ - sudo /etc/init.d/clamav-daemon start
6
8
  rvm:
7
9
  - 2.1
8
10
  cache:
data/README.md CHANGED
@@ -19,16 +19,20 @@ Or install it yourself as:
19
19
 
20
20
  $ gem install ddr-antivirus
21
21
 
22
- ## ClamAV Dependencies
22
+ ## ClamAV
23
23
 
24
- For system dependencies, see https://github.com/eagleas/clamav.
25
-
26
- Ddr::Antivirus intentionally does *not* include `clamav` as a runtime dependency. Rather you should add to you application's Gemfile:
24
+ Ddr::Antivirus does *not* include the `clamav` gem as a runtime dependency. Add to your application's Gemfile:
27
25
 
28
26
  gem 'clamav'
29
27
 
28
+ For system dependencies, see https://github.com/eagleas/clamav.
29
+
30
30
  Ddr::Antivirus will automatically use an adapter class for ClamAV if the Ruby gem is installed.
31
31
 
32
+ ## ClamAV Daemon Client (clamdscan)
33
+
34
+ Ddr::Antivirus will automatically use an adapter class for `clamdscan` if the executable is on the user's path.
35
+
32
36
  ## Usage
33
37
 
34
38
  ### Scanning ###
@@ -47,10 +51,14 @@ Ddr::Antivirus::Scanner.new do |scanner|
47
51
  end
48
52
  ```
49
53
 
54
+ The scanner raises an exception (Ddr::Antivirus::VirusFoundError) if a virus is found.
55
+
50
56
  ### Results
51
57
 
52
58
  Class: `Ddr::Antivirus::ScanResult`
53
59
 
60
+ A scanner adapter may subclass the base class to parse the raw result properly.
61
+
54
62
  ```ruby
55
63
  >> require "ddr-antivirus"
56
64
  => true
@@ -74,14 +82,14 @@ Class: `Ddr::Antivirus::ScanResult`
74
82
  >> result.raw
75
83
  => 0 # ClamAV example
76
84
 
77
- # String representation
85
+ # String representation (example)
78
86
  >> puts result.to_s
79
- Virus scan: OK - /path/to/blue-devil.png (ClamAV 0.98.3/19559/Thu Oct 30 06:39:46 2014)
87
+ => /path/to/blue-devil.png: OK (ClamAV 0.98.3/19559/Thu Oct 30 06:39:46 2014)
80
88
  ```
81
89
 
82
90
  ### The NullScannerAdapter
83
91
 
84
- In order to avoid the overhead of ClamAV in test and/or development environments, the package provides a no-op adapter that logs a message and returns a normal scan result (instance of Ddr::Antivirus::ScanResult).
92
+ In order to avoid the overhead of ClamAV in test and/or development environments, the package provides a no-op adapter that logs a message and returns a scan result object (instance of Ddr::Antivirus::ScanResult).
85
93
 
86
94
  ```ruby
87
95
  >> Ddr::Antivirus.scanner_adapter = :null
data/lib/ddr/antivirus.rb CHANGED
@@ -1,42 +1,52 @@
1
1
  require "ddr/antivirus/version"
2
+ require "ddr/antivirus/scanner"
3
+ require "ddr/antivirus/scan_result"
4
+ require "ddr/antivirus/adapters"
5
+
2
6
  require "active_support/core_ext/module/attribute_accessors"
3
- require "active_support/dependencies/autoload"
4
- require "logger"
5
7
 
6
8
  module Ddr
7
9
  module Antivirus
8
- extend ActiveSupport::Autoload
9
10
 
10
11
  class VirusFoundError < ::StandardError; end
11
12
 
12
- def self.clamav_installed?
13
- begin
14
- require 'clamav'
15
- rescue LoadError
16
- false
17
- else
18
- true
19
- end
20
- end
21
-
22
13
  def self.configure
23
14
  yield self
24
15
  end
25
16
 
26
- autoload :Scanner
27
- autoload :ScanResult
28
- autoload :Adapters
29
-
17
+ #
30
18
  # Custom logger
19
+ #
31
20
  # Defaults to Rails logger if Rails is loaded; otherwise logs to STDERR.
21
+ #
32
22
  mattr_accessor :logger do
33
- defined?(Rails) && Rails.logger ? Rails.logger : Logger.new(STDERR)
23
+ if defined?(Rails) && Rails.logger
24
+ Rails.logger
25
+ else
26
+ require "logger"
27
+ Logger.new(STDERR)
28
+ end
34
29
  end
35
30
 
31
+ #
36
32
  # Scanner adapter
37
- # Defaults to :clamav adapter if ClamAV is installed; otherwise uses the :null adapter
33
+ #
34
+ # Defaults to:
35
+ # - :clamav adapter if the 'clamav' gem is installed;
36
+ # - :clamd adapter if the 'clamdscan' executable is available;
37
+ # - otherwise, the :null adapter.
38
+ #
38
39
  mattr_accessor :scanner_adapter do
39
- clamav_installed? ? :clamav : :null
40
+ begin
41
+ require "clamav"
42
+ :clamav
43
+ rescue LoadError
44
+ if system "which -s clamdscan"
45
+ :clamd
46
+ else
47
+ :null
48
+ end
49
+ end
40
50
  end
41
51
 
42
52
  end
@@ -1,15 +1,11 @@
1
- require "active_support/dependencies/autoload"
1
+ require_relative "./adapters/scanner_adapter"
2
2
 
3
3
  module Ddr
4
4
  module Antivirus
5
5
  module Adapters
6
- extend ActiveSupport::Autoload
7
-
8
- autoload :ScannerAdapter
9
- autoload :NullScannerAdapter
10
- autoload :ClamavScannerAdapter if Ddr::Antivirus.clamav_installed?
11
6
 
12
7
  def self.get_adapter
8
+ require_relative adapter_module
13
9
  klass = self.const_get(adapter_name.to_sym, false)
14
10
  klass.new
15
11
  end
@@ -18,6 +14,10 @@ module Ddr
18
14
  "#{Ddr::Antivirus.scanner_adapter.to_s.capitalize}ScannerAdapter"
19
15
  end
20
16
 
17
+ def self.adapter_module
18
+ "./adapters/#{Ddr::Antivirus.scanner_adapter}_scanner_adapter"
19
+ end
20
+
21
21
  end
22
22
  end
23
23
  end
@@ -0,0 +1,53 @@
1
+ module Ddr
2
+ module Antivirus
3
+ module Adapters
4
+ #
5
+ # ClamdScannerAdapter uses an external ClamAV daemon (clamd)
6
+ #
7
+ # See https://github.com/soundarapandian/clamd for configuration method and options.
8
+ #
9
+ class ClamdScannerAdapter < ScannerAdapter
10
+
11
+ def scan(path)
12
+ raw = clamdscan(path)
13
+ ClamdScanResult.new(raw, path)
14
+ end
15
+
16
+ def clamdscan(path)
17
+ `clamdscan --no-summary #{path}`.strip
18
+ end
19
+
20
+ class ClamdScanResult < Ddr::Antivirus::ScanResult
21
+
22
+ def virus_found
23
+ if m = /: ([^\s]+) FOUND$/.match(raw)
24
+ m[1]
25
+ end
26
+ end
27
+
28
+ def has_virus?
29
+ raw =~ / FOUND$/
30
+ end
31
+
32
+ def error?
33
+ raw =~ / ERROR$/
34
+ end
35
+
36
+ def ok?
37
+ raw =~ / OK$/
38
+ end
39
+
40
+ def to_s
41
+ "#{raw} (#{version})"
42
+ end
43
+
44
+ def default_version
45
+ `sigtool --version`.strip
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
52
+ end
53
+ end
@@ -10,6 +10,10 @@ module Ddr
10
10
  raise NotImplementedError
11
11
  end
12
12
 
13
+ def config
14
+ Ddr::Antivirus.adapter_config
15
+ end
16
+
13
17
  end
14
18
  end
15
19
  end
@@ -1,5 +1,5 @@
1
1
  module Ddr
2
2
  module Antivirus
3
- VERSION = "1.0.2"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
Binary file
@@ -9,7 +9,7 @@ shared_examples "a scan result" do
9
9
  expect(subject.scanned_at).to be_a(Time)
10
10
  end
11
11
  it "should have a string representation" do
12
- expect(subject.to_s).to match(/^Virus scan:/)
12
+ expect(subject.to_s).not_to be_nil
13
13
  end
14
14
  end
15
15
 
@@ -36,6 +36,13 @@ shared_examples "an error scan result" do
36
36
  it "should have an error" do
37
37
  expect(subject).to be_error
38
38
  end
39
+ it "shoud not have a virus" do
40
+ expect(subject.virus_found).to be_nil
41
+ expect(subject).not_to have_virus
42
+ end
43
+ it "should not be ok" do
44
+ expect(subject).not_to be_ok
45
+ end
39
46
  end
40
47
 
41
48
  shared_examples "a virus scan result" do
@@ -43,6 +50,13 @@ shared_examples "a virus scan result" do
43
50
  expect(subject.status).to match(/^FOUND/)
44
51
  end
45
52
  it "shoud have a virus" do
53
+ expect(subject.virus_found).not_to be_nil
46
54
  expect(subject).to have_virus
47
55
  end
56
+ it "should not have an error" do
57
+ expect(subject).not_to be_error
58
+ end
59
+ it "should not be ok" do
60
+ expect(subject).not_to be_ok
61
+ end
48
62
  end
@@ -1,11 +1,12 @@
1
- require 'shared_examples_for_scan_results'
1
+ require "shared_examples_for_scan_results"
2
+ require "ddr/antivirus/adapters/clamav_scanner_adapter"
2
3
 
3
4
  module Ddr
4
5
  module Antivirus
5
6
  module Adapters
6
7
  RSpec.describe ClamavScannerAdapter do
7
8
 
8
- let(:path) { File.expand_path(File.join("..", "fixtures", "blue-devil.png"), __FILE__) }
9
+ let(:path) { File.expand_path(File.join("..", "..", "fixtures", "blue-devil.png"), __FILE__) }
9
10
 
10
11
  describe "#scan" do
11
12
  context "when the db is already loaded" do
@@ -0,0 +1,39 @@
1
+ require "shared_examples_for_scan_results"
2
+ require "ddr/antivirus/adapters/clamd_scanner_adapter"
3
+
4
+ module Ddr
5
+ module Antivirus
6
+ module Adapters
7
+ RSpec.describe ClamdScannerAdapter do
8
+
9
+ let(:path) { File.expand_path(File.join("..", "..", "fixtures", "blue-devil.png"), __FILE__) }
10
+
11
+ describe "result" do
12
+ subject { adapter.scan(path) }
13
+ let(:adapter) { described_class.new }
14
+ it "should be a scan result" do
15
+ expect(subject).to be_a(Ddr::Antivirus::ScanResult)
16
+ end
17
+ context "when a virus is found" do
18
+ before { allow(adapter).to receive(:clamdscan).with(path) { "#{path}: Bad-boy-35 FOUND" } }
19
+ it "should have a virus_found" do
20
+ expect(subject.virus_found).to eq "Bad-boy-35"
21
+ end
22
+ it_should_behave_like "a virus scan result"
23
+ end
24
+ context "when there is an error" do
25
+ before { allow(adapter).to receive(:clamdscan).with(path) { "#{path}: ERROR" } }
26
+ it "should not have a virus" do
27
+ expect(subject).not_to have_virus
28
+ end
29
+ it_should_behave_like "an error scan result"
30
+ end
31
+ context "success" do
32
+ before { allow(adapter).to receive(:clamdscan).with(path) { "#{path}: OK" } }
33
+ it_should_behave_like "a successful scan result"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddr-antivirus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Chandek-Stark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-31 00:00:00.000000000 Z
11
+ date: 2014-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -99,14 +99,17 @@ files:
99
99
  - lib/ddr/antivirus.rb
100
100
  - lib/ddr/antivirus/adapters.rb
101
101
  - lib/ddr/antivirus/adapters/clamav_scanner_adapter.rb
102
+ - lib/ddr/antivirus/adapters/clamd_scanner_adapter.rb
102
103
  - lib/ddr/antivirus/adapters/null_scanner_adapter.rb
103
104
  - lib/ddr/antivirus/adapters/scanner_adapter.rb
104
105
  - lib/ddr/antivirus/scan_result.rb
105
106
  - lib/ddr/antivirus/scanner.rb
106
107
  - lib/ddr/antivirus/version.rb
108
+ - spec/fixtures/blue-devil.png
107
109
  - spec/shared_examples_for_scan_results.rb
108
110
  - spec/spec_helper.rb
109
111
  - spec/unit/clamav_scanner_adapter_spec.rb
112
+ - spec/unit/clamd_scanner_adapter_spec.rb
110
113
  - spec/unit/scan_result_spec.rb
111
114
  - spec/unit/scanner_spec.rb
112
115
  homepage: https://github.com/duke-libraries/ddr-antivirus
@@ -134,8 +137,10 @@ signing_key:
134
137
  specification_version: 4
135
138
  summary: Antivirus scanning service.
136
139
  test_files:
140
+ - spec/fixtures/blue-devil.png
137
141
  - spec/shared_examples_for_scan_results.rb
138
142
  - spec/spec_helper.rb
139
143
  - spec/unit/clamav_scanner_adapter_spec.rb
144
+ - spec/unit/clamd_scanner_adapter_spec.rb
140
145
  - spec/unit/scan_result_spec.rb
141
146
  - spec/unit/scanner_spec.rb