ably-rest 0.8.2 → 0.8.3
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/CHANGELOG.md +1 -43
- data/SPEC.md +707 -580
- data/lib/submodules/ably-ruby/.travis.yml +1 -0
- data/lib/submodules/ably-ruby/CHANGELOG.md +143 -3
- data/lib/submodules/ably-ruby/README.md +1 -1
- data/lib/submodules/ably-ruby/SPEC.md +842 -520
- data/lib/submodules/ably-ruby/ably.gemspec +1 -1
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +114 -87
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +40 -14
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +3 -5
- data/lib/submodules/ably-ruby/lib/ably/models/paginated_result.rb +3 -12
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +8 -2
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +15 -3
- data/lib/submodules/ably-ruby/lib/ably/models/stat.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/channels_collection.rb +7 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/encodeable.rb +6 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/message_pack.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/model_common.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +191 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +97 -25
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +11 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +22 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +73 -40
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +48 -33
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +17 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +43 -16
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +57 -26
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +3 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +4 -2
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +242 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +277 -5
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channels_spec.rb +64 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +26 -5
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +23 -6
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +167 -16
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +9 -8
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +1 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +121 -10
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/stats_spec.rb +13 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +161 -79
- data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +3 -3
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +142 -15
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +23 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +180 -18
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +8 -8
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +136 -25
- data/lib/submodules/ably-ruby/spec/acceptance/rest/stats_spec.rb +60 -4
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +54 -3
- data/lib/submodules/ably-ruby/spec/unit/auth_spec.rb +7 -6
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +1 -9
- data/lib/submodules/ably-ruby/spec/unit/models/paginated_result_spec.rb +1 -18
- data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +21 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +10 -3
- data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +27 -8
- data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +0 -8
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +7 -7
- metadata +5 -2
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency 'faraday', '~> 0.9'
|
25
25
|
spec.add_runtime_dependency 'json'
|
26
26
|
spec.add_runtime_dependency 'websocket-driver', '~> 0.3'
|
27
|
-
spec.add_runtime_dependency 'msgpack', '0.6.
|
27
|
+
spec.add_runtime_dependency 'msgpack', '>= 0.6.2'
|
28
28
|
|
29
29
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
30
30
|
spec.add_development_dependency 'rake'
|
@@ -22,44 +22,53 @@ module Ably
|
|
22
22
|
# @!attribute [r] key_secret
|
23
23
|
# @return [String] Key secret (private secure part of the API key), if present
|
24
24
|
# @!attribute [r] options
|
25
|
-
# @return [Hash] {Ably::Auth} options configured for this client
|
26
|
-
|
25
|
+
# @return [Hash] Default {Ably::Auth} options configured for this client
|
26
|
+
# @!attribute [r] token_params
|
27
|
+
# @return [Hash] Default token params used for token requests, see {#request_token}
|
28
|
+
#
|
27
29
|
class Auth
|
28
30
|
include Ably::Modules::Conversions
|
29
31
|
include Ably::Modules::HttpHelpers
|
30
32
|
|
31
33
|
# Default capability Hash object and TTL in seconds for issued tokens
|
32
34
|
TOKEN_DEFAULTS = {
|
33
|
-
capability:
|
34
|
-
ttl:
|
35
|
-
|
35
|
+
capability: { '*' => ['*'] },
|
36
|
+
ttl: 60 * 60, # 1 hour in seconds
|
37
|
+
renew_token_buffer: 10 # buffer to allow a token to be reissued before the token is considered expired (Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER)
|
38
|
+
}.freeze
|
36
39
|
|
37
|
-
attr_reader :options, :current_token_details
|
40
|
+
attr_reader :options, :token_params, :current_token_details
|
38
41
|
alias_method :auth_options, :options
|
39
42
|
|
40
43
|
# Creates an Auth object
|
41
44
|
#
|
42
45
|
# @param [Ably::Rest::Client] client {Ably::Rest::Client} this Auth object uses
|
43
|
-
# @param [Hash] options
|
44
|
-
# @
|
46
|
+
# @param [Hash] auth_options the authentication options used as a default future token requests
|
47
|
+
# @param [Hash] token_params the token params used as a default for future token requests
|
48
|
+
# @option (see #request_token)
|
45
49
|
#
|
46
|
-
def initialize(client,
|
47
|
-
|
50
|
+
def initialize(client, auth_options, token_params)
|
51
|
+
unless auth_options.kind_of?(Hash)
|
52
|
+
raise ArgumentError, 'Expected auth_options to be a Hash'
|
53
|
+
end
|
48
54
|
|
49
|
-
|
55
|
+
unless token_params.kind_of?(Hash)
|
56
|
+
raise ArgumentError, 'Expected token_params to be a Hash'
|
57
|
+
end
|
58
|
+
|
59
|
+
ensure_valid_auth_attributes auth_options
|
50
60
|
|
51
61
|
@client = client
|
52
|
-
@options = auth_options
|
62
|
+
@options = auth_options.dup
|
63
|
+
@token_params = token_params.dup
|
53
64
|
|
54
|
-
|
55
|
-
raise ArgumentError, 'Expected auth_options to be a Hash'
|
56
|
-
end
|
65
|
+
@options.delete :force # Forcing token auth for every request is not a valid default
|
57
66
|
|
58
|
-
if
|
67
|
+
if options[:key] && (options[:key_secret] || options[:key_name])
|
59
68
|
raise ArgumentError, 'key and key_name or key_secret are mutually exclusive. Provider either a key or key_name & key_secret'
|
60
69
|
end
|
61
70
|
|
62
|
-
split_api_key_into_key_and_secret!
|
71
|
+
split_api_key_into_key_and_secret! options if options[:key]
|
63
72
|
|
64
73
|
if using_basic_auth? && !api_key_present?
|
65
74
|
raise ArgumentError, 'key is missing. Either an API key, token, or token auth method must be provided'
|
@@ -71,85 +80,90 @@ module Ably
|
|
71
80
|
end
|
72
81
|
|
73
82
|
@options.freeze
|
83
|
+
@token_params.freeze
|
74
84
|
end
|
75
85
|
|
76
86
|
# Ensures valid auth credentials are present for the library instance. This may rely on an already-known and valid token, and will obtain a new token if necessary.
|
77
87
|
#
|
78
|
-
# In the event that a new token request is made, the
|
88
|
+
# In the event that a new token request is made, the provided options are used.
|
79
89
|
#
|
80
|
-
# @param [Hash]
|
81
|
-
# @
|
82
|
-
# @option
|
83
|
-
# @option
|
90
|
+
# @param [Hash] auth_options the authentication options used for future token requests
|
91
|
+
# @param [Hash] token_params the token params used for future token requests
|
92
|
+
# @option auth_options [Boolean] :force obtains a new token even if the current token is valid
|
93
|
+
# @option (see #request_token)
|
84
94
|
#
|
85
|
-
# @return (see #
|
95
|
+
# @return (see #create_token_request)
|
86
96
|
#
|
87
97
|
# @example
|
88
98
|
# # will issue a simple token request using basic auth
|
89
99
|
# client = Ably::Rest::Client.new(key: 'key.id:secret')
|
90
|
-
#
|
100
|
+
# token_details = client.auth.authorise
|
91
101
|
#
|
92
102
|
# # will use token request from block to authorise if not already authorised
|
93
|
-
#
|
103
|
+
# token_details = client.auth.authorise auth_callback: Proc.new do
|
94
104
|
# # create token_request object
|
95
105
|
# token_request
|
96
106
|
# end
|
97
107
|
#
|
98
|
-
def authorise(
|
99
|
-
ensure_valid_auth_attributes
|
108
|
+
def authorise(auth_options = {}, token_params = {})
|
109
|
+
ensure_valid_auth_attributes auth_options
|
110
|
+
|
111
|
+
auth_options = auth_options.clone
|
100
112
|
|
101
|
-
if current_token_details && !
|
113
|
+
if current_token_details && !auth_options.delete(:force)
|
102
114
|
return current_token_details unless current_token_details.expired?
|
103
115
|
end
|
104
116
|
|
105
|
-
|
106
|
-
|
107
|
-
|
117
|
+
split_api_key_into_key_and_secret! auth_options if auth_options[:key]
|
118
|
+
@options = @options.merge(auth_options) # update defaults
|
119
|
+
|
120
|
+
token_params = (auth_options.delete(:token_params) || {}).merge(token_params)
|
121
|
+
@token_params = @token_params.merge(token_params) # update defaults
|
108
122
|
|
109
|
-
@current_token_details = request_token(
|
123
|
+
@current_token_details = request_token(auth_options, token_params)
|
110
124
|
end
|
111
125
|
|
112
126
|
# Request a {Ably::Models::TokenDetails} which can be used to make authenticated token based requests
|
113
127
|
#
|
114
|
-
# @param [Hash]
|
115
|
-
# @option
|
116
|
-
# @option
|
117
|
-
# @option
|
118
|
-
# @option
|
119
|
-
# @option
|
120
|
-
#
|
121
|
-
# @
|
122
|
-
#
|
123
|
-
# @option options [Integer] :ttl validity time in seconds for the requested {Ably::Models::TokenDetails}. Limits may apply, see {https://www.ably.io/documentation/other/authentication}
|
124
|
-
# @option options [Hash] :capability canonicalised representation of the resource paths and associated operations
|
125
|
-
# @option options [Boolean] :query_time when true will query the {https://www.ably.io Ably} system for the current time instead of using the local time
|
126
|
-
# @option options [Time] :timestamp the time of the of the request
|
127
|
-
# @option options [String] :nonce an unquoted, unescaped random string of at least 16 characters
|
128
|
+
# @param [Hash] auth_options (see #create_token_request)
|
129
|
+
# @option auth_options [String] :auth_url a URL to be used to GET or POST a set of token request params, to obtain a signed token request
|
130
|
+
# @option auth_options [Hash] :auth_headers a set of application-specific headers to be added to any request made to the +auth_url+
|
131
|
+
# @option auth_options [Hash] :auth_params a set of application-specific query params to be added to any request made to the +auth_url+
|
132
|
+
# @option auth_options [Symbol] :auth_method (:get) HTTP method to use with +auth_url+, must be either +:get+ or +:post+
|
133
|
+
# @option auth_options [Proc] :auth_callback when provided, the Proc will be called with the token params hash as the first argument, whenever a new token is required.
|
134
|
+
# The Proc should return a token string, {Ably::Models::TokenDetails} or JSON equivalent, {Ably::Models::TokenRequest} or JSON equivalent
|
135
|
+
# @param [Hash] token_params (see #create_token_request)
|
136
|
+
# @option (see #create_token_request)
|
128
137
|
#
|
129
138
|
# @return [Ably::Models::TokenDetails]
|
130
139
|
#
|
131
140
|
# @example
|
132
141
|
# # simple token request using basic auth
|
133
142
|
# client = Ably::Rest::Client.new(key: 'key.id:secret')
|
134
|
-
#
|
143
|
+
# token_details = client.auth.request_token
|
144
|
+
#
|
145
|
+
# # token request with token params
|
146
|
+
# client.auth.request_token token_params: { ttl: 1.hour }
|
135
147
|
#
|
136
148
|
# # token request using auth block
|
137
|
-
#
|
149
|
+
# token_details = client.auth.request_token auth_callback: Proc.new do
|
138
150
|
# # create token_request object
|
139
151
|
# token_request
|
140
152
|
# end
|
141
153
|
#
|
142
|
-
def request_token(
|
143
|
-
ensure_valid_auth_attributes
|
154
|
+
def request_token(auth_options = {}, token_params = {})
|
155
|
+
ensure_valid_auth_attributes auth_options
|
144
156
|
|
145
|
-
|
157
|
+
token_params = (auth_options[:token_params] || {}).merge(token_params)
|
158
|
+
token_params = self.token_params.merge(token_params)
|
159
|
+
auth_options = self.options.merge(auth_options)
|
146
160
|
|
147
|
-
token_request = if auth_callback =
|
148
|
-
auth_callback.call(
|
149
|
-
elsif auth_url =
|
150
|
-
token_request_from_auth_url(auth_url,
|
161
|
+
token_request = if auth_callback = auth_options.delete(:auth_callback)
|
162
|
+
auth_callback.call(token_params)
|
163
|
+
elsif auth_url = auth_options.delete(:auth_url)
|
164
|
+
token_request_from_auth_url(auth_url, auth_options)
|
151
165
|
else
|
152
|
-
create_token_request(
|
166
|
+
create_token_request(auth_options, token_params)
|
153
167
|
end
|
154
168
|
|
155
169
|
case token_request
|
@@ -172,19 +186,23 @@ module Ably
|
|
172
186
|
|
173
187
|
# Creates and signs a token request that can then subsequently be used by any client to request a token
|
174
188
|
#
|
175
|
-
# @param [Hash]
|
176
|
-
# @option
|
177
|
-
# @option
|
178
|
-
# @option
|
179
|
-
# @option
|
180
|
-
#
|
181
|
-
# @
|
182
|
-
# @option
|
189
|
+
# @param [Hash] auth_options the authentication options for the token request
|
190
|
+
# @option auth_options [String] :key API key comprising the key name and key secret in a single string
|
191
|
+
# @option auth_options [String] :client_id client ID identifying this connection to other clients (will use +client_id+ specified when library was instanced if provided)
|
192
|
+
# @option auth_options [Boolean] :query_time when true will query the {https://www.ably.io Ably} system for the current time instead of using the local time
|
193
|
+
# @option auth_options [Hash] :token_params convenience to pass in +token_params+ within the +auth_options+ argument, this helps avoid the following +authorise({key: key}, {ttl: 23})+ by allowing +authorise(key:key,token_params:{ttl:23})+
|
194
|
+
#
|
195
|
+
# @param [Hash] token_params the token params used in the token request
|
196
|
+
# @option token_params [String] :client_id A client ID to associate with this token. The generated token may be used to authenticate as this +client_id+
|
197
|
+
# @option token_params [Integer] :ttl validity time in seconds for the requested {Ably::Models::TokenDetails}. Limits may apply, see {https://www.ably.io/documentation/other/authentication}
|
198
|
+
# @option token_params [Hash] :capability canonicalised representation of the resource paths and associated operations
|
199
|
+
# @option token_params [Time] :timestamp the time of the request
|
200
|
+
# @option token_params [String] :nonce an unquoted, unescaped random string of at least 16 characters
|
183
201
|
#
|
184
202
|
# @return [Models::TokenRequest]
|
185
203
|
#
|
186
204
|
# @example
|
187
|
-
# client.auth.create_token_request(id: 'asd.asd', ttl: 3600)
|
205
|
+
# client.auth.create_token_request(id: 'asd.asd', token_params: { ttl: 3600 })
|
188
206
|
# #<Ably::Models::TokenRequest:0x007fd5d919df78
|
189
207
|
# # @hash={
|
190
208
|
# # :id=>"asds.adsa",
|
@@ -196,30 +214,37 @@ module Ably
|
|
196
214
|
# # :mac=>"881oZHeFo6oMim7....uE56a8gUxHw="
|
197
215
|
# # }
|
198
216
|
# #>>
|
199
|
-
def create_token_request(
|
200
|
-
ensure_valid_auth_attributes
|
217
|
+
def create_token_request(auth_options = {}, token_params = {})
|
218
|
+
ensure_valid_auth_attributes auth_options
|
201
219
|
|
202
|
-
|
220
|
+
auth_options = auth_options.clone
|
221
|
+
token_params = (auth_options[:token_params] || {}).merge(token_params)
|
203
222
|
|
204
|
-
split_api_key_into_key_and_secret!
|
205
|
-
request_key_name =
|
206
|
-
request_key_secret =
|
207
|
-
raise Ably::Exceptions::TokenRequestError, 'Key Name and Key Secret are required to generate a new token request' unless request_key_name && request_key_secret
|
223
|
+
split_api_key_into_key_and_secret! auth_options if auth_options[:key]
|
224
|
+
request_key_name = auth_options.delete(:key_name) || key_name
|
225
|
+
request_key_secret = auth_options.delete(:key_secret) || key_secret
|
208
226
|
|
209
|
-
|
227
|
+
raise Ably::Exceptions::TokenRequestFailed, 'Key Name and Key Secret are required to generate a new token request' unless request_key_name && request_key_secret
|
228
|
+
|
229
|
+
timestamp = if auth_options[:query_time]
|
210
230
|
client.time
|
211
231
|
else
|
212
|
-
|
232
|
+
token_params.delete(:timestamp) || Time.now
|
213
233
|
end
|
214
234
|
timestamp = Time.at(timestamp) if timestamp.kind_of?(Integer)
|
215
235
|
|
236
|
+
ttl = [
|
237
|
+
(token_params[:ttl] || TOKEN_DEFAULTS.fetch(:ttl)),
|
238
|
+
Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER + TOKEN_DEFAULTS.fetch(:renew_token_buffer) # never issue a token that will be immediately considered expired due to the buffer
|
239
|
+
].max
|
240
|
+
|
216
241
|
token_request = {
|
217
|
-
keyName:
|
218
|
-
clientId:
|
219
|
-
ttl: (
|
242
|
+
keyName: request_key_name,
|
243
|
+
clientId: token_params[:client_id] || auth_options[:client_id] || client_id,
|
244
|
+
ttl: (ttl * 1000).to_i,
|
220
245
|
timestamp: (timestamp.to_f * 1000).round,
|
221
|
-
capability:
|
222
|
-
nonce:
|
246
|
+
capability: token_params[:capability] || TOKEN_DEFAULTS.fetch(:capability),
|
247
|
+
nonce: token_params[:nonce] || SecureRandom.hex.force_encoding('UTF-8')
|
223
248
|
}
|
224
249
|
|
225
250
|
token_request[:capability] = JSON.dump(token_request[:capability]) if token_request[:capability].is_a?(Hash)
|
@@ -227,7 +252,7 @@ module Ably
|
|
227
252
|
token_request[:mac] = sign_params(token_request, request_key_secret)
|
228
253
|
|
229
254
|
# Undocumented feature to request a persisted token
|
230
|
-
token_request[:persisted] =
|
255
|
+
token_request[:persisted] = token_params[:persisted] if token_params[:persisted]
|
231
256
|
|
232
257
|
Models::TokenRequest.new(token_request)
|
233
258
|
end
|
@@ -252,7 +277,7 @@ module Ably
|
|
252
277
|
# True when Token Auth is being used to authenticate with Ably
|
253
278
|
def using_token_auth?
|
254
279
|
return options[:use_token_auth] if options.has_key?(:use_token_auth)
|
255
|
-
token || current_token_details || has_client_id? || token_creatable_externally?
|
280
|
+
!!(token || current_token_details || has_client_id? || token_creatable_externally?)
|
256
281
|
end
|
257
282
|
|
258
283
|
def client_id
|
@@ -270,6 +295,7 @@ module Ably
|
|
270
295
|
end
|
271
296
|
|
272
297
|
# Auth header string used in HTTP requests to Ably
|
298
|
+
# Will reauthorise implicitly if required and capable
|
273
299
|
#
|
274
300
|
# @return [String] HTTP authentication value used in HTTP_AUTHORIZATION header
|
275
301
|
def auth_header
|
@@ -281,6 +307,7 @@ module Ably
|
|
281
307
|
end
|
282
308
|
|
283
309
|
# Auth params used in URI endpoint for Realtime connections
|
310
|
+
# Will reauthorise implicitly if required and capable
|
284
311
|
#
|
285
312
|
# @return [Hash] Auth params for a new Realtime connection
|
286
313
|
def auth_params
|
@@ -353,7 +380,7 @@ module Ably
|
|
353
380
|
end
|
354
381
|
|
355
382
|
def ensure_api_key_sent_over_secure_connection
|
356
|
-
raise Ably::Exceptions::
|
383
|
+
raise Ably::Exceptions::InsecureRequest, 'Cannot use Basic Auth over non-TLS connections' unless authentication_security_requirements_met?
|
357
384
|
end
|
358
385
|
|
359
386
|
# Basic Auth HTTP Authorization header value
|
@@ -424,18 +451,18 @@ module Ably
|
|
424
451
|
# Retrieve a token request from a specified URL, expects a JSON response
|
425
452
|
#
|
426
453
|
# @return [Hash]
|
427
|
-
def token_request_from_auth_url(auth_url,
|
454
|
+
def token_request_from_auth_url(auth_url, auth_options)
|
428
455
|
uri = URI.parse(auth_url)
|
429
456
|
connection = Faraday.new("#{uri.scheme}://#{uri.host}", connection_options)
|
430
|
-
method =
|
457
|
+
method = auth_options[:auth_method] || :get
|
431
458
|
|
432
459
|
response = connection.send(method) do |request|
|
433
460
|
request.url uri.path
|
434
|
-
request.params =
|
435
|
-
request.headers =
|
461
|
+
request.params = CGI.parse(uri.query || '').merge(auth_options[:auth_params] || {})
|
462
|
+
request.headers = auth_options[:auth_headers] || {}
|
436
463
|
end
|
437
464
|
|
438
|
-
if !response.body.kind_of?(Hash) && response.headers['Content-Type']
|
465
|
+
if !response.body.kind_of?(Hash) && !response.headers['Content-Type'].to_s.match(%r{text/plain}i)
|
439
466
|
raise Ably::Exceptions::InvalidResponseBody,
|
440
467
|
"Content Type #{response.headers['Content-Type']} is not supported by this client library"
|
441
468
|
end
|
@@ -16,14 +16,22 @@ module Ably
|
|
16
16
|
@status = status
|
17
17
|
@code = code
|
18
18
|
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
message = [super]
|
22
|
+
if status || code
|
23
|
+
additional_info = []
|
24
|
+
additional_info << "code: #{code}" if code
|
25
|
+
additional_info << "http status: #{status}" if status
|
26
|
+
message << "(#{additional_info.join(', ')})"
|
27
|
+
end
|
28
|
+
message.join(' ')
|
29
|
+
end
|
19
30
|
end
|
20
31
|
|
21
32
|
# An invalid request was received by Ably
|
22
33
|
class InvalidRequest < BaseAblyException; end
|
23
34
|
|
24
|
-
# The token is invalid
|
25
|
-
class InvalidToken < BaseAblyException; end
|
26
|
-
|
27
35
|
# Ably Protocol message received that is invalid
|
28
36
|
class ProtocolError < BaseAblyException; end
|
29
37
|
|
@@ -39,19 +47,28 @@ module Ably
|
|
39
47
|
super message, status, code
|
40
48
|
@base_error = base_error
|
41
49
|
end
|
50
|
+
|
51
|
+
def to_s
|
52
|
+
message = [super]
|
53
|
+
message << "#{@base_error}" if @base_error
|
54
|
+
message.join(' < ')
|
55
|
+
end
|
42
56
|
end
|
43
57
|
|
44
58
|
# Connection Timeout accessing Realtime or REST service
|
45
|
-
class
|
59
|
+
class ConnectionTimeout < ConnectionError; end
|
46
60
|
|
47
61
|
# Connection closed unexpectedly
|
48
|
-
class
|
62
|
+
class ConnectionClosed < ConnectionError; end
|
49
63
|
|
50
|
-
#
|
51
|
-
class
|
64
|
+
# Connection suspended
|
65
|
+
class ConnectionSuspended < ConnectionError; end
|
52
66
|
|
53
|
-
#
|
54
|
-
class
|
67
|
+
# Connection failed
|
68
|
+
class ConnectionFailed < ConnectionError; end
|
69
|
+
|
70
|
+
# Invalid State Change error on a {https://github.com/gocardless/statesman Statesman State Machine}
|
71
|
+
class InvalidStateChange < BaseAblyException; end
|
55
72
|
|
56
73
|
# A generic Ably exception taht supports a status & code.
|
57
74
|
# See https://github.com/ably/ably-common/blob/master/protocol/errors.json for a list of Ably errors
|
@@ -61,21 +78,30 @@ module Ably
|
|
61
78
|
class ServerError < BaseAblyException; end
|
62
79
|
|
63
80
|
# PaginatedResult cannot retrieve the page
|
64
|
-
class
|
81
|
+
class PageMissing < BaseAblyException; end
|
65
82
|
|
66
83
|
# The expected response from the server was invalid
|
67
84
|
class InvalidResponseBody < BaseAblyException; end
|
68
85
|
|
69
86
|
# The request cannot be performed because it is insecure
|
70
|
-
class
|
87
|
+
class InsecureRequest < BaseAblyException; end
|
71
88
|
|
72
89
|
# The token request could not be created
|
73
|
-
class
|
90
|
+
class TokenRequestFailed < BaseAblyException; end
|
91
|
+
|
92
|
+
# The token has expired
|
93
|
+
class TokenExpired < BaseAblyException; end
|
74
94
|
|
75
95
|
# The message could not be delivered to the server
|
76
|
-
class
|
96
|
+
class MessageDeliveryFailed < BaseAblyException; end
|
97
|
+
|
98
|
+
# The client has been configured to not queue messages i.e. only publish down an active connection
|
99
|
+
class MessageQueueingDisabled < BaseAblyException; end
|
77
100
|
|
78
101
|
# The data payload type is not supported
|
79
|
-
class
|
102
|
+
class UnsupportedDataType < BaseAblyException; end
|
103
|
+
|
104
|
+
# When a channel is detached / failed, certain operations are not permitted such as publishing messages
|
105
|
+
class ChannelInactive < BaseAblyException; end
|
80
106
|
end
|
81
107
|
end
|