floodgate 0.0.7 → 0.0.8
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 +4 -4
- data/lib/floodgate/client.rb +11 -0
- data/lib/floodgate/config.rb +29 -0
- data/lib/floodgate/control.rb +33 -0
- data/lib/floodgate/version.rb +1 -1
- data/lib/floodgate.rb +3 -30
- data/spec/lib/floodgate/client_spec.rb +38 -0
- data/spec/lib/floodgate/config_spec.rb +43 -0
- data/spec/lib/floodgate/control_spec.rb +82 -0
- metadata +11 -4
- data/spec/floodgate_spec.rb +0 -111
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77b129e9d0e4ead27720019cd03c5b97a20270d2
|
4
|
+
data.tar.gz: af2b0d06583f2747a038ccbe4640c2ff708d884a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37ef2355c6421b1e6e8cad329ce01be0e54215631dafe761081e3784d6813e3e75bc0a0da21eecd9ef1746a88141aea1a59990e227d7db5f8d0a9042c0dae2eb
|
7
|
+
data.tar.gz: 0b19d251bff0fb95b28f35766f798180e7fe087889a015ebcddaec78a8a76f5785ba32c4886691df36b48f57bf214401a5ec1d19d80a0ed0cc230de65c2c39fa
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
module Floodgate
|
5
|
+
class Client
|
6
|
+
def self.status(app_id, api_token)
|
7
|
+
# TODO: Handle errors, timeouts, proxies, environments, etc.
|
8
|
+
JSON.parse(open("http://floodgate-api-staging.herokuapp.com/api/v1/apps/#{app_id}/status?token=#{api_token}").read)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# TODO: Use a real client real soon now, but not now
|
2
|
+
require 'open-uri'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Floodgate
|
6
|
+
class Config
|
7
|
+
attr_accessor :app_id, :api_token, :filter_traffic, :redirect_url
|
8
|
+
|
9
|
+
def initialize(app_id, api_token)
|
10
|
+
@app_id = app_id
|
11
|
+
@api_token = api_token
|
12
|
+
|
13
|
+
json = Client.status(app_id, api_token)
|
14
|
+
|
15
|
+
@filter_traffic = json['filter_traffic']
|
16
|
+
@redirect_url = json['redirect_url']
|
17
|
+
end
|
18
|
+
|
19
|
+
def redirect?
|
20
|
+
!redirect_url.nil? && !redirect_url.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def filter_traffic?(env)
|
24
|
+
filter_traffic
|
25
|
+
|
26
|
+
# TODO: Use env
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Floodgate
|
2
|
+
class Control
|
3
|
+
attr_accessor :app, :config
|
4
|
+
|
5
|
+
def initialize(app, app_id, api_token)
|
6
|
+
@app = app
|
7
|
+
@config = Config.new(app_id, api_token)
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
return app.call(env) unless filter_traffic?(env)
|
12
|
+
|
13
|
+
if redirect?
|
14
|
+
[307, { 'Location' => redirect_url }, []]
|
15
|
+
else
|
16
|
+
[503, {}, ['Application Unavailable']]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def filter_traffic?(env)
|
21
|
+
config.filter_traffic?(env)
|
22
|
+
end
|
23
|
+
|
24
|
+
def redirect?
|
25
|
+
config.redirect?
|
26
|
+
end
|
27
|
+
|
28
|
+
def redirect_url
|
29
|
+
config.redirect_url
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
data/lib/floodgate/version.rb
CHANGED
data/lib/floodgate.rb
CHANGED
@@ -1,32 +1,5 @@
|
|
1
|
+
require 'floodgate/client'
|
2
|
+
require 'floodgate/config'
|
3
|
+
require 'floodgate/control'
|
1
4
|
require 'floodgate/version'
|
2
5
|
|
3
|
-
module Floodgate
|
4
|
-
class Control
|
5
|
-
def initialize(app)
|
6
|
-
@app = app
|
7
|
-
end
|
8
|
-
|
9
|
-
def call(env)
|
10
|
-
return @app.call(env) unless filter_traffic?
|
11
|
-
|
12
|
-
if redirect?
|
13
|
-
[307, { 'Location' => redirect_url }, []]
|
14
|
-
else
|
15
|
-
[503, {}, ['Application Unavailable']]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def filter_traffic?
|
20
|
-
!(ENV['FLOODGATE_FILTER_TRAFFIC'].nil? || ENV['FLOODGATE_FILTER_TRAFFIC'] == '')
|
21
|
-
end
|
22
|
-
|
23
|
-
def redirect?
|
24
|
-
!(redirect_url.nil? || redirect_url == '')
|
25
|
-
end
|
26
|
-
|
27
|
-
def redirect_url
|
28
|
-
ENV['MAINTENANCE_PAGE_URL']
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Floodgate
|
4
|
+
describe Client do
|
5
|
+
let(:json) { Client.status(app_id, api_token) }
|
6
|
+
|
7
|
+
describe '.status' do
|
8
|
+
context 'when the credentials are not valid' do
|
9
|
+
let(:app_id) { 'foo' }
|
10
|
+
let(:api_token) { 'bar' }
|
11
|
+
|
12
|
+
it 'is an error' do
|
13
|
+
expect { json }.to raise_error(OpenURI::HTTPError)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the credentials are valid' do
|
18
|
+
context 'and traffic filtering is enabled' do
|
19
|
+
let(:app_id) { 'fa5d63bcf3d6b557eee782c9e61e4002' }
|
20
|
+
let(:api_token) { 'da2f2d06c102eea0f1971c2c90936ee3' }
|
21
|
+
|
22
|
+
it 'filter_traffic is true' do
|
23
|
+
expect(json['filter_traffic']).to be_true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'and traffic filtering is not enabled' do
|
28
|
+
let(:app_id) { 'cbaeb13b7f63956ef70c382a7a67407d' }
|
29
|
+
let(:api_token) { '349d2b1ee8ec56eb04b909b1eb9993b0' }
|
30
|
+
|
31
|
+
it 'filter_traffic is false' do
|
32
|
+
expect(json['filter_traffic']).to be_false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Floodgate
|
4
|
+
describe Config do
|
5
|
+
before { Client.stub(:status).and_return json }
|
6
|
+
|
7
|
+
let(:json) do
|
8
|
+
{
|
9
|
+
'filter_traffic' => filter_traffic,
|
10
|
+
'redirect_url' => redirect_url
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:filter_traffic) { false }
|
15
|
+
let(:redirect_url) { nil }
|
16
|
+
let(:app_id) { 'abc123' }
|
17
|
+
let(:api_token) { 'def456' }
|
18
|
+
let(:config) { Config.new(app_id, api_token) }
|
19
|
+
|
20
|
+
context 'when redirect_url is an empty string' do
|
21
|
+
let(:filter_traffic) { false }
|
22
|
+
let(:redirect_url) { '' }
|
23
|
+
|
24
|
+
describe '#redirect?' do
|
25
|
+
it 'is false' do
|
26
|
+
expect(config.redirect?).to be_false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when a redirect_url is specified' do
|
32
|
+
let(:filter_traffic) { false }
|
33
|
+
let(:redirect_url) { 'someurl' }
|
34
|
+
|
35
|
+
describe '#redirect?' do
|
36
|
+
it 'is true' do
|
37
|
+
expect(config.redirect?).to be_true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Floodgate
|
4
|
+
describe Control do
|
5
|
+
let(:app) { double().as_null_object }
|
6
|
+
let(:control) { Control.new(app, app_id, api_token) }
|
7
|
+
let(:env) { Hash.new }
|
8
|
+
let(:app_id) { 'abc123' }
|
9
|
+
let(:api_token) { 'def456' }
|
10
|
+
let(:filter_traffic) { false }
|
11
|
+
let(:redirect_url) { 'something' }
|
12
|
+
let(:json) do
|
13
|
+
{
|
14
|
+
'filter_traffic' => filter_traffic,
|
15
|
+
'redirect_url' => redirect_url
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
before { Client.stub(:status).and_return json }
|
20
|
+
|
21
|
+
describe '#call' do
|
22
|
+
it 'sends :call to the app with the specified environment' do
|
23
|
+
expect(app).to receive(:call).with(env)
|
24
|
+
control.call(env)
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when the filter_traffic is true' do
|
28
|
+
let(:filter_traffic) { true }
|
29
|
+
|
30
|
+
it 'does not send :call to the app' do
|
31
|
+
expect(app).not_to receive(:call).with(env)
|
32
|
+
control.call(env)
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when no redirect url is specified' do
|
36
|
+
let(:redirect_url) { nil }
|
37
|
+
|
38
|
+
it 'responds with a status of service unavailable' do
|
39
|
+
expect(control.call(env)[0]).to eq(503)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'has an appropriate message in the response' do
|
43
|
+
expect(control.call(env)[2]).to eq(['Application Unavailable'])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when a redirect url is specified' do
|
48
|
+
let(:redirect_url) { 'someurl' }
|
49
|
+
|
50
|
+
it 'redirects with a temporary redirect status' do
|
51
|
+
expect(control.call(env)[0]).to eq(307)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'has a location set to the maintenance page' do
|
55
|
+
expect(control.call(env)[1]['Location']).to eq('someurl')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#filter_traffic?' do
|
62
|
+
it 'delegates to config' do
|
63
|
+
expect(control.config).to receive(:filter_traffic?).with(env).and_return 'some boolean value'
|
64
|
+
expect(control.filter_traffic?(env)).to eq 'some boolean value'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#redirect?' do
|
69
|
+
it 'delegates to config' do
|
70
|
+
expect(control.config).to receive(:redirect?).and_return 'some boolean value'
|
71
|
+
expect(control.redirect?).to eq 'some boolean value'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#redirect_url' do
|
76
|
+
it 'delegates to config' do
|
77
|
+
expect(control.config).to receive(:redirect_url).and_return 'someurl'
|
78
|
+
expect(control.redirect_url).to eq 'someurl'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: floodgate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark McEahern
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-02-
|
12
|
+
date: 2014-02-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -70,8 +70,13 @@ files:
|
|
70
70
|
- Rakefile
|
71
71
|
- floodgate.gemspec
|
72
72
|
- lib/floodgate.rb
|
73
|
+
- lib/floodgate/client.rb
|
74
|
+
- lib/floodgate/config.rb
|
75
|
+
- lib/floodgate/control.rb
|
73
76
|
- lib/floodgate/version.rb
|
74
|
-
- spec/
|
77
|
+
- spec/lib/floodgate/client_spec.rb
|
78
|
+
- spec/lib/floodgate/config_spec.rb
|
79
|
+
- spec/lib/floodgate/control_spec.rb
|
75
80
|
- spec/spec_helper.rb
|
76
81
|
homepage: http://github.com/adorableio/floodgate
|
77
82
|
licenses:
|
@@ -98,5 +103,7 @@ signing_key:
|
|
98
103
|
specification_version: 4
|
99
104
|
summary: floodgate helps you control access to your app
|
100
105
|
test_files:
|
101
|
-
- spec/
|
106
|
+
- spec/lib/floodgate/client_spec.rb
|
107
|
+
- spec/lib/floodgate/config_spec.rb
|
108
|
+
- spec/lib/floodgate/control_spec.rb
|
102
109
|
- spec/spec_helper.rb
|
data/spec/floodgate_spec.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Floodgate
|
4
|
-
describe Control do
|
5
|
-
let(:app) { double().as_null_object }
|
6
|
-
let(:control) { described_class.new(app) }
|
7
|
-
let(:env) { Hash.new }
|
8
|
-
|
9
|
-
before do
|
10
|
-
ENV['FLOODGATE_FILTER_TRAFFIC'] = ''
|
11
|
-
ENV['MAINTENANCE_PAGE_URL'] = ''
|
12
|
-
end
|
13
|
-
|
14
|
-
after do
|
15
|
-
ENV['FLOODGATE_FILTER_TRAFFIC'] = ''
|
16
|
-
ENV['MAINTENANCE_PAGE_URL'] = ''
|
17
|
-
end
|
18
|
-
|
19
|
-
describe '#call' do
|
20
|
-
it 'sends :call to the app with the specified environment' do
|
21
|
-
expect(app).to receive(:call).with(env)
|
22
|
-
control.call(env)
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'when the floodgate is closed' do
|
26
|
-
before { ENV['FLOODGATE_FILTER_TRAFFIC'] = 'closed' }
|
27
|
-
|
28
|
-
let(:control) { described_class.new(app) }
|
29
|
-
|
30
|
-
it 'does not send :call to the app' do
|
31
|
-
expect(app).not_to receive(:call).with(env)
|
32
|
-
control.call(env)
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'when no maintenance page is specified in the environment' do
|
36
|
-
before { ENV['MAINTENANCE_PAGE_URL'] = '' }
|
37
|
-
|
38
|
-
it 'responds with a status of service unavailable' do
|
39
|
-
expect(control.call(env)[0]).to eq(503)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'has an appropriate message in the response' do
|
43
|
-
expect(control.call(env)[2]).to eq(['Application Unavailable'])
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context 'when a maintenance page is specified in the environment' do
|
48
|
-
before { ENV['MAINTENANCE_PAGE_URL'] = 'someurl' }
|
49
|
-
|
50
|
-
it 'redirects with a temporary redirect status' do
|
51
|
-
expect(control.call(env)[0]).to eq(307)
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'has a location set to the maintenance page' do
|
55
|
-
expect(control.call(env)[1]['Location']).to eq('someurl')
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe '#filter_traffic?' do
|
62
|
-
it 'returns false by default' do
|
63
|
-
expect(control.filter_traffic?).to eq(false)
|
64
|
-
end
|
65
|
-
|
66
|
-
context 'when traffic filtering is enabled in the environment' do
|
67
|
-
before { ENV['FLOODGATE_FILTER_TRAFFIC'] = 'closed' }
|
68
|
-
|
69
|
-
it 'returns true' do
|
70
|
-
expect(control.filter_traffic?).to eq(true)
|
71
|
-
end
|
72
|
-
|
73
|
-
after { ENV['FLOODGATE_FILTER_TRAFFIC'] = nil }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
describe '#redirect?' do
|
78
|
-
it 'is false by default' do
|
79
|
-
expect(control.redirect?).to eq(false)
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'when the redirect url is an empty string' do
|
83
|
-
before { control.stub(:redirect_url).and_return '' }
|
84
|
-
|
85
|
-
it 'is false' do
|
86
|
-
expect(control.redirect?).to eq(false)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context 'when the redirect url is a string' do
|
91
|
-
before { control.stub(:redirect_url).and_return 'someurl' }
|
92
|
-
|
93
|
-
it 'is true' do
|
94
|
-
expect(control.redirect?).to eq(true)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
describe '#redirect_url' do
|
100
|
-
context 'when a maintenance page is specified in the environment' do
|
101
|
-
before { ENV['MAINTENANCE_PAGE_URL'] = 'someurl' }
|
102
|
-
|
103
|
-
it 'returns the maintenance page url' do
|
104
|
-
expect(control.redirect_url).to eq('someurl')
|
105
|
-
end
|
106
|
-
|
107
|
-
after { ENV['MAINTENANCE_PAGE_URL'] = '' }
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|