rack-entrance 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -15,7 +15,7 @@ gem install rack-entrance
15
15
  #### Add it to your middleware stack
16
16
 
17
17
  ```ruby
18
- ENV['ENTRANCE_INTERNAL_IPS'] = "127.0.0.1,192.0.2.21"
18
+ ENV['ENTRANCE_INTERNAL_CIDRS'] = "127.0.0.1,192.0.2.21"
19
19
  use Rack::Entrance
20
20
  ````
21
21
 
data/lib/rack/entrance.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rack'
2
+ require 'ipaddr'
2
3
 
3
4
  module Rack
4
5
  class Entrance
@@ -7,24 +8,44 @@ module Rack
7
8
  @app = app
8
9
  end
9
10
 
11
+ def self.internal_cidrs
12
+ ENV['ENTRANCE_INTERNAL_CIDRS'].to_s.split ','
13
+ end
14
+
10
15
  def call(env)
11
- request = Rack::Request.new(env)
12
- ip = (env["action_dispatch.remote_ip"] || request.ip).to_s
13
- request.env['entrance.ip'] = ip
14
- request.env['entrance.internal_ips'] = internal_ips
15
- request.env['entrance.internal'] = internal?(ip)
16
+ @env = env
17
+ request.env['entrance.user_ip'] = user_ip.to_s if user_ip.to_s != ''
18
+ request.env['entrance.internal_cidrs'] = self.class.internal_cidrs
19
+ request.env['entrance.internal'] = internal?
16
20
  @app.call env
17
21
  end
18
22
 
19
- def internal?(ip)
20
- internal_ips.each do |internal_ip|
21
- return true if ip.to_s.start_with?(internal_ip)
22
- end
23
- false
23
+ def request
24
+ ::Rack::Request.new @env
25
+ end
26
+
27
+ def raw_user_ip
28
+ (@env["action_dispatch.remote_ip"] || request.ip).to_s
29
+ end
30
+
31
+ def user_ip
32
+ ::IPAddr.new raw_user_ip
33
+ rescue ArgumentError
34
+ nil
35
+ end
36
+
37
+ def internal?
38
+ internal_ips.any? { |ip| ip.include?(user_ip) }
24
39
  end
25
40
 
26
41
  def internal_ips
27
- @internal_ips ||= ENV['ENTRANCE_INTERNAL_IPS'].to_s.split(',')
42
+ @internal_ips ||= self.class.internal_cidrs.map do |cidr|
43
+ begin
44
+ ::IPAddr.new cidr
45
+ rescue ArgumentError
46
+ nil
47
+ end
48
+ end.compact
28
49
  end
29
50
 
30
51
  end
@@ -2,8 +2,8 @@ module Rack
2
2
  class Entrance
3
3
  module VERSION #:nodoc:
4
4
  MAJOR = 0
5
- MINOR = 0
6
- TINY = 4
5
+ MINOR = 1
6
+ TINY = 0
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].compact.join('.')
9
9
  end
@@ -1,55 +1,142 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Rack::Entrance do
4
- include Rack::Test::Methods
4
+ let(:next_app) { lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['All good!']] } }
5
+ let(:app) { Rack::Entrance.new next_app }
5
6
 
6
- let(:inner_app) do
7
- lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['All good!']] }
8
- end
7
+ let(:user_ip) { last_request.env['entrance.user_ip'] }
8
+ let(:internal) { last_request.env['entrance.internal'] }
9
+ let(:cidrs) { last_request.env['entrance.internal_cidrs'] }
9
10
 
10
- let(:app) { Rack::Entrance.new(inner_app) }
11
+ before do
12
+ ENV['ENTRANCE_INTERNAL_CIDRS'] = '192.0.2.0/24,198.51.100.0/32'
13
+ end
11
14
 
12
- context 'internal request' do
15
+ context 'missing ENV' do
13
16
  before do
14
- ENV['ENTRANCE_INTERNAL_IPS'] = '127.0.0.1,203.0.113.255'
17
+ ENV['ENTRANCE_INTERNAL_CIDRS'] = nil
15
18
  get '/'
16
19
  end
17
20
 
18
- it 'sets internal to true' do
19
- last_request.env['entrance.internal'].should be_true
21
+ it 'knows the user IP' do
22
+ expect(user_ip).to eq '127.0.0.1'
23
+ end
24
+
25
+ it 'has no cirds' do
26
+ expect(cidrs).to be_empty
27
+ end
28
+
29
+ it 'is external' do
30
+ expect(internal).to be false
20
31
  end
21
32
  end
22
33
 
23
- context 'internal request by prefix' do
34
+ context 'invalid ENV' do
24
35
  before do
25
- ENV['ENTRANCE_INTERNAL_IPS'] = '203.0.113.255,127.0.'
36
+ ENV['ENTRANCE_INTERNAL_CIDRS'] = 'but,why?,198.51.100.0/24,weird,,'
26
37
  get '/'
27
38
  end
28
39
 
29
- it 'sets internal to true' do
30
- last_request.env['entrance.internal'].should be_true
40
+ it 'knows the user IP' do
41
+ expect(user_ip).to eq '127.0.0.1'
42
+ end
43
+
44
+ it 'knows the original cidrs' do
45
+ expect(cidrs).to eq %w(but why? 198.51.100.0/24 weird)
46
+ end
47
+
48
+ it 'is external' do
49
+ expect(internal).to be false
31
50
  end
32
51
  end
33
52
 
34
- context 'external request' do
53
+ context 'invalid user IP' do
35
54
  before do
36
- ENV['ENTRANCE_INTERNAL_IPS'] = '192.0.2.21,203.0.113.255'
37
- get '/'
55
+ get '/', {}, 'action_dispatch.remote_ip' => 'what the?'
38
56
  end
39
57
 
40
- it 'sets internal to false' do
41
- last_request.env['entrance.internal'].should be_false
58
+ it 'has no user IP' do
59
+ expect(user_ip).to be nil
60
+ end
61
+
62
+ it 'knows the cidrs' do
63
+ expect(cidrs).to eq %w(192.0.2.0/24 198.51.100.0/32)
64
+ end
65
+
66
+ it 'is external' do
67
+ expect(internal).to be false
42
68
  end
43
69
  end
44
70
 
45
- context 'no env variable set' do
71
+ context 'internal request' do
46
72
  before do
47
- ENV['ENTRANCE_INTERNAL_IPS'] = nil
48
- get '/'
73
+ get '/', {}, 'action_dispatch.remote_ip' => '192.0.2.42'
74
+ end
75
+
76
+ it 'knows the user IP' do
77
+ expect(user_ip).to eq '192.0.2.42'
78
+ end
79
+
80
+ it 'knows the cidrs' do
81
+ expect(cidrs).to eq %w(192.0.2.0/24 198.51.100.0/32)
82
+ end
83
+
84
+ it 'is internal' do
85
+ expect(internal).to be true
86
+ end
87
+ end
88
+
89
+ context 'external request from same subnet in /16 range' do
90
+ before do
91
+ get '/', {}, 'action_dispatch.remote_ip' => '192.0.3.0'
92
+ end
93
+
94
+ it 'knows the user IP' do
95
+ expect(user_ip).to eq '192.0.3.0'
96
+ end
97
+
98
+ it 'knows the cidrs' do
99
+ expect(cidrs).to eq %w(192.0.2.0/24 198.51.100.0/32)
100
+ end
101
+
102
+ it 'is external' do
103
+ expect(internal).to be false
104
+ end
105
+ end
106
+
107
+ context 'external request from same subnet in /24 range' do
108
+ before do
109
+ get '/', {}, 'action_dispatch.remote_ip' => '198.51.101.0'
110
+ end
111
+
112
+ it 'knows the user IP' do
113
+ expect(user_ip).to eq '198.51.101.0'
114
+ end
115
+
116
+ it 'knows the cidrs' do
117
+ expect(cidrs).to eq %w(192.0.2.0/24 198.51.100.0/32)
118
+ end
119
+
120
+ it 'is external' do
121
+ expect(internal).to be false
122
+ end
123
+ end
124
+
125
+ context 'external request' do
126
+ before do
127
+ get '/', {}, 'action_dispatch.remote_ip' => '203.0.113.99'
128
+ end
129
+
130
+ it 'knows the user IP' do
131
+ expect(user_ip).to eq '203.0.113.99'
132
+ end
133
+
134
+ it 'knows the cidrs' do
135
+ expect(cidrs).to eq %w(192.0.2.0/24 198.51.100.0/32)
49
136
  end
50
137
 
51
- it 'sets internal to false' do
52
- last_request.env['entrance.internal'].should be_false
138
+ it 'is external' do
139
+ expect(internal).to be false
53
140
  end
54
141
  end
55
142
 
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,10 @@
1
1
  require 'rack/test'
2
2
  require 'rack/entrance'
3
+
4
+ RSpec.configure do |config|
5
+
6
+ include Rack::Test::Methods
7
+
8
+ config.raise_errors_for_deprecations!
9
+
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-entrance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-28 00:00:00.000000000 Z
12
+ date: 2014-09-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack