ably-pubsub-core 0.0.1.pre

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 (105) hide show
  1. checksums.yaml +7 -0
  2. data/lib/ably/agent.rb +8 -0
  3. data/lib/ably/auth.rb +791 -0
  4. data/lib/ably/exceptions.rb +169 -0
  5. data/lib/ably/logger.rb +119 -0
  6. data/lib/ably/models/auth_details.rb +45 -0
  7. data/lib/ably/models/channel_details.rb +69 -0
  8. data/lib/ably/models/channel_metrics.rb +107 -0
  9. data/lib/ably/models/channel_occupancy.rb +50 -0
  10. data/lib/ably/models/channel_options.rb +120 -0
  11. data/lib/ably/models/channel_state_change.rb +84 -0
  12. data/lib/ably/models/channel_status.rb +63 -0
  13. data/lib/ably/models/cipher_params.rb +137 -0
  14. data/lib/ably/models/connection_details.rb +149 -0
  15. data/lib/ably/models/connection_state_change.rb +83 -0
  16. data/lib/ably/models/delta_extras.rb +28 -0
  17. data/lib/ably/models/device_details.rb +126 -0
  18. data/lib/ably/models/device_push_details.rb +94 -0
  19. data/lib/ably/models/error_info.rb +104 -0
  20. data/lib/ably/models/http_paginated_response.rb +112 -0
  21. data/lib/ably/models/idiomatic_ruby_wrapper.rb +235 -0
  22. data/lib/ably/models/message.rb +223 -0
  23. data/lib/ably/models/message_encoders/base.rb +135 -0
  24. data/lib/ably/models/message_encoders/base64.rb +40 -0
  25. data/lib/ably/models/message_encoders/cipher.rb +84 -0
  26. data/lib/ably/models/message_encoders/json.rb +34 -0
  27. data/lib/ably/models/message_encoders/utf8.rb +26 -0
  28. data/lib/ably/models/nil_logger.rb +20 -0
  29. data/lib/ably/models/paginated_result.rb +201 -0
  30. data/lib/ably/models/presence_message.rb +244 -0
  31. data/lib/ably/models/protocol_message.rb +288 -0
  32. data/lib/ably/models/push_channel_subscription.rb +114 -0
  33. data/lib/ably/models/stats.rb +242 -0
  34. data/lib/ably/models/stats_types.rb +107 -0
  35. data/lib/ably/models/token_details.rb +148 -0
  36. data/lib/ably/models/token_request.rb +180 -0
  37. data/lib/ably/modules/ably.rb +26 -0
  38. data/lib/ably/modules/async_wrapper.rb +69 -0
  39. data/lib/ably/modules/channels_collection.rb +105 -0
  40. data/lib/ably/modules/conversions.rb +153 -0
  41. data/lib/ably/modules/encodeable.rb +111 -0
  42. data/lib/ably/modules/enum.rb +230 -0
  43. data/lib/ably/modules/event_emitter.rb +200 -0
  44. data/lib/ably/modules/event_machine_helpers.rb +26 -0
  45. data/lib/ably/modules/exception_codes.rb +128 -0
  46. data/lib/ably/modules/http_helpers.rb +41 -0
  47. data/lib/ably/modules/message_emitter.rb +78 -0
  48. data/lib/ably/modules/message_pack.rb +14 -0
  49. data/lib/ably/modules/model_common.rb +84 -0
  50. data/lib/ably/modules/safe_deferrable.rb +83 -0
  51. data/lib/ably/modules/safe_yield.rb +41 -0
  52. data/lib/ably/modules/state_emitter.rb +181 -0
  53. data/lib/ably/modules/state_machine.rb +59 -0
  54. data/lib/ably/modules/statesman_monkey_patch.rb +33 -0
  55. data/lib/ably/modules/uses_state_machine.rb +111 -0
  56. data/lib/ably/realtime/auth.rb +283 -0
  57. data/lib/ably/realtime/channel/channel_manager.rb +272 -0
  58. data/lib/ably/realtime/channel/channel_properties.rb +40 -0
  59. data/lib/ably/realtime/channel/channel_state_machine.rb +104 -0
  60. data/lib/ably/realtime/channel/publisher.rb +82 -0
  61. data/lib/ably/realtime/channel/push_channel.rb +69 -0
  62. data/lib/ably/realtime/channel.rb +440 -0
  63. data/lib/ably/realtime/channels.rb +71 -0
  64. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +225 -0
  65. data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +87 -0
  66. data/lib/ably/realtime/client.rb +363 -0
  67. data/lib/ably/realtime/connection/connection_manager.rb +594 -0
  68. data/lib/ably/realtime/connection/connection_state_machine.rb +144 -0
  69. data/lib/ably/realtime/connection/websocket_transport.rb +287 -0
  70. data/lib/ably/realtime/connection.rb +738 -0
  71. data/lib/ably/realtime/models/nil_channel.rb +30 -0
  72. data/lib/ably/realtime/presence/members_map.rb +395 -0
  73. data/lib/ably/realtime/presence/presence_manager.rb +78 -0
  74. data/lib/ably/realtime/presence/presence_state_machine.rb +57 -0
  75. data/lib/ably/realtime/presence.rb +502 -0
  76. data/lib/ably/realtime/push/admin.rb +75 -0
  77. data/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
  78. data/lib/ably/realtime/push/device_registrations.rb +105 -0
  79. data/lib/ably/realtime/push.rb +25 -0
  80. data/lib/ably/realtime/recovery_key_context.rb +36 -0
  81. data/lib/ably/realtime.rb +60 -0
  82. data/lib/ably/rest/channel/push_channel.rb +59 -0
  83. data/lib/ably/rest/channel.rb +194 -0
  84. data/lib/ably/rest/channels.rb +47 -0
  85. data/lib/ably/rest/client.rb +727 -0
  86. data/lib/ably/rest/middleware/encoder.rb +49 -0
  87. data/lib/ably/rest/middleware/exceptions.rb +53 -0
  88. data/lib/ably/rest/middleware/external_exceptions.rb +24 -0
  89. data/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +22 -0
  90. data/lib/ably/rest/middleware/logger.rb +58 -0
  91. data/lib/ably/rest/middleware/parse_json.rb +27 -0
  92. data/lib/ably/rest/middleware/parse_message_pack.rb +43 -0
  93. data/lib/ably/rest/presence.rb +113 -0
  94. data/lib/ably/rest/push/admin.rb +58 -0
  95. data/lib/ably/rest/push/channel_subscriptions.rb +121 -0
  96. data/lib/ably/rest/push/device_registrations.rb +114 -0
  97. data/lib/ably/rest/push.rb +25 -0
  98. data/lib/ably/rest.rb +40 -0
  99. data/lib/ably/util/ably_extensions.rb +29 -0
  100. data/lib/ably/util/crypto.rb +134 -0
  101. data/lib/ably/util/pub_sub.rb +45 -0
  102. data/lib/ably/util/safe_deferrable.rb +44 -0
  103. data/lib/ably/version.rb +7 -0
  104. data/lib/ably.rb +16 -0
  105. metadata +497 -0
@@ -0,0 +1,59 @@
1
+ require 'statesman'
2
+ require 'ably/modules/statesman_monkey_patch'
3
+
4
+ module Ably::Modules
5
+ # Module providing Statesman StateMachine functionality
6
+ #
7
+ # Expects method #logger to be defined
8
+ #
9
+ # @api private
10
+ module StateMachine
11
+ def self.included(klass)
12
+ klass.class_eval do
13
+ include Statesman::Machine
14
+ end
15
+ klass.extend Ably::Modules::StatesmanMonkeyPatch
16
+ klass.extend ClassMethods
17
+ end
18
+
19
+ # Alternative to Statesman's #transition_to that:
20
+ # * log state change failures to {Logger}
21
+ #
22
+ # @return [void]
23
+ #
24
+ def transition_state(state, *args)
25
+ unless result = transition_to(state.to_sym, *args)
26
+ exception = exception_for_state_change_to(state)
27
+ logger.fatal { "#{self.class}: #{exception.message}\n#{caller[0..20].join("\n")}" }
28
+ end
29
+ result
30
+ end
31
+
32
+ # @return [Statesman History Object]
33
+ #
34
+ def previous_transition
35
+ history[-2]
36
+ end
37
+
38
+ # @return [Symbol]
39
+ #
40
+ def previous_state
41
+ previous_transition.to_state if previous_transition
42
+ end
43
+
44
+ # @return [Ably::Exceptions::InvalidStateChange]
45
+ #
46
+ def exception_for_state_change_to(state)
47
+ error_message = "#{self.class}: Unable to transition from #{current_state} => #{state}"
48
+ Ably::Exceptions::InvalidStateChange.new(error_message, nil, Ably::Exceptions::Codes::CHANNEL_OPERATION_FAILED_INVALID_CHANNEL_STATE)
49
+ end
50
+
51
+ module ClassMethods
52
+ private
53
+
54
+ def is_error_type?(error)
55
+ error.kind_of?(Ably::Models::ErrorInfo) || error.kind_of?(StandardError)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,33 @@
1
+ module Ably::Modules
2
+ # @api private
3
+ module StatesmanMonkeyPatch
4
+ # Override Statesman's #before_transition to support :from arrays
5
+ # This can be removed once https://github.com/gocardless/statesman/issues/95 is solved
6
+ def before_transition(options = nil, &block)
7
+ arrayify_transition(options) do |options_without_from_array|
8
+ super(*options_without_from_array, &block)
9
+ end
10
+ end
11
+
12
+ # Override Statesman's #after_transition to support :from arrays
13
+ # This can be removed once https://github.com/gocardless/statesman/issues/95 is solved
14
+ def after_transition(options = nil, &block)
15
+ arrayify_transition(options) do |options_without_from_array|
16
+ super(*options_without_from_array, &block)
17
+ end
18
+ end
19
+
20
+ private
21
+ def arrayify_transition(options, &block)
22
+ if options.nil?
23
+ yield []
24
+ elsif options.fetch(:from, nil).kind_of?(Array)
25
+ options[:from].each do |from_state|
26
+ yield [options.merge(from: from_state)]
27
+ end
28
+ else
29
+ yield [options]
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,111 @@
1
+ module Ably::Modules
2
+ # Mixing module that assists with {https://github.com/gocardless/statesman Statemans State Machine} state transitions
3
+ # and maintaining state of this object's #state.
4
+ #
5
+ # Expects:
6
+ # - @state_machine is set to the StateMachine
7
+ # - StateEmitter is included in the object
8
+ #
9
+ module UsesStateMachine
10
+ extend Forwardable
11
+
12
+ # Call #transition_to on the StateMachine
13
+ #
14
+ # @return [Boolean] true if new_state can be transitioned to by state machine
15
+ # @api private
16
+ def transition_state_machine(new_state, emit_params = {})
17
+ state_machine.transition_state(new_state, emit_object(new_state, emit_params))
18
+ end
19
+
20
+ # Call #transition_to! on the StateMachine
21
+ # An exception wil be raised if new_state cannot be transitioned to by state machine
22
+ #
23
+ # @return [void]
24
+ # @api private
25
+ def transition_state_machine!(new_state, emit_params = {})
26
+ state_machine.transition_to!(new_state, emit_object(new_state, emit_params))
27
+ end
28
+
29
+ # Provides an internal method for this object's state to match the StateMachine's current state.
30
+ # The current object's state will be changed to the StateMachine state and will emit an event
31
+ # @api private
32
+ def synchronize_state_with_statemachine(*args)
33
+ log_state_machine_state_change
34
+ change_state state_machine.current_state, state_machine.last_transition.metadata
35
+ end
36
+
37
+ # @!attribute [r] previous_state
38
+ # @return [STATE,nil] The previous state for this connection
39
+ # @api private
40
+ def previous_state
41
+ if state_machine.previous_state
42
+ STATE(state_machine.previous_state)
43
+ end
44
+ end
45
+
46
+ # @!attribute [r] state_history
47
+ # @return [Array<Hash>] All previous states including the current state in date ascending order with Hash properties :state, :metadata, :transitioned_at
48
+ # @api private
49
+ def state_history
50
+ state_machine.history.map do |transition|
51
+ {
52
+ state: STATE(transition.to_state),
53
+ metadata: transition.metadata,
54
+ transitioned_at: transition.created_at
55
+ }
56
+ end
57
+ end
58
+
59
+ def_delegators :state_machine, :can_transition_to?
60
+
61
+ private
62
+ def state_machine
63
+ @state_machine
64
+ end
65
+
66
+ def_delegators :state_machine, :exception_for_state_change_to
67
+
68
+ def log_state_machine_state_change
69
+ if state_machine.previous_state
70
+ logger.debug { "#{self.class.name}: Transitioned from #{state_machine.previous_state} => #{state_machine.current_state}" }
71
+ else
72
+ logger.debug { "#{self.class.name}: Transitioned to #{state_machine.current_state}" }
73
+ end
74
+ end
75
+
76
+ def emit_object(new_state, emit_params)
77
+ if self.class.emits_klass
78
+ self.class.emits_klass.new((emit_params || {}).merge(
79
+ current: STATE(new_state),
80
+ previous: STATE(state_machine.current_state),
81
+ event: EVENT(new_state)
82
+ ))
83
+ else
84
+ emit_params
85
+ end
86
+ end
87
+
88
+ def self.included(base)
89
+ base.extend(ClassMethods)
90
+ end
91
+
92
+ module ClassMethods
93
+ def emits_klass
94
+ @emits_klass ||= if defined?(@emits_klass_name) && @emits_klass_name
95
+ get_const(@emits_klass_name)
96
+ end
97
+ end
98
+
99
+ def ensure_state_machine_emits(klass)
100
+ @emits_klass_name = klass
101
+ end
102
+
103
+ def get_const(klass_name)
104
+ klass_names = klass_name.split('::')
105
+ klass_names.inject(Kernel) do |klass, name|
106
+ klass.const_get(name)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,283 @@
1
+ require 'ably/auth'
2
+
3
+ module Ably
4
+ module Realtime
5
+ # Auth is responsible for authentication with {https://www.ably.com Ably} using basic or token authentication
6
+ # This {Ably::Realtime::Auth Realtime::Auth} class wraps the {Ably::Auth Synchronous Ably::Auth} class in an EventMachine friendly way using Deferrables for all IO. See {Ably::Auth Ably::Auth} for more information
7
+ #
8
+ # Find out more about Ably authentication at: https://www.ably.com/docs/general/authentication/
9
+ #
10
+ # @!attribute [r] client_id
11
+ # (see Ably::Auth#client_id)
12
+ # @!attribute [r] current_token_details
13
+ # (see Ably::Auth#current_token_details)
14
+ # @!attribute [r] token
15
+ # (see Ably::Auth#token)
16
+ # @!attribute [r] key
17
+ # (see Ably::Auth#key)
18
+ # @!attribute [r] key_name
19
+ # (see Ably::Auth#key_name)
20
+ # @!attribute [r] key_secret
21
+ # (see Ably::Auth#key_secret)
22
+ # @!attribute [r] options
23
+ # (see Ably::Auth#options)
24
+ # @!attribute [r] token_params
25
+ # (see Ably::Auth#options)
26
+ # @!attribute [r] using_basic_auth?
27
+ # (see Ably::Auth#using_basic_auth?)
28
+ # @!attribute [r] using_token_auth?
29
+ # (see Ably::Auth#using_token_auth?)
30
+ # @!attribute [r] token_renewable?
31
+ # (see Ably::Auth#token_renewable?)
32
+ # @!attribute [r] authentication_security_requirements_met?
33
+ # (see Ably::Auth#authentication_security_requirements_met?)
34
+ #
35
+ class Auth
36
+ extend Forwardable
37
+ include Ably::Modules::AsyncWrapper
38
+
39
+ def_delegators :auth_sync, :client_id
40
+ def_delegators :auth_sync, :token_client_id_allowed?, :configure_client_id, :client_id_validated?
41
+ def_delegators :auth_sync, :can_assume_client_id?, :has_client_id?
42
+ def_delegators :auth_sync, :current_token_details, :token
43
+ def_delegators :auth_sync, :key, :key_name, :key_secret, :options, :auth_options, :token_params
44
+ def_delegators :auth_sync, :using_basic_auth?, :using_token_auth?
45
+ def_delegators :auth_sync, :token_renewable?, :authentication_security_requirements_met?
46
+ def_delegators :client, :logger
47
+ def_delegators :client, :connection
48
+
49
+ def initialize(client)
50
+ @client = client
51
+ @auth_sync = client.rest_client.auth
52
+ end
53
+
54
+ # For new connections, 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.
55
+ # If a connection is already established, the connection will be upgraded with a new token
56
+ #
57
+ # In the event that a new token request is made, the provided options are used
58
+ #
59
+ # @param (see Ably::Auth#authorize)
60
+ # @option (see Ably::Auth#authorize)
61
+ #
62
+ # @return [Ably::Util::SafeDeferrable]
63
+ # @yield [Ably::Models::TokenDetails]
64
+ #
65
+ # @example
66
+ # # will issue a simple token request using basic auth
67
+ # client = Ably::Rest::Client.new(key: 'key.id:secret')
68
+ # client.auth.authorize do |token_details|
69
+ # token_details #=> Ably::Models::TokenDetails
70
+ # end
71
+ #
72
+ def authorize(token_params = nil, auth_options = nil, &success_callback)
73
+ Ably::Util::SafeDeferrable.new(logger).tap do |authorize_method_deferrable|
74
+ # Wrap the sync authorize method and wait for the result from the deferrable
75
+ async_wrap do
76
+ authorize_sync(token_params, auth_options)
77
+ end.tap do |auth_operation|
78
+ # Authorize operation succeeded and we have a new token, now let's perform inline authentication
79
+ auth_operation.callback do |token|
80
+ case connection.state.to_sym
81
+ when :initialized, :disconnected, :suspended, :closed, :closing, :failed
82
+ connection.connect
83
+ when :connected
84
+ perform_inline_auth token
85
+ when :connecting
86
+ # Fail all current connection attempts and try again with the new token, see #RTC8b
87
+ connection.manager.release_and_establish_new_transport
88
+ else
89
+ logger.fatal { "Auth#authorize: unsupported state #{connection.state}" }
90
+ authorize_method_deferrable.fail Ably::Exceptions::InvalidState.new("Unsupported state #{connection.state} for Auth#authorize")
91
+ next
92
+ end
93
+
94
+ # Indicate success or failure based on response from realtime, see #RTC8b1
95
+ auth_deferrable_resolved = false
96
+
97
+ connection.unsafe_once(:connected, :update) do
98
+ auth_deferrable_resolved = true
99
+ authorize_method_deferrable.succeed token
100
+ end
101
+ connection.unsafe_once(:suspended, :closed, :failed) do |state_change|
102
+ auth_deferrable_resolved = true
103
+ authorize_method_deferrable.fail state_change.reason
104
+ end
105
+ end
106
+
107
+ # Authorize failed, likely due to auth_url or auth_callback failing
108
+ auth_operation.errback do |error|
109
+ client.connection.transition_state_machine :failed, reason: error if error.kind_of?(Ably::Exceptions::IncompatibleClientId)
110
+ authorize_method_deferrable.fail error
111
+ end
112
+ end
113
+
114
+ # Call the block provided to this method upon success of this deferrable
115
+ authorize_method_deferrable.callback do |token|
116
+ yield token if block_given?
117
+ end
118
+ end
119
+ end
120
+
121
+ # @deprecated Use {#authorize} instead
122
+ def authorise(*args, &block)
123
+ logger.warn { "Auth#authorise is deprecated and will be removed in 1.0. Please use Auth#authorize instead" }
124
+ authorize(*args, &block)
125
+ end
126
+
127
+ # Synchronous version of {#authorize}. See {Ably::Auth#authorize} for method definition
128
+ # Please note that authorize_sync will however not upgrade the current connection's token as this requires
129
+ # an synchronous operation to send the new authentication details to Ably over a realtime connection
130
+ #
131
+ # @param (see Ably::Auth#authorize)
132
+ # @option (see Ably::Auth#authorize)
133
+ # @return [Ably::Models::TokenDetails]
134
+ #
135
+ def authorize_sync(token_params = nil, auth_options = nil)
136
+ @authorization_in_flight = true
137
+ auth_sync.authorize(token_params, auth_options)
138
+ ensure
139
+ @authorization_in_flight = false
140
+ end
141
+
142
+ # @api private
143
+ def authorization_in_flight?
144
+ @authorization_in_flight
145
+ end
146
+
147
+ # @deprecated Use {#authorize_sync} instead
148
+ def authorise_sync(*args)
149
+ logger.warn { "Auth#authorise_sync is deprecated and will be removed in 1.0. Please use Auth#authorize_sync instead" }
150
+ authorize_sync(*args)
151
+ end
152
+
153
+ # Request a {Ably::Models::TokenDetails} which can be used to make authenticated token based requests
154
+ #
155
+ # @param (see Ably::Auth#request_token)
156
+ # @option (see Ably::Auth#request_token)
157
+ #
158
+ # @return [Ably::Util::SafeDeferrable]
159
+ # @yield [Ably::Models::TokenDetails]
160
+ #
161
+ # @example
162
+ # # simple token request using basic auth
163
+ # client = Ably::Rest::Client.new(key: 'key.id:secret')
164
+ # client.auth.request_token do |token_details|
165
+ # token_details #=> Ably::Models::TokenDetails
166
+ # end
167
+ #
168
+ def request_token(token_params = {}, auth_options = {}, &success_callback)
169
+ async_wrap(success_callback) do
170
+ request_token_sync(token_params, auth_options)
171
+ end
172
+ end
173
+
174
+ # Synchronous version of {#request_token}. See {Ably::Auth#request_token} for method definition
175
+ # @param (see Ably::Auth#authorize)
176
+ # @option (see Ably::Auth#authorize)
177
+ # @return [Ably::Models::TokenDetails]
178
+ #
179
+ def request_token_sync(token_params = {}, auth_options = {})
180
+ auth_sync.request_token(token_params, auth_options)
181
+ end
182
+
183
+ # Creates and signs a token request that can then subsequently be used by any client to request a token
184
+ #
185
+ # @param (see Ably::Auth#create_token_request)
186
+ # @option (see Ably::Auth#create_token_request)
187
+ #
188
+ # @return [Ably::Util::SafeDeferrable]
189
+ # @yield [Models::TokenRequest]
190
+ #
191
+ # @example
192
+ # client.auth.create_token_request({ ttl: 3600 }, id: 'asd.asd') do |token_request|
193
+ # token_request #=> Ably::Models::TokenRequest
194
+ # end
195
+ def create_token_request(token_params = {}, auth_options = {}, &success_callback)
196
+ async_wrap(success_callback) do
197
+ create_token_request_sync(token_params, auth_options)
198
+ end
199
+ end
200
+
201
+ # Synchronous version of {#create_token_request}. See {Ably::Auth#create_token_request} for method definition
202
+ # @param (see Ably::Auth#authorize)
203
+ # @option (see Ably::Auth#authorize)
204
+ # @return [Ably::Models::TokenRequest]
205
+ #
206
+ def create_token_request_sync(token_params = {}, auth_options = {})
207
+ auth_sync.create_token_request(token_params, auth_options)
208
+ end
209
+
210
+ # Auth header string used in HTTP requests to Ably
211
+ # Will reauthorize implicitly if required and capable
212
+ #
213
+ # @return [Ably::Util::SafeDeferrable]
214
+ # @yield [String] HTTP authentication value used in HTTP_AUTHORIZATION header
215
+ #
216
+ def auth_header(&success_callback)
217
+ async_wrap(success_callback) do
218
+ auth_header_sync
219
+ end
220
+ end
221
+
222
+ # Synchronous version of {#auth_header}. See {Ably::Auth#auth_header} for method definition
223
+ # @return [String] HTTP authentication value used in HTTP_AUTHORIZATION header
224
+ #
225
+ def auth_header_sync
226
+ auth_sync.auth_header
227
+ end
228
+
229
+ def client_id_for_request_sync
230
+ auth_sync.client_id_for_request
231
+ end
232
+
233
+ # Auth params used in URI endpoint for Realtime connections
234
+ # Will reauthorize implicitly if required and capable
235
+ #
236
+ # @return [Ably::Util::SafeDeferrable]
237
+ # @yield [Hash] Auth params for a new Realtime connection
238
+ #
239
+ def auth_params(&success_callback)
240
+ fail_callback = lambda do |error, deferrable|
241
+ logger.error { "Failed to authenticate: #{error}" }
242
+ if error.kind_of?(Ably::Exceptions::BaseAblyException)
243
+ # Use base exception if it exists carrying forward the status codes
244
+ deferrable.fail Ably::Exceptions::AuthenticationFailed.new(error.message, nil, nil, error)
245
+ else
246
+ deferrable.fail Ably::Exceptions::AuthenticationFailed.new(error.message, 500, Ably::Exceptions::Codes::CLIENT_CONFIGURED_AUTHENTICATION_PROVIDER_REQUEST_FAILED)
247
+ end
248
+ end
249
+ async_wrap(success_callback, fail_callback) do
250
+ auth_params_sync
251
+ end
252
+ end
253
+
254
+ # Synchronous version of {#auth_params}. See {Ably::Auth#auth_params} for method definition
255
+ # @return [Hash] Auth params for a new Realtime connection
256
+ #
257
+ def auth_params_sync
258
+ auth_sync.auth_params
259
+ end
260
+
261
+ private
262
+ # The synchronous Auth class instanced by the Rest client
263
+ # @return [Ably::Auth]
264
+ def auth_sync
265
+ @auth_sync
266
+ end
267
+
268
+ def client
269
+ @client
270
+ end
271
+
272
+ # Sends an AUTH ProtocolMessage on the existing connection triggering
273
+ # an inline AUTH process, see #RTC8a
274
+ def perform_inline_auth(token)
275
+ logger.debug { "Performing inline AUTH with Ably using token #{token}" }
276
+ connection.send_protocol_message(
277
+ action: Ably::Models::ProtocolMessage::ACTION.Auth.to_i,
278
+ auth: { access_token: token.token }
279
+ )
280
+ end
281
+ end
282
+ end
283
+ end