pubnub 4.6.2 → 5.0.0

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.

@@ -0,0 +1,258 @@
1
+ require 'pubnub'
2
+
3
+ token_with_all = "qEF2AkF0GmEI03xDdHRsGDxDcmVzpURjaGFuoWljaGFubmVsLTEY70NncnChb2NoYW5uZWxfZ3JvdXAtMQVDdXNyoENzcGOgRHV1aWShZnV1aWQtMRhoQ3BhdKVEY2hhbqFtXmNoYW5uZWwtXFMqJBjvQ2dycKF0XjpjaGFubmVsX2dyb3VwLVxTKiQFQ3VzcqBDc3BjoER1dWlkoWpedXVpZC1cUyokGGhEbWV0YaBEdXVpZHR0ZXN0LWF1dGhvcml6ZWQtdXVpZENzaWdYIPpU-vCe9rkpYs87YUrFNWkyNq8CVvmKwEjVinnDrJJc"
4
+
5
+ Given('I have a keyset with access manager enabled') do
6
+ expect(ENV['PAM_SUB_KEY']).not_to be_nil
7
+ expect(ENV['PAM_PUB_KEY']).not_to be_nil
8
+ expect(ENV['PAM_SEC_KEY']).not_to be_nil
9
+ @pn_configuration['subscribe_key'] = ENV['PAM_SUB_KEY']
10
+ @pn_configuration['publish_key'] = ENV['PAM_PUB_KEY']
11
+ @pn_configuration['secret_key'] = ENV['PAM_SEC_KEY']
12
+ logger = Logger.new(STDOUT)
13
+ logger.level = Logger::DEBUG
14
+ @pn_configuration['logger'] = logger
15
+ @pn_configuration['uuid'] = Pubnub::UUID.generate
16
+
17
+ @pubnub = Pubnub.new(@pn_configuration)
18
+ end
19
+
20
+ Given('I have a keyset with access manager enabled - without secret key') do
21
+ expect(ENV['PAM_SUB_KEY']).not_to be_nil
22
+ expect(ENV['PAM_PUB_KEY']).not_to be_nil
23
+ @pn_configuration['subscribe_key'] = ENV['PAM_SUB_KEY']
24
+ @pn_configuration['publish_key'] = ENV['PAM_PUB_KEY']
25
+ logger = Logger.new(STDOUT)
26
+ logger.level = Logger::DEBUG
27
+ @pn_configuration['logger'] = logger
28
+ @pn_configuration['uuid'] = Pubnub::UUID.generate
29
+
30
+ @pubnub = Pubnub.new(@pn_configuration)
31
+ end
32
+
33
+ Given('the authorized UUID {string}') do |uuid|
34
+ @grant_token_state[:authorized_uuid] = uuid
35
+ end
36
+
37
+ Given('the TTL {int}') do |ttl|
38
+ @grant_token_state[:ttl] = ttl
39
+ end
40
+
41
+ Given('the {string} {resourceType} resource access permissions') do |name, resource_type|
42
+ @grant_token_state[:current_name] = name
43
+
44
+ @grant_token_state[:current_grant][name] = {
45
+ :name => name,
46
+ :resource_type => resource_type,
47
+ :permission_type => []
48
+ }
49
+ end
50
+
51
+ And('grant resource permission {permissionType}') do |permission_type|
52
+ current_name = @grant_token_state[:current_name]
53
+ @grant_token_state[:current_grant][current_name][:permission_type].push(permission_type)
54
+ end
55
+
56
+ Given('the {string} {resourceType} pattern access permissions') do |pattern, resource_type|
57
+ @grant_token_state[:current_pattern] = pattern
58
+ @grant_token_state[:current_grant][pattern] = {
59
+ :pattern => pattern,
60
+ :resource_type => resource_type,
61
+ :permission_type => []
62
+ }
63
+ end
64
+
65
+ Given('a valid token with permissions to publish with channel {string}') do |string|
66
+ @grant_token_state[:token] = token_with_all
67
+ end
68
+
69
+ Given('a token') do
70
+ @grant_token_state[:token] = token_with_all
71
+ end
72
+
73
+ Given('an expired token with permissions to publish with channel {string}') do |string|
74
+ @grant_token_state[:token] = token_with_all
75
+ end
76
+
77
+ And('grant pattern permission {permissionType}') do |permission_type|
78
+ current_pattern = @grant_token_state[:current_pattern]
79
+ @grant_token_state[:current_grant][current_pattern][:permission_type].push(permission_type)
80
+ end
81
+
82
+ When('I grant a token specifying those permissions') do
83
+ res = call_grant_token(@pubnub, @grant_token_state)
84
+ @grant_token_state[:parsed_token] = @pubnub.parse_token(res.result[:data]["token"])
85
+ end
86
+
87
+ When('I publish a message using that auth token with channel {string}') do |channel|
88
+ @pubnub.set_token(@grant_token_state[:token])
89
+ res = @pubnub.publish(
90
+ message: "This is message",
91
+ channel: channel,
92
+ http_sync: true
93
+ )
94
+ @global_state[:last_call_res] = res
95
+ end
96
+
97
+ When('I attempt to publish a message using that auth token with channel {string}') do |channel|
98
+ @pubnub.set_token(@grant_token_state[:token])
99
+ res = @pubnub.publish(
100
+ message: "This is message",
101
+ channel: channel,
102
+ http_sync: true
103
+ )
104
+ @global_state[:last_call_res] = res
105
+ end
106
+
107
+ When('I revoke a token') do
108
+ res = @pubnub.revoke_token(
109
+ token: @grant_token_state[:token],
110
+ http_sync: true
111
+ )
112
+ @global_state[:last_call_res] = res
113
+ end
114
+
115
+ Then('the token contains the authorized UUID {string}') do |expected_uuid|
116
+ expect(@grant_token_state[:parsed_token]["uuid"]).to eq expected_uuid
117
+ end
118
+
119
+ Then('the token contains the TTL {int}') do |ttl|
120
+ expect(@grant_token_state[:parsed_token]["ttl"]).to eq ttl
121
+ end
122
+
123
+ Then('the token has {string} {resourceType} resource access permissions') do |resource, resource_type|
124
+ case resource_type
125
+ when "CHANNEL"
126
+ @grant_token_state[:token_resource] = @grant_token_state[:parsed_token]["res"]["chan"][resource]
127
+ when "CHANNEL_GROUP"
128
+ @grant_token_state[:token_resource] = @grant_token_state[:parsed_token]["res"]["grp"][resource]
129
+ when "UUID"
130
+ @grant_token_state[:token_resource] = @grant_token_state[:parsed_token]["res"]["uuid"][resource]
131
+ else
132
+ fail
133
+ end
134
+
135
+ expect(@grant_token_state[:token_resource]).not_to eq nil
136
+ end
137
+
138
+ Then('token resource permission {permissionType}') do |permission_type|
139
+ expect(has_permission(@grant_token_state[:token_resource], permission_type)).to eq true
140
+ end
141
+
142
+ Then('the token has {string} {resourceType} pattern access permissions') do |pattern, resourceType|
143
+ case resourceType
144
+ when "CHANNEL"
145
+ @grant_token_state[:token_resource] = @grant_token_state[:parsed_token]["pat"]["chan"][pattern]
146
+ when "CHANNEL_GROUP"
147
+ @grant_token_state[:token_resource] = @grant_token_state[:parsed_token]["pat"]["grp"][pattern]
148
+ when "UUID"
149
+ @grant_token_state[:token_resource] = @grant_token_state[:parsed_token]["pat"]["uuid"][pattern]
150
+ else
151
+ fail
152
+ end
153
+
154
+ expect(@grant_token_state[:token_resource]).not_to eq nil
155
+ end
156
+
157
+ And('token pattern permission {permissionType}') do |permission_type|
158
+ expect(has_permission(@grant_token_state[:token_resource], permission_type)).to eq true
159
+ end
160
+
161
+ Then('the token does not contain an authorized uuid') do
162
+ expect(@grant_token_state[:parsed_token]["uuid"]).to eq nil
163
+ end
164
+
165
+ Given('deny resource permission {permissionType}') do |permission_type|
166
+ current_name = @grant_token_state[:current_name]
167
+ @grant_token_state[:current_grant][current_name][:permission_type].filter { |p| p != permission_type }
168
+ end
169
+
170
+ When('I attempt to grant a token specifying those permissions') do
171
+ @global_state[:last_call_res] = call_grant_token(@pubnub, @grant_token_state)
172
+ end
173
+
174
+ Then('an error is returned') do
175
+ envelope = @global_state[:last_call_res]
176
+ expect(envelope).not_to eq nil
177
+ expect(envelope.is_a?(Pubnub::ErrorEnvelope)).to eq true
178
+ end
179
+
180
+ Then('the error status code is {int}') do |code|
181
+ expect(@global_state[:last_call_res].status[:code]).to eq code
182
+ end
183
+
184
+ Then('the error message is {string}') do |error_message|
185
+ expect(parse_error_body(@global_state[:last_call_res])["error"]["message"]).to eq error_message
186
+ end
187
+
188
+ Then('the error source is {string}') do |error_source|
189
+ expect(parse_error_body(@global_state[:last_call_res])["error"]["source"]).to eq error_source
190
+ end
191
+
192
+ Then('the error detail message is {string}') do |details_message|
193
+ expect(parse_error_body(@global_state[:last_call_res])["error"]["details"][0]["message"]).to eq details_message
194
+ end
195
+
196
+ Then('the error detail location is {string}') do |details_location|
197
+ expect(parse_error_body(@global_state[:last_call_res])["error"]["details"][0]["location"]).to eq details_location
198
+ end
199
+
200
+ Then('the error detail location type is {string}') do |location_type|
201
+ expect(parse_error_body(@global_state[:last_call_res])["error"]["details"][0]["locationType"]).to eq location_type
202
+ end
203
+
204
+ Given('I have a known token containing an authorized UUID') do
205
+ @grant_token_state[:token] = token_with_all
206
+ end
207
+
208
+ When('I parse the token') do
209
+ @grant_token_state[:parsed_token] = @pubnub.parse_token(@grant_token_state[:token])
210
+ end
211
+
212
+ Then('the parsed token output contains the authorized UUID {string}') do |expected_uuid|
213
+ expect(@grant_token_state[:parsed_token]["uuid"]).to eq expected_uuid
214
+ end
215
+
216
+ Given('I have a known token containing UUID resource permissions') do
217
+ @grant_token_state[:token] = token_with_all
218
+ end
219
+
220
+ Given('I have a known token containing UUID pattern Permissions') do
221
+ @grant_token_state[:token] = token_with_all
222
+ end
223
+
224
+ Given('the token string {string}') do |token|
225
+ @grant_token_state[:token] = token
226
+ end
227
+
228
+ Then('the result is successful') do
229
+ envelope = @global_state[:last_call_res]
230
+ expect(envelope.is_a?(Pubnub::ErrorEnvelope)).to eq false
231
+ expect(envelope.status[:code]).to eq 200
232
+ end
233
+
234
+ Then('an auth error is returned') do
235
+ envelope = @global_state[:last_call_res]
236
+ expect(envelope).not_to eq nil
237
+ expect(envelope.is_a?(Pubnub::ErrorEnvelope)).to eq true
238
+ end
239
+
240
+ Then('the auth error message is {string}') do |error_message|
241
+ expect(parse_error_body(@global_state[:last_call_res])["message"]).to eq error_message
242
+ end
243
+
244
+ Then('the error service is {string}') do |service|
245
+ expect(parse_error_body(@global_state[:last_call_res])["service"]).to eq service
246
+ end
247
+
248
+ Then('I get confirmation that token has been revoked') do
249
+ envelope = @global_state[:last_call_res]
250
+ expect(envelope.is_a?(Pubnub::ErrorEnvelope)).to eq false
251
+ expect(envelope.status[:code]).to eq 200
252
+ end
253
+
254
+ Then('the error detail message is not empty') do
255
+ expect(parse_error_body(@global_state[:last_call_res])["error"]["message"].empty?).to eq false
256
+ end
257
+
258
+
@@ -0,0 +1,15 @@
1
+ ParameterType(
2
+ name: 'resourceType',
3
+ regexp: /CHANNEL|CHANNEL_GROUP|UUID/,
4
+ type: String,
5
+ transformer: ->(s) { s }
6
+ )
7
+
8
+ ParameterType(
9
+ name: 'permissionType',
10
+ regexp: /READ|WRITE|GET|MANAGE|UPDATE|JOIN|DELETE|/,
11
+ type: String,
12
+ transformer: ->(s) { s }
13
+ )
14
+
15
+
@@ -0,0 +1,39 @@
1
+ def has_permission(perms, permission_type)
2
+ current_perm = nil
3
+ eval "current_perm = Pubnub::Permissions.res(#{permission_type.downcase}: true).calculate_bitmask"
4
+ perms & current_perm != 0
5
+ end
6
+
7
+ def prepare_permissions_map(grants, resource_type)
8
+ grants
9
+ .select { |_, value|
10
+ value[:resource_type] == resource_type
11
+ }
12
+ .to_h { |name, value|
13
+ empty_permissions = if value[:pattern]
14
+ Pubnub::Permissions.pat
15
+ else
16
+ Pubnub::Permissions.res
17
+ end
18
+ permissions = value[:permission_type].reduce(empty_permissions) { |accumulated_permissions, string_perm|
19
+ accumulated_permissions.instance_variable_set("@" + string_perm.downcase, true)
20
+ accumulated_permissions
21
+ }
22
+ [name, permissions]
23
+ }
24
+ end
25
+
26
+ def call_grant_token(pubnub, grant_token_state)
27
+ pubnub.grant_token(
28
+ ttl: grant_token_state[:ttl],
29
+ http_sync: true,
30
+ channels: prepare_permissions_map(grant_token_state[:current_grant], "CHANNEL"),
31
+ channel_groups: prepare_permissions_map(grant_token_state[:current_grant], "CHANNEL_GROUP"),
32
+ uuids: prepare_permissions_map(grant_token_state[:current_grant], "UUID"),
33
+ authorized_uuid: grant_token_state[:authorized_uuid]
34
+ )
35
+ end
36
+
37
+ def parse_error_body(error_response)
38
+ Pubnub::Formatter.parse_json(error_response.status[:server_response].body)[0]
39
+ end
@@ -0,0 +1,98 @@
1
+ require 'net/http'
2
+ require 'json'
3
+
4
+ Before do |scenario|
5
+ @grant_token_state = {}
6
+ @global_state = {}
7
+ @grant_token_state[:current_grant] = {}
8
+ @pn_configuration = {}
9
+
10
+ when_mock_server_used {
11
+ puts "Using mock"
12
+ expect(ENV['SERVER_HOST']).not_to be_nil
13
+ expect(ENV['SERVER_PORT']).not_to be_nil
14
+ @pn_configuration = {
15
+ origin: ENV['SERVER_HOST'] + ":" + ENV['SERVER_PORT'],
16
+ isSecure: false,
17
+ }
18
+ }
19
+
20
+ when_mock_server_used {
21
+ init_mock(scenario)
22
+ }
23
+ end
24
+
25
+ After do |scenario|
26
+ when_mock_server_used {
27
+ expect_mock(scenario)
28
+ }
29
+ end
30
+
31
+ def when_mock_server_used(&block)
32
+ if ENV['SERVER_MOCK']&.to_s&.downcase == 'true'
33
+ block.call
34
+ end
35
+ end
36
+
37
+ def init_mock(scenario)
38
+ contract_name = contract_name(scenario)
39
+ if contract_name
40
+ call_init_endpoint(contract_name)
41
+ end
42
+ end
43
+
44
+ def call_init_endpoint(contract_name)
45
+ Net::HTTP.get_response("#{ENV['SERVER_HOST']}", "/init?__contract__script__=#{contract_name}", "#{ENV['SERVER_PORT']}")
46
+ end
47
+
48
+ def expect_mock(scenario)
49
+ contract_name = contract_name(scenario)
50
+ if contract_name
51
+ expect_result = call_expect_endpoint()
52
+ print(expect_result)
53
+ if still_pending?(expect_result) || some_failed?(expect_result)
54
+ message = "Scenario #{extract_contract(expect_result)} considered failure:
55
+ pending - #{extract_pending(expect_result)},
56
+ failed - #{extract_failed(expect_result)}"
57
+ RSpec::Expectations.fail_with(message)
58
+ end
59
+ end
60
+ end
61
+
62
+ def extract_contract(expect_result)
63
+ expect_result['contract']
64
+ end
65
+
66
+ def extract_pending(expect_result)
67
+ expect_result['expectations']['pending'].join(", ")
68
+ end
69
+
70
+ def extract_failed(expect_result)
71
+ expect_result['expectations']['failed'].join(", ")
72
+ end
73
+
74
+ def still_pending?(expect_result)
75
+ pending = expect_result['expectations']['pending']
76
+ not pending.empty?
77
+ end
78
+
79
+ def some_failed?(expect_result)
80
+ pending = expect_result['expectations']['failed']
81
+ not pending.empty?
82
+ end
83
+
84
+ def call_expect_endpoint
85
+ expect_response = Net::HTTP.get_response("#{ENV['SERVER_HOST']}", "/expect", "#{ENV['SERVER_PORT']}")
86
+
87
+ if expect_response == nil || expect_response.body == nil
88
+ RSpec::Expectations.fail_with("Expect response body is null")
89
+ else
90
+ JSON.parse(expect_response.body)
91
+ end
92
+ end
93
+
94
+ def contract_name(scenario)
95
+ scenario.source_tag_names&.
96
+ select { |tagName| tagName.start_with?("@contract") }&.
97
+ map { |tagName| tagName.split("=")[1] }&.first
98
+ end
@@ -0,0 +1,182 @@
1
+ module Pubnub
2
+ class Cbor
3
+
4
+ private
5
+
6
+ TYPE_MASK = 0b11100000
7
+ ADDITIONAL_MASK = 0b00011111
8
+
9
+ TYPE_UNSIGNED_INT = 0b00000000
10
+ TYPE_NEGATIVE_INT = 0b00100000
11
+ TYPE_BYTE_STRING = 0b01000000
12
+ TYPE_TEXT_STRING = 0b01100000
13
+ TYPE_ARRAY = 0b10000000
14
+ TYPE_HASHMAP = 0b10100000
15
+ TYPE_TAG = 0b11000000
16
+ TYPE_FLOAT = 0b11100000
17
+
18
+ ADDITIONAL_TYPE_INDEFINITE = 31
19
+ INDEFINITE_BREAK = 0b11111111
20
+
21
+ ADDITIONAL_LENGTH_1B = 24
22
+ ADDITIONAL_LENGTH_2B = 25
23
+ ADDITIONAL_LENGTH_4B = 26
24
+ ADDITIONAL_LENGTH_8B = 27
25
+
26
+ ADDITIONAL_LENGTH_BYTES = {
27
+ ADDITIONAL_LENGTH_1B => 1,
28
+ ADDITIONAL_LENGTH_2B => 2,
29
+ ADDITIONAL_LENGTH_4B => 4,
30
+ ADDITIONAL_LENGTH_8B => 8,
31
+ }
32
+
33
+ SIMPLE_VALUE_FALSE = 0xF4
34
+ SIMPLE_VALUE_TRUE = 0xF5
35
+ SIMPLE_VALUE_NULL = 0xF6
36
+ SIMPLE_VALUE_UNDEF = 0xF7
37
+
38
+ def bytearray_to_i(byte_array)
39
+ byte_array.reverse_each.map.with_index do |b, i|
40
+ b << 8 * i
41
+ end.reduce(0) do |reduced, byte|
42
+ reduced | byte
43
+ end
44
+ end
45
+
46
+ def decode_integer(data, additional)
47
+ if ADDITIONAL_LENGTH_BYTES.member?(additional)
48
+ bytearray_to_i(data.shift(ADDITIONAL_LENGTH_BYTES[additional]))
49
+ else
50
+ additional
51
+ end
52
+ end
53
+
54
+ def decode_float(data, additional)
55
+ if additional <= 23
56
+ additional
57
+ else
58
+ bytes = bytearray_to_i(data.shift(ADDITIONAL_LENGTH_BYTES[additional]))
59
+ case (additional)
60
+ when ADDITIONAL_LENGTH_1B
61
+ bytes
62
+ when ADDITIONAL_LENGTH_2B
63
+ sign = (bytes >> 15) != 0 ? -1 : 1
64
+ exp = (bytes & 0b0111110000000000) >> 10
65
+ mant = bytes & 0b1111111111
66
+ if exp == 0
67
+ result = (2 ** -14) * (mant / 1024.to_f)
68
+ elsif exp == 0b11111
69
+ result = Float::INFINITY
70
+ else
71
+ result = (2 ** (exp - 15)) * (1 + mant / 1024.to_f)
72
+ end
73
+ sign * result
74
+ when ADDITIONAL_LENGTH_4B
75
+ sign = (bytes >> 31) != 0 ? -1 : 1
76
+ x = (bytes & ((1 << 23) - 1)) + (1 << 23)
77
+ exp = (bytes >> 23 & 0xFF) - 127
78
+ x * (2 ** (exp - 23)) * sign
79
+ when ADDITIONAL_LENGTH_8B
80
+ sign = (bytes >> 63) != 0 ? -1 : 1
81
+ exp = (bytes >> 52) & 0x7FF
82
+
83
+ mant = bytes & 0xFFFFFFFFFFFFF
84
+
85
+ if 0 == exp
86
+ val = mant * 2 ** (-(1022 + 52))
87
+ elsif 0b11111111111 != exp
88
+ val = (mant + (1 << 52)) * 2 ** (exp - (1023 + 52))
89
+ else
90
+ val = 0 == mant ? Float::INFINITY : Float::NAN
91
+ end
92
+ sign * val
93
+ end
94
+ end
95
+ end
96
+
97
+ def indefinite_data(data)
98
+ result = []
99
+
100
+ loop do
101
+ byte = data.shift
102
+ break if byte == INDEFINITE_BREAK
103
+ result.append(byte)
104
+ break if data.empty?
105
+ end
106
+ result
107
+ end
108
+
109
+ def compute_length(data, additional)
110
+ if ADDITIONAL_LENGTH_BYTES.member?(additional)
111
+ bytearray_to_i(data.shift(ADDITIONAL_LENGTH_BYTES[additional]))
112
+ else
113
+ additional
114
+ end
115
+ end
116
+
117
+ def decode_string(data, additional)
118
+ if additional == ADDITIONAL_TYPE_INDEFINITE
119
+ indefinite_data(data).pack('C*').force_encoding('UTF-8')
120
+ else
121
+ length = compute_length(data, additional)
122
+ data.shift(length).pack('C*').force_encoding('UTF-8')
123
+ end
124
+ end
125
+
126
+ def decode_map(data, additional)
127
+ length = compute_length(data, additional)
128
+ result = Hash.new
129
+ (1..length).each { result.store(parse_data(data), parse_data(data)) }
130
+ result
131
+ end
132
+
133
+ def decode_array(data, additional)
134
+ length = compute_length(data, additional)
135
+ (1..length).map { parse_data(data) }
136
+ end
137
+
138
+ def parse_data(data)
139
+ byte = data.shift
140
+
141
+ case (byte)
142
+ when SIMPLE_VALUE_NULL
143
+ return nil
144
+ when SIMPLE_VALUE_TRUE
145
+ return true
146
+ when SIMPLE_VALUE_FALSE
147
+ return false
148
+ when SIMPLE_VALUE_UNDEF
149
+ return nil
150
+ else
151
+ type = byte & TYPE_MASK
152
+ additional = byte & ADDITIONAL_MASK
153
+
154
+ case (type)
155
+ when TYPE_NEGATIVE_INT
156
+ -1 - decode_integer(data, additional)
157
+ when TYPE_UNSIGNED_INT
158
+ decode_integer(data, additional)
159
+ when TYPE_FLOAT
160
+ decode_float(data, additional).to_f
161
+ when TYPE_BYTE_STRING
162
+ decode_string(data, additional)
163
+ when TYPE_TEXT_STRING
164
+ decode_string(data, additional)
165
+ when TYPE_ARRAY
166
+ decode_array(data, additional)
167
+ when TYPE_HASHMAP
168
+ decode_map(data, additional)
169
+ else
170
+ nil
171
+ end
172
+ end
173
+ end
174
+
175
+ public
176
+
177
+ def decode(value)
178
+ parse_data(value)
179
+ end
180
+ end
181
+
182
+ end
@@ -4,7 +4,7 @@ module Pubnub
4
4
  class Client
5
5
  # Module that holds generator for all events
6
6
  module Events
7
- EVENTS = %w[publish subscribe presence leave history here_now audit grant delete_messages
7
+ EVENTS = %w[publish subscribe presence leave history here_now audit grant grant_token revoke_token delete_messages
8
8
  revoke time heartbeat where_now set_state state channel_registration message_counts signal
9
9
  add_channels_to_push list_push_provisions remove_channels_from_push remove_device_from_push
10
10
  set_uuid_metadata set_channel_metadata remove_uuid_metadata remove_channel_metadata
@@ -1,9 +1,12 @@
1
+ require 'pubnub/validators/common_validator'
2
+
1
3
  # Toplevel Pubnub module.
2
4
  module Pubnub
3
5
  # Pubnub client Class
4
6
  class Client
5
7
  # Module that holds some getters and setters
6
8
  module GettersSetters
9
+
7
10
  def sdk_version
8
11
  "PubNub-Ruby/#{Pubnub::VERSION}"
9
12
  end
@@ -25,6 +28,8 @@ module Pubnub
25
28
  def change_uuid(uuid)
26
29
  Pubnub.logger.debug('Pubnub::Client') { 'Changing uuid' }
27
30
  raise('Cannot change UUID while subscribed.') if subscribed?
31
+ Validator::Client.validate_uuid uuid
32
+
28
33
  @env[:uuid] = uuid
29
34
  end
30
35