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.
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class RestrictAccess
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -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
@@ -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