ably 0.8.11 → 0.8.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -3
- data/lib/ably/auth.rb +72 -20
- data/lib/ably/realtime/auth.rb +22 -4
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +1 -1
- data/lib/ably/realtime/connection/connection_manager.rb +1 -1
- data/lib/ably/rest/client.rb +1 -1
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/auth_spec.rb +189 -0
- data/spec/acceptance/rest/auth_spec.rb +85 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83a334452c78f5a9522b8aef6edef8a376da22c4
|
4
|
+
data.tar.gz: e00a360302db7a510633beeb840c1a81d565d3f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46211a7336813fdcbc6160b161c97a7a66af8cc95ad02b40757d55326f30839a9754db67c95235a394805d1cea7afe52618311556c55436127f99f92349a26e0
|
7
|
+
data.tar.gz: 67674b15c02b127e72d0b982b40735f1366b6b0384e8e0cbe0945334e6c724fd2e1c162dac12c99d9c8a12a8d19fa78685749036da4ab3ac972ba9e3274890d8
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,28 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [v0.8.
|
3
|
+
## [v0.8.12](https://github.com/ably/ably-ruby/tree/v0.8.12)
|
4
4
|
|
5
|
-
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.
|
5
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.11...v0.8.12)
|
6
6
|
|
7
7
|
**Fixed bugs:**
|
8
8
|
|
9
|
-
-
|
9
|
+
- Ably::Exceptions::ConnectionError: SSL\_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed [\#87](https://github.com/ably/ably-ruby/issues/87)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Reauthorise [\#90](https://github.com/ably/ably-ruby/pull/90) ([mattheworiordan](https://github.com/mattheworiordan))
|
14
|
+
|
15
|
+
## [v0.8.11](https://github.com/ably/ably-ruby/tree/v0.8.11) (2016-04-05)
|
16
|
+
|
17
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.10...v0.8.11)
|
18
|
+
|
19
|
+
**Merged pull requests:**
|
20
|
+
|
21
|
+
- Ensure message emitter callbacks are safe \(i.e. cannot break the EM\) [\#85](https://github.com/ably/ably-ruby/pull/85) ([mattheworiordan](https://github.com/mattheworiordan))
|
22
|
+
|
23
|
+
## [v0.8.10](https://github.com/ably/ably-ruby/tree/v0.8.10) (2016-04-01)
|
24
|
+
|
25
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.9...v0.8.10)
|
10
26
|
|
11
27
|
## [v0.8.9](https://github.com/ably/ably-ruby/tree/v0.8.9) (2016-03-01)
|
12
28
|
|
data/lib/ably/auth.rb
CHANGED
@@ -72,6 +72,7 @@ module Ably
|
|
72
72
|
end
|
73
73
|
|
74
74
|
split_api_key_into_key_and_secret! options if options[:key]
|
75
|
+
store_and_delete_basic_auth_key_from_options! options
|
75
76
|
|
76
77
|
if using_basic_auth? && !api_key_present?
|
77
78
|
raise ArgumentError, 'key is missing. Either an API key, token, or token auth method must be provided'
|
@@ -104,9 +105,9 @@ module Ably
|
|
104
105
|
#
|
105
106
|
# In the event that a new token request is made, the provided options are used.
|
106
107
|
#
|
107
|
-
# @param [Hash] token_params the token params used for future token requests
|
108
|
-
# @param [Hash] auth_options the authentication options used for future token requests
|
109
|
-
# @option auth_options [Boolean] :force obtains a new token even if the current token is valid
|
108
|
+
# @param [Hash, nil] token_params the token params used for future token requests. When nil, previously configured token params are used
|
109
|
+
# @param [Hash, nil] auth_options the authentication options used for future token requests. When nil, previously configure authentication options are used
|
110
|
+
# @option auth_options [Boolean] :force obtains a new token even if the current token is valid. If the provided +auth_options+ Hash contains only this +:force+ attribute, the existing configured authentication options are not overwriten
|
110
111
|
# @option (see #request_token)
|
111
112
|
#
|
112
113
|
# @return (see #create_token_request)
|
@@ -122,23 +123,54 @@ module Ably
|
|
122
123
|
# token_request
|
123
124
|
# end
|
124
125
|
#
|
125
|
-
def authorise(token_params =
|
126
|
-
|
126
|
+
def authorise(token_params = nil, auth_options = nil)
|
127
|
+
if auth_options == { force: true }
|
128
|
+
auth_options = options.merge(force: true)
|
129
|
+
elsif auth_options.nil?
|
130
|
+
auth_options = options
|
131
|
+
else
|
132
|
+
ensure_valid_auth_attributes auth_options
|
127
133
|
|
128
|
-
|
134
|
+
auth_options = auth_options.clone
|
129
135
|
|
130
|
-
|
131
|
-
|
136
|
+
if auth_options[:token_params]
|
137
|
+
token_params = auth_options.delete(:token_params).merge(token_params || {})
|
138
|
+
end
|
139
|
+
|
140
|
+
# If basic credentials are provided then overwrite existing options
|
141
|
+
# otherwise we need to retain the existing credentials in the auth options
|
142
|
+
split_api_key_into_key_and_secret! auth_options if auth_options[:key]
|
143
|
+
if auth_options[:key_name] && auth_options[:key_secret]
|
144
|
+
store_and_delete_basic_auth_key_from_options! auth_options
|
145
|
+
end
|
146
|
+
|
147
|
+
@options = auth_options.clone
|
148
|
+
|
149
|
+
# Force reauth and query the server time only happens once
|
150
|
+
# the otpions remain in auth_options though so they are passed to request_token
|
151
|
+
@options.delete(:query_time)
|
152
|
+
@options.delete(:force)
|
153
|
+
|
154
|
+
@options.freeze
|
132
155
|
end
|
133
156
|
|
134
|
-
|
135
|
-
|
157
|
+
unless token_params.nil?
|
158
|
+
@token_params = token_params
|
159
|
+
@token_params.freeze
|
160
|
+
end
|
136
161
|
|
137
|
-
|
138
|
-
|
162
|
+
if current_token_details && !auth_options[:force]
|
163
|
+
return current_token_details unless current_token_details.expired?
|
164
|
+
end
|
139
165
|
|
140
|
-
authorise_with_token(request_token(token_params, auth_options)).tap do |new_token_details|
|
166
|
+
authorise_with_token(request_token(@token_params, auth_options)).tap do |new_token_details|
|
141
167
|
logger.debug "Auth: new token following authorisation: #{new_token_details}"
|
168
|
+
|
169
|
+
# If authorise was forced allow a block to be called so that the realtime library
|
170
|
+
# can force upgrade the authorisation
|
171
|
+
if auth_options[:force] && block_given?
|
172
|
+
yield new_token_details
|
173
|
+
end
|
142
174
|
end
|
143
175
|
end
|
144
176
|
|
@@ -240,11 +272,8 @@ module Ably
|
|
240
272
|
|
241
273
|
raise Ably::Exceptions::TokenRequestFailed, 'Key Name and Key Secret are required to generate a new token request' unless request_key_name && request_key_secret
|
242
274
|
|
243
|
-
|
244
|
-
|
245
|
-
else
|
246
|
-
token_params.delete(:timestamp) || Time.now
|
247
|
-
end
|
275
|
+
ensure_current_time_is_based_on_server_time if auth_options[:query_time]
|
276
|
+
timestamp = token_params.delete(:timestamp) || current_time
|
248
277
|
timestamp = Time.at(timestamp) if timestamp.kind_of?(Integer)
|
249
278
|
|
250
279
|
ttl = [
|
@@ -276,11 +305,11 @@ module Ably
|
|
276
305
|
end
|
277
306
|
|
278
307
|
def key_name
|
279
|
-
|
308
|
+
@key_name
|
280
309
|
end
|
281
310
|
|
282
311
|
def key_secret
|
283
|
-
|
312
|
+
@key_secret
|
284
313
|
end
|
285
314
|
|
286
315
|
# True when Basic Auth is being used to authenticate with Ably
|
@@ -413,6 +442,24 @@ module Ably
|
|
413
442
|
@token_option
|
414
443
|
end
|
415
444
|
|
445
|
+
# Returns the current device clock time unless the
|
446
|
+
# the server time has previously been requested with query_time: true
|
447
|
+
# and the @server_time_offset is configured
|
448
|
+
def current_time
|
449
|
+
if @server_time_offset
|
450
|
+
Time.now + @server_time_offset
|
451
|
+
else
|
452
|
+
Time.now
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
# Get the difference in time between the server
|
457
|
+
# and the local clock and store this for future time requests
|
458
|
+
def ensure_current_time_is_based_on_server_time
|
459
|
+
server_time = client.time
|
460
|
+
@server_time_offset = server_time.to_f - Time.now.to_f
|
461
|
+
end
|
462
|
+
|
416
463
|
def ensure_valid_auth_attributes(attributes)
|
417
464
|
if attributes[:timestamp]
|
418
465
|
unless attributes[:timestamp].kind_of?(Time) || attributes[:timestamp].kind_of?(Numeric)
|
@@ -471,6 +518,11 @@ module Ably
|
|
471
518
|
options.delete :key
|
472
519
|
end
|
473
520
|
|
521
|
+
def store_and_delete_basic_auth_key_from_options!(options)
|
522
|
+
@key_name = options.delete(:key_name)
|
523
|
+
@key_secret = options.delete(:key_secret)
|
524
|
+
end
|
525
|
+
|
474
526
|
# Returns the current token if it exists or authorises and retrieves a token
|
475
527
|
def token_auth_string
|
476
528
|
if !current_token_details && token_option
|
data/lib/ably/realtime/auth.rb
CHANGED
@@ -67,9 +67,9 @@ module Ably
|
|
67
67
|
# token_details #=> Ably::Models::TokenDetails
|
68
68
|
# end
|
69
69
|
#
|
70
|
-
def authorise(token_params =
|
70
|
+
def authorise(token_params = nil, auth_options = nil, &success_callback)
|
71
71
|
async_wrap(success_callback) do
|
72
|
-
auth_sync.authorise(token_params, auth_options)
|
72
|
+
auth_sync.authorise(token_params, auth_options, &method(:upgrade_authentication_block).to_proc)
|
73
73
|
end.tap do |deferrable|
|
74
74
|
deferrable.errback do |error|
|
75
75
|
client.connection.transition_state_machine :failed, reason: error if error.kind_of?(Ably::Exceptions::IncompatibleClientId)
|
@@ -82,8 +82,8 @@ module Ably
|
|
82
82
|
# @option (see Ably::Auth#authorise)
|
83
83
|
# @return [Ably::Models::TokenDetails]
|
84
84
|
#
|
85
|
-
def authorise_sync(token_params =
|
86
|
-
auth_sync.authorise(token_params, auth_options)
|
85
|
+
def authorise_sync(token_params = nil, auth_options = nil)
|
86
|
+
auth_sync.authorise(token_params, auth_options, &method(:upgrade_authentication_block).to_proc)
|
87
87
|
end
|
88
88
|
|
89
89
|
# def_delegator :auth_sync, :request_token, :request_token_sync
|
@@ -196,6 +196,24 @@ module Ably
|
|
196
196
|
def client
|
197
197
|
@client
|
198
198
|
end
|
199
|
+
|
200
|
+
# If authorise is called with true, this block is executed so that it
|
201
|
+
# can perform the authentication upgrade
|
202
|
+
def upgrade_authentication_block(new_token)
|
203
|
+
# This block is called if the authorisation was forced
|
204
|
+
if client.connection.connected? || client.connection.connecting?
|
205
|
+
logger.debug "Realtime::Auth - authorise called with { force: true } so forcibly disconnecting transport to initiate auth upgrade"
|
206
|
+
block = Proc.new do
|
207
|
+
if client.connection.transport
|
208
|
+
logger.debug "Realtime::Auth - current transport disconnected"
|
209
|
+
client.connection.transport.disconnect
|
210
|
+
else
|
211
|
+
EventMachine.add_timer(0.1, &block)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
block.call
|
215
|
+
end
|
216
|
+
end
|
199
217
|
end
|
200
218
|
end
|
201
219
|
end
|
@@ -144,7 +144,7 @@ module Ably::Realtime
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def process_connection_error(protocol_message)
|
147
|
-
connection.manager.error_received_from_server
|
147
|
+
connection.manager.error_received_from_server(protocol_message.error || Ably::Models::ErrorInfo.new(message: 'Error reason unknown'))
|
148
148
|
end
|
149
149
|
|
150
150
|
def process_connected_message(protocol_message)
|
@@ -402,7 +402,7 @@ module Ably::Realtime
|
|
402
402
|
@renewing_token = true
|
403
403
|
logger.info "ConnectionManager: Token has expired and is renewable, renewing token now"
|
404
404
|
|
405
|
-
client.auth.authorise(
|
405
|
+
client.auth.authorise(nil, force: true).tap do |authorise_deferrable|
|
406
406
|
authorise_deferrable.callback do |token_details|
|
407
407
|
logger.info 'ConnectionManager: Token renewed succesfully following expiration'
|
408
408
|
|
data/lib/ably/rest/client.rb
CHANGED
data/lib/ably/version.rb
CHANGED
@@ -254,6 +254,195 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
254
254
|
end
|
255
255
|
end
|
256
256
|
end
|
257
|
+
|
258
|
+
context 'with force: true to trigger an authentication upgrade' do
|
259
|
+
let(:rest_client) { Ably::Rest::Client.new(default_options) }
|
260
|
+
let(:client_publisher) { auto_close Ably::Realtime::Client.new(default_options) }
|
261
|
+
let(:basic_capability) { JSON.dump("foo" => ["subscribe"]) }
|
262
|
+
let(:basic_token_cb) { Proc.new do
|
263
|
+
rest_client.auth.create_token_request({ capability: basic_capability })
|
264
|
+
end }
|
265
|
+
let(:upgraded_capability) { JSON.dump({ "foo" => ["subscribe", "publish"] }) }
|
266
|
+
let(:upgraded_token_cb) { Proc.new do
|
267
|
+
rest_client.auth.create_token_request({ capability: upgraded_capability })
|
268
|
+
end }
|
269
|
+
let(:identified_token_cb) { Proc.new do
|
270
|
+
rest_client.auth.create_token_request({ client_id: 'bob' })
|
271
|
+
end }
|
272
|
+
let(:downgraded_capability) { JSON.dump({ "bar" => ["subscribe"] }) }
|
273
|
+
let(:downgraded_token_cb) { Proc.new do
|
274
|
+
rest_client.auth.create_token_request({ capability: downgraded_capability })
|
275
|
+
end }
|
276
|
+
|
277
|
+
let(:client_options) { default_options.merge(auth_callback: basic_token_cb) }
|
278
|
+
|
279
|
+
it 'forces the connection to disconnect and reconnect with a new token when in the CONNECTED state' do
|
280
|
+
client.connection.once(:connected) do
|
281
|
+
existing_token = client.auth.current_token_details
|
282
|
+
client.auth.authorise(nil, force: true)
|
283
|
+
client.connection.once(:disconnected) do
|
284
|
+
client.connection.once(:connected) do
|
285
|
+
expect(existing_token).to_not eql(client.auth.current_token_details)
|
286
|
+
stop_reactor
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'forces the connection to disconnect and reconnect with a new token when in the CONNECTING state' do
|
293
|
+
client.connection.once(:connecting) do
|
294
|
+
existing_token = client.auth.current_token_details
|
295
|
+
client.auth.authorise(nil, force: true)
|
296
|
+
client.connection.once(:disconnected) do
|
297
|
+
client.connection.once(:connected) do
|
298
|
+
expect(existing_token).to_not eql(client.auth.current_token_details)
|
299
|
+
stop_reactor
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
context 'when client is identified' do
|
306
|
+
let(:client_options) { default_options.merge(auth_callback: basic_token_cb, log_level: :none) }
|
307
|
+
|
308
|
+
let(:basic_token_cb) { Proc.new do
|
309
|
+
rest_client.auth.create_token_request({ client_id: 'mike', capability: basic_capability })
|
310
|
+
end }
|
311
|
+
|
312
|
+
it 'transisitions the connection state to FAILED if the client_id changes' do
|
313
|
+
client.connection.once(:connected) do
|
314
|
+
client.auth.authorise(nil, auth_callback: identified_token_cb, force: true)
|
315
|
+
client.connection.once(:failed) do
|
316
|
+
expect(client.connection.error_reason.message).to match(/incompatible.*client ID/)
|
317
|
+
stop_reactor
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'when upgrading capabilities' do
|
324
|
+
let(:client_options) { default_options.merge(auth_callback: basic_token_cb, log_level: :error) }
|
325
|
+
|
326
|
+
it 'is allowed' do
|
327
|
+
client.connection.once(:connected) do
|
328
|
+
channel = client.channels.get('foo')
|
329
|
+
channel.publish('not-allowed').errback do |error|
|
330
|
+
expect(error.code).to eql(40160)
|
331
|
+
expect(error.message).to match(/permission denied/)
|
332
|
+
client.auth.authorise(nil, auth_callback: upgraded_token_cb, force: true)
|
333
|
+
client.connection.once(:connected) do
|
334
|
+
expect(client.connection.error_reason).to be_nil
|
335
|
+
channel.subscribe('allowed') do |message|
|
336
|
+
stop_reactor
|
337
|
+
end
|
338
|
+
channel.publish 'allowed'
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
context 'when downgrading capabilities' do
|
346
|
+
let(:client_options) { default_options.merge(auth_callback: basic_token_cb, log_level: :none) }
|
347
|
+
|
348
|
+
it 'is allowed and channels are detached' do
|
349
|
+
client.connection.once(:connected) do
|
350
|
+
channel = client.channels.get('foo')
|
351
|
+
channel.attach do
|
352
|
+
client.auth.authorise(nil, auth_callback: downgraded_token_cb, force: true)
|
353
|
+
channel.once(:failed) do
|
354
|
+
expect(channel.error_reason.code).to eql(40160)
|
355
|
+
expect(channel.error_reason.message).to match(/Channel denied access/)
|
356
|
+
stop_reactor
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'ensures message delivery continuity whilst upgrading' do
|
364
|
+
received_messages = []
|
365
|
+
subscriber_channel = client.channels.get('foo')
|
366
|
+
publisher_channel = client_publisher.channels.get('foo')
|
367
|
+
subscriber_channel.attach do
|
368
|
+
subscriber_channel.subscribe do |message|
|
369
|
+
received_messages << message
|
370
|
+
end
|
371
|
+
publisher_channel.attach do
|
372
|
+
publisher_channel.publish('foo') do
|
373
|
+
EventMachine.add_timer(2) do
|
374
|
+
expect(received_messages.length).to eql(1)
|
375
|
+
client.auth.authorise(nil, force: true)
|
376
|
+
client.connection.once(:disconnected) do
|
377
|
+
publisher_channel.publish('bar') do
|
378
|
+
expect(received_messages.length).to eql(1)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
client.connection.once(:connected) do
|
382
|
+
EventMachine.add_timer(2) do
|
383
|
+
expect(received_messages.length).to eql(2)
|
384
|
+
stop_reactor
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
it 'does not change the connection state if current connection state is closing' do
|
394
|
+
client.connection.once(:connected) do
|
395
|
+
client.connection.once(:closing) do
|
396
|
+
client.auth.authorise(nil, force: true)
|
397
|
+
client.connection.once(:connected) do
|
398
|
+
raise "Should not reconnect following auth force: true"
|
399
|
+
end
|
400
|
+
EventMachine.add_timer(4) do
|
401
|
+
expect(client.connection).to be_closed
|
402
|
+
stop_reactor
|
403
|
+
end
|
404
|
+
end
|
405
|
+
client.connection.close
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
it 'does not change the connection state if current connection state is closed' do
|
410
|
+
client.connection.once(:connected) do
|
411
|
+
client.connection.once(:closed) do
|
412
|
+
client.auth.authorise(nil, force: true)
|
413
|
+
client.connection.once(:connected) do
|
414
|
+
raise "Should not reconnect following auth force: true"
|
415
|
+
end
|
416
|
+
EventMachine.add_timer(4) do
|
417
|
+
expect(client.connection).to be_closed
|
418
|
+
stop_reactor
|
419
|
+
end
|
420
|
+
end
|
421
|
+
client.connection.close
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
context 'when state is failed' do
|
426
|
+
let(:client_options) { default_options.merge(auth_callback: basic_token_cb, log_level: :none) }
|
427
|
+
|
428
|
+
it 'does not change the connection state' do
|
429
|
+
client.connection.once(:connected) do
|
430
|
+
client.connection.once(:failed) do
|
431
|
+
client.auth.authorise(nil, force: true)
|
432
|
+
client.connection.once(:connected) do
|
433
|
+
raise "Should not reconnect following auth force: true"
|
434
|
+
end
|
435
|
+
EventMachine.add_timer(4) do
|
436
|
+
expect(client.connection).to be_failed
|
437
|
+
stop_reactor
|
438
|
+
end
|
439
|
+
end
|
440
|
+
protocol_message = Ably::Models::ProtocolMessage.new(action: Ably::Models::ProtocolMessage::ACTION.Error.to_i)
|
441
|
+
client.connection.__incoming_protocol_msgbus__.publish :protocol_message, protocol_message
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
257
446
|
end
|
258
447
|
|
259
448
|
context '#authorise_async' do
|
@@ -612,6 +612,87 @@ describe Ably::Auth do
|
|
612
612
|
end
|
613
613
|
end
|
614
614
|
|
615
|
+
context 'query_time: true' do
|
616
|
+
let(:local_time) { @now - 60 }
|
617
|
+
let(:server_time) { @now }
|
618
|
+
|
619
|
+
before do
|
620
|
+
@now = Time.now
|
621
|
+
allow(Time).to receive(:now).and_return(local_time)
|
622
|
+
end
|
623
|
+
|
624
|
+
it 'only queries the server time once and then works out the offset, query_time option is never persisted' do
|
625
|
+
expect(client).to receive(:time).once.and_return(server_time)
|
626
|
+
|
627
|
+
auth.authorise({}, query_time: true)
|
628
|
+
auth.authorise({}, force: true)
|
629
|
+
expect(auth.auth_options).to_not have_key(:query_time)
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
context 'TokenParams argument' do
|
634
|
+
let(:default_token_params) { { ttl: 23 } }
|
635
|
+
|
636
|
+
before do
|
637
|
+
auth.authorise default_token_params
|
638
|
+
end
|
639
|
+
|
640
|
+
it 'has no effect on the defaults when null and TokenParam defaults remain the same' do
|
641
|
+
old_token = auth.current_token_details
|
642
|
+
auth.authorise(nil, force: true)
|
643
|
+
expect(old_token).to_not eql(auth.current_token_details)
|
644
|
+
expect(auth.token_params[:ttl]).to eql(23)
|
645
|
+
end
|
646
|
+
|
647
|
+
it 'updates defaults when present and all previous configured TokenParams are discarded' do
|
648
|
+
old_token = auth.current_token_details
|
649
|
+
auth.authorise({ client_id: 'bob' }, { force: true })
|
650
|
+
expect(old_token).to_not eql(auth.current_token_details)
|
651
|
+
expect(auth.token_params[:ttl]).to_not eql(23)
|
652
|
+
expect(auth.token_params[:client_id]).to eql('bob')
|
653
|
+
end
|
654
|
+
|
655
|
+
it 'updates Auth#token_params attribute with an immutable hash' do
|
656
|
+
auth.authorise({ client_id: 'bob' }, { force: true })
|
657
|
+
expect { auth.token_params['key_name'] = 'new_name' }.to raise_error RuntimeError, /can't modify frozen.*Hash/
|
658
|
+
end
|
659
|
+
end
|
660
|
+
|
661
|
+
context 'AuthOptions argument' do
|
662
|
+
let(:token_ttl) { 2 }
|
663
|
+
let(:auth_callback) { Proc.new do
|
664
|
+
auth.create_token_request(ttl: token_ttl)
|
665
|
+
end }
|
666
|
+
let(:default_auth_options) { { auth_callback: auth_callback } }
|
667
|
+
|
668
|
+
before do
|
669
|
+
stub_const 'Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER', 0 # allow token to be used even if about to expire
|
670
|
+
stub_const 'Ably::Auth::TOKEN_DEFAULTS', Ably::Auth::TOKEN_DEFAULTS.merge(renew_token_buffer: 0) # Ensure tokens issued expire immediately after issue
|
671
|
+
|
672
|
+
auth.authorise(nil, default_auth_options)
|
673
|
+
@old_token = auth.current_token_details
|
674
|
+
sleep token_ttl + 0.5
|
675
|
+
end
|
676
|
+
|
677
|
+
it 'has no effect on the defaults when null and AuthOptions defaults remain the same' do
|
678
|
+
auth.authorise(nil, nil)
|
679
|
+
expect(@old_token).to_not eql(auth.current_token_details)
|
680
|
+
expect(auth.options[:auth_callback]).to eql(auth_callback)
|
681
|
+
end
|
682
|
+
|
683
|
+
it 'updates defaults when present and all previous configured AuthOptions are discarded' do
|
684
|
+
auth.authorise(nil, auth_method: :post)
|
685
|
+
expect(@old_token).to_not eql(auth.current_token_details)
|
686
|
+
expect(auth.options[:auth_callback]).to be_nil
|
687
|
+
expect(auth.options[:auth_method]).to eql(:post)
|
688
|
+
end
|
689
|
+
|
690
|
+
it 'updates Auth#options attribute with an immutable hash' do
|
691
|
+
auth.authorise(nil, auth_callback: Proc.new { '1231232.12321:12321312' })
|
692
|
+
expect { auth.options['key_name'] = 'new_name' }.to raise_error RuntimeError, /can't modify frozen.*Hash/
|
693
|
+
end
|
694
|
+
end
|
695
|
+
|
615
696
|
context 'with previous authorisation' do
|
616
697
|
before do
|
617
698
|
auth.authorise
|
@@ -640,10 +721,10 @@ describe Ably::Auth do
|
|
640
721
|
expect(auth.token_params[:ttl]).to eql(26)
|
641
722
|
end
|
642
723
|
|
643
|
-
it 'updates the persisted
|
644
|
-
expect(auth.options[:
|
645
|
-
auth.authorise({},
|
646
|
-
expect(auth.options[:
|
724
|
+
it 'updates the persisted auth options that are then used for subsequent authorise requests' do
|
725
|
+
expect(auth.options[:authUrl]).to be_nil
|
726
|
+
auth.authorise({}, authUrl: 'http://foo.com')
|
727
|
+
expect(auth.options[:authUrl]).to eql('http://foo.com')
|
647
728
|
end
|
648
729
|
|
649
730
|
context 'with a Proc for the :auth_callback option' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ably
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lewis Marshall
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-05-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|