mauth-client 6.4.3 → 7.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.
@@ -1,133 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # methods common to RemoteRequestAuthenticator and LocalAuthenticator
4
-
5
- module MAuth
6
- class Client
7
- module AuthenticatorBase
8
- ALLOWED_DRIFT_SECONDS = 300
9
-
10
- # takes an incoming request or response object, and returns whether
11
- # the object is authentic according to its signature.
12
- def authentic?(object)
13
- log_authentication_request(object)
14
- begin
15
- authenticate!(object)
16
- true
17
- rescue InauthenticError, MAuthNotPresent, MissingV2Error
18
- false
19
- end
20
- end
21
-
22
- # raises InauthenticError unless the given object is authentic. Will only
23
- # authenticate with v2 if the environment variable V2_ONLY_AUTHENTICATE
24
- # is set. Otherwise will fall back to v1 when v2 authentication fails
25
- def authenticate!(object)
26
- case object.protocol_version
27
- when 2
28
- begin
29
- authenticate_v2!(object)
30
- rescue InauthenticError => e
31
- raise e if v2_only_authenticate?
32
- raise e if disable_fallback_to_v1_on_v2_failure?
33
-
34
- object.fall_back_to_mws_signature_info
35
- raise e unless object.signature
36
-
37
- log_authentication_request(object)
38
- authenticate_v1!(object)
39
- logger.warn('Completed successful authentication attempt after fallback to v1')
40
- end
41
- when 1
42
- if v2_only_authenticate?
43
- # If v2 is required but not present and v1 is present we raise MissingV2Error
44
- msg = 'This service requires mAuth v2 mcc-authentication header but only v1 x-mws-authentication is present'
45
- logger.error(msg)
46
- raise MissingV2Error, msg
47
- end
48
-
49
- authenticate_v1!(object)
50
- else
51
- sub_str = v2_only_authenticate? ? '' : 'X-MWS-Authentication header is blank, '
52
- msg = "Authentication Failed. No mAuth signature present; #{sub_str}MCC-Authentication header is blank."
53
- logger.warn("mAuth signature not present on #{object.class}. Exception: #{msg}")
54
- raise MAuthNotPresent, msg
55
- end
56
- end
57
-
58
- private
59
-
60
- # NOTE: This log is likely consumed downstream and the contents SHOULD NOT
61
- # be changed without a thorough review of downstream consumers.
62
- def log_authentication_request(object)
63
- object_app_uuid = object.signature_app_uuid || '[none provided]'
64
- object_token = object.signature_token || '[none provided]'
65
- logger.info(
66
- 'Mauth-client attempting to authenticate request from app with mauth' \
67
- " app uuid #{object_app_uuid} to app with mauth app uuid #{client_app_uuid}" \
68
- " using version #{object_token}."
69
- )
70
- end
71
-
72
- def log_inauthentic(object, message)
73
- logger.error("mAuth signature authentication failed for #{object.class}. Exception: #{message}")
74
- end
75
-
76
- def time_within_valid_range!(object, time_signed, now = Time.now)
77
- return if (-ALLOWED_DRIFT_SECONDS..ALLOWED_DRIFT_SECONDS).cover?(now.to_i - time_signed)
78
-
79
- msg = "Time verification failed. #{time_signed} not within #{ALLOWED_DRIFT_SECONDS} of #{now}"
80
- log_inauthentic(object, msg)
81
- raise InauthenticError, msg
82
- end
83
-
84
- # V1 helpers
85
- def authenticate_v1!(object)
86
- time_valid_v1!(object)
87
- token_valid_v1!(object)
88
- signature_valid_v1!(object)
89
- end
90
-
91
- def time_valid_v1!(object)
92
- if object.x_mws_time.nil?
93
- msg = 'Time verification failed. No x-mws-time present.'
94
- log_inauthentic(object, msg)
95
- raise InauthenticError, msg
96
- end
97
- time_within_valid_range!(object, object.x_mws_time.to_i)
98
- end
99
-
100
- def token_valid_v1!(object)
101
- return if object.signature_token == MWS_TOKEN
102
-
103
- msg = "Token verification failed. Expected #{MWS_TOKEN}; token was #{object.signature_token}"
104
- log_inauthentic(object, msg)
105
- raise InauthenticError, msg
106
- end
107
-
108
- # V2 helpers
109
- def authenticate_v2!(object)
110
- time_valid_v2!(object)
111
- token_valid_v2!(object)
112
- signature_valid_v2!(object)
113
- end
114
-
115
- def time_valid_v2!(object)
116
- if object.mcc_time.nil?
117
- msg = 'Time verification failed. No MCC-Time present.'
118
- log_inauthentic(object, msg)
119
- raise InauthenticError, msg
120
- end
121
- time_within_valid_range!(object, object.mcc_time.to_i)
122
- end
123
-
124
- def token_valid_v2!(object)
125
- return if object.signature_token == MWSV2_TOKEN
126
-
127
- msg = "Token verification failed. Expected #{MWSV2_TOKEN}; token was #{object.signature_token}"
128
- log_inauthentic(object, msg)
129
- raise InauthenticError, msg
130
- end
131
- end
132
- end
133
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # methods for remotely authenticating a request by sending it to the mauth service
4
-
5
- module MAuth
6
- class Client
7
- module RemoteRequestAuthenticator
8
- private
9
-
10
- # takes an incoming request object (no support for responses currently), and errors if the
11
- # object is not authentic according to its signature
12
- def signature_valid_v1!(object)
13
- unless object.is_a?(MAuth::Request)
14
- raise ArgumentError,
15
- "Remote Authenticator can only authenticate requests; received #{object.inspect}"
16
- end
17
-
18
- authentication_ticket = {
19
- 'verb' => object.attributes_for_signing[:verb],
20
- 'app_uuid' => object.signature_app_uuid,
21
- 'client_signature' => object.signature,
22
- 'request_url' => object.attributes_for_signing[:request_url],
23
- 'request_time' => object.x_mws_time,
24
- 'b64encoded_body' => Base64.encode64(object.attributes_for_signing[:body] || '')
25
- }
26
- make_mauth_request(authentication_ticket)
27
- end
28
-
29
- def signature_valid_v2!(object)
30
- unless object.is_a?(MAuth::Request)
31
- msg = "Remote Authenticator can only authenticate requests; received #{object.inspect}"
32
- raise ArgumentError, msg
33
- end
34
-
35
- authentication_ticket = {
36
- verb: object.attributes_for_signing[:verb],
37
- app_uuid: object.signature_app_uuid,
38
- client_signature: object.signature,
39
- request_url: object.attributes_for_signing[:request_url],
40
- request_time: object.mcc_time,
41
- b64encoded_body: Base64.encode64(object.attributes_for_signing[:body] || ''),
42
- query_string: object.attributes_for_signing[:query_string],
43
- token: object.signature_token
44
- }
45
- make_mauth_request(authentication_ticket)
46
- end
47
-
48
- def make_mauth_request(authentication_ticket)
49
- begin
50
- request_body = JSON.generate(authentication_ticket: authentication_ticket)
51
- response = mauth_connection.post("/mauth/#{mauth_api_version}/authentication_tickets.json", request_body)
52
- rescue ::Faraday::ConnectionFailed, ::Faraday::TimeoutError => e
53
- msg = "mAuth service did not respond; received #{e.class}: #{e.message}"
54
- logger.error("Unable to authenticate with MAuth. Exception #{msg}")
55
- raise UnableToAuthenticateError, msg
56
- end
57
- case response.status
58
- when 200..299
59
- nil
60
- when 412, 404
61
- # the mAuth service responds with 412 when the given request is not authentically signed.
62
- # older versions of the mAuth service respond with 404 when the given app_uuid
63
- # does not exist, which is also considered to not be authentically signed. newer
64
- # versions of the service respond 412 in all cases, so the 404 check may be removed
65
- # when the old version of the mAuth service is out of service.
66
- raise InauthenticError, "The mAuth service responded with #{response.status}: #{response.body}"
67
- else
68
- mauth_service_response_error(response)
69
- end
70
- end
71
-
72
- def mauth_connection
73
- @mauth_connection ||= begin
74
- require 'faraday'
75
-
76
- ::Faraday.new(mauth_baseurl,
77
- faraday_options.merge(headers: { 'Content-Type' => 'application/json' })) do |builder|
78
- builder.use MAuth::Faraday::MAuthClientUserAgent
79
- builder.adapter ::Faraday.default_adapter
80
- end
81
- end
82
- end
83
- end
84
- end
85
- end
@@ -1,12 +0,0 @@
1
- <%= warning.as_yaml_comment %>
2
-
3
- MAUTH_CONF = MAuth::Client.default_config
4
- require 'mauth/rack'
5
- # ResponseSigner OPTIONAL; only use if you are registered in mauth service
6
- Rails.application.config.middleware.insert_after Rack::Runtime, MAuth::Rack::ResponseSigner, MAUTH_CONF
7
- if Rails.env.test? || Rails.env.development?
8
- require 'mauth/fake/rack'
9
- Rails.application.config.middleware.insert_after MAuth::Rack::ResponseSigner, MAuth::Rack::RequestAuthenticationFaker, MAUTH_CONF
10
- else
11
- Rails.application.config.middleware.insert_after MAuth::Rack::ResponseSigner, MAuth::Rack::RequestAuthenticatorNoAppStatus, MAUTH_CONF
12
- end
@@ -1,18 +0,0 @@
1
- <%= warning.as_yaml_comment %>
2
-
3
- common: &common
4
- mauth_baseurl: <%= configured.mauth_url! || 'http://localhost:7000' %>
5
- mauth_api_version: v1
6
- app_uuid: <%= configured.mauth_app_uuid! || 'fb17460e-9868-11e1-8399-0090f5ccb4d3' %>
7
- private_key_file: config/mauth_key
8
- v2_only_authenticate: <%= configured.v2_only_authenticate || 'false' %>
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' %>
12
-
13
- production:
14
- <<: *common
15
- development:
16
- <<: *common
17
- test:
18
- <<: *common
@@ -1 +0,0 @@
1
- <%= ensure_is_private_key(configured.mauth_private_key! || generate_private_key.to_s) %>
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'dice_bag'
4
-
5
- class MauthTemplate < DiceBag::AvailableTemplates
6
- def templates
7
- ['mauth.yml.dice', 'mauth_key.dice'].map do |template|
8
- File.join(File.dirname(__FILE__), template)
9
- end
10
- end
11
- end
12
-
13
- class MauthInitializerTemplate < DiceBag::AvailableTemplates
14
- def templates_location
15
- 'config/initializers'
16
- end
17
-
18
- def templates
19
- [File.join(File.dirname(__FILE__), 'mauth.rb.dice')] if Object.const_defined?(:Rails)
20
- end
21
- end