faraday_middleware-escher 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 +61 -13
- data/Rakefile +3 -0
- data/VERSION +1 -1
- data/faraday_middleware-escher.gemspec +4 -0
- data/lib/faraday/middleware/escher/base.rb +2 -2
- data/lib/faraday/middleware/escher/request_signer.rb +14 -2
- data/lib/faraday/middleware/escher/response_validator.rb +39 -1
- data/lib/faraday/middleware/escher.rb +1 -0
- data/lib/faraday_middleware/escher.rb +1 -2
- data/prototype/client.rb +33 -0
- data/prototype/config.ru +78 -0
- data/prototype/credentials.rb +8 -0
- data/spec/escher/base_spec.rb +1 -4
- data/spec/escher/request_signer_spec.rb +9 -12
- metadata +48 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 309400c40fea573a439eb25d11507914f2647b40
|
4
|
+
data.tar.gz: 613bb193f0e441cb8a57a30ad58591fca1fa4497
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0413f1b8ac0506c3565263967b74c32653d9a637bed589deb0f15bac9aa2db53e3738ce751fa4e07267f542cac7f4ddcb6a0aa57da2baa1f99f9281e9e13689
|
7
|
+
data.tar.gz: 62872e747ddb40fc8df37fb2a686c8c44d9495cd9e40dae3a6b527f3e51fcc9ad6ffa1d4a1c357bc3a1956969854a9b8b401c0d7bc3a48c3f24a59bb424a02b8
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# FaradayMiddleware
|
1
|
+
# FaradayMiddleware for Escher secure authorization
|
2
2
|
|
3
3
|
escher sign and validation for faraday http rest client
|
4
4
|
|
@@ -23,25 +23,73 @@ Or install it yourself as:
|
|
23
23
|
The FaradayMiddleware::Escher::RequestSigner will help you sign your requests before sending them
|
24
24
|
|
25
25
|
```ruby
|
26
|
-
|
27
|
-
|
28
|
-
require 'faraday_middleware/escher'
|
29
|
-
conn = Faraday.new do |builder|
|
30
|
-
|
31
|
-
builder.use Faraday::Middleware::Escher::RequestSigner, credential_scope: 'example/credential/scope' do
|
32
|
-
{api_key_id: 'EscherExample', api_secret: 'TheBeginningOfABeautifulFriendship'}
|
33
|
-
end
|
34
26
|
|
35
|
-
|
36
|
-
|
37
|
-
|
27
|
+
require 'faraday_middleware/escher'
|
28
|
+
|
29
|
+
conn = Faraday.new do |builder|
|
30
|
+
|
31
|
+
builder.use FaradayMiddleware::Escher::RequestSigner,
|
32
|
+
credential_scope: CredentialScope,
|
33
|
+
options: AuthOptions,
|
34
|
+
active_key: -> { Escher::Keypool.new.get_active_key('EscherExample') }
|
35
|
+
|
36
|
+
builder.adapter :net_http
|
37
|
+
|
38
|
+
|
39
|
+
end
|
38
40
|
|
39
41
|
```
|
40
42
|
|
41
43
|
|
42
44
|
### Response Validator
|
43
45
|
|
44
|
-
|
46
|
+
The FaradayMiddleware::Escher::ResponseValidator will help you authenticate responses on receiving
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
|
50
|
+
require 'faraday_middleware/escher'
|
51
|
+
|
52
|
+
conn = Faraday.new do |builder|
|
53
|
+
|
54
|
+
builder.use FaradayMiddleware::Escher::ResponseValidator,
|
55
|
+
credential_scope: CredentialScope,
|
56
|
+
options: AuthOptions,
|
57
|
+
keydb_constructor: -> { Escher::Keypool.new.get_key_db }
|
58
|
+
|
59
|
+
builder.adapter :net_http
|
60
|
+
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
```
|
65
|
+
|
66
|
+
### You can mix the two in one case
|
67
|
+
|
68
|
+
Who loves Man in the Middle?
|
69
|
+
If you not, this is your setup!
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
|
73
|
+
require 'faraday_middleware/escher'
|
74
|
+
|
75
|
+
conn = Faraday.new do |builder|
|
76
|
+
|
77
|
+
builder.use FaradayMiddleware::Escher::RequestSigner,
|
78
|
+
credential_scope: CredentialScope,
|
79
|
+
options: AuthOptions,
|
80
|
+
active_key: -> { Escher::Keypool.new.get_active_key('EscherExample') }
|
81
|
+
|
82
|
+
builder.use FaradayMiddleware::Escher::ResponseValidator,
|
83
|
+
credential_scope: CredentialScope,
|
84
|
+
options: AuthOptions,
|
85
|
+
keydb_constructor: -> { Escher::Keypool.new.get_key_db }
|
86
|
+
|
87
|
+
builder.adapter :net_http
|
88
|
+
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
```
|
45
93
|
|
46
94
|
## Contributing
|
47
95
|
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.1
|
@@ -20,6 +20,10 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.add_development_dependency('rspec')
|
21
21
|
spec.add_development_dependency('webmock')
|
22
22
|
|
23
|
+
spec.add_development_dependency('rack')
|
24
|
+
spec.add_development_dependency('escher-keypool')
|
25
|
+
spec.add_development_dependency('escher-rack_middleware')
|
26
|
+
|
23
27
|
spec.add_dependency('faraday')
|
24
28
|
spec.add_dependency('escher')
|
25
29
|
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'socket'
|
2
|
+
require 'faraday/middleware/escher'
|
2
3
|
class Faraday::Middleware::Escher::Base < Faraday::Middleware
|
3
4
|
|
4
|
-
def initialize(app,options={}
|
5
|
+
def initialize(app,options={})
|
5
6
|
|
6
7
|
super(app)
|
7
8
|
@host = options[:host] || Socket.gethostname
|
8
9
|
|
9
10
|
@escher_options = options[:options] || {}
|
10
11
|
@escher_credential_scope = options[:credential_scope] || raise(ArgumentError,'missing escher credential scope!')
|
11
|
-
@escher_keydb_constructor = escher_keydb_constructor || raise(ArgumentError,'missing escher constructor')
|
12
12
|
|
13
13
|
end
|
14
14
|
|
@@ -1,14 +1,26 @@
|
|
1
|
+
require 'faraday/middleware/escher'
|
1
2
|
class Faraday::Middleware::Escher::RequestSigner < Faraday::Middleware::Escher::Base
|
2
3
|
|
4
|
+
def initialize(app,options={},&active_key)
|
5
|
+
|
6
|
+
super(app,options)
|
7
|
+
|
8
|
+
active_key_cons = active_key || options[:active_key] || options[:key]
|
9
|
+
raise('Escher active key constructor must be a lambda/block') unless active_key_cons.is_a?(Proc)
|
10
|
+
@escher_active_key_constructor = active_key_cons
|
11
|
+
|
12
|
+
end
|
13
|
+
|
3
14
|
def call(env)
|
4
15
|
|
5
16
|
escher = ::Escher::Auth.new(@escher_credential_scope, @escher_options)
|
6
17
|
|
7
18
|
uri_path = env[:url].path
|
8
19
|
endpoint = uri_path.empty? ? '/' : uri_path
|
20
|
+
endpoint_with_query = [endpoint,env[:url].query].join('?')
|
9
21
|
|
10
22
|
request_data = {
|
11
|
-
uri:
|
23
|
+
uri: endpoint_with_query,
|
12
24
|
method: env[:method].to_s.upcase,
|
13
25
|
headers: env[:request_headers].map{|k,v| [k,v] }.push(['host',@host])
|
14
26
|
}
|
@@ -17,7 +29,7 @@ class Faraday::Middleware::Escher::RequestSigner < Faraday::Middleware::Escher::
|
|
17
29
|
|
18
30
|
escher.sign!(
|
19
31
|
request_data,
|
20
|
-
@
|
32
|
+
@escher_active_key_constructor.call,
|
21
33
|
request_data[:headers].map{|ary| ary[0] }
|
22
34
|
)
|
23
35
|
|
@@ -1,2 +1,40 @@
|
|
1
|
-
|
1
|
+
require 'faraday/middleware/escher'
|
2
|
+
class Faraday::Middleware::Escher::ResponseValidator < Faraday::Middleware::Escher::Base
|
3
|
+
|
4
|
+
def initialize(app,options={},&keydb_as_block)
|
5
|
+
|
6
|
+
super(app,options)
|
7
|
+
|
8
|
+
keydb_constructor = keydb_as_block || options[:keydb_constructor] || options[:keydb]
|
9
|
+
raise('Key DB constuctor must be a lambda/block') unless keydb_constructor.is_a?(Proc)
|
10
|
+
@escher_active_key_constructor = keydb_constructor
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(request_env)
|
15
|
+
@app.call(request_env).on_complete do |env_on_response|
|
16
|
+
authenticate_env!(env_on_response)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def authenticate_env!(env_on_response)
|
23
|
+
|
24
|
+
escher = ::Escher::Auth.new(@escher_credential_scope, @escher_options)
|
25
|
+
|
26
|
+
url_path = env_on_response[:url].path
|
27
|
+
url_path = '/' if url_path.empty?
|
28
|
+
|
29
|
+
escher_hash_env = {
|
30
|
+
uri: url_path,
|
31
|
+
method: env_on_response[:method].to_s.upcase,
|
32
|
+
headers: env_on_response[:response_headers].map{|k,v| [k,v] }
|
33
|
+
}
|
34
|
+
|
35
|
+
escher_hash_env[:body] = env_on_response[:body] if env_on_response[:body]
|
36
|
+
escher.authenticate(escher_hash_env,@escher_active_key_constructor.call)
|
37
|
+
|
38
|
+
end
|
39
|
+
|
2
40
|
end
|
@@ -1,6 +1,4 @@
|
|
1
1
|
#backwardCompatibility
|
2
|
-
require 'faraday/middleware/escher'
|
3
|
-
|
4
2
|
begin
|
5
3
|
require 'faraday_middleware'
|
6
4
|
rescue LoadError
|
@@ -11,4 +9,5 @@ unless defined?(FaradayMiddleware)
|
|
11
9
|
end
|
12
10
|
end
|
13
11
|
|
12
|
+
require 'faraday/middleware/escher'
|
14
13
|
FaradayMiddleware::Escher ||= ::Faraday::Middleware::Escher
|
data/prototype/client.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.absolute_path(File.join(__dir__, '..', 'lib')))
|
2
|
+
|
3
|
+
require_relative 'credentials'
|
4
|
+
|
5
|
+
require 'faraday_middleware/escher'
|
6
|
+
|
7
|
+
conn = Faraday.new do |builder|
|
8
|
+
|
9
|
+
builder.use FaradayMiddleware::Escher::RequestSigner,
|
10
|
+
credential_scope: CredentialScope,
|
11
|
+
options: AuthOptions,
|
12
|
+
active_key: -> { Escher::Keypool.new.get_active_key('EscherExample') }
|
13
|
+
|
14
|
+
# builder.use FaradayMiddleware::Escher::ResponseValidator,
|
15
|
+
# credential_scope: CredentialScope,
|
16
|
+
# options: AuthOptions,
|
17
|
+
# keydb_constructor: -> { Escher::Keypool.new.get_key_db }
|
18
|
+
|
19
|
+
builder.adapter :net_http
|
20
|
+
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'json'
|
25
|
+
|
26
|
+
puts "\nResponse:",
|
27
|
+
conn.get { |r|
|
28
|
+
r.url('http://localhost:9292')
|
29
|
+
r.body='{ "name": "Unagi" }'
|
30
|
+
r.headers['X-Origin'] = JSON.generate(sender: 'cat', host: 'suite42')
|
31
|
+
r.params['kutya1']= 'cica1'
|
32
|
+
r.params['kutya2']= 'cica2'
|
33
|
+
}.body.inspect
|
data/prototype/config.ru
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative 'credentials'
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
require 'escher/rack_middleware'
|
5
|
+
Escher::RackMiddleware.config do |c|
|
6
|
+
c.add_escher_authenticator { Escher::Auth.new(CredentialScope, AuthOptions) }
|
7
|
+
c.add_credential_updater { Escher::Keypool.new.get_key_db }
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'socket'
|
11
|
+
class YourAwesomeApp
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
|
15
|
+
response = Rack::Response.new
|
16
|
+
response_payload = 'OK'
|
17
|
+
|
18
|
+
escher = ::Escher::Auth.new(CredentialScope, AuthOptions)
|
19
|
+
|
20
|
+
request_data = {
|
21
|
+
|
22
|
+
uri: '/',
|
23
|
+
method: 'GET',
|
24
|
+
headers: [['host',Socket.gethostname]],
|
25
|
+
body: response_payload
|
26
|
+
|
27
|
+
}
|
28
|
+
|
29
|
+
escher.sign!(
|
30
|
+
request_data,
|
31
|
+
Escher::Keypool.new.get_active_key( env['escher.request.api_key_id'] ),
|
32
|
+
response.headers.map { |k, _| k }
|
33
|
+
)
|
34
|
+
|
35
|
+
request_data[:headers].each do |key,value|
|
36
|
+
response.headers[key]=value
|
37
|
+
end
|
38
|
+
|
39
|
+
response.headers['kutya']='cica'
|
40
|
+
|
41
|
+
response.write response_payload
|
42
|
+
response.status = 200
|
43
|
+
response.finish
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
require 'yaml'
|
50
|
+
class EscherResponseSigner
|
51
|
+
|
52
|
+
def initialize(app,options={})
|
53
|
+
@app = app
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
def call(env)
|
59
|
+
rstatus,rheaders,rbody = @app.call(env)
|
60
|
+
response = Rack::Response.new(rbody,rstatus,rheaders)
|
61
|
+
|
62
|
+
<<-YAML
|
63
|
+
|
64
|
+
YAML
|
65
|
+
|
66
|
+
puts YAML.dump response
|
67
|
+
# puts YAML.dump response
|
68
|
+
|
69
|
+
|
70
|
+
response
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
use EscherResponseSigner
|
76
|
+
use Escher::RackMiddleware
|
77
|
+
|
78
|
+
run YourAwesomeApp.new
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'escher-keypool'
|
2
|
+
|
3
|
+
ENV['KEY_POOL'] = '[{"keyId":"EscherExample","secret":"TheBeginningOfABeautifulFriendship","acceptOnly":0}]'
|
4
|
+
ENV['ESCHEREXAMPLE_KEYID'] = 'EscherExample'
|
5
|
+
|
6
|
+
CredentialScope = 'example/credential/scope'
|
7
|
+
AuthOptions = {}
|
8
|
+
ESCHER_KEY = {api_key_id: 'EscherExample', api_secret: 'TheBeginningOfABeautifulFriendship'}
|
data/spec/escher/base_spec.rb
CHANGED
@@ -14,10 +14,7 @@ describe FaradayMiddleware::Escher::Base do
|
|
14
14
|
}
|
15
15
|
}
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
subject{ self.described_class.new(app,options) {key_db} }
|
17
|
+
subject{ self.described_class.new(app,options) }
|
21
18
|
|
22
19
|
before do
|
23
20
|
allow(Socket).to receive(:gethostname).and_return(host)
|
@@ -2,6 +2,8 @@ require_relative '../spec_helper'
|
|
2
2
|
describe Faraday::Middleware::Escher::RequestSigner do
|
3
3
|
describe 'this is a faraday middleware witch instance will response to call method' do
|
4
4
|
|
5
|
+
let(:key_db){{api_key_id: 'EscherExample', api_secret: 'TheBeginningOfABeautifulFriendship'}}
|
6
|
+
|
5
7
|
let(:api_key) { 'superKey' }
|
6
8
|
let(:api_secret) { 'superSecret' }
|
7
9
|
let(:host) { 'localhost' }
|
@@ -9,8 +11,13 @@ describe Faraday::Middleware::Escher::RequestSigner do
|
|
9
11
|
let(:target_url) { "http://api-with-escher.example.com" }
|
10
12
|
let(:stubs) { Faraday::Adapter::Test::Stubs.new }
|
11
13
|
|
12
|
-
let(:request_expectations){ -> env {} }
|
13
|
-
let(:response_expectations){ -> env {} }
|
14
|
+
let(:request_expectations){ -> env { @request_env = env } }
|
15
|
+
let(:response_expectations){ -> env { @response_env = env } }
|
16
|
+
|
17
|
+
before do
|
18
|
+
@request_env = nil
|
19
|
+
@response_env = nil
|
20
|
+
end
|
14
21
|
|
15
22
|
subject do
|
16
23
|
|
@@ -35,16 +42,6 @@ describe Faraday::Middleware::Escher::RequestSigner do
|
|
35
42
|
|
36
43
|
describe '#call' do
|
37
44
|
|
38
|
-
before do
|
39
|
-
@env = nil
|
40
|
-
end
|
41
|
-
|
42
|
-
let(:request_expectations) do
|
43
|
-
-> env do
|
44
|
-
@request_env = env
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
45
|
it 'should insert escher request headers for the call' do
|
49
46
|
|
50
47
|
expect( subject.get(target_url).status ).to eq 200
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faraday_middleware-escher
|
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: 2015-
|
11
|
+
date: 2015-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,48 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: escher-keypool
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: escher-rack_middleware
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
- !ruby/object:Gem::Dependency
|
70
112
|
name: faraday
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,6 +156,9 @@ files:
|
|
114
156
|
- lib/faraday/middleware/escher/request_signer.rb
|
115
157
|
- lib/faraday/middleware/escher/response_validator.rb
|
116
158
|
- lib/faraday_middleware/escher.rb
|
159
|
+
- prototype/client.rb
|
160
|
+
- prototype/config.ru
|
161
|
+
- prototype/credentials.rb
|
117
162
|
- spec/escher/base_spec.rb
|
118
163
|
- spec/escher/request_signer_spec.rb
|
119
164
|
- spec/spec_helper.rb
|
@@ -145,3 +190,4 @@ test_files:
|
|
145
190
|
- spec/escher/base_spec.rb
|
146
191
|
- spec/escher/request_signer_spec.rb
|
147
192
|
- spec/spec_helper.rb
|
193
|
+
has_rdoc:
|