/
content_type_allowlist_spec.rb
118 lines (90 loc) · 4.52 KB
/
content_type_allowlist_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
require 'spec_helper'
describe CarrierWave::Uploader do
let(:uploader_class) { Class.new(CarrierWave::Uploader::Base) }
let(:uploader) { uploader_class.new }
let(:ruby_file) { File.open(file_path('ruby.gif')) }
let(:bork_file) { File.open(file_path('bork.txt')) }
let(:vector_file) { File.open(file_path('ruby.svg')) }
after { FileUtils.rm_rf(public_path) }
describe '#cache!' do
before do
allow(CarrierWave).to receive(:generate_cache_id).and_return('1369894322-345-1234-2255')
end
context "when there is no allowlist" do
it "does not raise an integrity error" do
allow(uploader).to receive(:content_type_allowlist).and_return(nil)
expect { uploader.cache!(ruby_file) }.not_to raise_error
end
end
context "when there is an allowlist" do
context "when the allowlist is an array of values" do
it "does not raise an integrity error when the file has an allowlisted content type" do
allow(uploader).to receive(:content_type_allowlist).and_return(['image/png'])
expect { uploader.cache!(ruby_file) }.not_to raise_error
end
it "accepts content types with a + symbol" do
allow(uploader).to receive(:content_type_allowlist).and_return(['image/svg+xml'])
expect { uploader.cache!(vector_file) }.not_to raise_error
end
it "accepts a list of content types with mixed regular expressions and strings" do
allow(uploader).to receive(:content_type_allowlist).and_return(['application/pdf', %r{image/}])
expect { uploader.cache!(ruby_file) }.not_to raise_error
end
it "raises an integrity error the file has not an allowlisted content type" do
allow(uploader).to receive(:content_type_allowlist).and_return(['image/gif'])
expect { uploader.cache!(bork_file) }.to raise_error(CarrierWave::IntegrityError)
end
it "accepts content types as regular expressions" do
allow(uploader).to receive(:content_type_allowlist).and_return([/image\//])
expect { uploader.cache!(bork_file) }.to raise_error(CarrierWave::IntegrityError)
end
it "raises an integrity error which lists the allowed content types" do
allow(uploader).to receive(:content_type_allowlist).and_return(['image/gif', 'image/jpg'])
expect { uploader.cache!(bork_file) }.to raise_error(CarrierWave::IntegrityError, %r{(?:image/gif|image/jpg)})
end
end
context "when the allowlist is a single value" do
let(:test_file) { File.open(file_path('test.jpeg')) }
it "accepts a single content type string value" do
allow(uploader).to receive(:content_type_allowlist).and_return('image/png')
expect { uploader.cache!(ruby_file) }.not_to raise_error
end
it "accepts a single content type regular expression value" do
allow(uploader).to receive(:content_type_allowlist).and_return(/image\//)
expect { uploader.cache!(ruby_file) }.not_to raise_error
end
end
context "with a crafted content type" do
before do
allow(bork_file).to receive(:content_type).and_return('text/plain; image/png')
allow(uploader).to receive(:content_type_allowlist).and_return('image/png')
end
it "does not allow spoofing" do
expect { uploader.cache!(bork_file) }.to raise_error(CarrierWave::IntegrityError)
end
end
end
context "when there is a whitelist" do
it "uses the whitelist but shows deprecation" do
allow(uploader).to receive(:content_type_whitelist).and_return(['image/gif'])
expect(ActiveSupport::Deprecation).to receive(:warn).with('#content_type_whitelist is deprecated, use #content_type_allowlist instead.')
expect {
uploader.cache!(bork_file)
}.to raise_error(CarrierWave::IntegrityError)
end
it "looks for content_type_allowlist first for I18n translation" do
allow(uploader).to receive(:content_type_allowlist).and_return(['image/gif'])
change_locale_and_store_translations(:nl, :errors => {
:messages => {
:content_type_whitelist_error => "this will not be used",
:content_type_allowlist_error => "Het is niet toegestaan om %{content_type} bestanden te uploaden"
}
}) do
expect {
uploader.cache!(bork_file)
}.to raise_error(CarrierWave::IntegrityError, 'Het is niet toegestaan om text/plain bestanden te uploaden')
end
end
end
end
end