ably-rest 0.8.3 → 0.8.5
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/.travis.yml +1 -0
- data/lib/submodules/ably-ruby/CHANGELOG.md +10 -0
- data/lib/submodules/ably-ruby/README.md +1 -1
- data/lib/submodules/ably-ruby/Rakefile +1 -1
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +24 -20
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +3 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +41 -0
- data/lib/submodules/ably-ruby/lib/ably/models/connection_state_change.rb +43 -0
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +2 -1
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +8 -6
- data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +4 -0
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +4 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/uses_state_machine.rb +35 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +13 -13
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +13 -5
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +27 -7
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +22 -12
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +16 -10
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/outgoing_message_dispatcher.rb +6 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +5 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +42 -24
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +25 -17
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +4 -4
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +3 -2
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/util/crypto.rb +15 -0
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +9 -9
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +168 -21
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channels_spec.rb +6 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +6 -5
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +29 -19
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +150 -35
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +146 -23
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +44 -24
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/stats_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/time_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +77 -46
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +31 -3
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +15 -5
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +9 -7
- data/lib/submodules/ably-ruby/spec/support/event_machine_helper.rb +30 -4
- data/lib/submodules/ably-ruby/spec/support/protocol_helper.rb +9 -6
- data/lib/submodules/ably-ruby/spec/unit/auth_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/channel_state_change_spec.rb +44 -0
- data/lib/submodules/ably-ruby/spec/unit/models/connection_state_change_spec.rb +54 -0
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +8 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/async_wrapper_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +18 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1b1045e268247db9dd96742a0c11404b03fbb533
|
|
4
|
+
data.tar.gz: 180a9c3dfee6b05b4fc8c8f947e1081bba97b635
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 163805382715a09c67f446297b49c5c4588ff2c141c3cc6173eb9917423305b3f532d076f46af854d6b869439e9e465a02eb23735e40be64fe8d017773d782a0
|
|
7
|
+
data.tar.gz: b024865d3a6f266681e0ed4224b6a14c1e4248e21f93958d357d3009010a662d02d779615a21d0c4616e6397fc6c1053c0afc887ef7c52dcde9c286e24960d3d
|
data/.travis.yml
CHANGED
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
**Implemented enhancements:**
|
|
8
8
|
|
|
9
|
+
- Add compatibility support for default Crypto params [\#53](https://github.com/ably/ably-ruby/issues/53)
|
|
10
|
+
|
|
11
|
+
- EventEmitter on connection [\#52](https://github.com/ably/ably-ruby/issues/52)
|
|
12
|
+
|
|
13
|
+
- Add test for connectionId attribute for a message sent over REST [\#50](https://github.com/ably/ably-ruby/issues/50)
|
|
14
|
+
|
|
9
15
|
- Implement :queue\_messages option [\#36](https://github.com/ably/ably-ruby/issues/36)
|
|
10
16
|
|
|
11
17
|
- Check that a non 200-299 status code for REST requests uses fallback hosts [\#35](https://github.com/ably/ably-ruby/issues/35)
|
|
@@ -32,6 +38,10 @@
|
|
|
32
38
|
|
|
33
39
|
**Merged pull requests:**
|
|
34
40
|
|
|
41
|
+
- Spec update to fix a number of issues [\#60](https://github.com/ably/ably-ruby/pull/60) ([mattheworiordan](https://github.com/mattheworiordan))
|
|
42
|
+
|
|
43
|
+
- Allow clientId to be provided on init if using externally created token [\#58](https://github.com/ably/ably-ruby/pull/58) ([SimonWoolf](https://github.com/SimonWoolf))
|
|
44
|
+
|
|
35
45
|
- Separate token params for auth [\#57](https://github.com/ably/ably-ruby/pull/57) ([mattheworiordan](https://github.com/mattheworiordan))
|
|
36
46
|
|
|
37
47
|
- Ensure files are required in a consistent order [\#51](https://github.com/ably/ably-ruby/pull/51) ([SimonWoolf](https://github.com/SimonWoolf))
|
|
@@ -187,7 +187,7 @@ token_details = client.auth.request_token
|
|
|
187
187
|
token_details.token # => "xVLyHw.CLchevH3hF....MDh9ZC_Q"
|
|
188
188
|
client = Ably::Rest.new(token: token_details.token)
|
|
189
189
|
|
|
190
|
-
token = client.auth.create_token_request(
|
|
190
|
+
token = client.auth.create_token_request(ttl: 3600)
|
|
191
191
|
# => {"id"=>...,
|
|
192
192
|
# "clientId"=>nil,
|
|
193
193
|
# "ttl"=>3600,
|
|
@@ -16,7 +16,7 @@ begin
|
|
|
16
16
|
namespace :doc do
|
|
17
17
|
desc 'Generate Markdown Specification from the RSpec public API tests'
|
|
18
18
|
task :spec do
|
|
19
|
-
ENV['
|
|
19
|
+
ENV['PROTOCOL'] = 'json'
|
|
20
20
|
|
|
21
21
|
rspec_task.rspec_opts = %w(
|
|
22
22
|
--require ./spec/support/markdown_spec_formatter
|
|
@@ -43,11 +43,11 @@ module Ably
|
|
|
43
43
|
# Creates an Auth object
|
|
44
44
|
#
|
|
45
45
|
# @param [Ably::Rest::Client] client {Ably::Rest::Client} this Auth object uses
|
|
46
|
-
# @param [Hash] auth_options the authentication options used as a default future token requests
|
|
47
46
|
# @param [Hash] token_params the token params used as a default for future token requests
|
|
47
|
+
# @param [Hash] auth_options the authentication options used as a default future token requests
|
|
48
48
|
# @option (see #request_token)
|
|
49
49
|
#
|
|
50
|
-
def initialize(client,
|
|
50
|
+
def initialize(client, token_params, auth_options)
|
|
51
51
|
unless auth_options.kind_of?(Hash)
|
|
52
52
|
raise ArgumentError, 'Expected auth_options to be a Hash'
|
|
53
53
|
end
|
|
@@ -74,7 +74,7 @@ module Ably
|
|
|
74
74
|
raise ArgumentError, 'key is missing. Either an API key, token, or token auth method must be provided'
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
if has_client_id?
|
|
77
|
+
if has_client_id? && !token_creatable_externally?
|
|
78
78
|
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?
|
|
79
79
|
ensure_utf_8 :client_id, client_id
|
|
80
80
|
end
|
|
@@ -87,8 +87,8 @@ module Ably
|
|
|
87
87
|
#
|
|
88
88
|
# In the event that a new token request is made, the provided options are used.
|
|
89
89
|
#
|
|
90
|
-
# @param [Hash] auth_options the authentication options used for future token requests
|
|
91
90
|
# @param [Hash] token_params the token params used for future token requests
|
|
91
|
+
# @param [Hash] auth_options the authentication options used for future token requests
|
|
92
92
|
# @option auth_options [Boolean] :force obtains a new token even if the current token is valid
|
|
93
93
|
# @option (see #request_token)
|
|
94
94
|
#
|
|
@@ -100,12 +100,12 @@ module Ably
|
|
|
100
100
|
# token_details = client.auth.authorise
|
|
101
101
|
#
|
|
102
102
|
# # will use token request from block to authorise if not already authorised
|
|
103
|
-
# token_details = client.auth.authorise auth_callback: Proc.new do
|
|
103
|
+
# token_details = client.auth.authorise {}, auth_callback: Proc.new do
|
|
104
104
|
# # create token_request object
|
|
105
105
|
# token_request
|
|
106
106
|
# end
|
|
107
107
|
#
|
|
108
|
-
def authorise(
|
|
108
|
+
def authorise(token_params = {}, auth_options = {})
|
|
109
109
|
ensure_valid_auth_attributes auth_options
|
|
110
110
|
|
|
111
111
|
auth_options = auth_options.clone
|
|
@@ -120,7 +120,7 @@ module Ably
|
|
|
120
120
|
token_params = (auth_options.delete(:token_params) || {}).merge(token_params)
|
|
121
121
|
@token_params = @token_params.merge(token_params) # update defaults
|
|
122
122
|
|
|
123
|
-
@current_token_details = request_token(
|
|
123
|
+
@current_token_details = request_token(token_params, auth_options)
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
# Request a {Ably::Models::TokenDetails} which can be used to make authenticated token based requests
|
|
@@ -143,15 +143,15 @@ module Ably
|
|
|
143
143
|
# token_details = client.auth.request_token
|
|
144
144
|
#
|
|
145
145
|
# # token request with token params
|
|
146
|
-
# client.auth.request_token
|
|
146
|
+
# client.auth.request_token ttl: 1.hour
|
|
147
147
|
#
|
|
148
148
|
# # token request using auth block
|
|
149
|
-
# token_details = client.auth.request_token auth_callback: Proc.new do
|
|
149
|
+
# token_details = client.auth.request_token {}, auth_callback: Proc.new do
|
|
150
150
|
# # create token_request object
|
|
151
151
|
# token_request
|
|
152
152
|
# end
|
|
153
153
|
#
|
|
154
|
-
def request_token(
|
|
154
|
+
def request_token(token_params = {}, auth_options = {})
|
|
155
155
|
ensure_valid_auth_attributes auth_options
|
|
156
156
|
|
|
157
157
|
token_params = (auth_options[:token_params] || {}).merge(token_params)
|
|
@@ -163,7 +163,7 @@ module Ably
|
|
|
163
163
|
elsif auth_url = auth_options.delete(:auth_url)
|
|
164
164
|
token_request_from_auth_url(auth_url, auth_options)
|
|
165
165
|
else
|
|
166
|
-
create_token_request(
|
|
166
|
+
create_token_request(token_params, auth_options)
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
case token_request
|
|
@@ -186,12 +186,6 @@ module Ably
|
|
|
186
186
|
|
|
187
187
|
# Creates and signs a token request that can then subsequently be used by any client to request a token
|
|
188
188
|
#
|
|
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
189
|
# @param [Hash] token_params the token params used in the token request
|
|
196
190
|
# @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
191
|
# @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}
|
|
@@ -199,10 +193,16 @@ module Ably
|
|
|
199
193
|
# @option token_params [Time] :timestamp the time of the request
|
|
200
194
|
# @option token_params [String] :nonce an unquoted, unescaped random string of at least 16 characters
|
|
201
195
|
#
|
|
196
|
+
# @param [Hash] auth_options the authentication options for the token request
|
|
197
|
+
# @option auth_options [String] :key API key comprising the key name and key secret in a single string
|
|
198
|
+
# @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)
|
|
199
|
+
# @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
|
|
200
|
+
# @option auth_options [Hash] :token_params convenience to pass in +token_params+ within the +auth_options+ argument, especially useful when setting default token_params in the client constructor
|
|
201
|
+
#
|
|
202
202
|
# @return [Models::TokenRequest]
|
|
203
203
|
#
|
|
204
204
|
# @example
|
|
205
|
-
# client.auth.create_token_request(id: 'asd.asd'
|
|
205
|
+
# client.auth.create_token_request({ ttl: 3600 }, { id: 'asd.asd' })
|
|
206
206
|
# #<Ably::Models::TokenRequest:0x007fd5d919df78
|
|
207
207
|
# # @hash={
|
|
208
208
|
# # :id=>"asds.adsa",
|
|
@@ -214,7 +214,7 @@ module Ably
|
|
|
214
214
|
# # :mac=>"881oZHeFo6oMim7....uE56a8gUxHw="
|
|
215
215
|
# # }
|
|
216
216
|
# #>>
|
|
217
|
-
def create_token_request(
|
|
217
|
+
def create_token_request(token_params = {}, auth_options = {})
|
|
218
218
|
ensure_valid_auth_attributes auth_options
|
|
219
219
|
|
|
220
220
|
auth_options = auth_options.clone
|
|
@@ -401,7 +401,11 @@ module Ably
|
|
|
401
401
|
|
|
402
402
|
# Returns the current token if it exists or authorises and retrieves a token
|
|
403
403
|
def token_auth_string
|
|
404
|
-
|
|
404
|
+
# If a TokenDetails object has been issued by this library
|
|
405
|
+
# then that Token will take precedence
|
|
406
|
+
if @current_token_details
|
|
407
|
+
authorise.token
|
|
408
|
+
elsif token # token string was configured in the options
|
|
405
409
|
token
|
|
406
410
|
else
|
|
407
411
|
authorise.token
|
|
@@ -58,6 +58,9 @@ module Ably
|
|
|
58
58
|
# Connection Timeout accessing Realtime or REST service
|
|
59
59
|
class ConnectionTimeout < ConnectionError; end
|
|
60
60
|
|
|
61
|
+
# Transport closed unexpectedly
|
|
62
|
+
class TransportClosed < ConnectionError; end
|
|
63
|
+
|
|
61
64
|
# Connection closed unexpectedly
|
|
62
65
|
class ConnectionClosed < ConnectionError; end
|
|
63
66
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Ably::Models
|
|
2
|
+
# ChannelStateChange is a class that is emitted by the {Ably::Realtime::Channel} object
|
|
3
|
+
# when a state change occurs
|
|
4
|
+
#
|
|
5
|
+
# @!attribute [r] current
|
|
6
|
+
# @return [Connection::STATE] Current connection state
|
|
7
|
+
# @!attribute [r] previous
|
|
8
|
+
# @return [Connection::STATE] Previous connection state
|
|
9
|
+
# @!attribute [r] reason
|
|
10
|
+
# @return [Ably::Models::ErrorInfo] Object describing the reason for a state change when not initiated by the consumer of the client library
|
|
11
|
+
#
|
|
12
|
+
class ChannelStateChange
|
|
13
|
+
include Ably::Modules::ModelCommon
|
|
14
|
+
|
|
15
|
+
def initialize(hash_object)
|
|
16
|
+
unless (hash_object.keys - [:current, :previous, :reason, :protocol_message]).empty?
|
|
17
|
+
raise ArgumentError, 'Invalid attributes, expecting :current, :previous, :reason'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
@hash_object = {
|
|
21
|
+
current: hash_object.fetch(:current),
|
|
22
|
+
previous: hash_object.fetch(:previous),
|
|
23
|
+
retry_in: hash_object[:retry_in],
|
|
24
|
+
reason: hash_object[:reason],
|
|
25
|
+
protocol_message: hash_object[:protocol_message]
|
|
26
|
+
}
|
|
27
|
+
rescue KeyError => e
|
|
28
|
+
raise ArgumentError, e
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
%w(current previous reason protocol_message).each do |attribute|
|
|
32
|
+
define_method attribute do
|
|
33
|
+
@hash_object[attribute.to_sym]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_s
|
|
38
|
+
"ChannelStateChange: current state #{current}, previous state #{previous}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Ably::Models
|
|
2
|
+
# ConnectionStateChange is a class that is emitted by the {Ably::Realtime::Connection} object
|
|
3
|
+
# when a state change occurs
|
|
4
|
+
#
|
|
5
|
+
# @!attribute [r] current
|
|
6
|
+
# @return [Connection::STATE] Current connection state
|
|
7
|
+
# @!attribute [r] previous
|
|
8
|
+
# @return [Connection::STATE] Previous connection state
|
|
9
|
+
# @!attribute [r] retry_in
|
|
10
|
+
# @return [Integer] Time in seconds until the connection will reattempt to connect when in the +:disconnected+ or +:suspended+ state
|
|
11
|
+
# @!attribute [r] reason
|
|
12
|
+
# @return [Ably::Models::ErrorInfo] Object describing the reason for a state change when not initiated by the consumer of the client library
|
|
13
|
+
#
|
|
14
|
+
class ConnectionStateChange
|
|
15
|
+
include Ably::Modules::ModelCommon
|
|
16
|
+
|
|
17
|
+
def initialize(hash_object)
|
|
18
|
+
unless (hash_object.keys - [:current, :previous, :retry_in, :reason, :protocol_message]).empty?
|
|
19
|
+
raise ArgumentError, 'Invalid attributes, expecting :current, :previous, :retry_in, :reason'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
@hash_object = {
|
|
23
|
+
current: hash_object.fetch(:current),
|
|
24
|
+
previous: hash_object.fetch(:previous),
|
|
25
|
+
retry_in: hash_object[:retry_in],
|
|
26
|
+
reason: hash_object[:reason],
|
|
27
|
+
protocol_message: hash_object[:protocol_message]
|
|
28
|
+
}
|
|
29
|
+
rescue KeyError => e
|
|
30
|
+
raise ArgumentError, e
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
%w(current previous retry_in reason protocol_message).each do |attribute|
|
|
34
|
+
define_method attribute do
|
|
35
|
+
@hash_object[attribute.to_sym]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def to_s
|
|
40
|
+
"ConnectionStateChange: current state #{current}, previous state #{previous}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -34,7 +34,7 @@ module Ably::Models
|
|
|
34
34
|
# @param attributes
|
|
35
35
|
# @option attributes [String] :token token used to authenticate requests
|
|
36
36
|
# @option attributes [String] :key_name API key name used to create this token
|
|
37
|
-
# @option attributes [Time,Integer] :issued
|
|
37
|
+
# @option attributes [Time,Integer] :issued Time the token was issued as Time or Integer in milliseconds
|
|
38
38
|
# @option attributes [Time,Integer] :expires Time the token expires as Time or Integer in milliseconds
|
|
39
39
|
# @option attributes [String] :capability JSON stringified capabilities assigned to this token
|
|
40
40
|
# @option attributes [String] :client_id client ID assigned to this token
|
|
@@ -52,31 +52,31 @@ module Ably::Models
|
|
|
52
52
|
# @!attribute [r] token
|
|
53
53
|
# @return [String] Token used to authenticate requests
|
|
54
54
|
def token
|
|
55
|
-
hash
|
|
55
|
+
hash[:token]
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# @!attribute [r] key_name
|
|
59
59
|
# @return [String] API key name used to create this token. An API key is made up of an API key name and secret delimited by a +:+
|
|
60
60
|
def key_name
|
|
61
|
-
hash
|
|
61
|
+
hash[:key_name]
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
# @!attribute [r] issued
|
|
65
65
|
# @return [Time] Time the token was issued
|
|
66
66
|
def issued
|
|
67
|
-
as_time_from_epoch(hash
|
|
67
|
+
as_time_from_epoch(hash[:issued], granularity: :ms, allow_nil: :true)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
# @!attribute [r] expires
|
|
71
71
|
# @return [Time] Time the token expires
|
|
72
72
|
def expires
|
|
73
|
-
as_time_from_epoch(hash
|
|
73
|
+
as_time_from_epoch(hash[:expires], granularity: :ms, allow_nil: :true)
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
# @!attribute [r] capability
|
|
77
77
|
# @return [Hash] Capabilities assigned to this token
|
|
78
78
|
def capability
|
|
79
|
-
JSON.parse(hash.fetch(:capability))
|
|
79
|
+
JSON.parse(hash.fetch(:capability)) if hash.fetch(:capability)
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
# @!attribute [r] client_id
|
|
@@ -86,9 +86,11 @@ module Ably::Models
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
# Returns true if token is expired or about to expire
|
|
89
|
+
# For tokens that have not got an explicit expires attribute expired? will always return true
|
|
89
90
|
#
|
|
90
91
|
# @return [Boolean]
|
|
91
92
|
def expired?
|
|
93
|
+
return false if !expires
|
|
92
94
|
expires < Time.now + TOKEN_EXPIRY_BUFFER
|
|
93
95
|
end
|
|
94
96
|
|
|
@@ -6,6 +6,8 @@ module Ably::Modules
|
|
|
6
6
|
|
|
7
7
|
private
|
|
8
8
|
def as_since_epoch(time, options = {})
|
|
9
|
+
return nil if options[:allow_nil] && !time
|
|
10
|
+
|
|
9
11
|
granularity = options.fetch(:granularity, :ms)
|
|
10
12
|
|
|
11
13
|
case time
|
|
@@ -19,6 +21,8 @@ module Ably::Modules
|
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def as_time_from_epoch(time, options = {})
|
|
24
|
+
return nil if options[:allow_nil] && !time
|
|
25
|
+
|
|
22
26
|
granularity = options.fetch(:granularity, :ms)
|
|
23
27
|
|
|
24
28
|
case time
|
|
@@ -141,7 +141,10 @@ module Ably::Modules
|
|
|
141
141
|
#
|
|
142
142
|
def deferrable_for_state_change_to(target_state)
|
|
143
143
|
Ably::Util::SafeDeferrable.new(logger).tap do |deferrable|
|
|
144
|
-
|
|
144
|
+
fail_proc = Proc.new do |state_change|
|
|
145
|
+
deferrable.fail state_change.reason
|
|
146
|
+
end
|
|
147
|
+
once_or_if(target_state, else: fail_proc) do
|
|
145
148
|
yield self if block_given?
|
|
146
149
|
deferrable.succeed self
|
|
147
150
|
end
|
|
@@ -13,8 +13,8 @@ module Ably::Modules
|
|
|
13
13
|
#
|
|
14
14
|
# @return [Boolean] true if new_state can be transitioned to by state machine
|
|
15
15
|
# @api private
|
|
16
|
-
def transition_state_machine(new_state,
|
|
17
|
-
state_machine.transition_state(new_state, emit_object)
|
|
16
|
+
def transition_state_machine(new_state, emit_params = {})
|
|
17
|
+
state_machine.transition_state(new_state, emit_object(new_state, emit_params))
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# Call #transition_to! on the StateMachine
|
|
@@ -22,8 +22,8 @@ module Ably::Modules
|
|
|
22
22
|
#
|
|
23
23
|
# @return [void]
|
|
24
24
|
# @api private
|
|
25
|
-
def transition_state_machine!(new_state,
|
|
26
|
-
state_machine.transition_to!(new_state, emit_object)
|
|
25
|
+
def transition_state_machine!(new_state, emit_params = {})
|
|
26
|
+
state_machine.transition_to!(new_state, emit_object(new_state, emit_params))
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# Provides an internal method for this object's state to match the StateMachine's current state.
|
|
@@ -70,5 +70,36 @@ module Ably::Modules
|
|
|
70
70
|
logger.debug "#{self.class.name}: Transitioned to #{state_machine.current_state}"
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
|
+
|
|
74
|
+
def emit_object(new_state, emit_params)
|
|
75
|
+
if self.class.emits_klass
|
|
76
|
+
self.class.emits_klass.new((emit_params || {}).merge(current: STATE(new_state), previous: STATE(state_machine.current_state)))
|
|
77
|
+
else
|
|
78
|
+
emit_params
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def self.included(base)
|
|
83
|
+
base.extend(ClassMethods)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
module ClassMethods
|
|
87
|
+
def emits_klass
|
|
88
|
+
@emits_klass ||= if @emits_klass_name
|
|
89
|
+
get_const(@emits_klass_name)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def ensure_state_machine_emits(klass)
|
|
94
|
+
@emits_klass_name = klass
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def get_const(klass_name)
|
|
98
|
+
klass_names = klass_name.split('::')
|
|
99
|
+
klass_names.inject(Kernel) do |klass, name|
|
|
100
|
+
klass.const_get(name)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
73
104
|
end
|
|
74
105
|
end
|