ably 0.7.6 → 0.8.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -7
  3. data/SPEC.md +310 -269
  4. data/lib/ably/auth.rb +177 -127
  5. data/lib/ably/models/presence_message.rb +1 -1
  6. data/lib/ably/models/protocol_message.rb +1 -2
  7. data/lib/ably/models/token_details.rb +101 -0
  8. data/lib/ably/models/token_request.rb +108 -0
  9. data/lib/ably/modules/http_helpers.rb +1 -1
  10. data/lib/ably/realtime.rb +2 -6
  11. data/lib/ably/realtime/channel.rb +14 -8
  12. data/lib/ably/realtime/client.rb +2 -6
  13. data/lib/ably/realtime/connection.rb +4 -2
  14. data/lib/ably/rest.rb +2 -6
  15. data/lib/ably/rest/channel.rb +10 -6
  16. data/lib/ably/rest/client.rb +15 -16
  17. data/lib/ably/rest/presence.rb +12 -10
  18. data/lib/ably/version.rb +1 -1
  19. data/spec/acceptance/realtime/client_spec.rb +15 -15
  20. data/spec/acceptance/realtime/connection_failures_spec.rb +3 -3
  21. data/spec/acceptance/realtime/connection_spec.rb +9 -9
  22. data/spec/acceptance/rest/auth_spec.rb +248 -172
  23. data/spec/acceptance/rest/base_spec.rb +8 -6
  24. data/spec/acceptance/rest/channel_spec.rb +9 -2
  25. data/spec/acceptance/rest/client_spec.rb +21 -21
  26. data/spec/acceptance/rest/presence_spec.rb +12 -5
  27. data/spec/acceptance/rest/stats_spec.rb +4 -4
  28. data/spec/rspec_config.rb +3 -2
  29. data/spec/shared/client_initializer_behaviour.rb +21 -24
  30. data/spec/support/api_helper.rb +3 -3
  31. data/spec/support/test_app.rb +9 -9
  32. data/spec/unit/auth_spec.rb +17 -0
  33. data/spec/unit/models/token_details_spec.rb +111 -0
  34. data/spec/unit/models/token_request_spec.rb +110 -0
  35. data/spec/unit/rest/client_spec.rb +1 -1
  36. metadata +8 -5
  37. data/lib/ably/models/token.rb +0 -74
  38. data/spec/unit/models/token_spec.rb +0 -86
@@ -5,20 +5,20 @@ require 'securerandom'
5
5
  require 'ably/rest/middleware/external_exceptions'
6
6
 
7
7
  module Ably
8
- # Auth is responsible for authentication with {https://ably.io Ably} using basic or token authentication
8
+ # Auth is responsible for authentication with {https://www.ably.io Ably} using basic or token authentication
9
9
  #
10
- # Find out more about Ably authentication at: http://docs.ably.io/other/authentication/
10
+ # Find out more about Ably authentication at: https://www.ably.io/documentation/general/authentication/
11
11
  #
12
12
  # @!attribute [r] client_id
13
13
  # @return [String] The provided client ID, used for identifying this client for presence purposes
14
- # @!attribute [r] current_token
15
- # @return [Ably::Models::Token] Current {Ably::Models::Token} issued by this library or one of the provided callbacks used to authenticate requests
16
- # @!attribute [r] token_id
17
- # @return [String] Token ID provided to the {Ably::Client} constructor that is used to authenticate all requests
14
+ # @!attribute [r] current_token_details
15
+ # @return [Ably::Models::TokenDetails] Current {Ably::Models::TokenDetails} issued by this library or one of the provided callbacks used to authenticate requests
16
+ # @!attribute [r] token
17
+ # @return [String] Token string provided to the {Ably::Client} constructor that is used to authenticate all requests
18
18
  # @!attribute [r] key
19
- # @return [String] Complete API key containing both the key ID and key secret, if present
20
- # @!attribute [r] key_id
21
- # @return [String] Key ID (public part of the API key), if present
19
+ # @return [String] Complete API key containing both the key name and key secret, if present
20
+ # @!attribute [r] key_name
21
+ # @return [String] Key name (public part of the API key), if present
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
@@ -28,7 +28,13 @@ module Ably
28
28
  include Ably::Modules::Conversions
29
29
  include Ably::Modules::HttpHelpers
30
30
 
31
- attr_reader :options, :current_token
31
+ # Default capability Hash object and TTL in seconds for issued tokens
32
+ TOKEN_DEFAULTS = {
33
+ capability: { '*' => ['*'] },
34
+ ttl: 60 * 60 # 1 hour in seconds
35
+ }
36
+
37
+ attr_reader :options, :current_token_details
32
38
  alias_method :auth_options, :options
33
39
 
34
40
  # Creates an Auth object
@@ -36,33 +42,31 @@ module Ably
36
42
  # @param [Ably::Rest::Client] client {Ably::Rest::Client} this Auth object uses
37
43
  # @param [Hash] options (see Ably::Rest::Client#initialize)
38
44
  # @option (see Ably::Rest::Client#initialize)
39
- # @yield (see Ably::Rest::Client#initialize)
40
45
  #
41
- def initialize(client, options, &token_request_block)
46
+ def initialize(client, options)
47
+ ensure_valid_auth_attributes options
48
+
42
49
  auth_options = options.dup
43
50
 
44
51
  @client = client
45
52
  @options = auth_options
46
- @default_token_block = token_request_block if block_given?
47
53
 
48
54
  unless auth_options.kind_of?(Hash)
49
55
  raise ArgumentError, 'Expected auth_options to be a Hash'
50
56
  end
51
57
 
52
- api_key = auth_options[:key] || auth_options[:api_key] # backwards support for previously used :api_key
53
-
54
- if api_key && (auth_options[:key_secret] || auth_options[:key_id])
55
- raise ArgumentError, 'key and key_id or key_secret are mutually exclusive. Provider either a key or key_id & key_secret'
58
+ if auth_options[:key] && (auth_options[:key_secret] || auth_options[:key_name])
59
+ raise ArgumentError, 'key and key_name or key_secret are mutually exclusive. Provider either a key or key_name & key_secret'
56
60
  end
57
61
 
58
- split_api_key_into_key_and_secret! auth_options if api_key
62
+ split_api_key_into_key_and_secret! auth_options if auth_options[:key]
59
63
 
60
64
  if using_basic_auth? && !api_key_present?
61
65
  raise ArgumentError, 'key is missing. Either an API key, token, or token auth method must be provided'
62
66
  end
63
67
 
64
68
  if has_client_id?
65
- raise ArgumentError, 'client_id cannot be provided without a complete API key. Key ID & Secret is needed to authenticate with Ably and obtain a token' unless api_key_present?
69
+ raise ArgumentError, 'client_id cannot be provided without a complete API key. Key name & Secret is needed to authenticate with Ably and obtain a token' unless api_key_present?
66
70
  ensure_utf_8 :client_id, client_id
67
71
  end
68
72
 
@@ -75,12 +79,8 @@ module Ably
75
79
  #
76
80
  # @param [Hash] options the options for the token request
77
81
  # @option options (see #request_token)
78
- # @option options [String] :key API key comprising the key ID and key secret in a single string
79
- # @option options [Boolean] :force obtains a new token even if the current token is valid
80
- #
81
- # @yield (see #request_token)
82
- # @yieldparam [Hash] options options passed to {#authorise} will be in turn sent to the block in this argument
83
- # @yieldreturn (see #request_token)
82
+ # @option options [String] :key API key comprising the key name and key secret in a single string
83
+ # @option options [Boolean] :force obtains a new token even if the current token is valid
84
84
  #
85
85
  # @return (see #request_token)
86
86
  #
@@ -95,43 +95,38 @@ module Ably
95
95
  # token_request
96
96
  # end
97
97
  #
98
- def authorise(options = {}, &token_request_block)
99
- if !options[:force] && current_token
100
- return current_token unless current_token.expired?
98
+ def authorise(options = {})
99
+ ensure_valid_auth_attributes options
100
+
101
+ if current_token_details && !options[:force]
102
+ return current_token_details unless current_token_details.expired?
101
103
  end
102
104
 
103
105
  options = options.clone
106
+ split_api_key_into_key_and_secret! options if options[:key]
107
+ @options = @options.merge(options) # update default options
104
108
 
105
- api_key = options[:key] || options[:api_key] # backwards support for previously used :api_key
106
- split_api_key_into_key_and_secret! options if api_key
107
-
108
- @options = @options.merge(options)
109
- @default_token_block = token_request_block if block_given?
110
-
111
- @current_token = request_token(options, &token_request_block)
109
+ @current_token_details = request_token(options)
112
110
  end
113
111
 
114
- # Request a {Ably::Models::Token} which can be used to make authenticated token based requests
112
+ # Request a {Ably::Models::TokenDetails} which can be used to make authenticated token based requests
115
113
  #
116
114
  # @param [Hash] options the options for the token request
117
- # @option options [String] :key_id key ID for the designated application (defaults to client key_id)
118
- # @option options [String] :key_secret key secret for the designated application used to sign token requests (defaults to client key_secret)
119
- # @option options [String] :client_id client ID identifying this connection to other clients (defaults to client client_id if configured)
120
- # @option 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.
121
- # @option options [Hash] :auth_headers a set of application-specific headers to be added to any request made to the authUrl
122
- # @option options [Hash] :auth_params a set of application-specific query params to be added to any request made to the authUrl
123
- # @option options [Symbol] :auth_method HTTP method to use with auth_url, must be either `:get` or `:post` (defaults to :get)
124
- # @option options [Integer] :ttl validity time in seconds for the requested {Ably::Models::Token}. Limits may apply, see {http://docs.ably.io/other/authentication/}
125
- # @option options [Hash] :capability canonicalised representation of the resource paths and associated operations
126
- # @option options [Boolean] :query_time when true will query the {https://ably.io Ably} system for the current time instead of using the local time
127
- # @option options [Time] :timestamp the time of the of the request
128
- # @option options [String] :nonce an unquoted, unescaped random string of at least 16 characters
129
- #
130
- # @yield [options] (optional) if a token request block is passed to this method, then this block will be called whenever a new token is required
131
- # @yieldparam [Hash] options options passed to {#request_token} will be in turn sent to the block in this argument
132
- # @yieldreturn [Hash] expects a valid token request object, see {#create_token_request}
115
+ # @option options [String] :key complete API key for the designated application
116
+ # @option options [String] :client_id client ID identifying this connection to other clients (defaults to client client_id if configured)
117
+ # @option 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.
118
+ # @option options [Hash] :auth_headers a set of application-specific headers to be added to any request made to the authUrl
119
+ # @option options [Hash] :auth_params a set of application-specific query params to be added to any request made to the authUrl
120
+ # @option options [Symbol] :auth_method HTTP method to use with auth_url, must be either `:get` or `:post` (defaults to :get)
121
+ # @option options [Proc] :auth_callback this Proc / block will be called with the {#auth_options Auth#auth_options Hash} as the first argument whenever a new token is required.
122
+ # The Proc should return a token string, {Ably::Models::TokenDetails} or JSON equivalent, {Ably::Models::TokenRequest} or JSON equivalent
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
133
128
  #
134
- # @return [Ably::Models::Token]
129
+ # @return [Ably::Models::TokenDetails]
135
130
  #
136
131
  # @example
137
132
  # # simple token request using basic auth
@@ -145,96 +140,104 @@ module Ably
145
140
  # end
146
141
  #
147
142
  def request_token(options = {})
148
- token_options = self.auth_options.merge(options)
149
-
150
- auth_url = token_options.delete(:auth_url)
151
- token_request = if block_given?
152
- yield token_options
153
- elsif default_token_block
154
- default_token_block.call(token_options)
155
- elsif auth_url
143
+ ensure_valid_auth_attributes options
144
+
145
+ token_options = auth_options.merge(options)
146
+
147
+ token_request = if auth_callback = token_options.delete(:auth_callback)
148
+ auth_callback.call(token_options)
149
+ elsif auth_url = token_options.delete(:auth_url)
156
150
  token_request_from_auth_url(auth_url, token_options)
157
151
  else
158
152
  create_token_request(token_options)
159
153
  end
160
154
 
161
- token_request = IdiomaticRubyWrapper(token_request)
162
-
163
- if token_request.has_key?(:issued_at) && token_request.has_key?(:expires)
164
- Ably::Models::Token.new(token_request)
165
- else
166
- response = client.post("/keys/#{token_request.fetch(:id)}/requestToken", token_request.hash, send_auth_header: false, disable_automatic_reauthorise: true)
167
- body = IdiomaticRubyWrapper(response.body)
168
- Ably::Models::Token.new(body.fetch(:access_token))
155
+ case token_request
156
+ when Ably::Models::TokenDetails
157
+ return token_request
158
+ when Hash
159
+ return Ably::Models::TokenDetails.new(token_request) if IdiomaticRubyWrapper(token_request).has_key?(:issued)
160
+ when String
161
+ return Ably::Models::TokenDetails.new(token: token_request)
169
162
  end
163
+
164
+ token_request = Ably::Models::TokenRequest(token_request)
165
+
166
+ response = client.post("/keys/#{token_request.key_name}/requestToken",
167
+ token_request.hash, send_auth_header: false,
168
+ disable_automatic_reauthorise: true)
169
+
170
+ Ably::Models::TokenDetails.new(response.body)
170
171
  end
171
172
 
172
173
  # Creates and signs a token request that can then subsequently be used by any client to request a token
173
174
  #
174
175
  # @param [Hash] options the options for the token request
175
- # @option options [String] :key_id key ID for the designated application
176
- # @option options [String] :key_secret key secret for the designated application used to sign token requests (defaults to client key_secret)
176
+ # @option options [String] :key complete API key for the designated application
177
177
  # @option options [String] :client_id client ID identifying this connection to other clients
178
- # @option options [Integer] :ttl validity time in seconds for the requested {Ably::Models::Token}. Limits may apply, see {http://docs.ably.io/other/authentication/}
178
+ # @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}
179
179
  # @option options [Hash] :capability canonicalised representation of the resource paths and associated operations
180
- # @option options [Boolean] :query_time when true will query the {https://ably.io Ably} system for the current time instead of using the local time
180
+ # @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
181
181
  # @option options [Time] :timestamp the time of the of the request
182
182
  # @option options [String] :nonce an unquoted, unescaped random string of at least 16 characters
183
- # @return [Hash]
183
+ #
184
+ # @return [Models::TokenRequest]
184
185
  #
185
186
  # @example
186
187
  # client.auth.create_token_request(id: 'asd.asd', ttl: 3600)
187
- # # => {
188
+ # #<Ably::Models::TokenRequest:0x007fd5d919df78
189
+ # # @hash={
188
190
  # # :id=>"asds.adsa",
189
- # # :client_id=>nil,
190
- # # :ttl=>3600,
191
- # # :timestamp=>1410718527,
191
+ # # :clientId=>nil,
192
+ # # :ttl=>3600000,
193
+ # # :timestamp=>1428973674000,
192
194
  # # :capability=>"{\"*\":[\"*\"]}",
193
195
  # # :nonce=>"95e543b88299f6bae83df9b12fbd1ecd",
194
- # # :mac=>"881oZHeFo6oMim7N64y2vFHtSlpQ2gn/uE56a8gUxHw="
195
- # # }
196
+ # # :mac=>"881oZHeFo6oMim7....uE56a8gUxHw="
197
+ # # }
198
+ # #>>
196
199
  def create_token_request(options = {})
197
- token_attributes = %w(id client_id ttl timestamp capability nonce persisted)
200
+ ensure_valid_auth_attributes options
198
201
 
199
- token_options = options.clone
202
+ token_options = options.clone
200
203
 
201
- request_key_id = token_options.delete(:key_id) || key_id
204
+ split_api_key_into_key_and_secret! token_options if token_options[:key]
205
+ request_key_name = token_options.delete(:key_name) || key_name
202
206
  request_key_secret = token_options.delete(:key_secret) || key_secret
203
-
204
- raise Ably::Exceptions::TokenRequestError, 'Key ID and Key Secret are required to generate a new token request' unless request_key_id && 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
205
208
 
206
209
  timestamp = if token_options[:query_time]
207
210
  client.time
208
211
  else
209
212
  token_options.delete(:timestamp) || Time.now
210
- end.to_i
213
+ end
214
+ timestamp = Time.at(timestamp) if timestamp.kind_of?(Integer)
211
215
 
212
216
  token_request = {
213
- id: request_key_id,
214
- clientId: client_id,
215
- ttl: Ably::Models::Token::DEFAULTS[:ttl],
216
- timestamp: timestamp,
217
- capability: Ably::Models::Token::DEFAULTS[:capability],
218
- nonce: SecureRandom.hex
219
- }.merge(token_options.select { |key, val| token_attributes.include?(key.to_s) })
220
-
221
- if token_request[:capability].is_a?(Hash)
222
- token_request[:capability] = token_request[:capability].to_json
223
- end
217
+ keyName: token_options[:key_name] || request_key_name,
218
+ clientId: token_options[:client_id] || client_id,
219
+ ttl: ((token_options[:ttl] || TOKEN_DEFAULTS.fetch(:ttl)) * 1000).to_i,
220
+ timestamp: (timestamp.to_f * 1000).round,
221
+ capability: token_options[:capability] || TOKEN_DEFAULTS.fetch(:capability),
222
+ nonce: token_options[:nonce] || SecureRandom.hex
223
+ }
224
224
 
225
- ensure_utf_8 :nonce, token_request[:nonce], allow_nil: true
225
+ token_request[:capability] = JSON.dump(token_request[:capability]) if token_request[:capability].is_a?(Hash)
226
226
 
227
227
  token_request[:mac] = sign_params(token_request, request_key_secret)
228
228
 
229
- convert_to_mixed_case_hash(token_request)
229
+ # Undocumented feature to request a persisted token
230
+ token_request[:persisted] = options[:persisted] if options[:persisted]
231
+
232
+ Models::TokenRequest.new(token_request)
230
233
  end
231
234
 
232
235
  def key
233
- "#{key_id}:#{key_secret}" if api_key_present?
236
+ "#{key_name}:#{key_secret}" if api_key_present?
234
237
  end
235
238
 
236
- def key_id
237
- options[:key_id]
239
+ def key_name
240
+ options[:key_name]
238
241
  end
239
242
 
240
243
  def key_secret
@@ -249,15 +252,21 @@ module Ably
249
252
  # True when Token Auth is being used to authenticate with Ably
250
253
  def using_token_auth?
251
254
  return options[:use_token_auth] if options.has_key?(:use_token_auth)
252
- token_id || current_token || has_client_id? || token_creatable_externally?
255
+ token || current_token_details || has_client_id? || token_creatable_externally?
253
256
  end
254
257
 
255
258
  def client_id
256
259
  options[:client_id]
257
260
  end
258
261
 
259
- def token_id
260
- options[:token_id]
262
+ def token
263
+ token_object = options[:token] || options[:token_details]
264
+
265
+ if token_object.kind_of?(Ably::Models::TokenDetails)
266
+ token_object.token
267
+ else
268
+ token_object
269
+ end
261
270
  end
262
271
 
263
272
  # Auth header string used in HTTP requests to Ably
@@ -285,13 +294,13 @@ module Ably
285
294
  # True if prerequisites for creating a new token request are present
286
295
  #
287
296
  # One of the following criterion must be met:
288
- # * Valid key id and secret and token_id option not provided as token options cannot be determined
297
+ # * Valid API key and token option not provided as token options cannot be determined
289
298
  # * Authentication callback for new token requests
290
299
  # * Authentication URL for new token requests
291
300
  #
292
301
  # @return [Boolean]
293
302
  def token_renewable?
294
- token_creatable_externally? || (api_key_present? && !token_id)
303
+ token_creatable_externally? || (api_key_present? && !token)
295
304
  end
296
305
 
297
306
  # Returns false when attempting to send an API Key over a non-secure connection
@@ -303,7 +312,45 @@ module Ably
303
312
  end
304
313
 
305
314
  private
306
- attr_reader :client, :default_token_block
315
+ attr_reader :client
316
+
317
+ def ensure_valid_auth_attributes(attributes)
318
+ if attributes[:timestamp]
319
+ unless attributes[:timestamp].kind_of?(Time) || attributes[:timestamp].kind_of?(Numeric)
320
+ raise ArgumentError, ':timestamp must be a Time or positive Integer value of seconds since epoch'
321
+ end
322
+ end
323
+
324
+ if attributes[:ttl]
325
+ unless attributes[:ttl].kind_of?(Numeric) && attributes[:ttl].to_f > 0
326
+ raise ArgumentError, ':ttl must be a positive Numeric value representing time to live in seconds'
327
+ end
328
+ end
329
+
330
+ if attributes[:auth_headers]
331
+ unless attributes[:auth_headers].kind_of?(Hash)
332
+ raise ArgumentError, ':auth_headers must be a valid Hash'
333
+ end
334
+ end
335
+
336
+ if attributes[:auth_params]
337
+ unless attributes[:auth_params].kind_of?(Hash)
338
+ raise ArgumentError, ':auth_params must be a valid Hash'
339
+ end
340
+ end
341
+
342
+ if attributes[:auth_method]
343
+ unless %(get post).include?(attributes[:auth_method].to_s)
344
+ raise ArgumentError, ':auth_method must be either :get or :post'
345
+ end
346
+ end
347
+
348
+ if attributes[:auth_callback]
349
+ unless attributes[:auth_callback].respond_to?(:call)
350
+ raise ArgumentError, ':auth_callback must be a Proc'
351
+ end
352
+ end
353
+ end
307
354
 
308
355
  def ensure_api_key_sent_over_secure_connection
309
356
  raise Ably::Exceptions::InsecureRequestError, 'Cannot use Basic Auth over non-TLS connections' unless authentication_security_requirements_met?
@@ -316,40 +363,41 @@ module Ably
316
363
  end
317
364
 
318
365
  def split_api_key_into_key_and_secret!(options)
319
- api_key_parts = (options[:key] || options[:api_key]).to_s.match(/(?<id>[\w_-]+\.[\w_-]+):(?<secret>[\w_-]+)/)
366
+ api_key_parts = options[:key].to_s.match(/(?<name>[\w_-]+\.[\w_-]+):(?<secret>[\w_-]+)/)
320
367
  raise ArgumentError, 'key is invalid' unless api_key_parts
321
368
 
322
- options[:key_id] = api_key_parts[:id].encode(Encoding::UTF_8)
369
+ options[:key_name] = api_key_parts[:name].encode(Encoding::UTF_8)
323
370
  options[:key_secret] = api_key_parts[:secret].encode(Encoding::UTF_8)
371
+
372
+ options.delete :key
324
373
  end
325
374
 
326
- def token_auth_id
327
- if token_id
328
- token_id
375
+ # Returns the current token if it exists or authorises and retrieves a token
376
+ def token_auth_string
377
+ if token
378
+ token
329
379
  else
330
- authorise.id
380
+ authorise.token
331
381
  end
332
382
  end
333
383
 
334
384
  # Token Auth HTTP Authorization header value
335
385
  def token_auth_header
336
- "Bearer #{encode64(token_auth_id)}"
386
+ "Bearer #{encode64(token_auth_string)}"
337
387
  end
338
388
 
339
389
  # Basic Auth params to authenticate the Realtime connection
340
390
  def basic_auth_params
341
391
  ensure_api_key_sent_over_secure_connection
342
- # TODO: Change to key_secret when API is updated
343
392
  {
344
- key_id: key_id,
345
- key_value: key_secret
393
+ key: key
346
394
  }
347
395
  end
348
396
 
349
397
  # Token Auth params to authenticate the Realtime connection
350
398
  def token_auth_params
351
399
  {
352
- access_token: token_auth_id
400
+ access_token: token_auth_string
353
401
  }
354
402
  end
355
403
 
@@ -358,13 +406,15 @@ module Ably
358
406
  # @return [Hash]
359
407
  def sign_params(params, secret)
360
408
  text = params.values_at(
361
- :id,
409
+ :keyName,
362
410
  :ttl,
363
411
  :capability,
364
- :client_id,
412
+ :clientId,
365
413
  :timestamp,
366
414
  :nonce
367
- ).map { |t| "#{t}\n" }.join("")
415
+ ).map do |val|
416
+ "#{val}\n"
417
+ end.join('')
368
418
 
369
419
  encode64(
370
420
  OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, secret, text)
@@ -385,7 +435,7 @@ module Ably
385
435
  request.headers = options[:auth_headers] || {}
386
436
  end
387
437
 
388
- unless response.body.kind_of?(Hash)
438
+ if !response.body.kind_of?(Hash) && response.headers['Content-Type'] != 'text/plain'
389
439
  raise Ably::Exceptions::InvalidResponseBody,
390
440
  "Content Type #{response.headers['Content-Type']} is not supported by this client library"
391
441
  end
@@ -427,8 +477,8 @@ module Ably
427
477
  end
428
478
  end
429
479
 
430
- def token_callback_present?
431
- !!default_token_block
480
+ def auth_callback_present?
481
+ !!options[:auth_callback]
432
482
  end
433
483
 
434
484
  def token_url_present?
@@ -436,7 +486,7 @@ module Ably
436
486
  end
437
487
 
438
488
  def token_creatable_externally?
439
- token_callback_present? || token_url_present?
489
+ auth_callback_present? || token_url_present?
440
490
  end
441
491
 
442
492
  def has_client_id?
@@ -444,7 +494,7 @@ module Ably
444
494
  end
445
495
 
446
496
  def api_key_present?
447
- key_id && key_secret
497
+ key_name && key_secret
448
498
  end
449
499
  end
450
500
  end