pubnub 4.0.9 → 4.0.12

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pubnub might be problematic. Click here for more details.

Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.pubnub.yml +49 -3
  3. data/CHANGELOG.md +10 -0
  4. data/Gemfile.lock +2 -2
  5. data/VERSION +1 -1
  6. data/fixtures/vcr_cassettes/examples/status_request_message_count_exceeded.yml +1484 -0
  7. data/fixtures/vcr_cassettes/lib/super_admin/cg.yml +47 -0
  8. data/fixtures/vcr_cassettes/lib/super_admin/here_now.yml +47 -0
  9. data/fixtures/vcr_cassettes/lib/super_admin/history.yml +46 -0
  10. data/fixtures/vcr_cassettes/lib/super_admin/leave.yml +46 -0
  11. data/fixtures/vcr_cassettes/lib/super_admin/presence.yml +79 -0
  12. data/fixtures/vcr_cassettes/lib/super_admin/publish.yml +40 -0
  13. data/fixtures/vcr_cassettes/lib/super_admin/state.yml +47 -0
  14. data/fixtures/vcr_cassettes/lib/super_admin/subscribe.yml +77 -0
  15. data/fixtures/vcr_cassettes/lib/super_admin/time.yml +40 -0
  16. data/fixtures/vcr_cassettes/lib/super_admin/where_now.yml +47 -0
  17. data/lib/pubnub/client.rb +4 -0
  18. data/lib/pubnub/configuration.rb +2 -1
  19. data/lib/pubnub/constants.rb +2 -0
  20. data/lib/pubnub/event.rb +78 -20
  21. data/lib/pubnub/events/audit.rb +4 -0
  22. data/lib/pubnub/events/channel_registration.rb +3 -36
  23. data/lib/pubnub/events/grant.rb +4 -0
  24. data/lib/pubnub/events/heartbeat.rb +5 -38
  25. data/lib/pubnub/events/here_now.rb +5 -38
  26. data/lib/pubnub/events/history.rb +5 -38
  27. data/lib/pubnub/events/leave.rb +4 -39
  28. data/lib/pubnub/events/presence.rb +6 -0
  29. data/lib/pubnub/events/publish.rb +12 -45
  30. data/lib/pubnub/events/revoke.rb +4 -0
  31. data/lib/pubnub/events/set_state.rb +5 -33
  32. data/lib/pubnub/events/state.rb +5 -38
  33. data/lib/pubnub/events/subscribe.rb +6 -0
  34. data/lib/pubnub/events/time.rb +4 -37
  35. data/lib/pubnub/events/where_now.rb +4 -37
  36. data/lib/pubnub/formatter.rb +7 -5
  37. data/lib/pubnub/pam.rb +0 -18
  38. data/lib/pubnub/single_event.rb +0 -4
  39. data/lib/pubnub/subscribe_event.rb +3 -1
  40. data/lib/pubnub/subscribe_event/callbacks.rb +11 -0
  41. data/lib/pubnub/subscriber.rb +31 -0
  42. data/lib/pubnub/version.rb +1 -1
  43. data/spec/examples/channel_registration_examples_spec.rb +0 -1
  44. data/spec/examples/heartbeat_examples_spec.rb +0 -1
  45. data/spec/examples/here_now_examples_spec.rb +0 -1
  46. data/spec/examples/history_examples_spec.rb +0 -1
  47. data/spec/examples/leave_examples_spec.rb +0 -1
  48. data/spec/examples/presence_examples_spec.rb +0 -1
  49. data/spec/examples/publish_examples_spec.rb +0 -865
  50. data/spec/examples/revoke_examples_spec.rb +3888 -3888
  51. data/spec/examples/set_state_examples_spec.rb +0 -1
  52. data/spec/examples/state_examples_spec.rb +0 -1
  53. data/spec/examples/status_request_message_count_exceeded_spec.rb +41 -0
  54. data/spec/examples/subscribe_examples_spec.rb +0 -445
  55. data/spec/examples/time_examples_spec.rb +0 -1
  56. data/spec/examples/where_now_examples_spec.rb +0 -1
  57. data/spec/lib/events/channel_registration_spec.rb +0 -1
  58. data/spec/lib/events/heartbeat_spec.rb +0 -1
  59. data/spec/lib/events/here_now_spec.rb +0 -1
  60. data/spec/lib/events/history_spec.rb +0 -1
  61. data/spec/lib/events/leave_spec.rb +0 -1
  62. data/spec/lib/events/presence_spec.rb +0 -4
  63. data/spec/lib/events/publish_spec.rb +0 -3
  64. data/spec/lib/events/state_spec.rb +0 -1
  65. data/spec/lib/events/subscribe_spec.rb +0 -7
  66. data/spec/lib/events/time_spec.rb +0 -1
  67. data/spec/lib/events/timeout_handling_spec.rb +30 -0
  68. data/spec/lib/events/where_now_spec.rb +0 -1
  69. data/spec/lib/super_admin_spec.rb +166 -0
  70. data/spec/spec_helper.rb +5 -3
  71. metadata +33 -16
@@ -0,0 +1,47 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://pubsub.pubnub.com/v2/presence/sub-key/sub-c-f9f24520-9c56-11e6-a681-02ee2ddab7fe/uuid/ruby-test?pnsdk=PubNub-Ruby/4.0.10&signature=MLqC9qndFXjMgXfRxgky4YS%2B/r0G5hS%2BcD8LCW3tz7E=&timestamp=1477672693&uuid=ruby-test
6
+ body:
7
+ encoding: UTF-8
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - HTTPClient/1.0 (2.8.2.4, ruby 2.3.1 (2016-04-26))
12
+ Accept:
13
+ - "*/*"
14
+ Date:
15
+ - Fri, 28 Oct 2016 16:38:13 GMT
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Fri, 28 Oct 2016 16:38:13 GMT
23
+ Content-Type:
24
+ - text/javascript; charset="UTF-8"
25
+ Content-Length:
26
+ - '84'
27
+ Connection:
28
+ - keep-alive
29
+ Access-Control-Allow-Origin:
30
+ - "*"
31
+ Access-Control-Allow-Methods:
32
+ - OPTIONS, GET, POST
33
+ Cache-Control:
34
+ - no-cache
35
+ Accept-Ranges:
36
+ - bytes
37
+ Age:
38
+ - '0'
39
+ Server:
40
+ - Pubnub Presence
41
+ body:
42
+ encoding: UTF-8
43
+ string: '{"status": 200, "message": "OK", "payload": {"channels": []}, "service":
44
+ "Presence"}'
45
+ http_version:
46
+ recorded_at: Fri, 28 Oct 2016 16:38:13 GMT
47
+ recorded_with: VCR 3.0.1
data/lib/pubnub/client.rb CHANGED
@@ -404,6 +404,10 @@ module Pubnub
404
404
  @env[:subscribe_filter]
405
405
  end
406
406
 
407
+ def sdk_version
408
+ "PubNub-Ruby/#{Pubnub::VERSION}"
409
+ end
410
+
407
411
  private
408
412
 
409
413
  def create_state_pools(event)
@@ -15,7 +15,8 @@ module Pubnub
15
15
  reconnect_attempts: Pubnub::Constants::DEFAULT_RECONNECT_ATTEMPTS,
16
16
  reconnect_interval: Pubnub::Constants::DEFAULT_RECONNECT_INTERVAL,
17
17
  region: Pubnub::Constants::DEFAULT_REGION,
18
- ssl: Pubnub::Constants::DEFAULT_SSL
18
+ ssl: Pubnub::Constants::DEFAULT_SSL,
19
+ request_message_count_threshold: Pubnub::Constants::REQUEST_MESSAGE_COUNT_THRESHOLD
19
20
  }
20
21
  end
21
22
  end
@@ -18,6 +18,7 @@ module Pubnub
18
18
  DEFAULT_TTL = 1440
19
19
  DEFAULT_REGION = '0'
20
20
  DEFAULT_SSL = false
21
+ REQUEST_MESSAGE_COUNT_THRESHOLD = 0
21
22
 
22
23
  # Envelope values
23
24
  # Errors
@@ -26,6 +27,7 @@ module Pubnub
26
27
  STATUS_NON_JSON_RESPONSE = :non_json_response
27
28
  STATUS_ERROR = :error
28
29
  STATUS_API_KEY_ERROR = :api_key_error
30
+ STATUS_REQUEST_MESSAGE_COUNT_EXCEEDED = :request_message_count_exceeded
29
31
 
30
32
  # Successes
31
33
  STATUS_ACK = :ack
data/lib/pubnub/event.rb CHANGED
@@ -49,10 +49,13 @@ module Pubnub
49
49
  end
50
50
 
51
51
  def uri
52
+ sa_signature = super_admin_signature unless parameters.include?(:signature)
53
+
52
54
  uri = @ssl ? 'https://' : 'http://'
53
55
  uri += @origin
54
56
  uri += path
55
57
  uri += '?' + Formatter.params_hash_to_url_params(parameters)
58
+ uri += "&signature=#{sa_signature}" if sa_signature
56
59
  Pubnub.logger.debug('Pubnub::Event') { "Requested URI: #{uri}" }
57
60
  URI uri
58
61
  end
@@ -67,6 +70,35 @@ module Pubnub
67
70
 
68
71
  private
69
72
 
73
+ def super_admin_signature
74
+ return unless @app.env[:secret_key]
75
+
76
+ message = [
77
+ @app.env[:subscribe_key],
78
+ @app.env[:publish_key],
79
+ path,
80
+ variables_for_signature
81
+ ].join("\n")
82
+
83
+ URI.encode_www_form_component(Base64.encode64(
84
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'),
85
+ @app.env[:secret_key].to_s, message)
86
+ ).strip).gsub('+', '%20')
87
+ end
88
+
89
+ def variables_for_signature
90
+ parameters(true).map do |k, v|
91
+ if %w(meta ortt).include?(k.to_s)
92
+ encoded_value = URI.encode_www_form_component(v.to_json).gsub('+', '%20')
93
+ "#{k}=#{encoded_value}"
94
+ elsif %w(t state filter-expr).include?(k.to_s)
95
+ "#{k}=#{v}"
96
+ else
97
+ "#{k}=#{URI.encode_www_form_component(v.to_s).gsub('+', '%20')}"
98
+ end
99
+ end.sort.join('&')
100
+ end
101
+
70
102
  def secure_call(cb, arg)
71
103
  cb.call arg
72
104
  rescue => error
@@ -86,9 +118,9 @@ module Pubnub
86
118
  envelope
87
119
  end
88
120
 
89
- def parameters
121
+ def parameters(_set_signature = false)
90
122
  required = {
91
- pnsdk: "PubNub-Ruby/#{Pubnub::VERSION}"
123
+ pnsdk: @app.sdk_version
92
124
  }
93
125
 
94
126
  empty_if_blank = {
@@ -96,6 +128,8 @@ module Pubnub
96
128
  uuid: @app.env[:uuid]
97
129
  }
98
130
 
131
+ required.merge!({timestamp: @timestamp}) if @app.env[:secret_key] && ![:grant, :revoke, :audit].include?(@event)
132
+
99
133
  empty_if_blank.delete_if { |_k, v| v.blank? }
100
134
 
101
135
  required.merge(empty_if_blank)
@@ -106,9 +140,21 @@ module Pubnub
106
140
  @envelopes = format_envelopes response, request
107
141
  end
108
142
 
109
- # def connection
110
- # @app.connection_for(self)
111
- # end
143
+ def format_envelopes(response, request)
144
+ if response.is_a? HTTPClient::ReceiveTimeoutError
145
+ return error_envelope(nil, response, request: request, response: response)
146
+ else
147
+ parsed_response, error = Formatter.parse_json(response.body)
148
+ end
149
+
150
+ error = response if parsed_response && response.code.to_i != 200
151
+
152
+ if error
153
+ error_envelope(parsed_response, error, request: request, response: response)
154
+ else
155
+ valid_envelope(parsed_response, request: request, response: response)
156
+ end
157
+ end
112
158
 
113
159
  def create_variables_from_options(options)
114
160
  variables = %w(channel channels message http_sync callback
@@ -172,22 +218,34 @@ module Pubnub
172
218
  end
173
219
 
174
220
  def error_envelope(_parsed_response, error, req_res_objects)
221
+ case error
222
+ when JSON::ParserError
223
+ error_category = Pubnub::Constants::STATUS_NON_JSON_RESPONSE
224
+ code = req_res_objects[:response].code
225
+ when HTTPClient::ReceiveTimeoutError
226
+ error_category = Pubnub::Constants::STATUS_TIMEOUT
227
+ code = 408
228
+ else
229
+ error_category = Pubnub::Constants::STATUS_ERROR
230
+ code = req_res_objects[:response].code
231
+ end
232
+
175
233
  Pubnub::ErrorEnvelope.new(
176
- event: @event,
177
- event_options: @given_options,
178
- timetoken: nil,
179
- status: {
180
- code: req_res_objects[:response].code,
181
- operation: Pubnub::Constants::OPERATION_HEARTBEAT,
182
- client_request: req_res_objects[:request],
183
- server_response: req_res_objects[:response],
184
- data: nil,
185
- category: (error ? Pubnub::Constants::STATUS_NON_JSON_RESPONSE : Pubnub::Constants::STATUS_ERROR),
186
- error: true,
187
- auto_retried: false,
188
-
189
- config: get_config
190
- }
234
+ event: @event,
235
+ event_options: @given_options,
236
+ timetoken: nil,
237
+ status: {
238
+ code: code,
239
+ operation: current_operation,
240
+ client_request: req_res_objects[:request],
241
+ server_response: req_res_objects[:response],
242
+ data: nil,
243
+ category: error_category,
244
+ error: true,
245
+ auto_retried: false,
246
+
247
+ config: get_config
248
+ }
191
249
  )
192
250
  end
193
251
  end
@@ -12,6 +12,10 @@ module Pubnub
12
12
 
13
13
  private
14
14
 
15
+ def current_operation
16
+ Pubnub::Constants::OPERATION_AUDIT
17
+ end
18
+
15
19
  def parameters(signature = false)
16
20
  { timestamp: @timestamp }.merge(super(signature))
17
21
  end
@@ -13,7 +13,7 @@ module Pubnub
13
13
 
14
14
  private
15
15
 
16
- def parameters
16
+ def parameters(*_args)
17
17
  parameters = super
18
18
  if @action == :add && !@channel.blank?
19
19
  parameters.merge!(add: @channel.join(','))
@@ -94,18 +94,6 @@ module Pubnub
94
94
  ].delete_if(&:blank?).join('/')
95
95
  end
96
96
 
97
- def format_envelopes(response, request)
98
- parsed_response, error = Formatter.parse_json(response.body)
99
-
100
- error = response if parsed_response && response.code.to_i != 200
101
-
102
- if error
103
- error_envelope(parsed_response, error, request: request, response: response)
104
- else
105
- valid_envelope(parsed_response, request: request, response: response)
106
- end
107
- end
108
-
109
97
  def valid_envelope(parsed_response, req_res_objects)
110
98
  # {"status"=>200, "message"=>"OK", "service"=>"channel-registry", "error"=>false}
111
99
  Pubnub::Envelope.new(
@@ -140,29 +128,8 @@ module Pubnub
140
128
  )
141
129
  end
142
130
 
143
- def error_envelope(parsed_response, error, req_res_objects)
144
- Pubnub::ErrorEnvelope.new(
145
- event: @event,
146
- event_options: @given_options,
147
- timetoken: nil,
148
- status: {
149
- code: req_res_objects[:response].code,
150
- operation: define_operation,
151
- client_request: req_res_objects[:request],
152
- server_response: req_res_objects[:response],
153
- data: nil,
154
- category: (error ? Pubnub::Constants::STATUS_NON_JSON_RESPONSE : Pubnub::Constants::STATUS_ERROR),
155
- error: true,
156
- auto_retried: false,
157
-
158
- current_timetoken: nil,
159
- last_timetoken: nil,
160
- subscribed_channels: nil,
161
- subscribed_channel_groups: nil,
162
-
163
- config: get_config
164
- }
165
- )
131
+ def current_operation
132
+ define_operation
166
133
  end
167
134
 
168
135
  def define_operation
@@ -13,6 +13,10 @@ module Pubnub
13
13
 
14
14
  private
15
15
 
16
+ def current_operation
17
+ Pubnub::Constants::OPERATION_GRANT
18
+ end
19
+
16
20
  def parameters(signature = false)
17
21
  write = [0, '0', false].include?(@write) ? 0 : 1
18
22
  read = [0, '0', false].include?(@read) ? 0 : 1
@@ -13,6 +13,10 @@ module Pubnub
13
13
 
14
14
  private
15
15
 
16
+ def current_operation
17
+ Pubnub::Constants::OPERATION_HEARTBEAT
18
+ end
19
+
16
20
  def path
17
21
  '/' + [
18
22
  'v2',
@@ -25,7 +29,7 @@ module Pubnub
25
29
  ].join('/')
26
30
  end
27
31
 
28
- def parameters
32
+ def parameters(*_args)
29
33
  parameters = super
30
34
  if @app.env[:state] && @app.env[:state][@origin]
31
35
  parameters.merge!(state: encode_state(@app.env[:state][@origin]))
@@ -41,18 +45,6 @@ module Pubnub
41
45
  URI.encode_www_form_component(state.to_json).gsub('+', '%20')
42
46
  end
43
47
 
44
- def format_envelopes(response, request)
45
- parsed_response, error = Formatter.parse_json(response.body)
46
-
47
- error = response if parsed_response && response.code.to_i != 200
48
-
49
- if error
50
- error_envelope(parsed_response, error, request: request, response: response)
51
- else
52
- valid_envelope(parsed_response, request: request, response: response)
53
- end
54
- end
55
-
56
48
  def valid_envelope(_parsed_response, req_res_objects)
57
49
  # {"status": 200, "message": "OK", "service": "Presence"}
58
50
  Pubnub::Envelope.new(
@@ -78,30 +70,5 @@ module Pubnub
78
70
  }
79
71
  )
80
72
  end
81
-
82
- def error_envelope(_parsed_response, error, req_res_objects)
83
- Pubnub::ErrorEnvelope.new(
84
- event: @event,
85
- event_options: @given_options,
86
- timetoken: nil,
87
- status: {
88
- code: req_res_objects[:response].code,
89
- operation: Pubnub::Constants::OPERATION_HEARTBEAT,
90
- client_request: req_res_objects[:request],
91
- server_response: req_res_objects[:response],
92
- data: nil,
93
- category: (error ? Pubnub::Constants::STATUS_NON_JSON_RESPONSE : Pubnub::Constants::STATUS_ERROR),
94
- error: true,
95
- auto_retried: false,
96
-
97
- current_timetoken: nil,
98
- last_timetoken: nil,
99
- subscribed_channels: nil,
100
- subscribed_channel_groups: nil,
101
-
102
- config: get_config
103
- }
104
- )
105
- end
106
73
  end
107
74
  end
@@ -12,6 +12,10 @@ module Pubnub
12
12
 
13
13
  private
14
14
 
15
+ def current_operation
16
+ get_operation
17
+ end
18
+
15
19
  def path
16
20
  if @channel.first.blank?
17
21
  global_path
@@ -42,7 +46,7 @@ module Pubnub
42
46
  ].delete_if(&:nil?).join('/')
43
47
  end
44
48
 
45
- def parameters
49
+ def parameters(*_args)
46
50
  parameters = super
47
51
  parameters.merge!(
48
52
  'channel-group' => @group.join(',')
@@ -50,18 +54,6 @@ module Pubnub
50
54
  parameters
51
55
  end
52
56
 
53
- def format_envelopes(response, request)
54
- parsed_response, error = Formatter.parse_json(response.body)
55
-
56
- error = response if parsed_response && response.code.to_i != 200
57
-
58
- if error
59
- error_envelope(parsed_response, error, request: request, response: response)
60
- else
61
- valid_envelope(parsed_response, request: request, response: response)
62
- end
63
- end
64
-
65
57
  def valid_envelope(parsed_response, req_res_objects)
66
58
  Pubnub::Envelope.new(
67
59
  event: @event,
@@ -101,31 +93,6 @@ module Pubnub
101
93
  )
102
94
  end
103
95
 
104
- def error_envelope(_parsed_response, error, req_res_objects)
105
- Pubnub::ErrorEnvelope.new(
106
- event: @event,
107
- event_options: @given_options,
108
- timetoken: nil,
109
- status: {
110
- code: req_res_objects[:response].code,
111
- operation: Pubnub::Constants::OPERATION_HEARTBEAT,
112
- client_request: req_res_objects[:request],
113
- server_response: req_res_objects[:response],
114
- data: nil,
115
- category: (error ? Pubnub::Constants::STATUS_NON_JSON_RESPONSE : Pubnub::Constants::STATUS_ERROR),
116
- error: true,
117
- auto_retried: false,
118
-
119
- current_timetoken: nil,
120
- last_timetoken: nil,
121
- subscribed_channels: nil,
122
- subscribed_channel_groups: nil,
123
-
124
- config: get_config
125
- }
126
- )
127
- end
128
-
129
96
  def get_operation
130
97
  if @channel.empty? && @group.empty?
131
98
  Pubnub::Constants::OPERATION_GLOBAL_HERE_NOW