rack-entrance 0.0.4 → 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.
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