rack-secure-upload 0.0.1 → 0.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: cbe05978464d47ac087ea6adeb658393255286a1
4
- data.tar.gz: 665a3cf199c8842d9e462817731bdd7eda1bf680
3
+ metadata.gz: d0ba9f53bce6aa9b457f8e3b239d6a4d3bc3ffaf
4
+ data.tar.gz: ebd770e5e8bb8a5043f0ab6c7a1305a790471f67
5
5
  SHA512:
6
- metadata.gz: 586489032e752102f6fecc512fb2c382479ba6ba1866ae7f0eb85a3af91e7d7e240c23ec79d8c8023d3ba412442983574e6f8190dbd77fac382330ae9c85da0f
7
- data.tar.gz: 2babc6bedc1898e099e400c80a4b9f5bbe14a594dc458d7c2dcda38a6b38fda2d2aaf5fd1a7592b5ff913086ff724a04674a84bb2dc8d6af751f9d0059883afd
6
+ metadata.gz: a05f9640d310478531800cb2ffe6661e1badb469d95eabe720e24d1211056edf2ee6a96ecdd09f94bdf78c515b88ea2ca4376608c912aedd1754d756c4591727
7
+ data.tar.gz: 6643d906405bff3ab54651a8fc2f2f9513981fb9adf2a1e8d99f2857a957b3bb9b391698b088494b3c74db4c8999d1b6afb08cdf9cf3eaaf909776d5de792b79
@@ -8,8 +8,6 @@ gemfile:
8
8
  - gemfiles/gemfile
9
9
  - gemfiles/rack.1.4.x.gemfile
10
10
  - gemfiles/rack.1.3.x.gemfile
11
- - gemfiles/rack.1.2.x.gemfile
12
- - gemfiles/rack.1.1.x.gemfile
13
11
 
14
12
  script: "bundle exec rake spec"
15
13
 
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # rack-secure-upload
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/rack-secure-upload.svg)](http://badge.fury.io/rb/rack-secure-upload) [![Build Status](https://travis-ci.org/dtaniwaki/rack-secure-upload.svg?branch=master)](https://travis-ci.org/dtaniwaki/rack-secure-upload) [![Coverage Status](https://coveralls.io/repos/dtaniwaki/rack-secure-upload/badge.png)](https://coveralls.io/r/dtaniwaki/rack-secure-upload)
4
+
3
5
  Upload files securely
4
6
 
5
7
  ## Installation
@@ -34,9 +36,21 @@ end
34
36
 
35
37
  ## AntiVirus Softwares
36
38
 
39
+ ### Avast
40
+
41
+ 1. Get [license](http://www.avast.com/registration-free-antivirus.php)
42
+ 2. Install the package
43
+
44
+ ```bash
45
+ wget -c http://files.avast.com/files/linux/avast4workstation-1.3.0-1.i586.rpm
46
+ sudo yum localinstall avast4workstation-1.3.0-1.i586.rpm
47
+ avast -V # Input your license
48
+ avast-update
49
+ ```
50
+
37
51
  ### F-Secure
38
52
 
39
- 1. Get [license](http://www.f-secure.com/en/web/business_global/trial)
53
+ 1. Get [license](http://www.f-secure.com/en/web/business_global/trial) (Optional)
40
54
  2. Install the package
41
55
 
42
56
  ```bash
@@ -45,6 +59,13 @@ tar xvzf f-secure-linux-security-10.00.60.tar.gz
45
59
  sudo ./f-secure-linux-security-10.00.60/f-secure-linux-security-10.00.60
46
60
  ```
47
61
 
62
+ ## Test this middleware
63
+
64
+ 1. Download [eicar test file](http://www.f-secure.com/virus-info/eicar.com)
65
+ 2. Upload it
66
+
67
+ You can try this with [sample app](https://github.com/dtaniwaki/rack-secure-upload-sample-app)
68
+
48
69
  ## Contributing
49
70
 
50
71
  1. Fork it
@@ -1,6 +1,7 @@
1
1
  module Rack
2
2
  module SecureUpload
3
3
  class RuntimeError < ::RuntimeError; end
4
+ class SetupError < RuntimeError; end
4
5
  class InsecureFileError < RuntimeError; end
5
6
  end
6
7
  end
@@ -10,10 +10,14 @@ module Rack
10
10
  def initialize(app, scanners)
11
11
  @app = app
12
12
  @scanners = [scanners].flatten.map { |scanner| scanner.is_a?(Symbol) ? Rack::SecureUpload::Scanner.const_get(camelize(scanner.to_s)).new : scanner }
13
+ @scanners.each do |scanner|
14
+ scanner.setup
15
+ end
13
16
  end
14
17
 
15
18
  def call(env)
16
19
  params = Rack::Multipart.parse_multipart(env)
20
+
17
21
  if params && !params.empty?
18
22
  traverse(params) do |value|
19
23
  next unless [Tempfile, File].any?{ |klass| value.is_a?(klass) }
@@ -0,0 +1,50 @@
1
+ require 'rack/secure_upload/scanner/base'
2
+
3
+ module Rack
4
+ module SecureUpload
5
+ module Scanner
6
+ class Avast < Base
7
+ def setup
8
+ raise SetupError, "#{options[:bin_path]} is not found." unless ::File.exists?(options[:bin_path])
9
+ end
10
+
11
+ def scan(path)
12
+ now_umask = ::File.umask(0)
13
+
14
+ lock do
15
+ output = command.run(path: path)
16
+ logger.info output
17
+ end
18
+
19
+ ::File.exist?(path)
20
+ ensure
21
+ ::File.umask(now_umask)
22
+ end
23
+
24
+ private
25
+
26
+ def lock
27
+ ::File.open(options[:lockfile_path], 'w', 0666) do |f|
28
+ f.flock(::File::LOCK_EX)
29
+ begin
30
+ yield
31
+ ensure
32
+ f.flock(::File::LOCK_UN)
33
+ end
34
+ end
35
+ end
36
+
37
+ def command
38
+ Cocaine::CommandLine.new(options[:bin_path], "-p 1 :path", :expected_outcodes => [0, 1])
39
+ end
40
+
41
+ def default_options
42
+ {
43
+ :bin_path => "/usr/bin/avast",
44
+ :lockfile_path => "/tmp/avast_lock"
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,3 +1,4 @@
1
+ require 'cocaine'
1
2
  require 'rack/secure_upload/errors'
2
3
 
3
4
  module Rack
@@ -11,6 +12,9 @@ module Rack
11
12
  @options = default_options.merge(options)
12
13
  end
13
14
 
15
+ def setup
16
+ end
17
+
14
18
  def scan(path)
15
19
  # Scan the file here
16
20
  end
@@ -1,10 +1,13 @@
1
- require 'cocaine'
2
- require 'rack/secure_upload/errors'
1
+ require 'rack/secure_upload/scanner/base'
3
2
 
4
3
  module Rack
5
4
  module SecureUpload
6
5
  module Scanner
7
6
  class Fsecure < Base
7
+ def setup
8
+ raise SetupError, "#{options[:bin_path]} is not found." unless ::File.exists?(options[:bin_path])
9
+ end
10
+
8
11
  def scan(path)
9
12
  now_umask = ::File.umask(0)
10
13
 
@@ -32,7 +35,7 @@ module Rack
32
35
  end
33
36
 
34
37
  def command
35
- Cocaine::CommandLine.new(options[:bin_path], "--auto --virus-action1=remove :path")
38
+ Cocaine::CommandLine.new(options[:bin_path], "--auto --virus-action1=remove :path", :expected_outcodes => [0, 1])
36
39
  end
37
40
 
38
41
  def default_options
@@ -15,6 +15,10 @@ module Rack
15
15
  block.call(value)
16
16
  end
17
17
  end
18
+
19
+ def camelize(s)
20
+ s.split('_').map{ |_s| "#{_s[0].upcase}#{_s[1..-1]}" }.join
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module SecureUpload
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.require_paths = ['lib']
18
18
 
19
19
  gem.add_dependency 'logger', '>= 1.2'
20
- gem.add_dependency "rack", ">= 1.1"
20
+ gem.add_dependency "rack", ">= 1.3"
21
21
  gem.add_dependency "cocaine"
22
22
 
23
23
  gem.add_development_dependency "rake"
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  describe Rack::SecureUpload::Middleware do
4
4
  let(:env) { Rack::MockRequest.env_for('/') }
5
5
  let(:file) { Rack::Multipart::UploadedFile.new(__FILE__) }
6
- let(:scanner) { double scan: true }
6
+ let(:scanner) { double setup: true, scan: true }
7
7
  subject { Rack::SecureUpload::Middleware.new(->env { ":)" }, scanner) }
8
8
 
9
9
  context "with uploaded file" do
@@ -0,0 +1,51 @@
1
+ require "spec_helper"
2
+
3
+ describe Rack::SecureUpload::Scanner::Avast do
4
+ let(:path) { 'tmp/avast_spec_target' }
5
+ subject { Rack::SecureUpload::Scanner::Avast.new }
6
+
7
+ before do
8
+ ::File.open(path, 'w').close
9
+ end
10
+
11
+ describe "#setup" do
12
+ subject { Rack::SecureUpload::Scanner::Avast.new(bin_path: 'tmp/avast_binary') }
13
+ context "bin file exists" do
14
+ before do
15
+ ::File.open('tmp/avast_binary', 'w').close
16
+ end
17
+ it "does not raise an exception" do
18
+ expect{ subject.setup }.not_to raise_error
19
+ end
20
+ end
21
+ context "no bin file" do
22
+ it "raises an exception" do
23
+ expect{ subject.setup }.to raise_error(Rack::SecureUpload::SetupError)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "#scan" do
29
+ context "normal files" do
30
+ let(:command) { double run: lambda {} }
31
+ it "detects an insecure file" do
32
+ allow(subject).to receive(:command).and_return(command)
33
+ expect(subject.scan(path)).to eq(true)
34
+ end
35
+ end
36
+
37
+ context "insecure files" do
38
+ let(:command) do
39
+ d = double
40
+ allow(d).to receive(:run) do
41
+ ::FileUtils.rm path
42
+ end
43
+ d
44
+ end
45
+ it "does not detect normal file" do
46
+ allow(subject).to receive(:command).and_return(command)
47
+ expect(subject.scan(path)).to eq(false)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -7,29 +7,45 @@ describe Rack::SecureUpload::Scanner::Fsecure do
7
7
  before do
8
8
  ::File.open(path, 'w').close
9
9
  end
10
- after do
11
- ::FileUtils.rm path if ::File.exists?(path)
12
- end
13
10
 
14
- context "normal files" do
15
- let(:command) { double run: lambda {} }
16
- it "detects an insecure file" do
17
- allow(subject).to receive(:command).and_return(command)
18
- expect(subject.scan(path)).to eq(true)
11
+ describe "#setup" do
12
+ subject { Rack::SecureUpload::Scanner::Fsecure.new(bin_path: 'tmp/fsecure_binary') }
13
+ context "bin file exists" do
14
+ before do
15
+ ::File.open('tmp/fsecure_binary', 'w').close
16
+ end
17
+ it "does not raise an exception" do
18
+ expect{ subject.setup }.not_to raise_error
19
+ end
20
+ end
21
+ context "no bin file" do
22
+ it "raises an exception" do
23
+ expect{ subject.setup }.to raise_error(Rack::SecureUpload::SetupError)
24
+ end
19
25
  end
20
26
  end
21
27
 
22
- context "insecure files" do
23
- let(:command) do
24
- d = double
25
- allow(d).to receive(:run) do
26
- ::FileUtils.rm path
28
+ describe "#scan" do
29
+ context "normal files" do
30
+ let(:command) { double run: lambda {} }
31
+ it "detects an insecure file" do
32
+ allow(subject).to receive(:command).and_return(command)
33
+ expect(subject.scan(path)).to eq(true)
27
34
  end
28
- d
29
35
  end
30
- it "does not detect normal file" do
31
- allow(subject).to receive(:command).and_return(command)
32
- expect(subject.scan(path)).to eq(false)
36
+
37
+ context "insecure files" do
38
+ let(:command) do
39
+ d = double
40
+ allow(d).to receive(:run) do
41
+ ::FileUtils.rm path
42
+ end
43
+ d
44
+ end
45
+ it "does not detect normal file" do
46
+ allow(subject).to receive(:command).and_return(command)
47
+ expect(subject.scan(path)).to eq(false)
48
+ end
33
49
  end
34
50
  end
35
51
  end
@@ -37,4 +37,10 @@ describe Rack::SecureUpload::Utility do
37
37
  end
38
38
  end
39
39
  end
40
+
41
+ describe "#camelize" do
42
+ it "camelizes" do
43
+ expect(subject.camelize("test_test_test")).to eq("TestTestTest")
44
+ end
45
+ end
40
46
  end
@@ -9,5 +9,11 @@ Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each {|f| require f }
9
9
 
10
10
  ENV['RACK_ENV'] = 'test'
11
11
  RSpec.configure do |config|
12
+ config.before do
13
+ ::FileUtils.mkdir_p 'tmp'
14
+ end
15
+ config.after do
16
+ ::FileUtils.remove_dir 'tmp'
17
+ end
12
18
  end
13
19
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-secure-upload
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daisuke Taniwaki
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.1'
33
+ version: '1.3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.1'
40
+ version: '1.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: cocaine
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -108,8 +108,6 @@ files:
108
108
  - README.md
109
109
  - Rakefile
110
110
  - gemfiles/gemfile
111
- - gemfiles/rack.1.1.x.gemfile
112
- - gemfiles/rack.1.2.x.gemfile
113
111
  - gemfiles/rack.1.3.x.gemfile
114
112
  - gemfiles/rack.1.4.x.gemfile
115
113
  - lib/rack-secure-upload.rb
@@ -117,12 +115,14 @@ files:
117
115
  - lib/rack/secure_upload/errors.rb
118
116
  - lib/rack/secure_upload/middleware.rb
119
117
  - lib/rack/secure_upload/scanner.rb
118
+ - lib/rack/secure_upload/scanner/avast.rb
120
119
  - lib/rack/secure_upload/scanner/base.rb
121
120
  - lib/rack/secure_upload/scanner/fsecure.rb
122
121
  - lib/rack/secure_upload/utility.rb
123
122
  - lib/rack/secure_upload/version.rb
124
123
  - rack-secure-upload.gemspec
125
124
  - spec/rack/secure_upload/middleware_spec.rb
125
+ - spec/rack/secure_upload/scanner/avast_spec.rb
126
126
  - spec/rack/secure_upload/scanner/base_spec.rb
127
127
  - spec/rack/secure_upload/scanner/fsecure_spec.rb
128
128
  - spec/rack/secure_upload/utility_spec.rb
@@ -154,6 +154,7 @@ specification_version: 4
154
154
  summary: Upload files securely
155
155
  test_files:
156
156
  - spec/rack/secure_upload/middleware_spec.rb
157
+ - spec/rack/secure_upload/scanner/avast_spec.rb
157
158
  - spec/rack/secure_upload/scanner/base_spec.rb
158
159
  - spec/rack/secure_upload/scanner/fsecure_spec.rb
159
160
  - spec/rack/secure_upload/utility_spec.rb
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gem 'rack', '~> 1.1.0'
4
- gemspec :path => '../'
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gem 'rack', '~> 1.2.0'
4
- gemspec :path => '../'