escher-rack_middleware 0.2.0 → 0.3.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 +4 -4
- data/README.md +9 -0
- data/VERSION +1 -0
- data/escher-rack_middleware.gemspec +2 -5
- data/lib/escher/rack_middleware/default_options.rb +17 -0
- data/lib/escher/rack_middleware/include_path.rb +18 -0
- data/lib/escher/rack_middleware/include_paths/helper.rb +17 -0
- data/lib/escher/rack_middleware/version.rb +2 -1
- data/lib/escher/rack_middleware.rb +35 -10
- data/spec/escher/rack_middleware_spec.rb +29 -0
- data/spec/spec_helper.rb +100 -0
- metadata +26 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be0496a2d9fffdce4c6390d4e6d21994dccdcda2
|
4
|
+
data.tar.gz: a2ca061cbb91af559d81d39a14b7a4685bb0866a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc25a4f9901ec663bd4b0e54bc12a67fc623a498ea3b17e49606b66ddef5f5e3c28e84829de0914738b6085c3048f89933167a6458179dbdd37e035a1709ff90
|
7
|
+
data.tar.gz: d9beafe02fd7f23a4d225a28913e4340df0139ddb64267b05b4cfde4fcbcb03bacf3c5d5d8d1cff4f0b3bea01b62fa0e2ec02e847915855f532fca961f10703b
|
data/README.md
CHANGED
@@ -33,9 +33,18 @@ Escher::RackMiddleware.config do |c|
|
|
33
33
|
# this will be triggered every time a request hit your appication
|
34
34
|
c.add_credential_updater{ Escher::Keypool.new.get_key_db }
|
35
35
|
|
36
|
+
# autorization defaults to all paths
|
36
37
|
# this help you exclude path(s) if you dont want require authorization for every endpoint
|
37
38
|
c.add_exclude_path(/^\/*monitoring\//)
|
38
39
|
|
40
|
+
# Alternatively, you can just authorize some paths:
|
41
|
+
# this help you just include certain paths for authorization
|
42
|
+
# c.add_include_path(/^\/*integrations\//)
|
43
|
+
|
44
|
+
# NOTE: You can either use excluded paths or included_paths, using both will throw an
|
45
|
+
# exception.
|
46
|
+
|
47
|
+
|
39
48
|
end
|
40
49
|
|
41
50
|
use Escher::RackMiddleware
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.1
|
@@ -1,12 +1,8 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'escher/rack_middleware/version'
|
5
|
-
|
6
2
|
Gem::Specification.new do |spec|
|
7
3
|
|
8
4
|
spec.name = 'escher-rack_middleware'
|
9
|
-
spec.version =
|
5
|
+
spec.version = File.read(File.join(File.dirname(__FILE__),'VERSION'))
|
10
6
|
spec.authors = ['Adam Luzsi']
|
11
7
|
spec.email = ['aluzsi@emarsys.com']
|
12
8
|
spec.summary = %q{Escher authorization for rack based http servers}
|
@@ -23,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
23
19
|
spec.add_development_dependency 'rake'
|
24
20
|
spec.add_development_dependency 'spec'
|
25
21
|
|
22
|
+
spec.add_dependency 'rack'
|
26
23
|
spec.add_dependency 'escher', '>= 0.3.3'
|
27
24
|
|
28
25
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Escher::RackMiddleware::DefaultOptions
|
2
|
+
|
3
|
+
protected
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
def default_options
|
8
|
+
{
|
9
|
+
:logger => Escher::RackMiddleware.logger,
|
10
|
+
:excluded_paths => Escher::RackMiddleware.excluded_paths,
|
11
|
+
:included_paths => Escher::RackMiddleware.included_paths,
|
12
|
+
:escher_authenticators => Escher::RackMiddleware.escher_authenticators,
|
13
|
+
:credentials => Escher::RackMiddleware.credentials
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Escher::RackMiddleware::IncludePath
|
2
|
+
|
3
|
+
require 'escher/rack_middleware/include_paths/helper'
|
4
|
+
def self.extended(klass)
|
5
|
+
klass.__send__(:include, self::Helper)
|
6
|
+
end
|
7
|
+
|
8
|
+
def add_include_paths(*paths)
|
9
|
+
included_paths.push(*paths)
|
10
|
+
end
|
11
|
+
|
12
|
+
alias add_include_path add_include_paths
|
13
|
+
|
14
|
+
def included_paths
|
15
|
+
@included_paths ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Escher::RackMiddleware::IncludePath::Helper
|
2
|
+
|
3
|
+
def included_paths
|
4
|
+
@included_paths ||= self.class.included_paths.dup
|
5
|
+
end
|
6
|
+
|
7
|
+
def included_path?(path)
|
8
|
+
included_paths.any? do |matcher|
|
9
|
+
if matcher.is_a?(Regexp)
|
10
|
+
!!(path =~ matcher)
|
11
|
+
else
|
12
|
+
path == matcher.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -5,25 +5,28 @@ class Escher::RackMiddleware
|
|
5
5
|
require 'escher/rack_middleware/logging'
|
6
6
|
require 'escher/rack_middleware/credential'
|
7
7
|
require 'escher/rack_middleware/exclude_path'
|
8
|
+
require 'escher/rack_middleware/include_path'
|
8
9
|
require 'escher/rack_middleware/authenticator'
|
10
|
+
require 'escher/rack_middleware/default_options'
|
9
11
|
|
10
12
|
extend Logging
|
11
13
|
extend Credential
|
12
14
|
extend ExcludePath
|
15
|
+
extend IncludePath
|
13
16
|
extend Authenticator
|
17
|
+
include DefaultOptions
|
14
18
|
|
15
|
-
def initialize(app)
|
19
|
+
def initialize(app,options={})
|
16
20
|
@app = app
|
21
|
+
@options = default_options.merge(options)
|
17
22
|
end
|
18
23
|
|
19
24
|
def call(request_env)
|
20
|
-
|
21
|
-
unless excluded_path?(request_env['REQUEST_URI'])
|
25
|
+
if authorize_path?(::Rack::Utils.clean_path_info(request_env[::Rack::PATH_INFO]))
|
22
26
|
return unauthorized_response unless authorized?(request_env)
|
23
27
|
end
|
24
28
|
|
25
29
|
@app.call(request_env)
|
26
|
-
|
27
30
|
end
|
28
31
|
|
29
32
|
protected
|
@@ -35,13 +38,35 @@ class Escher::RackMiddleware
|
|
35
38
|
response.finish
|
36
39
|
end
|
37
40
|
|
38
|
-
def env_dump_string(request_env)
|
39
|
-
require 'yaml' unless defined?(YAML)
|
40
|
-
YAML.dump(request_env)
|
41
|
-
end
|
42
|
-
|
43
41
|
def self.config(&block)
|
44
42
|
block.call(self)
|
45
43
|
end
|
46
44
|
|
47
|
-
|
45
|
+
def authorize_path?(path)
|
46
|
+
case true
|
47
|
+
|
48
|
+
when paths_of(:included_paths, include: path)
|
49
|
+
true
|
50
|
+
|
51
|
+
when paths_of(:excluded_paths, include: path)
|
52
|
+
false
|
53
|
+
|
54
|
+
else
|
55
|
+
true
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def paths_of(option_key, h)
|
61
|
+
path = h[:include]
|
62
|
+
@options[option_key].any? do |matcher|
|
63
|
+
if matcher.is_a?(Regexp)
|
64
|
+
!!(path =~ matcher)
|
65
|
+
else
|
66
|
+
path == matcher.to_s
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Escher::RackMiddleware do
|
4
|
+
|
5
|
+
let(:escher_rack_middleware) { described_class }
|
6
|
+
|
7
|
+
it 'serves correct, Escher signed requests only' do
|
8
|
+
expect(get('/any_path').status).to eq 401
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'allow pass on valid request' do
|
12
|
+
expect(escher_signed_get('/').status).to eq 200
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should exclude the excluded paths' do
|
16
|
+
expect(get('/not_protected').status).to eq 200
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should include the included paths alike' do
|
20
|
+
expect(get('/protected').status).to eq 401
|
21
|
+
expect(escher_signed_get('/protected').status).to eq 200
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should include the included paths even on partial matching with exclude paths' do
|
25
|
+
expect(get('/unprotected_namespace/except_this_endpoint_which_is_included').status).to eq 401
|
26
|
+
expect(escher_signed_get('/unprotected_namespace/except_this_endpoint_which_is_included').status).to eq 200
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rack'
|
3
|
+
$LOAD_PATH.unshift(File.join(File.dirname(File.dirname(__FILE__)), 'lib'))
|
4
|
+
require 'escher/rack_middleware'
|
5
|
+
|
6
|
+
CREDENTIAL_SCOPE = 'a/b/c'
|
7
|
+
|
8
|
+
AUTH_OPTIONS = {
|
9
|
+
algo_prefix: 'AWS',
|
10
|
+
vendor_key: 'AWS',
|
11
|
+
auth_header_name: 'X-AWS-Auth',
|
12
|
+
date_header_name: 'X-AWS-Date'
|
13
|
+
}
|
14
|
+
|
15
|
+
require 'logger'
|
16
|
+
SPEC_LOGGER = Logger.new($stdout)
|
17
|
+
SPEC_LOGGER.level= Logger::Severity::UNKNOWN
|
18
|
+
|
19
|
+
Escher::RackMiddleware.config do |global_settings|
|
20
|
+
|
21
|
+
global_settings.logger = SPEC_LOGGER
|
22
|
+
|
23
|
+
global_settings.add_exclude_path '/not_protected', '/endpoint', /^\/unprotected_namespace/
|
24
|
+
global_settings.add_include_path '/protected', '/endpoint_path', '/unprotected_namespace/except_this_endpoint_which_is_included'
|
25
|
+
|
26
|
+
global_settings.add_credential_updater { {"a_b_v1" => "development_secret"} }
|
27
|
+
global_settings.add_escher_authenticator { Escher::Auth.new(CREDENTIAL_SCOPE, AUTH_OPTIONS) }
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
module SpecRackHelpers
|
33
|
+
|
34
|
+
def escher_signed_get(uri, opts={})
|
35
|
+
|
36
|
+
request_hash = {}
|
37
|
+
request_hash[:method] = 'GET'
|
38
|
+
request_hash[:uri] = uri
|
39
|
+
request_hash[:headers] = ({'host' => 'localhost'}.merge(opts[:headers] || {})).to_a
|
40
|
+
request_hash[:body] = opts[:body]
|
41
|
+
|
42
|
+
client = {:api_key_id => "a_b_v1", :api_secret => "development_secret"}
|
43
|
+
escher.sign!(request_hash, client)
|
44
|
+
|
45
|
+
env = {}
|
46
|
+
request_hash[:headers].each do |key, value|
|
47
|
+
env["HTTP_#{key.to_s.upcase}"]= value
|
48
|
+
end
|
49
|
+
|
50
|
+
env[:input]= request_hash[:body]
|
51
|
+
env['REQUEST_URI'] = uri
|
52
|
+
env['REQUEST_PATH'] = uri
|
53
|
+
env['REQUEST_METHOD'] = 'GET'
|
54
|
+
|
55
|
+
get(uri, env)
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def escher
|
60
|
+
Escher::Auth.new(CREDENTIAL_SCOPE, AUTH_OPTIONS)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get(*args)
|
64
|
+
::Rack::MockRequest.new(app).get(*args)
|
65
|
+
end
|
66
|
+
|
67
|
+
def app
|
68
|
+
builder = Rack::Builder.new
|
69
|
+
builder.use(escher_rack_middleware)
|
70
|
+
builder.run(rack_app)
|
71
|
+
builder.to_app
|
72
|
+
end
|
73
|
+
|
74
|
+
def rack_app
|
75
|
+
Proc.new do |env|
|
76
|
+
|
77
|
+
resp = Rack::Response.new
|
78
|
+
case env[::Rack::PATH_INFO]
|
79
|
+
|
80
|
+
when '/'
|
81
|
+
resp.write('default')
|
82
|
+
|
83
|
+
when '/protected', '/endpoint_path', '/unprotected_namespace/except_this_endpoint_which_is_included'
|
84
|
+
resp.write('included')
|
85
|
+
|
86
|
+
when '/not_protected', '/endpoint', /^\/unprotected_namespace/
|
87
|
+
resp.write('excluded')
|
88
|
+
|
89
|
+
else
|
90
|
+
resp.status = 404
|
91
|
+
|
92
|
+
end
|
93
|
+
resp.finish
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
RSpec.configuration.include(SpecRackHelpers)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: escher-rack_middleware
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Luzsi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: escher
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,17 +93,23 @@ files:
|
|
79
93
|
- LICENSE.txt
|
80
94
|
- README.md
|
81
95
|
- Rakefile
|
96
|
+
- VERSION
|
82
97
|
- escher-rack_middleware.gemspec
|
83
98
|
- lib/escher/rack_middleware.rb
|
84
99
|
- lib/escher/rack_middleware/authenticator.rb
|
85
100
|
- lib/escher/rack_middleware/authenticator/helper.rb
|
86
101
|
- lib/escher/rack_middleware/credential.rb
|
87
102
|
- lib/escher/rack_middleware/credential/helper.rb
|
103
|
+
- lib/escher/rack_middleware/default_options.rb
|
88
104
|
- lib/escher/rack_middleware/exclude_path.rb
|
89
105
|
- lib/escher/rack_middleware/exclude_paths/helper.rb
|
106
|
+
- lib/escher/rack_middleware/include_path.rb
|
107
|
+
- lib/escher/rack_middleware/include_paths/helper.rb
|
90
108
|
- lib/escher/rack_middleware/logging.rb
|
91
109
|
- lib/escher/rack_middleware/logging/helper.rb
|
92
110
|
- lib/escher/rack_middleware/version.rb
|
111
|
+
- spec/escher/rack_middleware_spec.rb
|
112
|
+
- spec/spec_helper.rb
|
93
113
|
homepage: https://github.com/emartech/escher-rack_middleware-ruby
|
94
114
|
licenses:
|
95
115
|
- MIT
|
@@ -110,8 +130,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
130
|
version: '0'
|
111
131
|
requirements: []
|
112
132
|
rubyforge_project:
|
113
|
-
rubygems_version: 2.
|
133
|
+
rubygems_version: 2.4.8
|
114
134
|
signing_key:
|
115
135
|
specification_version: 4
|
116
136
|
summary: Escher authorization for rack based http servers
|
117
|
-
test_files:
|
137
|
+
test_files:
|
138
|
+
- spec/escher/rack_middleware_spec.rb
|
139
|
+
- spec/spec_helper.rb
|