rack-restrict_access 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +177 -0
- data/Rakefile +1 -0
- data/lib/rack/restrict_access.rb +313 -0
- data/lib/rack/restrict_access/version.rb +5 -0
- data/rack-restrict_access.gemspec +29 -0
- data/spec/allow_filter_spec.rb +54 -0
- data/spec/block_filter_spec.rb +82 -0
- data/spec/filter_spec.rb +392 -0
- data/spec/restrict_access_spec.rb +311 -0
- data/spec/restrict_filter_spec.rb +175 -0
- data/spec/spec_helper.rb +2 -0
- metadata +179 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rack/restrict_access/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rack-restrict_access"
|
8
|
+
spec.version = Rack::RestrictAccess::VERSION
|
9
|
+
spec.authors = ["Mainor Claros"]
|
10
|
+
spec.email = ["m_claros@live.com"]
|
11
|
+
spec.summary = %q{Middleware to add basic auth, or block, specific host paths and requester IPs.}
|
12
|
+
spec.description = %q{Compares env 'REMOTE_ADDR' and 'PATH_INFO' against user-defined values to block (403), restrict (401 basic auth), or allow access to the rack app. Intended for use in simple access control. Should not be considered a security solution.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec", "~> 2.4"
|
24
|
+
spec.add_development_dependency "rspec-nc"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "pry-remote"
|
27
|
+
spec.add_development_dependency "pry-nav"
|
28
|
+
spec.add_runtime_dependency "rack"
|
29
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rack::RestrictAccess::AllowFilter do
|
4
|
+
it "should inherit from Filter class" do
|
5
|
+
expect(Rack::RestrictAccess::AllowFilter.superclass).to eq(Rack::RestrictAccess::Filter)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "initialize" do
|
9
|
+
it "sets defaults" do
|
10
|
+
allow_filter = Rack::RestrictAccess::AllowFilter.new
|
11
|
+
expect(allow_filter.instance_variable_get(:@ips)).to eq([])
|
12
|
+
expect(allow_filter.instance_variable_get(:@resources)).to eq([])
|
13
|
+
expect(allow_filter.instance_variable_get(:@applies_to_all_resources)).to be false
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should execute block if given" do
|
17
|
+
expect_any_instance_of(Rack::RestrictAccess::AllowFilter).to receive(:bogus_method)
|
18
|
+
Rack::RestrictAccess::AllowFilter.new do
|
19
|
+
bogus_method
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "allows_resource?" do
|
25
|
+
it "should delegate its arguments to #applies_to_resource?" do
|
26
|
+
allow_filter = Rack::RestrictAccess::AllowFilter.new
|
27
|
+
path = "/home"
|
28
|
+
expect(allow_filter).to receive(:applies_to_resource?).with(path).and_return(false)
|
29
|
+
expect(allow_filter.allows_resource?(path)).to eq false
|
30
|
+
|
31
|
+
allow_filter.instance_variable_set(:@resources, ["/home"])
|
32
|
+
expect(allow_filter).to receive(:applies_to_resource?).with(path).and_return(true)
|
33
|
+
expect(allow_filter.allows_resource?(path)).to eq true
|
34
|
+
|
35
|
+
allow_filter.instance_variable_set(:@resources, [])
|
36
|
+
allow_filter.instance_variable_set(:@applies_to_all_resources, true)
|
37
|
+
expect(allow_filter).to receive(:applies_to_resource?).with(path).and_return(true)
|
38
|
+
expect(allow_filter.allows_resource?(path)).to eq true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "allows_ip?" do
|
43
|
+
it "should delegate its arguments to #applies_to_ip?" do
|
44
|
+
allow_filter = Rack::RestrictAccess::AllowFilter.new
|
45
|
+
ip = "123.456.7.8"
|
46
|
+
expect(allow_filter).to receive(:applies_to_ip?).with(ip).and_return(false)
|
47
|
+
expect(allow_filter.allows_ip?(ip)).to eq false
|
48
|
+
|
49
|
+
allow_filter.instance_variable_set(:@ips, ["123.456.7.8"])
|
50
|
+
expect(allow_filter).to receive(:applies_to_ip?).with(ip).and_return(true)
|
51
|
+
expect(allow_filter.allows_ip?(ip)).to eq true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rack::RestrictAccess::BlockFilter do
|
4
|
+
it "should inherit from Filter class" do
|
5
|
+
expect(Rack::RestrictAccess::BlockFilter.superclass).to eq(Rack::RestrictAccess::Filter)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "initialize" do
|
9
|
+
it "should set defaults" do
|
10
|
+
block_filter = Rack::RestrictAccess::BlockFilter.new
|
11
|
+
expect(block_filter.instance_variable_get(:@body)).to eq(["<h1>Forbidden</h1>"])
|
12
|
+
expect(block_filter.instance_variable_get(:@status_code)).to eq(403)
|
13
|
+
expect(block_filter.instance_variable_get(:@ips)).to eq([])
|
14
|
+
expect(block_filter.instance_variable_get(:@resources)).to eq([])
|
15
|
+
expect(block_filter.instance_variable_get(:@applies_to_all_resources)).to be false
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should execute block if given" do
|
19
|
+
expect_any_instance_of(Rack::RestrictAccess::BlockFilter).to receive(:bogus_method)
|
20
|
+
Rack::RestrictAccess::BlockFilter.new do
|
21
|
+
bogus_method
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "body" do
|
27
|
+
it "should override default @body" do
|
28
|
+
block_filter = Rack::RestrictAccess::BlockFilter.new
|
29
|
+
expect(block_filter.instance_variable_get(:@body)).to eq(["<h1>Forbidden</h1>"])
|
30
|
+
block_filter.body(["You shall not pass!"])
|
31
|
+
expect(block_filter.instance_variable_get(:@body)).to eq(["You shall not pass!"])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should raise exception if given body does not respond to :each" do
|
35
|
+
block_filter = Rack::RestrictAccess::BlockFilter.new
|
36
|
+
expect{block_filter.body("You shall not pass!")}.to raise_exception(ArgumentError, "Body must respond to #each")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "status_code" do
|
41
|
+
it "should override default @status_code" do
|
42
|
+
block_filter = Rack::RestrictAccess::BlockFilter.new
|
43
|
+
expect(block_filter.instance_variable_get(:@status_code)).to eq(403)
|
44
|
+
block_filter.status_code(401)
|
45
|
+
expect(block_filter.instance_variable_get(:@status_code)).to eq(401)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "blocks_resource?" do
|
50
|
+
it "should delegate its arguments to #applies_to_resource?" do
|
51
|
+
block_filter = Rack::RestrictAccess::BlockFilter.new
|
52
|
+
expect(block_filter.instance_variable_get(:@applies_to_all_resources)).to be false
|
53
|
+
expect(block_filter.instance_variable_get(:@resources)).to be_empty
|
54
|
+
path = "/admin"
|
55
|
+
expect(block_filter).to receive(:applies_to_resource?).with(path).and_return(false)
|
56
|
+
expect(block_filter.blocks_resource?(path)).to eq false
|
57
|
+
|
58
|
+
block_filter.instance_variable_set(:@resources, ["/admin"])
|
59
|
+
expect(block_filter).to receive(:applies_to_resource?).with(path).and_return(true)
|
60
|
+
expect(block_filter.blocks_resource?(path)).to eq true
|
61
|
+
|
62
|
+
block_filter.instance_variable_set(:@resources, [])
|
63
|
+
block_filter.instance_variable_set(:@applies_to_all_resources, true)
|
64
|
+
expect(block_filter).to receive(:applies_to_resource?).with(path).and_return(true)
|
65
|
+
expect(block_filter.blocks_resource?(path)).to eq true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "blocks_ip?" do
|
70
|
+
it "should delegate its arguments to #applies_to_ip?" do
|
71
|
+
block_filter = Rack::RestrictAccess::BlockFilter.new
|
72
|
+
expect(block_filter.instance_variable_get(:@ips)).to be_empty
|
73
|
+
ip = "123.456.7.8"
|
74
|
+
expect(block_filter).to receive(:applies_to_ip?).with(ip).and_return(false)
|
75
|
+
expect(block_filter.blocks_ip?(ip)).to eq false
|
76
|
+
|
77
|
+
block_filter.instance_variable_set(:@ips, ["123.456.7.8"])
|
78
|
+
expect(block_filter).to receive(:applies_to_ip?).with(ip).and_return(true)
|
79
|
+
expect(block_filter.blocks_ip?(ip)).to eq true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/spec/filter_spec.rb
ADDED
@@ -0,0 +1,392 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rack::RestrictAccess::Filter do
|
4
|
+
describe "initialize" do
|
5
|
+
it "should set defaults" do
|
6
|
+
filter = Rack::RestrictAccess::Filter.new
|
7
|
+
expect(filter.instance_variable_get(:@ips)).to eq([])
|
8
|
+
expect(filter.instance_variable_get(:@resources)).to eq([])
|
9
|
+
expect(filter.instance_variable_get(:@applies_to_all_resources)).to be false
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should execute block if given" do
|
13
|
+
expect_any_instance_of(Rack::RestrictAccess::Filter).to receive(:bogus_method)
|
14
|
+
Rack::RestrictAccess::Filter.new do
|
15
|
+
bogus_method
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "restricts_resource?" do
|
21
|
+
it "should delegate its arguments to #applies_to_resource?" do
|
22
|
+
restrict_filter = Rack::RestrictAccess::RestrictFilter.new
|
23
|
+
expect(restrict_filter.instance_variable_get(:@applies_to_all_resources)).to be false
|
24
|
+
expect(restrict_filter.instance_variable_get(:@resources)).to eq([])
|
25
|
+
path = "/admin"
|
26
|
+
expect(restrict_filter).to receive(:applies_to_resource?).with(path).and_return(false)
|
27
|
+
expect(restrict_filter.restricts_resource?(path)).to eq false
|
28
|
+
|
29
|
+
restrict_filter.instance_variable_set(:@resources, ["/admin"])
|
30
|
+
expect(restrict_filter).to receive(:applies_to_resource?).with(path).and_return(true)
|
31
|
+
expect(restrict_filter.restricts_resource?(path)).to eq true
|
32
|
+
|
33
|
+
restrict_filter.instance_variable_set(:@resources, [])
|
34
|
+
restrict_filter.instance_variable_set(:@applies_to_all_resources, true)
|
35
|
+
expect(restrict_filter).to receive(:applies_to_resource?).with(path).and_return(true)
|
36
|
+
expect(restrict_filter.restricts_resource?(path)).to eq true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "restricts_ip?" do
|
41
|
+
it "should delegate its arguments to #applies_to_ip?" do
|
42
|
+
restrict_filter = Rack::RestrictAccess::RestrictFilter.new
|
43
|
+
expect(restrict_filter.instance_variable_get(:@ips)).to eq([])
|
44
|
+
ip = "123.456.7.8"
|
45
|
+
expect(restrict_filter).to receive(:applies_to_ip?).with(ip).and_return(false)
|
46
|
+
expect(restrict_filter.restricts_ip?(ip)).to eq false
|
47
|
+
|
48
|
+
restrict_filter.instance_variable_set(:@ips, ["123.456.7.8"])
|
49
|
+
expect(restrict_filter).to receive(:applies_to_ip?).with(ip).and_return(true)
|
50
|
+
expect(restrict_filter.restricts_ip?(ip)).to eq true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "path_to_regexp" do
|
55
|
+
let(:filter) { Rack::RestrictAccess::Filter.new }
|
56
|
+
|
57
|
+
it "should return the given input if it's already a regexp" do
|
58
|
+
reg = /\/secret\/?/
|
59
|
+
expect(filter.path_to_regexp(reg)).to eq(reg)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should convert string into regexp with anchors" do
|
63
|
+
str = '/secret'
|
64
|
+
expect(filter.path_to_regexp(str)).to eq(/^\/secret\/?$/)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should raise exception if argument is does not respond to :match or :to_str" do
|
68
|
+
expect{filter.path_to_regexp(999)}.to raise_exception(TypeError)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "all_resources!" do
|
73
|
+
it "should set @applies_to_all_resources to true" do
|
74
|
+
filter = Rack::RestrictAccess::Filter.new
|
75
|
+
expect(filter.instance_variable_get(:@applies_to_all_resources)).to be false
|
76
|
+
filter.all_resources!
|
77
|
+
expect(filter.instance_variable_get(:@applies_to_all_resources)).to be true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "resources" do
|
82
|
+
it "should call path_to_regexp on given string and save the result to @resources" do
|
83
|
+
filter = Rack::RestrictAccess::Filter.new
|
84
|
+
expect(filter.instance_variable_get(:@resources)).to be_empty
|
85
|
+
arg = '/some-path'
|
86
|
+
filter.resources(arg)
|
87
|
+
expect(filter.instance_variable_get(:@resources)).to eq([/^\/some\-path\/?$/])
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should handle multiple strings" do
|
91
|
+
filter = Rack::RestrictAccess::Filter.new
|
92
|
+
expect(filter.instance_variable_get(:@resources)).to be_empty
|
93
|
+
arg1 = '/some-path'
|
94
|
+
arg2 = '/accounts'
|
95
|
+
arg3 = '/admin'
|
96
|
+
filter.resources(arg1, arg2, arg3)
|
97
|
+
expect(filter.instance_variable_get(:@resources)).to eq([/^\/some\-path\/?$/, /^\/accounts\/?$/, /^\/admin\/?$/])
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should handle delimited string when given delimiter string option" do
|
101
|
+
csv = '/some-path,/accounts,/admin'
|
102
|
+
filter2 = Rack::RestrictAccess::Filter.new
|
103
|
+
expect(filter2.instance_variable_get(:@resources)).to be_empty
|
104
|
+
filter2.resources(csv, delimiter: ',')
|
105
|
+
expect(filter2.instance_variable_get(:@resources)).to eq([/^\/some\-path\/?$/, /^\/accounts\/?$/, /^\/admin\/?$/])
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should handle delimited string when given delimiter regexp option" do
|
109
|
+
regexp_delimited = '/some-path | /accounts | /admin'
|
110
|
+
filter3 = Rack::RestrictAccess::Filter.new
|
111
|
+
expect(filter3.instance_variable_get(:@resources)).to be_empty
|
112
|
+
filter3.resources(regexp_delimited, delimiter: /[\s]*\|[\s]*/)
|
113
|
+
expect(filter3.instance_variable_get(:@resources)).to eq([/^\/some\-path\/?$/, /^\/accounts\/?$/, /^\/admin\/?$/])
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should not split string if no delimiter option is given" do
|
117
|
+
not_delimited_csv = '/some-path,/accounts,/admin'
|
118
|
+
filter1 = Rack::RestrictAccess::Filter.new
|
119
|
+
expect(filter1.instance_variable_get(:@resources)).to be_empty
|
120
|
+
filter1.resources(not_delimited_csv)
|
121
|
+
expect(filter1.instance_variable_get(:@resources)).to eq([/^#{Regexp.escape(not_delimited_csv)}\/?$/])
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should handle multiple delimited strings" do
|
125
|
+
csv = "/one, /two, /three"
|
126
|
+
tsv = "/four\t/five\t/six"
|
127
|
+
filter = Rack::RestrictAccess::Filter.new
|
128
|
+
filter.resources(csv, tsv, delimiter: /\s*,\s*|\t/)
|
129
|
+
expect(filter.instance_variable_get(:@resources)).to eq([/^\/one\/?$/, /^\/two\/?$/, /^\/three\/?$/, /^\/four\/?$/, /^\/five\/?$/, /^\/six\/?$/])
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should handle a regexp argument" do
|
133
|
+
arg = /\/some\-path/
|
134
|
+
filter = Rack::RestrictAccess::Filter.new
|
135
|
+
expect(filter.instance_variable_get(:@resources)).to be_empty
|
136
|
+
filter.resources(arg)
|
137
|
+
expect(filter.instance_variable_get(:@resources)).to eq([/\/some\-path/])
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should handle multiple regexps" do
|
141
|
+
filter = Rack::RestrictAccess::Filter.new
|
142
|
+
expect(filter.instance_variable_get(:@resources)).to be_empty
|
143
|
+
arg1 = /\/some\-path/
|
144
|
+
arg2 = /\/some\-other\-path/
|
145
|
+
arg3 = /^\/exact$/
|
146
|
+
filter.resources(arg1, arg2, arg3)
|
147
|
+
expect(filter.instance_variable_get(:@resources)).to eq([/\/some\-path/, /\/some\-other\-path/, /^\/exact$/])
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should handle single array of strings or regexps" do
|
151
|
+
arr = ['/admin', /^.*\/secret\/?.*$/, '/users']
|
152
|
+
filter = Rack::RestrictAccess::Filter.new
|
153
|
+
filter.resources(arr)
|
154
|
+
expect(filter.instance_variable_get(:@resources)).to eq([/^\/admin\/?$/, /^.*\/secret\/?.*$/, /^\/users\/?$/])
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should handle multiple arrays of strings or regexps" do
|
158
|
+
arr1 = ['/admin', /^.*\/secret\/?.*$/, '/users']
|
159
|
+
arr2 = [/^\/first\/?$/, '/second', /^\/third/]
|
160
|
+
filter = Rack::RestrictAccess::Filter.new
|
161
|
+
filter.resources(arr1, arr2)
|
162
|
+
expect(filter.instance_variable_get(:@resources)).to eq([/^\/admin\/?$/, /^.*\/secret\/?.*$/, /^\/users\/?$/, /^\/first\/?$/, /^\/second\/?$/, /^\/third/])
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should split strings in array if delimiter is given" do
|
166
|
+
arr1 = ['/first', '/second,/third', '/fourth']
|
167
|
+
arr2 = [/^\/fifth\/?/, '/sixth,/seventh,/eighth', /^\/ninth/]
|
168
|
+
filter = Rack::RestrictAccess::Filter.new
|
169
|
+
filter.resources(arr1, arr2, delimiter: ',')
|
170
|
+
expect(filter.instance_variable_get(:@resources))
|
171
|
+
.to eq([/^\/first\/?$/, /^\/second\/?$/, /^\/third\/?$/, /^\/fourth\/?$/,
|
172
|
+
/^\/fifth\/?/, /^\/sixth\/?$/, /^\/seventh\/?$/, /^\/eighth\/?$/, /^\/ninth/])
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should handle a combination of strings, regexps, and arrays" do
|
176
|
+
str = '/one,/two/three,/four'
|
177
|
+
regexp1 = /\/between\//
|
178
|
+
regexp2 = /\/ending\/?$/
|
179
|
+
arr = ['/fifth/sixth,/seventh', '/eighth', /^\/ninth$/]
|
180
|
+
filter = Rack::RestrictAccess::Filter.new
|
181
|
+
filter.resources(str, regexp1, arr, regexp2, delimiter: ',')
|
182
|
+
expect(filter.instance_variable_get(:@resources))
|
183
|
+
.to eq([/^\/one\/?$/, /^\/two\/three\/?$/, /^\/four\/?$/,
|
184
|
+
/\/between\//, /^\/fifth\/sixth\/?$/, /^\/seventh\/?$/, /^\/eighth\/?$/, /^\/ninth$/,
|
185
|
+
/\/ending\/?$/])
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should continue to add to @resources if called repeatedly" do
|
189
|
+
str = '/home,/alone'
|
190
|
+
reg = /^\/home2/
|
191
|
+
arr = ['/cheers']
|
192
|
+
filter = Rack::RestrictAccess::Filter.new
|
193
|
+
filter.resources str, delimiter: ','
|
194
|
+
filter.resources reg
|
195
|
+
filter.resources arr
|
196
|
+
expect(filter.instance_variable_get(:@resources))
|
197
|
+
.to eq([/^\/home\/?$/, /^\/alone\/?$/, /^\/home2/, /^\/cheers\/?$/])
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "applies_to_resource?" do
|
202
|
+
it "should return true if @applies_to_all_resources is true" do
|
203
|
+
filter = Rack::RestrictAccess::Filter.new
|
204
|
+
filter.instance_variable_set(:@applies_to_all_resources, true)
|
205
|
+
expect(filter.applies_to_resource?('/some_path')).to be true
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should return true if any @resources match requested_resource" do
|
209
|
+
filter = Rack::RestrictAccess::Filter.new
|
210
|
+
filter.instance_variable_set(:@resources, [/^\/admin$/])
|
211
|
+
expect(filter.applies_to_resource?("/admin")).to be true
|
212
|
+
expect(filter.applies_to_resource?("/admin/cp")).to be false
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should return false if no @resources match requested_resource" do
|
216
|
+
filter = Rack::RestrictAccess::Filter.new
|
217
|
+
filter.instance_variable_set(:@resources, [/^\/admin$/, /^\/one$/, /^\/two$/])
|
218
|
+
expect(filter.applies_to_resource?("/three")).to be false
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should raise exception if argument cannot be converted to_str" do
|
222
|
+
filter = Rack::RestrictAccess::Filter.new
|
223
|
+
expect{filter.applies_to_resource?(9)}.to raise_exception(TypeError)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe "ip_to_regexp" do
|
228
|
+
let(:filter) { Rack::RestrictAccess::Filter.new }
|
229
|
+
|
230
|
+
it "should return the given input if it's already a regexp" do
|
231
|
+
reg = /^192\.168\.\S*/
|
232
|
+
expect(filter.ip_to_regexp(reg)).to eq(reg)
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should convert string into regexp with anchors" do
|
236
|
+
str = '192.168.0.1'
|
237
|
+
expect(filter.ip_to_regexp(str)).to eq(/^192\.168\.0\.1$/)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should raise exception if argument does not respond to :match or :to_str" do
|
241
|
+
expect{filter.ip_to_regexp(999)}.to raise_exception(TypeError)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe "origin_ips" do
|
246
|
+
it "should call ip_to_regexp on given string and save the result to @ips" do
|
247
|
+
filter = Rack::RestrictAccess::Filter.new
|
248
|
+
expect(filter.instance_variable_get(:@ips)).to be_empty
|
249
|
+
ip = '192.168.0.1'
|
250
|
+
filter.origin_ips(ip)
|
251
|
+
expect(filter.instance_variable_get(:@ips)).to eq([/^192\.168\.0\.1$/])
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should handle multiple strings" do
|
255
|
+
filter = Rack::RestrictAccess::Filter.new
|
256
|
+
expect(filter.instance_variable_get(:@ips)).to be_empty
|
257
|
+
ip1 = '0.0.0.0'
|
258
|
+
ip2 = '192.168.1.1'
|
259
|
+
ip3 = '192.168.1.2'
|
260
|
+
filter.origin_ips(ip1, ip2, ip3)
|
261
|
+
expect(filter.instance_variable_get(:@ips))
|
262
|
+
.to eq([/^0\.0\.0\.0$/, /^192\.168\.1\.1$/, /^192\.168\.1\.2$/])
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should handle delimited string when given delimiter string option" do
|
266
|
+
csv = '192.168.1.1,192.168.1.2,192.168.1.3'
|
267
|
+
filter2 = Rack::RestrictAccess::Filter.new
|
268
|
+
expect(filter2.instance_variable_get(:@ips)).to be_empty
|
269
|
+
filter2.origin_ips(csv, delimiter: ',')
|
270
|
+
expect(filter2.instance_variable_get(:@ips))
|
271
|
+
.to eq([/^192\.168\.1\.1$/, /^192\.168\.1\.2$/, /^192\.168\.1\.3$/])
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should handle delimited string when given delimiter regexp option" do
|
275
|
+
regexp_delimited = '192.168.1.1 | 192.168.1.2 | 192.168.1.3'
|
276
|
+
filter3 = Rack::RestrictAccess::Filter.new
|
277
|
+
expect(filter3.instance_variable_get(:@ips)).to be_empty
|
278
|
+
filter3.origin_ips(regexp_delimited, delimiter: /[\s]*\|[\s]*/)
|
279
|
+
expect(filter3.instance_variable_get(:@ips))
|
280
|
+
.to eq([/^192\.168\.1\.1$/, /^192\.168\.1\.2$/, /^192\.168\.1\.3$/])
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should not split string if no delimiter option is given" do
|
284
|
+
not_delimited_csv = '192.168.1.1,192.168.1.2,192.168.1.3'
|
285
|
+
filter1 = Rack::RestrictAccess::Filter.new
|
286
|
+
expect(filter1.instance_variable_get(:@ips)).to be_empty
|
287
|
+
filter1.origin_ips(not_delimited_csv)
|
288
|
+
expect(filter1.instance_variable_get(:@ips))
|
289
|
+
.to eq([/^192\.168\.1\.1,192\.168\.1\.2,192\.168\.1\.3$/])
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should handle multiple delimited strings" do
|
293
|
+
csv = "192.168.1.1, 192.168.1.2,192.168.1.3"
|
294
|
+
tsv = "192.168.1.4\t192.168.1.5\t192.168.1.6"
|
295
|
+
filter = Rack::RestrictAccess::Filter.new
|
296
|
+
filter.origin_ips(csv, tsv, delimiter: /\s*,\s*|\t/)
|
297
|
+
expect(filter.instance_variable_get(:@ips))
|
298
|
+
.to eq([/^192\.168\.1\.1$/, /^192\.168\.1\.2$/, /^192\.168\.1\.3$/, /^192\.168\.1\.4$/, /^192\.168\.1\.5$/, /^192\.168\.1\.6$/])
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should handle a regexp argument" do
|
302
|
+
arg = /^192\.168\.\S*/
|
303
|
+
filter = Rack::RestrictAccess::Filter.new
|
304
|
+
expect(filter.instance_variable_get(:@ips)).to be_empty
|
305
|
+
filter.origin_ips(arg)
|
306
|
+
expect(filter.instance_variable_get(:@ips)).to eq([/^192\.168\.\S*/])
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should handle multiple regexps" do
|
310
|
+
filter = Rack::RestrictAccess::Filter.new
|
311
|
+
expect(filter.instance_variable_get(:@ips)).to be_empty
|
312
|
+
arg1 = /^192\.168\.\S*/
|
313
|
+
arg2 = /^\d{3}\.168\.1\.1$/
|
314
|
+
arg3 = /^193\.168\.\S*/
|
315
|
+
filter.origin_ips(arg1, arg2, arg3)
|
316
|
+
expect(filter.instance_variable_get(:@ips))
|
317
|
+
.to eq([/^192\.168\.\S*/, /^\d{3}\.168\.1\.1$/, /^193\.168\.\S*/])
|
318
|
+
end
|
319
|
+
|
320
|
+
it "should handle single array of strings or regexps" do
|
321
|
+
arr = ['192.168.1.1', /168\.1/, '192.168.1.3']
|
322
|
+
filter = Rack::RestrictAccess::Filter.new
|
323
|
+
filter.origin_ips(arr)
|
324
|
+
expect(filter.instance_variable_get(:@ips))
|
325
|
+
.to eq([/^192\.168\.1\.1$/, /168\.1/, /^192\.168\.1\.3$/])
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should handle multiple arrays of strings or regexps" do
|
329
|
+
arr1 = ['192.168.1.1', /168\.1/, '192.168.1.3']
|
330
|
+
arr2 = [/\.1\.1$/, '192.168.1.4', /^192\.168\.1\.5$/]
|
331
|
+
filter = Rack::RestrictAccess::Filter.new
|
332
|
+
filter.origin_ips(arr1, arr2)
|
333
|
+
expect(filter.instance_variable_get(:@ips))
|
334
|
+
.to eq([/^192\.168\.1\.1$/, /168\.1/, /^192\.168\.1\.3$/, /\.1\.1$/, /^192\.168\.1\.4$/, /^192\.168\.1\.5$/])
|
335
|
+
end
|
336
|
+
|
337
|
+
it "should split strings in array if delimiter is given" do
|
338
|
+
arr1 = ['192.168.1.1', '192.168.1.2,192.168.1.3', '192.168.1.4']
|
339
|
+
arr2 = [/192\.168\.1\.5/, '192.168.1.6,192.168.1.7,192.168.1.8', /^192\.168\./]
|
340
|
+
filter = Rack::RestrictAccess::Filter.new
|
341
|
+
filter.origin_ips(arr1, arr2, delimiter: ',')
|
342
|
+
expect(filter.instance_variable_get(:@ips))
|
343
|
+
.to eq([/^192\.168\.1\.1$/, /^192\.168\.1\.2$/, /^192\.168\.1\.3$/, /^192\.168\.1\.4$/,
|
344
|
+
/192\.168\.1\.5/, /^192\.168\.1\.6$/, /^192\.168\.1\.7$/, /^192\.168\.1\.8$/, /^192\.168\./])
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should handle a combination of strings, regexps, and arrays" do
|
348
|
+
str = '192.168.1.1,192.168.1.2,192.168.1.3'
|
349
|
+
regexp1 = /192\.168/
|
350
|
+
regexp2 = /\.168\.1\.$/
|
351
|
+
arr = ['192.168.1.4,192.168.1.5', '192.168.1.6', /^199\S+$/]
|
352
|
+
filter = Rack::RestrictAccess::Filter.new
|
353
|
+
filter.origin_ips(str, regexp1, arr, regexp2, delimiter: ',')
|
354
|
+
expect(filter.instance_variable_get(:@ips))
|
355
|
+
.to eq([/^192\.168\.1\.1$/, /^192\.168\.1\.2$/, /^192\.168\.1\.3$/, /192\.168/,
|
356
|
+
/^192\.168\.1\.4$/, /^192\.168\.1\.5$/, /^192\.168\.1\.6$/, /^199\S+$/, /\.168\.1\.$/])
|
357
|
+
end
|
358
|
+
|
359
|
+
it "should continue to add to @ips if called repeatedly" do
|
360
|
+
str = '192.168.1.1,192.168.1.2'
|
361
|
+
reg = /^192\.168\./
|
362
|
+
arr = ['192.168.1.3']
|
363
|
+
filter = Rack::RestrictAccess::Filter.new
|
364
|
+
filter.origin_ips str, delimiter: ','
|
365
|
+
filter.origin_ips reg
|
366
|
+
filter.origin_ips arr
|
367
|
+
expect(filter.instance_variable_get(:@ips))
|
368
|
+
.to eq([/^192\.168\.1\.1$/, /^192\.168\.1\.2$/, /^192\.168\./, /^192\.168\.1\.3$/])
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
describe "applies_to_ip?" do
|
373
|
+
it "should return true if any @ips match remote_addr" do
|
374
|
+
filter = Rack::RestrictAccess::Filter.new
|
375
|
+
expect(filter.instance_variable_get(:@ips)).to be_empty
|
376
|
+
filter.instance_variable_set(:@ips, [/^192.168.0.1$/])
|
377
|
+
expect(filter.applies_to_ip?('192.168.0.1')).to be true
|
378
|
+
end
|
379
|
+
|
380
|
+
it "should return false if no @ips match remote_addr" do
|
381
|
+
filter = Rack::RestrictAccess::Filter.new
|
382
|
+
expect(filter.instance_variable_get(:@ips)).to be_empty
|
383
|
+
filter.instance_variable_set(:@ips, [/^192.168.0.1$/])
|
384
|
+
expect(filter.applies_to_ip?('192.168.1.1')).to be false
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should raise exception if argument cannot be coerced to_str" do
|
388
|
+
filter = Rack::RestrictAccess::Filter.new
|
389
|
+
expect{filter.applies_to_ip?(9001)}.to raise_exception(TypeError)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|