ably-rest 0.8.5 → 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|