ably 0.8.8 → 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -2
- data/LICENSE +2 -2
- data/README.md +81 -20
- data/SPEC.md +235 -178
- data/lib/ably/auth.rb +1 -1
- data/lib/ably/exceptions.rb +10 -1
- data/lib/ably/models/cipher_params.rb +114 -0
- data/lib/ably/models/connection_details.rb +8 -6
- data/lib/ably/models/error_info.rb +3 -3
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +27 -20
- data/lib/ably/models/message.rb +15 -15
- data/lib/ably/models/message_encoders/cipher.rb +8 -7
- data/lib/ably/models/presence_message.rb +17 -17
- data/lib/ably/models/protocol_message.rb +26 -19
- data/lib/ably/models/stats.rb +15 -15
- data/lib/ably/models/token_details.rb +14 -12
- data/lib/ably/models/token_request.rb +16 -14
- data/lib/ably/modules/async_wrapper.rb +1 -1
- data/lib/ably/modules/encodeable.rb +10 -10
- data/lib/ably/modules/model_common.rb +13 -5
- data/lib/ably/realtime/channel.rb +1 -2
- data/lib/ably/realtime/presence.rb +29 -58
- data/lib/ably/realtime/presence/members_map.rb +2 -2
- data/lib/ably/rest/channel.rb +1 -2
- data/lib/ably/rest/middleware/exceptions.rb +14 -4
- data/lib/ably/rest/presence.rb +3 -1
- data/lib/ably/util/crypto.rb +50 -40
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/message_spec.rb +20 -20
- data/spec/acceptance/realtime/presence_history_spec.rb +7 -7
- data/spec/acceptance/realtime/presence_spec.rb +65 -77
- data/spec/acceptance/rest/auth_spec.rb +8 -8
- data/spec/acceptance/rest/base_spec.rb +4 -4
- data/spec/acceptance/rest/channel_spec.rb +1 -1
- data/spec/acceptance/rest/client_spec.rb +1 -1
- data/spec/acceptance/rest/encoders_spec.rb +4 -4
- data/spec/acceptance/rest/message_spec.rb +15 -15
- data/spec/acceptance/rest/presence_spec.rb +4 -4
- data/spec/shared/model_behaviour.rb +7 -7
- data/spec/unit/models/cipher_params_spec.rb +140 -0
- data/spec/unit/models/idiomatic_ruby_wrapper_spec.rb +15 -8
- data/spec/unit/models/message_encoders/cipher_spec.rb +28 -22
- data/spec/unit/models/message_encoders/json_spec.rb +24 -0
- data/spec/unit/models/protocol_message_spec.rb +3 -3
- data/spec/unit/util/crypto_spec.rb +50 -17
- metadata +5 -2
data/lib/ably/auth.rb
CHANGED
@@ -585,7 +585,7 @@ module Ably
|
|
585
585
|
token_request = Ably::Models::TokenRequest(token_request)
|
586
586
|
|
587
587
|
response = client.post("/keys/#{token_request.key_name}/requestToken",
|
588
|
-
token_request.
|
588
|
+
token_request.attributes, send_auth_header: false,
|
589
589
|
disable_automatic_reauthorise: true)
|
590
590
|
|
591
591
|
Ably::Models::TokenDetails.new(response.body)
|
data/lib/ably/exceptions.rb
CHANGED
@@ -32,6 +32,15 @@ module Ably
|
|
32
32
|
# An invalid request was received by Ably
|
33
33
|
class InvalidRequest < BaseAblyException; end
|
34
34
|
|
35
|
+
# Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided
|
36
|
+
class UnauthorizedRequest < BaseAblyException; end
|
37
|
+
|
38
|
+
# The request was a valid request, but Ably is refusing to respond to it
|
39
|
+
class ForbiddenRequest < BaseAblyException; end
|
40
|
+
|
41
|
+
# The requested resource could not be found but may be available again in the future
|
42
|
+
class ResourceMissing < BaseAblyException; end
|
43
|
+
|
35
44
|
# Ably Protocol message received that is invalid
|
36
45
|
class ProtocolError < BaseAblyException; end
|
37
46
|
|
@@ -92,7 +101,7 @@ module Ably
|
|
92
101
|
# The token request could not be created
|
93
102
|
class TokenRequestFailed < BaseAblyException; end
|
94
103
|
|
95
|
-
# The token has expired
|
104
|
+
# The token has expired, 40140..40149
|
96
105
|
class TokenExpired < BaseAblyException; end
|
97
106
|
|
98
107
|
# The message could not be delivered to the server
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'ably/util/crypto'
|
3
|
+
|
4
|
+
module Ably::Models
|
5
|
+
# Convert cipher param attributes to a {CipherParams} object
|
6
|
+
#
|
7
|
+
# @param attributes (see #initialize)
|
8
|
+
#
|
9
|
+
# @return [CipherParams]
|
10
|
+
def self.CipherParams(attributes)
|
11
|
+
case attributes
|
12
|
+
when CipherParams
|
13
|
+
return attributes
|
14
|
+
else
|
15
|
+
CipherParams.new(attributes || {})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# CipherParams is used to configure a channel for encryption
|
20
|
+
#
|
21
|
+
class CipherParams
|
22
|
+
include Ably::Modules::ModelCommon
|
23
|
+
|
24
|
+
# @param params [Hash]
|
25
|
+
# @option params [String,Binary] :key Required private key must be either a binary (e.g. a ASCII_8BIT encoded string), or a base64-encoded string. If the key is a base64-encoded string, the it will be automatically converted into a binary
|
26
|
+
# @option params [String] :algorithm optional (default AES), specify the encryption algorithm supported by {http://ruby-doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html OpenSSL::Cipher}
|
27
|
+
# @option params [String] :mode optional (default CBC), specify the cipher mode supported by {http://ruby-doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html OpenSSL::Cipher}
|
28
|
+
# @option params [Integer] :key_length optional (default 128), specify the key length of the cipher supported by {http://ruby-doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html OpenSSL::Cipher}
|
29
|
+
# @option params [String] :combined optional (default AES-128-CBC), specify in one option the algorithm, key length and cipher of the cipher supported by {http://ruby-doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html OpenSSL::Cipher}
|
30
|
+
#
|
31
|
+
def initialize(params = {})
|
32
|
+
@attributes = IdiomaticRubyWrapper(params.clone)
|
33
|
+
|
34
|
+
raise Ably::Exceptions::CipherError, ':key param is required' unless attributes[:key]
|
35
|
+
raise Ably::Exceptions::CipherError, ':key param must be a base64-encoded string or byte array (ASCII_8BIT enocdede string)' unless key.kind_of?(String)
|
36
|
+
attributes[:key] = decode_key(key) if key.kind_of?(String) && key.encoding != Encoding::ASCII_8BIT
|
37
|
+
|
38
|
+
if attributes[:combined]
|
39
|
+
match = /(?<algorithm>\w+)-(?<key_length>\d+)-(?<mode>\w+)/.match(attributes[:combined])
|
40
|
+
raise Ably::Exceptions::CipherError, "Invalid :combined param, expecting format such as AES-256-CBC" unless match
|
41
|
+
attributes[:algorithm] = match[:algorithm]
|
42
|
+
attributes[:key_length] = match[:key_length].to_i
|
43
|
+
attributes[:mode] = match[:mode]
|
44
|
+
end
|
45
|
+
|
46
|
+
if attributes[:key_length] && (key_length != attributes[:key_length])
|
47
|
+
raise Ably::Exceptions::CipherError, "Incompatible :key length of #{key_length} and provided :key_length of #{attributes[:key_length]}"
|
48
|
+
end
|
49
|
+
|
50
|
+
if algorithm == 'aes' && mode == 'cbc'
|
51
|
+
unless [128, 256].include?(key_length)
|
52
|
+
raise Ably::Exceptions::CipherError, "Unsupported key length #{key_length} for aes-cbc encryption. Encryption key must be 128 or 256 bits (16 or 32 ASCII characters)"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
attributes.freeze
|
57
|
+
end
|
58
|
+
|
59
|
+
# The Cipher algorithm string such as AES-128-CBC
|
60
|
+
# @param [Hash] params Hash containing :algorithm, :key_length and :mode key values
|
61
|
+
#
|
62
|
+
# @return [String]
|
63
|
+
def self.cipher_type(params)
|
64
|
+
"#{params[:algorithm]}-#{params[:key_length]}-#{params[:mode]}".to_s.upcase
|
65
|
+
end
|
66
|
+
|
67
|
+
# @!attribute [r] algorithm
|
68
|
+
# @return [String] The algorithm to use for encryption, currently only +AES+ is supported
|
69
|
+
def algorithm
|
70
|
+
attributes.fetch(:algorithm) do
|
71
|
+
Ably::Util::Crypto::DEFAULTS.fetch(:algorithm)
|
72
|
+
end.downcase
|
73
|
+
end
|
74
|
+
|
75
|
+
# @!attribute [r] key
|
76
|
+
# @return [Binary] Private key used to encrypt and decrypt payloads
|
77
|
+
def key
|
78
|
+
attributes[:key]
|
79
|
+
end
|
80
|
+
|
81
|
+
# @!attribute [r] key_length
|
82
|
+
# @return [Integer] The length in bits of the +key+
|
83
|
+
def key_length
|
84
|
+
key.unpack('b*').first.length
|
85
|
+
end
|
86
|
+
|
87
|
+
# @!attribute [r] mode
|
88
|
+
# @return [String] The cipher mode, currently only +CBC+ is supported
|
89
|
+
def mode
|
90
|
+
attributes.fetch(:mode) do
|
91
|
+
Ably::Util::Crypto::DEFAULTS.fetch(:mode)
|
92
|
+
end.downcase
|
93
|
+
end
|
94
|
+
|
95
|
+
# @!attribute [r] cipher_type
|
96
|
+
# @return [String] The complete Cipher algorithm string such as AES-128-CBC
|
97
|
+
def cipher_type
|
98
|
+
self.class.cipher_type(algorithm: algorithm, key_length: key_length, mode: mode)
|
99
|
+
end
|
100
|
+
|
101
|
+
# @!attribute [r] attributes
|
102
|
+
# @return [Hash] Access the token details Hash object ruby'fied to use symbolized keys
|
103
|
+
def attributes
|
104
|
+
@attributes
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def decode_key(encoded_key)
|
110
|
+
normalised_key = encoded_key.gsub('_', '/').gsub('-', '+')
|
111
|
+
Base64.decode64(normalised_key)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -32,23 +32,25 @@ module Ably::Models
|
|
32
32
|
#
|
33
33
|
def initialize(attributes = {})
|
34
34
|
@hash_object = IdiomaticRubyWrapper(attributes.clone)
|
35
|
-
|
36
|
-
|
35
|
+
if self.attributes[:connection_state_ttl]
|
36
|
+
self.attributes[:connection_state_ttl] = (self.attributes[:connection_state_ttl].to_f / 1000).round
|
37
|
+
end
|
38
|
+
self.attributes.freeze
|
37
39
|
end
|
38
40
|
|
39
41
|
%w(client_id connection_key max_message_size max_frame_size max_inbound_rate connection_state_ttl server_id).each do |attribute|
|
40
42
|
define_method attribute do
|
41
|
-
|
43
|
+
attributes[attribute.to_sym]
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
47
|
def has_client_id?
|
46
|
-
|
48
|
+
attributes.has_key?(:client_id)
|
47
49
|
end
|
48
50
|
|
49
|
-
# @!attribute [r]
|
51
|
+
# @!attribute [r] attributes
|
50
52
|
# @return [Hash] Access the token details Hash object ruby'fied to use symbolized keys
|
51
|
-
def
|
53
|
+
def attributes
|
52
54
|
@hash_object
|
53
55
|
end
|
54
56
|
end
|
@@ -8,7 +8,7 @@ module Ably::Models
|
|
8
8
|
# @return [Integer] Ably error code (see ably-common/protocol/errors.json)
|
9
9
|
# @!attribute [r] status
|
10
10
|
# @return [Integer] HTTP Status Code corresponding to this error, where applicable
|
11
|
-
# @!attribute [r]
|
11
|
+
# @!attribute [r] attributes
|
12
12
|
# @return [Hash] Access the protocol message Hash object ruby'fied to use symbolized keys
|
13
13
|
#
|
14
14
|
class ErrorInfo
|
@@ -21,12 +21,12 @@ module Ably::Models
|
|
21
21
|
|
22
22
|
%w(message code status_code).each do |attribute|
|
23
23
|
define_method attribute do
|
24
|
-
|
24
|
+
attributes[attribute.to_sym]
|
25
25
|
end
|
26
26
|
end
|
27
27
|
alias_method :status, :status_code
|
28
28
|
|
29
|
-
def
|
29
|
+
def attributes
|
30
30
|
@hash_object
|
31
31
|
end
|
32
32
|
|
@@ -57,14 +57,14 @@ module Ably::Models
|
|
57
57
|
$stderr.puts "<IdiomaticRubyWrapper#initialize> WARNING: Wrapping a IdiomaticRubyWrapper with another IdiomaticRubyWrapper"
|
58
58
|
end
|
59
59
|
|
60
|
-
@
|
61
|
-
@stop_at = Array(stop_at).each_with_object({}) do |key,
|
62
|
-
|
60
|
+
@attributes = mixedCaseHashObject
|
61
|
+
@stop_at = Array(stop_at).each_with_object({}) do |key, object|
|
62
|
+
object[convert_to_snake_case_symbol(key)] = true
|
63
63
|
end.freeze
|
64
64
|
end
|
65
65
|
|
66
66
|
def [](key)
|
67
|
-
value =
|
67
|
+
value = attributes[source_key_for(key)]
|
68
68
|
if stop_at?(key) || !value.kind_of?(Hash)
|
69
69
|
value
|
70
70
|
else
|
@@ -73,7 +73,7 @@ module Ably::Models
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def []=(key, value)
|
76
|
-
|
76
|
+
attributes[source_key_for(key)] = value
|
77
77
|
end
|
78
78
|
|
79
79
|
def fetch(key, default = nil)
|
@@ -91,7 +91,7 @@ module Ably::Models
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def size
|
94
|
-
|
94
|
+
attributes.size
|
95
95
|
end
|
96
96
|
|
97
97
|
def keys
|
@@ -103,14 +103,14 @@ module Ably::Models
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def has_key?(key)
|
106
|
-
|
106
|
+
attributes.has_key?(source_key_for(key))
|
107
107
|
end
|
108
108
|
|
109
109
|
# Method ensuring this {IdiomaticRubyWrapper} is {http://ruby-doc.org/core-2.1.3/Enumerable.html Enumerable}
|
110
110
|
def each
|
111
111
|
return to_enum(:each) unless block_given?
|
112
112
|
|
113
|
-
|
113
|
+
attributes.each do |key, value|
|
114
114
|
key = convert_to_snake_case_symbol(key)
|
115
115
|
value = self[key]
|
116
116
|
yield key, value
|
@@ -138,9 +138,10 @@ module Ably::Models
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
-
#
|
142
|
-
|
143
|
-
|
141
|
+
# @!attribute [r] Hash
|
142
|
+
# @return [Hash] Access to the raw Hash object provided to the constructer of this wrapper
|
143
|
+
def attributes
|
144
|
+
@attributes
|
144
145
|
end
|
145
146
|
|
146
147
|
# Takes the underlying Hash object and returns it in as a JSON ready Hash object using snakeCase for compability with the Ably service.
|
@@ -149,7 +150,7 @@ module Ably::Models
|
|
149
150
|
# wrapper = IdiomaticRubyWrapper({ 'mixedCase': true, mixed_case: false, 'snake_case': 1 })
|
150
151
|
# wrapper.as_json({ 'mixedCase': true, 'snakeCase': 1 })
|
151
152
|
def as_json(*args)
|
152
|
-
|
153
|
+
attributes.each_with_object({}) do |key_val, new_hash|
|
153
154
|
key = key_val[0]
|
154
155
|
mixed_case_key = convert_to_mixed_case(key)
|
155
156
|
wrapped_val = self[key]
|
@@ -171,26 +172,32 @@ module Ably::Models
|
|
171
172
|
# wrapper = IdiomaticRubyWrapper({ 'mixedCase': true, mixed_case: false, 'snake_case': 1 })
|
172
173
|
# wrapper.to_hash({ mixed_case: true, snake_case: 1 })
|
173
174
|
def to_hash(*args)
|
174
|
-
each_with_object({}) do |key_val,
|
175
|
-
key, val
|
176
|
-
val
|
177
|
-
|
175
|
+
each_with_object({}) do |key_val, object|
|
176
|
+
key, val = key_val
|
177
|
+
val = val.to_hash(args) if val.kind_of?(IdiomaticRubyWrapper)
|
178
|
+
object[key] = val
|
178
179
|
end
|
179
180
|
end
|
180
181
|
|
181
182
|
# Method to create a duplicate of the underlying Hash object
|
182
183
|
# Useful when underlying Hash is frozen
|
183
184
|
def dup
|
184
|
-
Ably::Models::IdiomaticRubyWrapper.new(
|
185
|
+
Ably::Models::IdiomaticRubyWrapper.new(attributes.dup, stop_at: stop_at.keys)
|
185
186
|
end
|
186
187
|
|
187
188
|
# Freeze the underlying data
|
188
189
|
def freeze
|
189
|
-
|
190
|
+
attributes.freeze
|
190
191
|
end
|
191
192
|
|
192
193
|
def to_s
|
193
|
-
|
194
|
+
attributes.to_s
|
195
|
+
end
|
196
|
+
|
197
|
+
# @!attribute [r] hash
|
198
|
+
# @return [Integer] Compute a hash-code for this hash. Two hashes with the same content will have the same hash code
|
199
|
+
def hash
|
200
|
+
attributes.hash
|
194
201
|
end
|
195
202
|
|
196
203
|
private
|
@@ -214,7 +221,7 @@ module Ably::Models
|
|
214
221
|
]
|
215
222
|
|
216
223
|
preferred_format = format_preferences.detect do |format|
|
217
|
-
|
224
|
+
attributes.has_key?(format.call(symbolized_key))
|
218
225
|
end || format_preferences.first
|
219
226
|
|
220
227
|
preferred_format.call(symbolized_key)
|
data/lib/ably/models/message.rb
CHANGED
@@ -34,7 +34,7 @@ module Ably::Models
|
|
34
34
|
# @return [String] A globally unique message ID
|
35
35
|
# @!attribute [r] connection_id
|
36
36
|
# @return [String] The connection_id of the publisher of the message
|
37
|
-
# @!attribute [r]
|
37
|
+
# @!attribute [r] attributes
|
38
38
|
# @return [Hash] Access the protocol message Hash object ruby'fied to use symbolized keys
|
39
39
|
#
|
40
40
|
class Message
|
@@ -45,17 +45,17 @@ module Ably::Models
|
|
45
45
|
|
46
46
|
# {Message} initializer
|
47
47
|
#
|
48
|
-
# @param
|
48
|
+
# @param attributes [Hash] object with the underlying message detail key value attributes
|
49
49
|
# @param [Hash] options an options Hash for this initializer
|
50
50
|
# @option options [ProtocolMessage] :protocol_message An optional protocol message to assocate the presence message with
|
51
51
|
# @option options [Logger] :logger An optional Logger to be used by {Ably::Modules::SafeDeferrable} if an exception is caught in a callback
|
52
52
|
#
|
53
|
-
def initialize(
|
53
|
+
def initialize(attributes, options = {})
|
54
54
|
@logger = options[:logger] # Logger expected for SafeDeferrable
|
55
55
|
@protocol_message = options[:protocol_message]
|
56
|
-
@raw_hash_object =
|
56
|
+
@raw_hash_object = attributes
|
57
57
|
|
58
|
-
|
58
|
+
set_attributes_object attributes
|
59
59
|
|
60
60
|
ensure_utf_8 :name, name, allow_nil: true
|
61
61
|
ensure_utf_8 :client_id, client_id, allow_nil: true
|
@@ -64,32 +64,32 @@ module Ably::Models
|
|
64
64
|
|
65
65
|
%w( name client_id encoding ).each do |attribute|
|
66
66
|
define_method attribute do
|
67
|
-
|
67
|
+
attributes[attribute.to_sym]
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
71
|
def data
|
72
|
-
@data ||=
|
72
|
+
@data ||= attributes[:data].freeze
|
73
73
|
end
|
74
74
|
|
75
75
|
def id
|
76
|
-
|
76
|
+
attributes.fetch(:id) { "#{protocol_message.id!}:#{protocol_message_index}" }
|
77
77
|
end
|
78
78
|
|
79
79
|
def connection_id
|
80
|
-
|
80
|
+
attributes.fetch(:connection_id) { protocol_message.connection_id if assigned_to_protocol_message? }
|
81
81
|
end
|
82
82
|
|
83
83
|
def timestamp
|
84
|
-
if
|
85
|
-
as_time_from_epoch(
|
84
|
+
if attributes[:timestamp]
|
85
|
+
as_time_from_epoch(attributes[:timestamp])
|
86
86
|
else
|
87
87
|
protocol_message.timestamp
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
-
def
|
92
|
-
@
|
91
|
+
def attributes
|
92
|
+
@attributes
|
93
93
|
end
|
94
94
|
|
95
95
|
def to_json(*args)
|
@@ -128,8 +128,8 @@ module Ably::Models
|
|
128
128
|
protocol_message.messages.map(&:object_id).index(self.object_id)
|
129
129
|
end
|
130
130
|
|
131
|
-
def
|
132
|
-
@
|
131
|
+
def set_attributes_object(new_attributes)
|
132
|
+
@attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data])
|
133
133
|
end
|
134
134
|
|
135
135
|
def logger
|
@@ -4,7 +4,7 @@ require 'ably/util/crypto'
|
|
4
4
|
|
5
5
|
module Ably::Models::MessageEncoders
|
6
6
|
# Cipher Encoder & Decoder that automatically encrypts & decrypts messages using Ably::Util::Crypto
|
7
|
-
# when a channel has option
|
7
|
+
# when a channel has the +:cipher+ channel option configured
|
8
8
|
#
|
9
9
|
class Cipher < Base
|
10
10
|
ENCODING_ID = 'cipher'
|
@@ -20,16 +20,17 @@ module Ably::Models::MessageEncoders
|
|
20
20
|
|
21
21
|
if channel_configured_for_encryption?(channel_options)
|
22
22
|
add_encoding_to_message 'utf-8', message unless is_binary?(message) || is_utf8_encoded?(message)
|
23
|
-
|
24
23
|
crypto = crypto_for(channel_options)
|
25
24
|
message[:data] = crypto.encrypt(message[:data])
|
26
|
-
add_encoding_to_message "#{ENCODING_ID}+#{crypto.cipher_type.downcase}", message
|
25
|
+
add_encoding_to_message "#{ENCODING_ID}+#{crypto.cipher_params.cipher_type.downcase}", message
|
27
26
|
end
|
28
27
|
rescue ArgumentError => e
|
29
28
|
raise Ably::Exceptions::CipherError.new(e.message, nil, 92005)
|
30
29
|
rescue RuntimeError => e
|
31
30
|
if e.message.match(/unsupported cipher algorithm/i)
|
32
31
|
raise Ably::Exceptions::CipherError.new(e.message, nil, 92004)
|
32
|
+
else
|
33
|
+
raise e
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
@@ -40,8 +41,8 @@ module Ably::Models::MessageEncoders
|
|
40
41
|
end
|
41
42
|
|
42
43
|
crypto = crypto_for(channel_options)
|
43
|
-
unless crypto.cipher_type == cipher_algorithm(message).upcase
|
44
|
-
raise Ably::Exceptions::CipherError.new("Cipher algorithm #{crypto.cipher_type} does not match message cipher algorithm of #{cipher_algorithm(message).upcase}", nil, 92002)
|
44
|
+
unless crypto.cipher_params.cipher_type == cipher_algorithm(message).upcase
|
45
|
+
raise Ably::Exceptions::CipherError.new("Cipher algorithm #{crypto.cipher_params.cipher_type} does not match message cipher algorithm of #{cipher_algorithm(message).upcase}", nil, 92002)
|
45
46
|
end
|
46
47
|
|
47
48
|
message[:data] = crypto.decrypt(message[:data])
|
@@ -61,11 +62,11 @@ module Ably::Models::MessageEncoders
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def crypto_for(channel_options)
|
64
|
-
@cryptos[channel_options.
|
65
|
+
@cryptos[channel_options.to_s] ||= Ably::Util::Crypto.new(channel_options.fetch(:cipher, {}))
|
65
66
|
end
|
66
67
|
|
67
68
|
def channel_configured_for_encryption?(channel_options)
|
68
|
-
channel_options
|
69
|
+
channel_options[:cipher]
|
69
70
|
end
|
70
71
|
|
71
72
|
def is_cipher_encoded?(message)
|