ratonvirus 0.2.0 → 0.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: 7fa55b1025e3d8099f86b8b9e9157cbd4473980441aac2c7acc98b92cf2c3ff6
4
- data.tar.gz: f219700545adb3593677af4fad1bb9d198892fc94bd128101a817169118254a0
3
+ metadata.gz: a0ee734de35bb79c99398afaf866f42c87e023aa4ab813ee8e582f4a1ea89597
4
+ data.tar.gz: 3d15112835af1745bf61d7d7a0d6017a31b4e1d638211d26e909564baa19e733
5
5
  SHA512:
6
- metadata.gz: 5fcd623e174c648393cc5489c27ce685ee0da9282a7289122a537daacff67950323123e7698da610af6a77b19b63753accb41ca22d06098dc95f4f8d41a109f9
7
- data.tar.gz: 85100d78a0e6a476cb4c4e3dde833381e7ac2219d4c9127cef4f07458b8ca56ba3a0977275f5d715f64cbab7989bbcb047c733dade35e6d6a95192b48005d0bd
6
+ metadata.gz: a663b2d27b3c98c8f4d83093cb87f4dc5f7ad87cdd8897358a923d1105ff69cfcd1bbb10831b657aad6d1bf1ef84a7b1ef42ed4817eccdb27782fbf081be3b7d
7
+ data.tar.gz: 5ba1e916ee109f4988c46c6bc325be84616af57f9a35b28390f55ea616b24a15de6a812d4dcbc58df11006b1d80b2636b4880c70abd45e517551392d64afc239
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ # v0.3.0
2
+
3
+ Changed:
4
+
5
+ - Minimum Ruby version is now set to 2.5
6
+
7
+ Fixed:
8
+
9
+ - Issue related with scanning files with CarrierWave storage engine using remote storage engines such as Fog. Related
10
+ to [#9](https://github.com/mainio/ratonvirus/pull/9)
11
+
12
+ # v0.2.0
13
+
14
+ Support for Rails 6
15
+
16
+ The ActiveStorage storage engine has been updated and partly rewritten due to changes in its API. The new API introduces
17
+ a changes concept in the library which this update takes in to account. In the new API, the blobs will not get uploaded
18
+ to the storage service before the validations have been successful, which led to rethinking how this storage engine
19
+ works in Ratonvirus.
20
+
21
+
1
22
  # v0.1.1
2
23
 
3
24
  Fixed:
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Rails antivirus made easy.
4
4
  Developed by [Mainio Tech](https://www.mainiotech.fi/).
5
5
 
6
- [![Build Status](https://travis-ci.org/mainio/ratonvirus.svg?branch=master)](https://travis-ci.org/mainio/ratonvirus)
6
+ [![Build Status](https://github.com/mainio/ratonvirus/actions/workflows/ci_ratonvirus.yml/badge.svg)](https://github.com/mainio/ratonvirus/actions)
7
7
  [![codecov](https://codecov.io/gh/mainio/ratonvirus/branch/master/graph/badge.svg)](https://codecov.io/gh/mainio/ratonvirus)
8
8
 
9
9
  Ratonvirus allows your Rails application to rat on the viruses that your users
data/lib/ratonvirus.rb CHANGED
@@ -12,6 +12,7 @@ require_relative "ratonvirus/scanner/support/callbacks"
12
12
  require_relative "ratonvirus/scanner/base"
13
13
  require_relative "ratonvirus/scanner/eicar"
14
14
  require_relative "ratonvirus/scanner/addon/remove_infected"
15
+ require_relative "ratonvirus/storage/support/io_handling"
15
16
  require_relative "ratonvirus/storage/base"
16
17
  require_relative "ratonvirus/storage/filepath"
17
18
  require_relative "ratonvirus/storage/active_storage"
@@ -4,6 +4,8 @@ module Ratonvirus
4
4
  class Error < StandardError; end
5
5
 
6
6
  class InvalidError < Error; end
7
+
7
8
  class NotDefinedError < Error; end
9
+
8
10
  class NotImplementedError < Error; end
9
11
  end
@@ -11,8 +11,8 @@ module Ratonvirus
11
11
  end
12
12
  end
13
13
 
14
- attr_reader :config
15
- attr_reader :errors # Only available after `virus?` has been called.
14
+ # :errors - Only available after `virus?` has been called.
15
+ attr_reader :config, :errors
16
16
 
17
17
  def initialize(configuration = {})
18
18
  @config = default_config.merge!(configuration)
@@ -19,11 +19,11 @@ module Ratonvirus
19
19
  protected
20
20
 
21
21
  def run_scan(path)
22
- if !File.file?(path)
23
- errors << :antivirus_file_not_found
24
- else
22
+ if File.file?(path)
25
23
  sha256 = Digest::SHA256.file path
26
24
  errors << :antivirus_virus_detected if sha256 == EICAR_SHA256
25
+ else
26
+ errors << :antivirus_file_not_found
27
27
  end
28
28
  rescue StandardError
29
29
  errors << :antivirus_client_error
@@ -3,6 +3,8 @@
3
3
  module Ratonvirus
4
4
  module Storage
5
5
  class ActiveStorage < Base
6
+ include Ratonvirus::Storage::Support::IoHandling
7
+
6
8
  def changed?(record, attribute)
7
9
  resource = record.public_send attribute
8
10
  !resource.record.attachment_changes[resource.name].nil?
@@ -20,9 +22,10 @@ module Ratonvirus
20
22
 
21
23
  change = resource.record.attachment_changes[resource.name]
22
24
 
23
- if change.is_a?(::ActiveStorage::Attached::Changes::CreateOne)
25
+ case change
26
+ when ::ActiveStorage::Attached::Changes::CreateOne
24
27
  handle_create_one(change, &block)
25
- elsif change.is_a?(::ActiveStorage::Attached::Changes::CreateMany)
28
+ when ::ActiveStorage::Attached::Changes::CreateMany
26
29
  handle_create_many(change, &block)
27
30
  end
28
31
  end
@@ -101,39 +104,6 @@ module Ratonvirus
101
104
 
102
105
  yield processable([change.attachment, attachable])
103
106
  end
104
-
105
- # This creates a local copy of the io contents for the scanning process. A
106
- # local copy is needed for processing because the io object may be a file
107
- # stream in the memory which may not have a path associated with it on the
108
- # filesystem.
109
- def io_path(io, extension)
110
- tempfile = Tempfile.open(
111
- ["Ratonvirus", extension],
112
- tempdir
113
- )
114
- # Important for the scanner to be able to access the file.
115
- prepare_for_scanner tempfile.path
116
-
117
- begin
118
- tempfile.binmode
119
- IO.copy_stream(io, tempfile)
120
- tempfile.flush
121
- tempfile.rewind
122
-
123
- yield tempfile.path
124
- ensure
125
- tempfile.close!
126
- end
127
- end
128
-
129
- def tempdir
130
- Dir.tmpdir
131
- end
132
-
133
- def prepare_for_scanner(filepath)
134
- # Important for the scanner to be able to access the file.
135
- File.chmod(0o644, filepath)
136
- end
137
107
  end
138
108
  end
139
109
  end
@@ -3,6 +3,8 @@
3
3
  module Ratonvirus
4
4
  module Storage
5
5
  class Carrierwave < Base
6
+ include Ratonvirus::Storage::Support::IoHandling
7
+
6
8
  def changed?(record, attribute)
7
9
  record.public_send :"#{attribute}_changed?"
8
10
  end
@@ -15,12 +17,22 @@ module Ratonvirus
15
17
  end
16
18
  end
17
19
 
18
- def asset_path(asset)
20
+ def asset_path(asset, &block)
19
21
  return unless block_given?
20
22
  return if asset.nil?
21
23
  return if asset.file.nil?
22
24
 
23
- yield asset.file.path
25
+ # If the file is a local SanitizedFile, it is faster to run the scan
26
+ # directly against that file instead of copying it to a tempfile first
27
+ # as below for external file storages.
28
+ return yield asset.file.path if asset.file.is_a?(::CarrierWave::SanitizedFile)
29
+
30
+ # The file could be externally stored, so we need to read it to memory
31
+ # in order to create a temporary file for the scanner to perform the
32
+ # scan on.
33
+ io = StringIO.new(asset.file.read)
34
+ ext = File.extname(asset.file.path)
35
+ io_path(io, ext, &block)
24
36
  end
25
37
 
26
38
  def asset_remove(asset)
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tempfile"
4
+
5
+ module Ratonvirus
6
+ module Storage
7
+ module Support
8
+ module IoHandling
9
+ private
10
+
11
+ # This creates a local copy of the io contents for the scanning process.
12
+ # A local copy is needed for processing because the io object may be a
13
+ # file stream in the memory which may not have a path associated with it
14
+ # on the filesystem.
15
+ def io_path(io, extension)
16
+ tempfile = Tempfile.open(
17
+ ["Ratonvirus", extension],
18
+ tempdir
19
+ )
20
+ # Important for the scanner to be able to access the file.
21
+ prepare_for_scanner tempfile.path
22
+
23
+ begin
24
+ tempfile.binmode
25
+ IO.copy_stream(io, tempfile)
26
+ tempfile.flush
27
+ tempfile.rewind
28
+
29
+ yield tempfile.path
30
+ ensure
31
+ tempfile.close!
32
+ end
33
+ end
34
+
35
+ def tempdir
36
+ Dir.tmpdir
37
+ end
38
+
39
+ def prepare_for_scanner(filepath)
40
+ # Important for the scanner to be able to access the file.
41
+ File.chmod(0o644, filepath)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -88,37 +88,37 @@ module Ratonvirus
88
88
  def define_backend(backend_type, backend_subclass)
89
89
  class_eval <<-CODE, __FILE__, __LINE__ + 1
90
90
  # Getter for #{backend_type}
91
- def self.#{backend_type}
92
- @#{backend_type} ||= create_#{backend_type}
93
- end
91
+ def self.#{backend_type} # def self.foo
92
+ @#{backend_type} ||= create_#{backend_type} # @foo ||= create_foo
93
+ end # end
94
94
 
95
95
  # Setter for #{backend_type}
96
- def self.#{backend_type}=(#{backend_type}_value)
97
- set_backend(
98
- :#{backend_type},
99
- "#{backend_subclass}",
100
- #{backend_type}_value
101
- )
102
- end
96
+ def self.#{backend_type}=(#{backend_type}_value) # def self.foo=(foo_value)
97
+ set_backend( # set_backend(
98
+ :#{backend_type}, # :foo
99
+ "#{backend_subclass}", # "Foo"
100
+ #{backend_type}_value # foo_value
101
+ ) # )
102
+ end # end
103
103
 
104
104
  # Destroys the currently active #{backend_type}.
105
105
  # The #{backend_type} is re-initialized when the getter is called.
106
- def self.destroy_#{backend_type}
107
- @#{backend_type} = nil
108
- end
106
+ def self.destroy_#{backend_type} # def self.destroy_foo
107
+ @#{backend_type} = nil # @foo = nil
108
+ end # end
109
109
 
110
110
  # Creates a new backend instance
111
111
  # private
112
- def self.create_#{backend_type}
113
- if @#{backend_type}_defs.nil?
114
- raise NotDefinedError.new("#{backend_subclass} not defined!")
115
- end
116
-
117
- @#{backend_type}_defs[:klass].new(
118
- @#{backend_type}_defs[:config]
119
- )
120
- end
121
- private_class_method :create_#{backend_type}
112
+ def self.create_#{backend_type} # def self.create_foo
113
+ if @#{backend_type}_defs.nil? # if @foo_defs.nil?
114
+ raise NotDefinedError.new("#{backend_subclass} not defined!") # raise NotDefinedError.new("Foo not defined")
115
+ end # end
116
+ #
117
+ @#{backend_type}_defs[:klass].new( # @foo_defs[:klass].new(
118
+ @#{backend_type}_defs[:config] # @foo_defs[:config]
119
+ ) # )
120
+ end # end
121
+ private_class_method :create_#{backend_type} # private_class_method :create_foo
122
122
  CODE
123
123
  end
124
124
 
@@ -154,12 +154,13 @@ module Ratonvirus
154
154
  subtype = backend_value.class
155
155
  config = backend_value.config
156
156
  else
157
- if backend_value.is_a?(Array)
157
+ case backend_value
158
+ when Array
158
159
  subtype = backend_value.shift
159
160
  config = backend_value.shift || {}
160
161
 
161
162
  raise InvalidError, "Invalid #{backend_type} type: #{subtype}" unless subtype.is_a?(Symbol)
162
- elsif backend_value.is_a?(Symbol)
163
+ when Symbol
163
164
  subtype = backend_value
164
165
  config = {}
165
166
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ratonvirus
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratonvirus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antti Hukkanen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-27 00:00:00.000000000 Z
11
+ date: 2021-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -128,28 +128,28 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.86.0
131
+ version: 1.11.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.86.0
138
+ version: 1.11.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rubocop-rspec
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '1.40'
145
+ version: 2.2.0
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '1.40'
152
+ version: 2.2.0
153
153
  description: Adds antivirus check capability for Rails applications.
154
154
  email:
155
155
  - antti.hukkanen@mainiotech.fi
@@ -177,6 +177,7 @@ files:
177
177
  - lib/ratonvirus/storage/carrierwave.rb
178
178
  - lib/ratonvirus/storage/filepath.rb
179
179
  - lib/ratonvirus/storage/multi.rb
180
+ - lib/ratonvirus/storage/support/io_handling.rb
180
181
  - lib/ratonvirus/support/backend.rb
181
182
  - lib/ratonvirus/version.rb
182
183
  - lib/tasks/ratonvirus.rake
@@ -192,7 +193,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
193
  requirements:
193
194
  - - ">="
194
195
  - !ruby/object:Gem::Version
195
- version: '0'
196
+ version: '2.5'
196
197
  required_rubygems_version: !ruby/object:Gem::Requirement
197
198
  requirements:
198
199
  - - ">="