mauth-client 5.1.0 → 6.0.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.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/CHANGELOG.md +8 -0
- data/CONTRIBUTING.md +8 -0
- data/doc/mauth.yml.md +7 -2
- data/lib/mauth/client.rb +14 -0
- data/lib/mauth/client/authenticator_base.rb +2 -1
- data/lib/mauth/client/signer.rb +2 -0
- data/lib/mauth/dice_bag/mauth.yml.dice +2 -0
- data/lib/mauth/request_and_response.rb +22 -6
- data/lib/mauth/version.rb +1 -1
- data/mauth-client.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ac6251a66453ac4fe6f1f449d407173851a6c34e3dd17bf3b80d816e619e045
|
4
|
+
data.tar.gz: bf6f603408e51a6af3965e458f736ee3ed07763a7f0a662f1af0bd67a1cbeab3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4faea9d5bcf10c64b3c3bc10dded82d14b68bce39312b87140e38ba5410ba9d67b993f94e2e96036d7d88550837a6088d43deb75d7e4fed8164b51ed81b296c
|
7
|
+
data.tar.gz: a7a71824118eb6b4ca88a7f8a7afdb85719613997754392147dfa348eae7c04faf4ba7458eb28375d8b596c6b609ecbe6e8c42d5caed4931b9427c843bbf9448
|
data/.rspec
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## v.6.0.0
|
2
|
+
- Added parsing code to test with mauth-protocol-test-suite.
|
3
|
+
- Added unescape step in query_string encoding in order to remove 'double encoding'.
|
4
|
+
- Added normalization of paths.
|
5
|
+
- Added flag to sign only with V1.
|
6
|
+
- Changed V2 to V1 fallback to be configurable.
|
7
|
+
- Fixed bug in sorting query parameters.
|
8
|
+
|
1
9
|
## v5.1.0
|
2
10
|
- Fall back to V1 when V2 authentication fails.
|
3
11
|
|
data/CONTRIBUTING.md
CHANGED
@@ -19,6 +19,14 @@ Next, run the tests:
|
|
19
19
|
bundle exec rspec
|
20
20
|
```
|
21
21
|
|
22
|
+
# Running mauth-protocol-test-suite
|
23
|
+
|
24
|
+
To run the mauth-protocol-test-suite clone the latest test suite onto your machine and place it in the same parent directory as this repo (or supply the ENV var `TEST_SUITE_RELATIVE_PATH` with the path to the test suite relative to this repo). Then run:
|
25
|
+
|
26
|
+
```
|
27
|
+
bundle exec rspec --tag protocol_suite
|
28
|
+
```
|
29
|
+
|
22
30
|
## Running Benchmark
|
23
31
|
|
24
32
|
If you make changes which could affect performance, please run the benchmark before and after the change as a sanity check.
|
data/doc/mauth.yml.md
CHANGED
@@ -31,6 +31,7 @@ common: &common
|
|
31
31
|
-----END RSA PRIVATE KEY-----
|
32
32
|
v2_only_authenticate: false
|
33
33
|
v2_only_sign_requests: false
|
34
|
+
disable_fallback_to_v1_on_v2_failure: true
|
34
35
|
|
35
36
|
production:
|
36
37
|
<<: *common
|
@@ -50,6 +51,8 @@ common: &common
|
|
50
51
|
private_key_file: config/my_mauth_private.key
|
51
52
|
v2_only_authenticate: false
|
52
53
|
v2_only_sign_requests: false
|
54
|
+
disable_fallback_to_v1_on_v2_failure: true
|
55
|
+
v1_only_sign_requests: false
|
53
56
|
|
54
57
|
production:
|
55
58
|
<<: *common
|
@@ -66,8 +69,10 @@ test:
|
|
66
69
|
- `app_uuid` - Required in the same circumstances where a `private_key` is required.
|
67
70
|
- `mauth_baseurl` - Required for authentication but not for signing. Needed for local authentication to retrieve public keys and for remote authentication. Usually this is `https://mauth.imedidata.com` for production.
|
68
71
|
- `mauth_api_version` - Required for authentication but not for signing. only `v1` exists as of this writing.
|
69
|
-
- `
|
70
|
-
- `
|
72
|
+
- `v2_only_sign_requests` - If true, all outgoing requests will be signed with only the V2 protocol. Defaults to false.
|
73
|
+
- `v2_only_authenticate` - If true, any incoming request or incoming response that does not use the V2 protocol will be rejected. Defaults to false.
|
74
|
+
- `disable_fallback_to_v1_on_v2_failure` - If true, any incoming V2 requests that fail authentication will not fall back to V1 authentication. Defaults to false.
|
75
|
+
- `v1_only_sign_requests` - If true, all outgoing requests will be signed with only the V1 protocol. Defaults to true. Note, cannot be `true` if `v2_only_sign_requests` is also `true`.
|
71
76
|
|
72
77
|
## Usage in your application
|
73
78
|
|
data/lib/mauth/client.rb
CHANGED
@@ -153,6 +153,12 @@ module MAuth
|
|
153
153
|
@config['ssl_certs_path'] = given_config['ssl_certs_path'] if given_config['ssl_certs_path']
|
154
154
|
@config['v2_only_authenticate'] = given_config['v2_only_authenticate'].to_s.downcase == 'true'
|
155
155
|
@config['v2_only_sign_requests'] = given_config['v2_only_sign_requests'].to_s.downcase == 'true'
|
156
|
+
@config['disable_fallback_to_v1_on_v2_failure'] = given_config['disable_fallback_to_v1_on_v2_failure'].to_s.downcase == 'true'
|
157
|
+
@config['v1_only_sign_requests'] = given_config['v1_only_sign_requests'].to_s.downcase == 'true'
|
158
|
+
|
159
|
+
if @config['v2_only_sign_requests'] && @config['v1_only_sign_requests']
|
160
|
+
raise MAuth::Client::ConfigurationError, "v2_only_sign_requests and v1_only_sign_requests may not both be true"
|
161
|
+
end
|
156
162
|
|
157
163
|
# if 'authenticator' was given, don't override that - including if it was given as nil / false
|
158
164
|
if given_config.key?('authenticator')
|
@@ -205,6 +211,14 @@ module MAuth
|
|
205
211
|
@config['v2_only_authenticate']
|
206
212
|
end
|
207
213
|
|
214
|
+
def disable_fallback_to_v1_on_v2_failure?
|
215
|
+
@config['disable_fallback_to_v1_on_v2_failure']
|
216
|
+
end
|
217
|
+
|
218
|
+
def v1_only_sign_requests?
|
219
|
+
@config['v1_only_sign_requests']
|
220
|
+
end
|
221
|
+
|
208
222
|
def assert_private_key(err)
|
209
223
|
raise err unless private_key
|
210
224
|
end
|
@@ -19,13 +19,14 @@ module MAuth
|
|
19
19
|
|
20
20
|
# raises InauthenticError unless the given object is authentic. Will only
|
21
21
|
# authenticate with v2 if the environment variable V2_ONLY_AUTHENTICATE
|
22
|
-
# is set. Otherwise will
|
22
|
+
# is set. Otherwise will fall back to v1 when v2 authentication fails
|
23
23
|
def authenticate!(object)
|
24
24
|
if object.protocol_version == 2
|
25
25
|
begin
|
26
26
|
authenticate_v2!(object)
|
27
27
|
rescue InauthenticError => e
|
28
28
|
raise e if v2_only_authenticate?
|
29
|
+
raise e if disable_fallback_to_v1_on_v2_failure?
|
29
30
|
|
30
31
|
object.fall_back_to_mws_signature_info
|
31
32
|
raise e unless object.signature
|
data/lib/mauth/client/signer.rb
CHANGED
@@ -30,6 +30,8 @@ module MAuth
|
|
30
30
|
def signed_headers(object, attributes = {})
|
31
31
|
if v2_only_sign_requests?
|
32
32
|
signed_headers_v2(object, attributes)
|
33
|
+
elsif v1_only_sign_requests?
|
34
|
+
signed_headers_v1(object, attributes)
|
33
35
|
else # by default sign with both the v1 and v2 protocol
|
34
36
|
signed_headers_v1(object, attributes).merge(signed_headers_v2(object, attributes))
|
35
37
|
end
|
@@ -7,6 +7,8 @@ common: &common
|
|
7
7
|
private_key_file: config/mauth_key
|
8
8
|
v2_only_authenticate: <%= configured.v2_only_authenticate || 'false' %>
|
9
9
|
v2_only_sign_requests: <%= configured.v2_only_sign_requests || 'false' %>
|
10
|
+
disable_fallback_to_v1_on_v2_failure: <%= configured.disable_fallback_to_v1_on_v2_failure || 'false' %>
|
11
|
+
v1_only_sign_requests: <%= configured.v1_only_sign_requests || 'true' %>
|
10
12
|
|
11
13
|
production:
|
12
14
|
<<: *common
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'digest'
|
2
|
+
require 'addressable'
|
2
3
|
|
3
4
|
module MAuth
|
4
5
|
# module which composes a string to sign.
|
@@ -61,7 +62,8 @@ module MAuth
|
|
61
62
|
# string_to_sign_v2 three times in client#signature_valid_v2!
|
62
63
|
# note that if :body is nil we hash an empty string ('')
|
63
64
|
attrs_with_overrides[:body_digest] ||= Digest::SHA512.hexdigest(attrs_with_overrides[:body] || '')
|
64
|
-
attrs_with_overrides[:encoded_query_params] =
|
65
|
+
attrs_with_overrides[:encoded_query_params] = unescape_encode_query_string(attrs_with_overrides[:query_string] || '')
|
66
|
+
attrs_with_overrides[:request_url] = normalize_path(attrs_with_overrides[:request_url])
|
65
67
|
|
66
68
|
missing_attributes = self.class::SIGNATURE_COMPONENTS_V2.reject do |key|
|
67
69
|
attrs_with_overrides.dig(key)
|
@@ -78,12 +80,26 @@ module MAuth
|
|
78
80
|
end.join("\n")
|
79
81
|
end
|
80
82
|
|
83
|
+
# Addressable::URI.parse(path).normalize.to_s.squeeze('/')
|
84
|
+
def normalize_path(path)
|
85
|
+
return if path.nil?
|
86
|
+
|
87
|
+
# Addressable::URI.normalize_path normalizes `.` and `..` in path
|
88
|
+
# i.e. /./example => /example ; /example/.. => /
|
89
|
+
# String#squeeze removes duplicated slahes i.e. /// => /
|
90
|
+
# String#gsub normalizes percent encoding to uppercase i.e. %cf%80 => %CF%80
|
91
|
+
Addressable::URI.normalize_path(path).squeeze('/').
|
92
|
+
gsub(/%[a-f0-9]{2}/, &:upcase)
|
93
|
+
end
|
94
|
+
|
81
95
|
# sorts query string parameters by codepoint, uri encodes keys and values,
|
82
96
|
# and rejoins parameters into a query string
|
83
|
-
def
|
84
|
-
q_string.split('&').
|
85
|
-
k,
|
86
|
-
|
97
|
+
def unescape_encode_query_string(q_string)
|
98
|
+
fir = q_string.split('&').map do |part|
|
99
|
+
k, _eq, v = part.partition('=')
|
100
|
+
[CGI.unescape(k), CGI.unescape(v)]
|
101
|
+
end.sort.map do |k, v|
|
102
|
+
"#{uri_escape(k)}=#{uri_escape(v)}"
|
87
103
|
end.join('&')
|
88
104
|
end
|
89
105
|
|
@@ -116,7 +132,7 @@ module MAuth
|
|
116
132
|
# - #x_mws_time
|
117
133
|
module Signed
|
118
134
|
# mauth_client will authenticate with the highest protocol version present and if authentication fails,
|
119
|
-
# will
|
135
|
+
# will fall back to lower protocol versions (if provided).
|
120
136
|
# returns a hash with keys :token, :app_uuid, and :signature parsed from the MCC-Authentication header
|
121
137
|
# if it is present and if not then the X-MWS-Authentication header if it is present.
|
122
138
|
# Note MWSV2 protocol no longer allows more than one space between the token and app uuid.
|
data/lib/mauth/version.rb
CHANGED
data/mauth-client.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_dependency 'coderay', '~> 1.0'
|
25
25
|
spec.add_dependency 'rack'
|
26
26
|
spec.add_dependency 'dice_bag', '>= 0.9', '< 2.0'
|
27
|
+
spec.add_dependency 'addressable', '~> 2.0'
|
27
28
|
|
28
29
|
spec.add_development_dependency 'bundler', '>= 1.17'
|
29
30
|
spec.add_development_dependency 'byebug'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mauth-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Szenher
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2020-
|
14
|
+
date: 2020-05-07 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: faraday
|
@@ -103,6 +103,20 @@ dependencies:
|
|
103
103
|
- - "<"
|
104
104
|
- !ruby/object:Gem::Version
|
105
105
|
version: '2.0'
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: addressable
|
108
|
+
requirement: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '2.0'
|
113
|
+
type: :runtime
|
114
|
+
prerelease: false
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '2.0'
|
106
120
|
- !ruby/object:Gem::Dependency
|
107
121
|
name: bundler
|
108
122
|
requirement: !ruby/object:Gem::Requirement
|
@@ -228,6 +242,7 @@ extra_rdoc_files: []
|
|
228
242
|
files:
|
229
243
|
- ".fossa.yml"
|
230
244
|
- ".gitignore"
|
245
|
+
- ".rspec"
|
231
246
|
- ".travis.yml"
|
232
247
|
- ".yardopts"
|
233
248
|
- CHANGELOG.md
|