hydra-works 0.10.0 → 0.11.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
  SHA1:
3
- metadata.gz: 95116717ae44d85ac45f788033d74e18f8144df6
4
- data.tar.gz: eef16574d1817c0c984474457676997e34af7b17
3
+ metadata.gz: 1ab0358efa05c2000773dbf94f9fdce307613889
4
+ data.tar.gz: 15dddd5f77310395add9882e5cf2887135bf0721
5
5
  SHA512:
6
- metadata.gz: f7fa861ac89d69f55d7e70cf19b88feb0b0a4922eaf003dc703d29a5ba3d0bcbcefeee85888414ce19ea81ca74cc8d35442b1f407e69ce64a956657f6215b7fd
7
- data.tar.gz: 1ec0c85363b2f9eebf497bb22ea26ade58ace1508620f07762b0f6d6e4f67b979a2111ab07a7fa8dbbaa61d302f29085faee89a99a2522c04faac35e4e77f4f2
6
+ metadata.gz: 2063fa30e2d4f5d26cd34d8b6968bcb046b414375a3c704974f10678630f4d72bf4bc92cec360734b6119c539b30eb28c3143b544cf7d9026e7b75d5ee95d151
7
+ data.tar.gz: 9002fa2a214853d15d44ff95eb96009d8d78c0a3e6bc826309d0bb7475cc0de7b69c7c4a9d69a8c6d5aa27433d3d152a200ba246e56faa35c7986483d00ac8db
@@ -6,6 +6,13 @@ module Hydra
6
6
  module Works
7
7
  extend ActiveSupport::Autoload
8
8
 
9
+ autoload :VirusScanner
10
+
11
+ class << self
12
+ class_attribute :default_system_virus_scanner
13
+ self.default_system_virus_scanner = VirusScanner
14
+ end
15
+
9
16
  module Vocab
10
17
  extend ActiveSupport::Autoload
11
18
  eager_autoload do
@@ -6,14 +6,12 @@ module Hydra::Works
6
6
 
7
7
  # @api public
8
8
  # @param original_file [String, #path]
9
- # @return true if a virus was detected
10
- # @return true if anti-virus was not able to run
11
- # @return false if the file was scanned and no viruses were found
9
+ # @return true or false result from system_virus_scanner
12
10
  def self.file_has_virus?(original_file)
13
11
  new(original_file).file_has_virus?
14
12
  end
15
13
 
16
- def initialize(original_file, system_virus_scanner = default_system_virus_scanner)
14
+ def initialize(original_file, system_virus_scanner = Hydra::Works.default_system_virus_scanner)
17
15
  self.original_file = original_file
18
16
  self.system_virus_scanner = system_virus_scanner
19
17
  end
@@ -21,42 +19,11 @@ module Hydra::Works
21
19
  # Default behavior is to raise a validation error and halt the save if a virus is found
22
20
  def file_has_virus?
23
21
  path = original_file.is_a?(String) ? original_file : local_path_for_file(original_file)
24
- scan_result = system_virus_scanner.call(path)
25
- handle_virus_scan_results(path, scan_result)
22
+ system_virus_scanner.infected?(path)
26
23
  end
27
24
 
28
25
  private
29
26
 
30
- # Stubbing out the behavior of "The Clam" was growing into a rather nasty
31
- # challenge. So instead I'm injecting a system scanner. This allows me to
32
- # now test the default system scanner in isolation from the general response
33
- # to a system scan.
34
- def default_system_virus_scanner
35
- if defined?(ClamAV)
36
- ClamAV.instance.method(:scanfile)
37
- else
38
- lambda do |_path|
39
- :no_anti_virus_was_run
40
- end
41
- end
42
- end
43
-
44
- def handle_virus_scan_results(path, scan_result)
45
- case scan_result
46
- when 0 then return false
47
- when 1
48
- warning("A virus was found in #{path}: #{scan_result}")
49
- true
50
- else
51
- warning "Virus checking disabled, #{path} not checked"
52
- true
53
- end
54
- end
55
-
56
- def warning(msg)
57
- ActiveFedora::Base.logger.warn msg if ActiveFedora::Base.logger
58
- end
59
-
60
27
  # Returns a path for reading the content of +file+
61
28
  # @param [File] file object to retrieve a path for
62
29
  def local_path_for_file(file)
@@ -1,5 +1,5 @@
1
1
  module Hydra
2
2
  module Works
3
- VERSION = '0.10.0'.freeze
3
+ VERSION = '0.11.0'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,56 @@
1
+ # The default virus scanner for Hydra::Works
2
+ # If ClamAV is present, it will be used to check for the presence of a virus. If ClamAV is not
3
+ # installed or otherwise not available to your application, Hydra::Works does no virus checking
4
+ # add assumes files have no viruses.
5
+ #
6
+ # To use a virus checker other than ClamAV:
7
+ # class MyScanner < Hydra::Works::VirusScanner
8
+ # def infected?
9
+ # my_result = Scanner.check_for_viruses(file)
10
+ # [return true or false]
11
+ # end
12
+ # end
13
+ #
14
+ # Then set Hydra::Works to use your scanner either in a config file or initializer:
15
+ # Hydra::Works.default_system_virus_scanner = MyScanner
16
+ module Hydra::Works
17
+ class VirusScanner
18
+ attr_reader :file
19
+
20
+ # @api public
21
+ # @param file [String]
22
+ def self.infected?(file)
23
+ new(file).infected?
24
+ end
25
+
26
+ def initialize(file)
27
+ @file = file
28
+ end
29
+
30
+ # Override this method to use your own virus checking software
31
+ # @return [Boolean]
32
+ def infected?
33
+ defined?(ClamAV) ? clam_av_scanner : null_scanner
34
+ end
35
+
36
+ def clam_av_scanner
37
+ scan_result = ClamAV.instance.method(:scanfile).call(file)
38
+ return false if scan_result == 0
39
+ warning "A virus was found in #{file}: #{scan_result}"
40
+ true
41
+ end
42
+
43
+ # Always return zero if there's nothing available to check for viruses. This means that
44
+ # we assume all files have no viruses because we can't conclusively say if they have or not.
45
+ def null_scanner
46
+ warning "Unable to check #{file} for viruses because no virus scanner is defined"
47
+ false
48
+ end
49
+
50
+ private
51
+
52
+ def warning(msg)
53
+ ActiveFedora::Base.logger.warn(msg) if ActiveFedora::Base.logger
54
+ end
55
+ end
56
+ end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Hydra::Works::VirusCheckerService do
4
- let(:system_virus_scanner) { double(call: nil) }
4
+ let(:system_virus_scanner) { double }
5
5
  let(:file) { Hydra::PCDM::File.new { |f| f.content = File.new(File.join(fixture_path, 'sample-file.pdf')) } }
6
6
  let(:virus_checker) { described_class.new(file, system_virus_scanner) }
7
7
 
@@ -14,27 +14,17 @@ describe Hydra::Works::VirusCheckerService do
14
14
  end
15
15
  end
16
16
 
17
- context 'with a system virus scanner that did not run' do
18
- let(:virus_checker) { described_class.new(file) }
19
- it 'will return false and set a system warning' do
20
- expect(defined?(ClamAV)).to eq(nil) # A bit of a sanity test to make sure the default behaves
21
- allow(file).to receive(:path).and_return('/tmp/file.pdf')
22
- expect(virus_checker).to receive(:warning).with(kind_of(String))
23
- expect(virus_checker.file_has_virus?).to eq(true)
24
- end
25
- end
26
-
27
17
  context 'with an infected file' do
28
18
  context 'that responds to :path' do
29
19
  it 'will return false' do
30
- expect(system_virus_scanner).to receive(:call).with('/tmp/file.pdf').and_return(1)
20
+ expect(system_virus_scanner).to receive(:infected?).with('/tmp/file.pdf').and_return(true)
31
21
  allow(file).to receive(:path).and_return('/tmp/file.pdf')
32
22
  expect(virus_checker.file_has_virus?).to eq(true)
33
23
  end
34
24
  end
35
25
  context 'that does not respond to :path' do
36
26
  it 'will return false' do
37
- expect(system_virus_scanner).to receive(:call).with(kind_of(String)).and_return(1)
27
+ expect(system_virus_scanner).to receive(:infected?).with(kind_of(String)).and_return(true)
38
28
  allow(file).to receive(:respond_to?).and_call_original
39
29
  allow(file).to receive(:respond_to?).with(:path).and_return(false)
40
30
  expect(virus_checker.file_has_virus?).to eq(true)
@@ -45,51 +35,18 @@ describe Hydra::Works::VirusCheckerService do
45
35
  context 'with a clean file' do
46
36
  context 'that responds to :path' do
47
37
  it 'will return true' do
48
- expect(system_virus_scanner).to receive(:call).with('/tmp/file.pdf').and_return(0)
38
+ expect(system_virus_scanner).to receive(:infected?).with('/tmp/file.pdf').and_return(false)
49
39
  allow(file).to receive(:path).and_return('/tmp/file.pdf')
50
40
  expect(virus_checker.file_has_virus?).to eq(false)
51
41
  end
52
42
  end
53
43
  context 'that does not respond to :path' do
54
44
  it 'will return true' do
55
- expect(system_virus_scanner).to receive(:call).with(kind_of(String)).and_return(0)
45
+ expect(system_virus_scanner).to receive(:infected?).with(kind_of(String)).and_return(false)
56
46
  allow(file).to receive(:respond_to?).and_call_original
57
47
  allow(file).to receive(:respond_to?).with(:path).and_return(false)
58
48
  expect(virus_checker.file_has_virus?).to eq(false)
59
49
  end
60
50
  end
61
51
  end
62
-
63
- context '#default_system_virus_scanner' do
64
- let(:virus_checker) { described_class.new(file) }
65
- let(:system_virus_scanner) { virus_checker.send(:default_system_virus_scanner) }
66
- it 'is callable' do
67
- expect(system_virus_scanner).to respond_to(:call)
68
- end
69
- context 'when called and ClamAV is NOT defined' do
70
- it 'will warn and return :no_anti_virus_was_run if ClamAV is not defined' do
71
- expect(system_virus_scanner.call('/tmp/path')).to eq(:no_anti_virus_was_run)
72
- end
73
- end
74
- context 'when called and ClamAV is defined' do
75
- before do
76
- class ClamAV
77
- def self.instance
78
- @instance ||= ClamAV.new
79
- end
80
-
81
- def scanfile(path)
82
- puts "scanfile: #{path}"
83
- end
84
- end
85
- end
86
- after do
87
- Object.send(:remove_const, :ClamAV)
88
- end
89
- it "will call the Clam's scanfile" do
90
- expect(ClamAV.instance).to receive(:scanfile).with('/tmp/path')
91
- system_virus_scanner.call('/tmp/path')
92
- end
93
- end
94
- end
95
52
  end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hydra::Works::VirusScanner do
4
+ let(:file) { '/tmp/path' }
5
+ let(:logger) { Logger.new(nil) }
6
+
7
+ before { allow(ActiveFedora::Base).to receive(:logger).and_return(logger) }
8
+
9
+ subject { described_class.new(file) }
10
+
11
+ context 'when ClamAV is defined' do
12
+ before do
13
+ class ClamAV
14
+ def self.instance
15
+ @instance ||= ClamAV.new
16
+ end
17
+
18
+ def scanfile(path)
19
+ puts "scanfile: #{path}"
20
+ end
21
+ end
22
+ end
23
+ after do
24
+ Object.send(:remove_const, :ClamAV)
25
+ end
26
+ context 'with a clean file' do
27
+ before { allow(ClamAV.instance).to receive(:scanfile).with('/tmp/path').and_return(0) }
28
+ it 'returns false with no warning' do
29
+ expect(ActiveFedora::Base.logger).not_to receive(:warn)
30
+ is_expected.not_to be_infected
31
+ end
32
+ end
33
+ context 'with an infected file' do
34
+ before { allow(ClamAV.instance).to receive(:scanfile).with('/tmp/path').and_return(1) }
35
+ it 'returns true with a warning' do
36
+ expect(ActiveFedora::Base.logger).to receive(:warn).with(kind_of(String))
37
+ is_expected.to be_infected
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'when ClamAV is not defined' do
43
+ it 'returns false with a warning' do
44
+ expect(ActiveFedora::Base.logger).to receive(:warn).with(kind_of(String))
45
+ is_expected.not_to be_infected
46
+ end
47
+ end
48
+ end
@@ -106,4 +106,9 @@ describe Hydra::Works do
106
106
  end
107
107
  end
108
108
  end
109
+
110
+ describe '::default_system_virus_scanner' do
111
+ subject { described_class.default_system_virus_scanner }
112
+ it { is_expected.to eq(Hydra::Works::VirusScanner) }
113
+ end
109
114
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra-works
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-13 00:00:00.000000000 Z
11
+ date: 2016-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hydra-pcdm
@@ -217,6 +217,7 @@ files:
217
217
  - lib/hydra/works/services/upload_file_to_file_set.rb
218
218
  - lib/hydra/works/services/virus_checker_service.rb
219
219
  - lib/hydra/works/version.rb
220
+ - lib/hydra/works/virus_scanner.rb
220
221
  - lib/hydra/works/vocab/works_terms.rb
221
222
  - solr/config/_rest_managed.json
222
223
  - solr/config/admin-extra.html
@@ -270,6 +271,7 @@ files:
270
271
  - spec/hydra/works/services/persist_derivatives_spec.rb
271
272
  - spec/hydra/works/services/upload_file_spec.rb
272
273
  - spec/hydra/works/services/virus_checker_service_spec.rb
274
+ - spec/hydra/works/virus_scanner_spec.rb
273
275
  - spec/hydra/works_spec.rb
274
276
  - spec/spec_helper.rb
275
277
  - spec/support/file_set_helper.rb
@@ -302,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
302
304
  version: '0'
303
305
  requirements: []
304
306
  rubyforge_project:
305
- rubygems_version: 2.6.4
307
+ rubygems_version: 2.4.8
306
308
  signing_key:
307
309
  specification_version: 4
308
310
  summary: Fundamental repository data model for hydra
@@ -343,6 +345,7 @@ test_files:
343
345
  - spec/hydra/works/services/persist_derivatives_spec.rb
344
346
  - spec/hydra/works/services/upload_file_spec.rb
345
347
  - spec/hydra/works/services/virus_checker_service_spec.rb
348
+ - spec/hydra/works/virus_scanner_spec.rb
346
349
  - spec/hydra/works_spec.rb
347
350
  - spec/spec_helper.rb
348
351
  - spec/support/file_set_helper.rb