ably-rest 0.8.5 → 0.8.6
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/README.md +1 -1
- data/SPEC.md +1380 -631
- data/ably-rest.gemspec +11 -5
- data/lib/submodules/ably-ruby/.travis.yml +1 -1
- data/lib/submodules/ably-ruby/CHANGELOG.md +42 -48
- data/lib/submodules/ably-ruby/ably.gemspec +7 -1
- data/lib/submodules/ably-ruby/lib/ably.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +155 -47
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +2 -3
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +54 -0
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +14 -4
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +13 -7
- data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +1 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/ably.rb +3 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/message_emitter.rb +1 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +6 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +15 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +10 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +11 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +62 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +58 -54
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +18 -5
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +9 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +32 -14
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +251 -11
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +12 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +316 -24
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +93 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +177 -86
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +284 -60
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +45 -6
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +4 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +181 -49
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/time_spec.rb +13 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +222 -4
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +132 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +129 -28
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +7 -7
- data/lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb +10 -0
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +41 -17
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +1 -0
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +16 -0
- data/lib/submodules/ably-ruby/spec/unit/models/connection_details_spec.rb +60 -0
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +45 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +3 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +6 -5
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +5 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +5 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/realtime_spec.rb +5 -1
- metadata +57 -13
data/ably-rest.gemspec
CHANGED
@@ -14,10 +14,10 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.version = Ably::VERSION
|
15
15
|
spec.authors = ['Matthew O\'Riordan']
|
16
16
|
spec.email = ['matt@ably.io']
|
17
|
-
spec.description = %q{A Ruby REST only client library for ably.io
|
18
|
-
spec.summary = %q{A Ruby REST only client library for ably.io
|
17
|
+
spec.description = %q{A Ruby REST only client library for ably.io realtime messaging}
|
18
|
+
spec.summary = %q{A Ruby REST only client library for ably.io realtime messaging}
|
19
19
|
spec.homepage = 'http://github.com/ably/ably-ruby-rest'
|
20
|
-
spec.license = '
|
20
|
+
spec.license = 'Apache 2'
|
21
21
|
|
22
22
|
submodule_path = File.expand_path('../lib/submodules/ably-ruby', __FILE__)
|
23
23
|
submodule_files = Dir.chdir(submodule_path) do
|
@@ -33,13 +33,19 @@ Gem::Specification.new do |spec|
|
|
33
33
|
|
34
34
|
spec.add_runtime_dependency 'faraday', '~> 0.9'
|
35
35
|
spec.add_runtime_dependency 'json'
|
36
|
-
spec.add_runtime_dependency 'msgpack
|
36
|
+
spec.add_runtime_dependency 'msgpack', '>= 0.6.2'
|
37
|
+
spec.add_runtime_dependency 'addressable', '>= 2.0.0'
|
37
38
|
|
38
39
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
39
40
|
spec.add_development_dependency 'rake'
|
40
41
|
spec.add_development_dependency 'redcarpet'
|
41
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
42
|
+
spec.add_development_dependency 'rspec', '~> 3.2.0'
|
42
43
|
spec.add_development_dependency 'rspec-retry'
|
43
44
|
spec.add_development_dependency 'yard'
|
44
45
|
spec.add_development_dependency 'webmock'
|
46
|
+
|
47
|
+
if RUBY_VERSION.match(/^2/)
|
48
|
+
spec.add_development_dependency 'pry'
|
49
|
+
spec.add_development_dependency 'pry-byebug'
|
50
|
+
end
|
45
51
|
end
|
@@ -1,29 +1,59 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [
|
3
|
+
## [v0.8.6](https://github.com/ably/ably-ruby/tree/v0.8.6) (2015-12-02)
|
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.5...v0.8.6)
|
6
|
+
|
7
|
+
**Merged pull requests:**
|
8
|
+
|
9
|
+
- Some intermittent test fixes & enable tests that were blocked [\#70](https://github.com/ably/ably-ruby/pull/70) ([mattheworiordan](https://github.com/mattheworiordan))
|
10
|
+
|
11
|
+
- Output detailed log for any text failures [\#67](https://github.com/ably/ably-ruby/pull/67) ([mattheworiordan](https://github.com/mattheworiordan))
|
12
|
+
|
13
|
+
- 0.8 final spec \(98% compliance\) [\#66](https://github.com/ably/ably-ruby/pull/66) ([mattheworiordan](https://github.com/mattheworiordan))
|
14
|
+
|
15
|
+
## [v0.8.5](https://github.com/ably/ably-ruby/tree/v0.8.5) (2015-10-08)
|
16
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.4...v0.8.5)
|
6
17
|
|
7
18
|
**Implemented enhancements:**
|
8
19
|
|
9
|
-
-
|
20
|
+
- Switch arity of auth methods [\#61](https://github.com/ably/ably-ruby/issues/61)
|
10
21
|
|
11
|
-
|
22
|
+
**Fixed bugs:**
|
12
23
|
|
24
|
+
- Switch arity of auth methods [\#61](https://github.com/ably/ably-ruby/issues/61)
|
25
|
+
- Add test: Message published, connection dropped, then restores to point before last message was published [\#56](https://github.com/ably/ably-ruby/issues/56)
|
26
|
+
- Documentation for constructor is incorrect [\#49](https://github.com/ably/ably-ruby/issues/49)
|
27
|
+
|
28
|
+
**Merged pull requests:**
|
29
|
+
|
30
|
+
- Ensure connections are always closed in tests [\#63](https://github.com/ably/ably-ruby/pull/63) ([mattheworiordan](https://github.com/mattheworiordan))
|
31
|
+
|
32
|
+
## [v0.8.4](https://github.com/ably/ably-ruby/tree/v0.8.4) (2015-09-08)
|
33
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.3...v0.8.4)
|
34
|
+
|
35
|
+
**Implemented enhancements:**
|
36
|
+
|
37
|
+
- Add compatibility support for default Crypto params [\#53](https://github.com/ably/ably-ruby/issues/53)
|
38
|
+
- EventEmitter on connection [\#52](https://github.com/ably/ably-ruby/issues/52)
|
13
39
|
- Add test for connectionId attribute for a message sent over REST [\#50](https://github.com/ably/ably-ruby/issues/50)
|
14
40
|
|
15
|
-
|
41
|
+
**Merged pull requests:**
|
16
42
|
|
17
|
-
-
|
43
|
+
- Spec update to fix a number of issues [\#60](https://github.com/ably/ably-ruby/pull/60) ([mattheworiordan](https://github.com/mattheworiordan))
|
44
|
+
- 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))
|
18
45
|
|
19
|
-
|
46
|
+
## [v0.8.3](https://github.com/ably/ably-ruby/tree/v0.8.3) (2015-08-19)
|
47
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.2...v0.8.3)
|
20
48
|
|
21
|
-
|
49
|
+
**Implemented enhancements:**
|
22
50
|
|
51
|
+
- Implement :queue\_messages option [\#36](https://github.com/ably/ably-ruby/issues/36)
|
52
|
+
- Check that a non 200-299 status code for REST requests uses fallback hosts [\#35](https://github.com/ably/ably-ruby/issues/35)
|
53
|
+
- Move stats fixtures into ably-common [\#34](https://github.com/ably/ably-ruby/issues/34)
|
54
|
+
- Add tests for messages with no data or name fields [\#21](https://github.com/ably/ably-ruby/issues/21)
|
23
55
|
- Namespace MsgPack as MsgPack5 because compliance is not merged in [\#12](https://github.com/ably/ably-ruby/issues/12)
|
24
|
-
|
25
56
|
- Add test coverage for receiving messages more than once i.e. historical messages resent somehow on reconnect [\#11](https://github.com/ably/ably-ruby/issues/11)
|
26
|
-
|
27
57
|
- Add async methods for Authentication in the realtime library [\#8](https://github.com/ably/ably-ruby/issues/8)
|
28
58
|
|
29
59
|
**Fixed bugs:**
|
@@ -33,41 +63,28 @@
|
|
33
63
|
**Closed issues:**
|
34
64
|
|
35
65
|
- Scope default token params in arguments [\#55](https://github.com/ably/ably-ruby/issues/55)
|
36
|
-
|
37
66
|
- Channel options can be reset when accessing a channel with \#get [\#46](https://github.com/ably/ably-ruby/issues/46)
|
38
67
|
|
39
68
|
**Merged pull requests:**
|
40
69
|
|
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
|
-
|
45
70
|
- Separate token params for auth [\#57](https://github.com/ably/ably-ruby/pull/57) ([mattheworiordan](https://github.com/mattheworiordan))
|
46
|
-
|
47
71
|
- Ensure files are required in a consistent order [\#51](https://github.com/ably/ably-ruby/pull/51) ([SimonWoolf](https://github.com/SimonWoolf))
|
48
72
|
|
49
73
|
## [v0.8.2](https://github.com/ably/ably-ruby/tree/v0.8.2) (2015-05-20)
|
50
|
-
|
51
74
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.1...v0.8.2)
|
52
75
|
|
53
76
|
**Implemented enhancements:**
|
54
77
|
|
55
78
|
- Ensure Array object can be used in place of Hash for payload [\#44](https://github.com/ably/ably-ruby/issues/44)
|
56
|
-
|
57
79
|
- Change connect\_automatically option to auto\_connect for consistency [\#42](https://github.com/ably/ably-ruby/issues/42)
|
58
|
-
|
59
80
|
- Rename PaginatedResource to PaginatedResult for consistency [\#40](https://github.com/ably/ably-ruby/issues/40)
|
60
|
-
|
61
81
|
- EventEmitter should use `emit` not `trigger` to be consistent with other libs [\#31](https://github.com/ably/ably-ruby/issues/31)
|
62
|
-
|
63
82
|
- Add exceptions when data attribute for messages/presence is not String, Binary or JSON data [\#4](https://github.com/ably/ably-ruby/issues/4)
|
64
|
-
|
65
83
|
- Auth Callback and Auth URL should support tokens as well as token requests [\#2](https://github.com/ably/ably-ruby/issues/2)
|
66
84
|
|
67
85
|
**Closed issues:**
|
68
86
|
|
69
87
|
- Realtime Presence\#get does not wait by default [\#47](https://github.com/ably/ably-ruby/issues/47)
|
70
|
-
|
71
88
|
- No implicit attach when accessing channel.presence [\#45](https://github.com/ably/ably-ruby/issues/45)
|
72
89
|
|
73
90
|
**Merged pull requests:**
|
@@ -75,11 +92,9 @@
|
|
75
92
|
- Reject invalid payload type [\#48](https://github.com/ably/ably-ruby/pull/48) ([mattheworiordan](https://github.com/mattheworiordan))
|
76
93
|
|
77
94
|
## [v0.8.1](https://github.com/ably/ably-ruby/tree/v0.8.1) (2015-04-23)
|
78
|
-
|
79
95
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.0...v0.8.1)
|
80
96
|
|
81
97
|
## [v0.8.0](https://github.com/ably/ably-ruby/tree/v0.8.0) (2015-04-23)
|
82
|
-
|
83
98
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.7.6...v0.8.0)
|
84
99
|
|
85
100
|
**Merged pull requests:**
|
@@ -87,18 +102,15 @@
|
|
87
102
|
- Token naming refactor [\#29](https://github.com/ably/ably-ruby/pull/29) ([mattheworiordan](https://github.com/mattheworiordan))
|
88
103
|
|
89
104
|
## [v0.7.6](https://github.com/ably/ably-ruby/tree/v0.7.6) (2015-04-17)
|
90
|
-
|
91
105
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.7.5...v0.7.6)
|
92
106
|
|
93
107
|
**Implemented enhancements:**
|
94
108
|
|
95
109
|
- Rename Stat to Stats for consistency [\#32](https://github.com/ably/ably-ruby/issues/32)
|
96
|
-
|
97
110
|
- Stats objects [\#24](https://github.com/ably/ably-ruby/issues/24)
|
98
|
-
|
99
111
|
- Need a test to handle errors in callbacks [\#13](https://github.com/ably/ably-ruby/issues/13)
|
100
|
-
|
101
112
|
- Allow token ID or API key in the client constructor [\#5](https://github.com/ably/ably-ruby/issues/5)
|
113
|
+
- Typed stats similar to Java library + zero default for empty stats [\#25](https://github.com/ably/ably-ruby/pull/25) ([mattheworiordan](https://github.com/mattheworiordan))
|
102
114
|
|
103
115
|
**Fixed bugs:**
|
104
116
|
|
@@ -111,19 +123,14 @@
|
|
111
123
|
**Merged pull requests:**
|
112
124
|
|
113
125
|
- Test encoded presence fixture data for \#get & \#history [\#28](https://github.com/ably/ably-ruby/pull/28) ([mattheworiordan](https://github.com/mattheworiordan))
|
114
|
-
|
115
126
|
- Add coveralls.io coverage reporting [\#27](https://github.com/ably/ably-ruby/pull/27) ([mattheworiordan](https://github.com/mattheworiordan))
|
116
|
-
|
117
127
|
- New paginated resource [\#26](https://github.com/ably/ably-ruby/pull/26) ([mattheworiordan](https://github.com/mattheworiordan))
|
118
|
-
|
119
|
-
- Typed stats similar to Java library + zero default for empty stats [\#25](https://github.com/ably/ably-ruby/pull/25) ([mattheworiordan](https://github.com/mattheworiordan))
|
128
|
+
- History since attach [\#22](https://github.com/ably/ably-ruby/pull/22) ([mattheworiordan](https://github.com/mattheworiordan))
|
120
129
|
|
121
130
|
## [v0.7.5](https://github.com/ably/ably-ruby/tree/v0.7.5) (2015-03-21)
|
122
|
-
|
123
131
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.7.4...v0.7.5)
|
124
132
|
|
125
133
|
## [v0.7.4](https://github.com/ably/ably-ruby/tree/v0.7.4) (2015-03-21)
|
126
|
-
|
127
134
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.7.2...v0.7.4)
|
128
135
|
|
129
136
|
**Merged pull requests:**
|
@@ -131,7 +138,6 @@
|
|
131
138
|
- Presence Member Map [\#14](https://github.com/ably/ably-ruby/pull/14) ([mattheworiordan](https://github.com/mattheworiordan))
|
132
139
|
|
133
140
|
## [v0.7.2](https://github.com/ably/ably-ruby/tree/v0.7.2) (2015-02-10)
|
134
|
-
|
135
141
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.7.1...v0.7.2)
|
136
142
|
|
137
143
|
**Implemented enhancements:**
|
@@ -141,15 +147,12 @@
|
|
141
147
|
**Merged pull requests:**
|
142
148
|
|
143
149
|
- Update README to include various missing snippets for core features [\#9](https://github.com/ably/ably-ruby/pull/9) ([kouno](https://github.com/kouno))
|
144
|
-
|
145
150
|
- Fix connection retry frequency [\#7](https://github.com/ably/ably-ruby/pull/7) ([kouno](https://github.com/kouno))
|
146
151
|
|
147
152
|
## [v0.7.1](https://github.com/ably/ably-ruby/tree/v0.7.1) (2015-01-18)
|
148
|
-
|
149
153
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.7.0...v0.7.1)
|
150
154
|
|
151
155
|
## [v0.7.0](https://github.com/ably/ably-ruby/tree/v0.7.0) (2015-01-12)
|
152
|
-
|
153
156
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.6.2...v0.7.0)
|
154
157
|
|
155
158
|
**Closed issues:**
|
@@ -157,39 +160,30 @@
|
|
157
160
|
- JSON encoder should only append utf-8 before a cipher encoder is applied [\#1](https://github.com/ably/ably-ruby/issues/1)
|
158
161
|
|
159
162
|
## [v0.6.2](https://github.com/ably/ably-ruby/tree/v0.6.2) (2014-12-10)
|
160
|
-
|
161
163
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.2.0...v0.6.2)
|
162
164
|
|
163
165
|
## [v0.2.0](https://github.com/ably/ably-ruby/tree/v0.2.0) (2014-12-09)
|
164
|
-
|
165
166
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.1.6...v0.2.0)
|
166
167
|
|
167
168
|
## [v0.1.6](https://github.com/ably/ably-ruby/tree/v0.1.6) (2014-10-31)
|
168
|
-
|
169
169
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.1.5...v0.1.6)
|
170
170
|
|
171
171
|
## [v0.1.5](https://github.com/ably/ably-ruby/tree/v0.1.5) (2014-10-23)
|
172
|
-
|
173
172
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.1.4...v0.1.5)
|
174
173
|
|
175
174
|
## [v0.1.4](https://github.com/ably/ably-ruby/tree/v0.1.4) (2014-09-27)
|
176
|
-
|
177
175
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.1.3...v0.1.4)
|
178
176
|
|
179
177
|
## [v0.1.3](https://github.com/ably/ably-ruby/tree/v0.1.3) (2014-09-26)
|
180
|
-
|
181
178
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.1.2...v0.1.3)
|
182
179
|
|
183
180
|
## [v0.1.2](https://github.com/ably/ably-ruby/tree/v0.1.2) (2014-09-25)
|
184
|
-
|
185
181
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.1.1...v0.1.2)
|
186
182
|
|
187
183
|
## [v0.1.1](https://github.com/ably/ably-ruby/tree/v0.1.1) (2014-09-23)
|
188
|
-
|
189
184
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v0.1.0...v0.1.1)
|
190
185
|
|
191
186
|
## [v0.1.0](https://github.com/ably/ably-ruby/tree/v0.1.0) (2014-09-23)
|
192
187
|
|
193
188
|
|
194
|
-
|
195
189
|
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
@@ -25,14 +25,20 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_runtime_dependency 'json'
|
26
26
|
spec.add_runtime_dependency 'websocket-driver', '~> 0.3'
|
27
27
|
spec.add_runtime_dependency 'msgpack', '>= 0.6.2'
|
28
|
+
spec.add_runtime_dependency 'addressable', '>= 2.0.0'
|
28
29
|
|
29
30
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
30
31
|
spec.add_development_dependency 'rake'
|
31
32
|
spec.add_development_dependency 'redcarpet'
|
32
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
33
|
+
spec.add_development_dependency 'rspec', '~> 3.2.0' # version lock, see config.around(:example, :event_machine) in event_machine_helper.rb
|
33
34
|
spec.add_development_dependency 'rspec-retry'
|
34
35
|
spec.add_development_dependency 'yard'
|
35
36
|
spec.add_development_dependency 'webmock'
|
36
37
|
|
37
38
|
spec.add_development_dependency 'coveralls'
|
39
|
+
|
40
|
+
if RUBY_VERSION.match(/^2/)
|
41
|
+
spec.add_development_dependency 'pry'
|
42
|
+
spec.add_development_dependency 'pry-byebug'
|
43
|
+
end
|
38
44
|
end
|
@@ -13,8 +13,6 @@ module Ably
|
|
13
13
|
# @return [String] The provided client ID, used for identifying this client for presence purposes
|
14
14
|
# @!attribute [r] current_token_details
|
15
15
|
# @return [Ably::Models::TokenDetails] Current {Ably::Models::TokenDetails} issued by this library or one of the provided callbacks used to authenticate requests
|
16
|
-
# @!attribute [r] token
|
17
|
-
# @return [String] Token string provided to the {Ably::Client} constructor that is used to authenticate all requests
|
18
16
|
# @!attribute [r] key
|
19
17
|
# @return [String] Complete API key containing both the key name and key secret, if present
|
20
18
|
# @!attribute [r] key_name
|
@@ -61,6 +59,7 @@ module Ably
|
|
61
59
|
@client = client
|
62
60
|
@options = auth_options.dup
|
63
61
|
@token_params = token_params.dup
|
62
|
+
@token_option = options[:token] || options[:token_details]
|
64
63
|
|
65
64
|
@options.delete :force # Forcing token auth for every request is not a valid default
|
66
65
|
|
@@ -74,11 +73,25 @@ module Ably
|
|
74
73
|
raise ArgumentError, 'key is missing. Either an API key, token, or token auth method must be provided'
|
75
74
|
end
|
76
75
|
|
77
|
-
if
|
78
|
-
raise ArgumentError, '
|
76
|
+
if options[:client_id] == '*'
|
77
|
+
raise ArgumentError, 'A client cannot be configured with a wildcard client_id'
|
78
|
+
end
|
79
|
+
|
80
|
+
if has_client_id? && !token_creatable_externally? && !token_option
|
81
|
+
raise ArgumentError, 'client_id cannot be provided without a complete API key or means to authenticate. An API key is needed to automatically authenticate with Ably and obtain a token' unless api_key_present?
|
79
82
|
ensure_utf_8 :client_id, client_id
|
80
83
|
end
|
81
84
|
|
85
|
+
# If a token details object or token string is provided in the initializer
|
86
|
+
# then the client can be authorised immediately using this token
|
87
|
+
if token_option
|
88
|
+
token_details = convert_to_token_details(token_option)
|
89
|
+
if token_details
|
90
|
+
token_details = authorise_with_token(token_details)
|
91
|
+
logger.debug "Auth: new token passed in to the initializer: #{token_details}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
82
95
|
@options.freeze
|
83
96
|
@token_params.freeze
|
84
97
|
end
|
@@ -120,7 +133,9 @@ module Ably
|
|
120
133
|
token_params = (auth_options.delete(:token_params) || {}).merge(token_params)
|
121
134
|
@token_params = @token_params.merge(token_params) # update defaults
|
122
135
|
|
123
|
-
|
136
|
+
authorise_with_token(request_token(token_params, auth_options)).tap do |new_token_details|
|
137
|
+
logger.debug "Auth: new token following authorisation: #{new_token_details}"
|
138
|
+
end
|
124
139
|
end
|
125
140
|
|
126
141
|
# Request a {Ably::Models::TokenDetails} which can be used to make authenticated token based requests
|
@@ -154,34 +169,29 @@ module Ably
|
|
154
169
|
def request_token(token_params = {}, auth_options = {})
|
155
170
|
ensure_valid_auth_attributes auth_options
|
156
171
|
|
157
|
-
|
158
|
-
token_params
|
172
|
+
# Token param precedence (lowest to highest):
|
173
|
+
# Auth default => client_id => auth_options[:token_params] arg => token_params arg
|
174
|
+
token_params = self.token_params.merge(
|
175
|
+
(client_id ? { client_id: client_id } : {}).
|
176
|
+
merge(auth_options[:token_params] || {}).
|
177
|
+
merge(token_params)
|
178
|
+
)
|
179
|
+
|
159
180
|
auth_options = self.options.merge(auth_options)
|
160
181
|
|
161
182
|
token_request = if auth_callback = auth_options.delete(:auth_callback)
|
162
183
|
auth_callback.call(token_params)
|
163
184
|
elsif auth_url = auth_options.delete(:auth_url)
|
164
|
-
token_request_from_auth_url(auth_url, auth_options)
|
185
|
+
token_request_from_auth_url(auth_url, auth_options, token_params)
|
165
186
|
else
|
166
187
|
create_token_request(token_params, auth_options)
|
167
188
|
end
|
168
189
|
|
169
|
-
|
170
|
-
|
171
|
-
return token_request
|
172
|
-
when Hash
|
173
|
-
return Ably::Models::TokenDetails.new(token_request) if IdiomaticRubyWrapper(token_request).has_key?(:issued)
|
174
|
-
when String
|
175
|
-
return Ably::Models::TokenDetails.new(token: token_request)
|
190
|
+
convert_to_token_details(token_request).tap do |token_details|
|
191
|
+
return token_details if token_details
|
176
192
|
end
|
177
193
|
|
178
|
-
|
179
|
-
|
180
|
-
response = client.post("/keys/#{token_request.key_name}/requestToken",
|
181
|
-
token_request.hash, send_auth_header: false,
|
182
|
-
disable_automatic_reauthorise: true)
|
183
|
-
|
184
|
-
Ably::Models::TokenDetails.new(response.body)
|
194
|
+
send_token_request(token_request)
|
185
195
|
end
|
186
196
|
|
187
197
|
# Creates and signs a token request that can then subsequently be used by any client to request a token
|
@@ -277,21 +287,23 @@ module Ably
|
|
277
287
|
# True when Token Auth is being used to authenticate with Ably
|
278
288
|
def using_token_auth?
|
279
289
|
return options[:use_token_auth] if options.has_key?(:use_token_auth)
|
280
|
-
!!(
|
290
|
+
!!(token_option || current_token_details || has_client_id? || token_creatable_externally?)
|
281
291
|
end
|
282
292
|
|
283
293
|
def client_id
|
284
|
-
options[:client_id]
|
294
|
+
@client_id || options[:client_id]
|
285
295
|
end
|
286
296
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
297
|
+
# When a client has authenticated with Ably and the client is either anonymous (cannot assume a +client_id+)
|
298
|
+
# or has an assigned +client_id+ (implicit in all operations), then this client has a validated +client_id+, even
|
299
|
+
# if that client_id is +nil+ (anonymous)
|
300
|
+
#
|
301
|
+
# Once validated by Ably, the client library will enforce the use of the +client_id+ identity provided by Ably, rejecting
|
302
|
+
# messages with an invalid +client_id+ immediately
|
303
|
+
#
|
304
|
+
# @return [Boolean]
|
305
|
+
def client_id_validated?
|
306
|
+
!!@client_id_validated
|
295
307
|
end
|
296
308
|
|
297
309
|
# Auth header string used in HTTP requests to Ably
|
@@ -327,7 +339,7 @@ module Ably
|
|
327
339
|
#
|
328
340
|
# @return [Boolean]
|
329
341
|
def token_renewable?
|
330
|
-
token_creatable_externally? || (api_key_present? && !
|
342
|
+
token_creatable_externally? || (api_key_present? && !token_option)
|
331
343
|
end
|
332
344
|
|
333
345
|
# Returns false when attempting to send an API Key over a non-secure connection
|
@@ -338,8 +350,59 @@ module Ably
|
|
338
350
|
client.use_tls? || using_token_auth?
|
339
351
|
end
|
340
352
|
|
353
|
+
# True if token provided client_id is compatible with the client's configured +client_id+, when applicable
|
354
|
+
#
|
355
|
+
# @return [Boolean]
|
356
|
+
# @api private
|
357
|
+
def token_client_id_allowed?(token_client_id)
|
358
|
+
return true if client_id.nil? # no explicit client_id specified for this client
|
359
|
+
return true if client_id == '*' || token_client_id == '*' # wildcard supported always
|
360
|
+
token_client_id == client_id
|
361
|
+
end
|
362
|
+
|
363
|
+
# True if assumed_client_id is compatible with the client's configured or Ably assigned +client_id+
|
364
|
+
#
|
365
|
+
# @return [Boolean]
|
366
|
+
# @api private
|
367
|
+
def can_assume_client_id?(assumed_client_id)
|
368
|
+
if client_id_validated?
|
369
|
+
client_id == '*' || (client_id == assumed_client_id)
|
370
|
+
elsif !options[:client_id] || options[:client_id] == '*'
|
371
|
+
true # client ID is unknown
|
372
|
+
else
|
373
|
+
options[:client_id] == assumed_client_id
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
# Configures the client ID for this client
|
378
|
+
# Typically this occurs following an Auth or receiving a {Ably::Models::ProtocolMessage} with a +client_id+ in the {Ably::Models::ConnectionDetails}
|
379
|
+
#
|
380
|
+
# @api private
|
381
|
+
def configure_client_id(new_client_id)
|
382
|
+
# If new client ID from Ably is a wildcard, but preconfigured clientId is set, then keep the existing clientId
|
383
|
+
if has_client_id? && new_client_id == '*'
|
384
|
+
@client_id_validated = true
|
385
|
+
return
|
386
|
+
end
|
387
|
+
|
388
|
+
# If client_id is defined and not a wildcard, prevent it changing, this is not supported
|
389
|
+
if client_id && client_id != '*' && new_client_id != client_id
|
390
|
+
raise Ably::Exceptions::IncompatibleClientId.new("Client ID is immutable once configured for a client. Client ID cannot be changed to '#{new_client_id}'", 400, 40012)
|
391
|
+
end
|
392
|
+
@client_id_validated = true
|
393
|
+
@client_id = new_client_id
|
394
|
+
end
|
395
|
+
|
396
|
+
# True when a client_id other than a wildcard is configured for Auth
|
397
|
+
#
|
398
|
+
# @api private
|
399
|
+
def has_client_id?
|
400
|
+
client_id && (client_id != '*')
|
401
|
+
end
|
402
|
+
|
341
403
|
private
|
342
404
|
attr_reader :client
|
405
|
+
attr_reader :token_option
|
343
406
|
|
344
407
|
def ensure_valid_auth_attributes(attributes)
|
345
408
|
if attributes[:timestamp]
|
@@ -401,17 +464,21 @@ module Ably
|
|
401
464
|
|
402
465
|
# Returns the current token if it exists or authorises and retrieves a token
|
403
466
|
def token_auth_string
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
token
|
467
|
+
if !current_token_details && token_option
|
468
|
+
# A TokenRequest was configured in the ClientOptions +:token field+ and no current token exists
|
469
|
+
# Note: If a Token or TokenDetails is provided in the initializer, the token is stored in +current_token_details+
|
470
|
+
authorise_with_token send_token_request(token_option)
|
471
|
+
current_token_details.token
|
410
472
|
else
|
473
|
+
# Authorise will use the current token if one exists and is not expired, otherwise a new token will be issued
|
411
474
|
authorise.token
|
412
475
|
end
|
413
476
|
end
|
414
477
|
|
478
|
+
def configure_current_token_details(token_details)
|
479
|
+
@current_token_details = token_details
|
480
|
+
end
|
481
|
+
|
415
482
|
# Token Auth HTTP Authorization header value
|
416
483
|
def token_auth_header
|
417
484
|
"Bearer #{encode64(token_auth_string)}"
|
@@ -455,15 +522,20 @@ module Ably
|
|
455
522
|
# Retrieve a token request from a specified URL, expects a JSON response
|
456
523
|
#
|
457
524
|
# @return [Hash]
|
458
|
-
def token_request_from_auth_url(auth_url, auth_options)
|
525
|
+
def token_request_from_auth_url(auth_url, auth_options, token_params)
|
459
526
|
uri = URI.parse(auth_url)
|
460
527
|
connection = Faraday.new("#{uri.scheme}://#{uri.host}", connection_options)
|
461
|
-
method = auth_options[:auth_method] || :get
|
528
|
+
method = auth_options[:auth_method] || options[:auth_method] || :get
|
529
|
+
params = (auth_options[:auth_params] || options[:auth_method] || {}).merge(token_params)
|
462
530
|
|
463
531
|
response = connection.send(method) do |request|
|
464
532
|
request.url uri.path
|
465
|
-
request.params = CGI.parse(uri.query || '').merge(auth_options[:auth_params] || {})
|
466
533
|
request.headers = auth_options[:auth_headers] || {}
|
534
|
+
if method.to_s.downcase == 'post'
|
535
|
+
request.body = params
|
536
|
+
else
|
537
|
+
request.params = (Addressable::URI.parse(uri.to_s).query_values || {}).merge(params)
|
538
|
+
end
|
467
539
|
end
|
468
540
|
|
469
541
|
if !response.body.kind_of?(Hash) && !response.headers['Content-Type'].to_s.match(%r{text/plain}i)
|
@@ -474,6 +546,42 @@ module Ably
|
|
474
546
|
response.body
|
475
547
|
end
|
476
548
|
|
549
|
+
# Use the provided token to authenticate immediately and store the token details in +current_token_details+
|
550
|
+
def authorise_with_token(new_token_details)
|
551
|
+
if new_token_details && !new_token_details.from_token_string?
|
552
|
+
if !token_client_id_allowed?(new_token_details.client_id)
|
553
|
+
raise Ably::Exceptions::IncompatibleClientId.new("Client ID '#{new_token_details.client_id}' in the token is incompatible with the current client ID '#{client_id}'", 400, 40012)
|
554
|
+
end
|
555
|
+
configure_client_id new_token_details.client_id
|
556
|
+
end
|
557
|
+
configure_current_token_details new_token_details
|
558
|
+
end
|
559
|
+
|
560
|
+
# Returns a TokenDetails object if the provided token_details_obj argument is a TokenDetails object, Token String
|
561
|
+
# or TokenDetails JSON object.
|
562
|
+
# If the token_details_obj is not a Token or TokenDetails +nil+ is returned
|
563
|
+
def convert_to_token_details(token_details_obj)
|
564
|
+
case token_details_obj
|
565
|
+
when Ably::Models::TokenDetails
|
566
|
+
return token_details_obj
|
567
|
+
when Hash
|
568
|
+
return Ably::Models::TokenDetails.new(token_details_obj) if IdiomaticRubyWrapper(token_details_obj).has_key?(:issued)
|
569
|
+
when String
|
570
|
+
return Ably::Models::TokenDetails.new(token: token_details_obj)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
# @return [Ably::Models::TokenDetails]
|
575
|
+
def send_token_request(token_request)
|
576
|
+
token_request = Ably::Models::TokenRequest(token_request)
|
577
|
+
|
578
|
+
response = client.post("/keys/#{token_request.key_name}/requestToken",
|
579
|
+
token_request.hash, send_auth_header: false,
|
580
|
+
disable_automatic_reauthorise: true)
|
581
|
+
|
582
|
+
Ably::Models::TokenDetails.new(response.body)
|
583
|
+
end
|
584
|
+
|
477
585
|
# Return a Hash of connection options to initiate the Faraday::Connection with
|
478
586
|
#
|
479
587
|
# @return [Hash]
|
@@ -501,7 +609,7 @@ module Ably
|
|
501
609
|
# Raise exceptions if response code is invalid
|
502
610
|
builder.use Ably::Rest::Middleware::ExternalExceptions
|
503
611
|
|
504
|
-
setup_incoming_middleware builder,
|
612
|
+
setup_incoming_middleware builder, logger
|
505
613
|
|
506
614
|
# Set Faraday's HTTP adapter
|
507
615
|
builder.adapter Faraday.default_adapter
|
@@ -520,12 +628,12 @@ module Ably
|
|
520
628
|
auth_callback_present? || token_url_present?
|
521
629
|
end
|
522
630
|
|
523
|
-
def has_client_id?
|
524
|
-
!!client_id
|
525
|
-
end
|
526
|
-
|
527
631
|
def api_key_present?
|
528
632
|
key_name && key_secret
|
529
633
|
end
|
634
|
+
|
635
|
+
def logger
|
636
|
+
client.logger
|
637
|
+
end
|
530
638
|
end
|
531
639
|
end
|