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.

@@ -1,19 +1,46 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Toplevel Pubnub module.
2
4
  module Pubnub
3
5
  # Pubnub client Class
4
6
  class Client
5
7
  # Module that holds paged_history event logic
6
8
  module PagedHistory
9
+ # Fetch messages as long as one of criteria won't be met.
10
+ # Messages returned as single envelope.
11
+ def all_history_messages(options = {}, &block)
12
+ channel = options.fetch(:channel)
13
+ # Time frame between which messages should be fetched.
14
+ start_tt = options.fetch(:start, nil)
15
+ end_tt = options.fetch(:end, nil)
16
+ page_size = options.fetch(:page_size, 100) # How many messages per-request should be fetched.
17
+ reverse = options.fetch(:reverse, false) # Order in which messages should be retrieved if :end not set.
18
+ include_token = options.fetch(:include_token, true) # Whether timetoken should be included with message or not.
19
+ maximum = options.fetch(:max, 500) # Maximum number of messages which should be fetched.
20
+ callback = options.fetch(:callback, block)
21
+
22
+ reverse = false unless end_tt.nil? # Disable revers if closed time interval specified.
23
+ maximum = nil unless end_tt.nil? # Disable maximum messages count if closed time interval specified.
24
+
25
+ if options[:http_sync]
26
+ sync_all_history_messages(channel, include_token, page_size, reverse, maximum, callback, start: start_tt, end: end_tt)
27
+ else
28
+ async_all_history_messages(options)
29
+ end
30
+ end
31
+
7
32
  def paged_history(options = {}, &block)
8
33
  channel = options.fetch(:channel)
9
- page = options.fetch(:page, 1)
10
- limit = options.fetch(:limit, 100)
34
+ page = options.fetch(:page, 1) # How many mages should be fetched with specified limit.
35
+ limit = options.fetch(:limit, 100) # How many messages per page should be fetched.
36
+ include_token = options.fetch(:include_token, false) # Whether timetoken should be included with message or not.
11
37
  callback = options.fetch(:callback, block)
12
- sync = options[:http_sync]
13
- start_tt = options.fetch(:start)
14
- end_tt = options.fetch(:end)
15
- if sync
16
- sync_paged_history(channel, page, limit, callback, start: start_tt, end: end_tt)
38
+ # Time frame between which messages should be fetched.
39
+ start_tt = options.fetch(:start, nil)
40
+ end_tt = options.fetch(:end, nil)
41
+
42
+ if options[:http_sync]
43
+ sync_paged_history(channel, page, limit, include_token, callback, start: start_tt, end: end_tt)
17
44
  else
18
45
  async_paged_history(options)
19
46
  end
@@ -21,40 +48,140 @@ module Pubnub
21
48
 
22
49
  private
23
50
 
24
- def sync_paged_history(channel, page, limit, callback, timetokens)
51
+ def sync_all_history_messages(channel, include_token, page_size, reverse, maximum, callback, timetokens)
52
+ next_timetoken = timetokens[:start]
53
+ messages_timetokens = timetokens.dup
54
+ final_envelope = nil
55
+ keep_fetching = true
56
+ messages = []
57
+
58
+ while keep_fetching
59
+ envelope = history(
60
+ channel: channel,
61
+ include_token: include_token,
62
+ count: page_size,
63
+ reverse: reverse,
64
+ start: next_timetoken,
65
+ end: timetokens[:end],
66
+ http_sync: true
67
+ )
68
+
69
+ # Terminate fetch because last attempt failed.
70
+ if envelope.status[:category] != :ack
71
+ final_envelope = envelope
72
+ break
73
+ end
74
+
75
+ result_data = envelope.result[:data]
76
+ result_messages = result_data[:messages]
77
+ break if result_messages.empty?
78
+
79
+ if reverse || timetokens[:end]
80
+ messages_timetokens[:start] = result_data[:start].to_i if messages.empty?
81
+ messages_timetokens[:end] = result_data[:end].to_i
82
+ messages.concat(result_messages)
83
+ else
84
+ messages_timetokens[:end] = result_data[:end].to_i if messages.empty?
85
+ messages_timetokens[:start] = result_data[:start].to_i
86
+ messages.unshift(*result_messages)
87
+ end
88
+
89
+ keep_fetching = result_messages.length == page_size
90
+ keep_fetching = messages.length < maximum if keep_fetching && maximum && maximum > 0
91
+
92
+ if keep_fetching
93
+ next_timetoken = reverse ? result_data[:end].to_i : result_data[:start].to_i
94
+ next_timetoken = result_data[:end].to_i unless timetokens[:end].nil?
95
+ end
96
+ end
97
+
98
+ # Create envelop if no error should be reported.
99
+ final_envelope = envelope_with_messages(messages, messages_timetokens) if final_envelope.nil?
100
+
101
+ callback&.call final_envelope
102
+ final_envelope
103
+ end
104
+
105
+ # Retrieve results page-by-page (callback called for each page).
106
+ def sync_paged_history(channel, page, limit, include_token, callback, timetokens)
25
107
  envelopes = []
26
- page.times do |i|
27
- envelopes << history(
108
+ page.times do |_i|
109
+ envelope = history(
28
110
  channel: channel,
111
+ include_token: include_token,
29
112
  http_sync: true,
30
113
  count: limit,
31
114
  start: timetokens[:start],
32
115
  end: timetokens[:end]
33
116
  )
34
- envelopes.flatten!
35
- timetokens[:end] = envelopes.last.history_start.to_i
36
- envelopes = [] unless i == page - 1
117
+
118
+ break if envelope.result[:data][:messages].empty?
119
+
120
+ envelopes.push envelope
121
+ timetokens[:start] = envelope.result[:data][:start].to_i
122
+ # No need to iterate further if there is no more messages.
123
+ break if envelope.result[:data][:messages].length < limit
37
124
  end
38
125
 
39
126
  call_callback(envelopes, callback)
40
127
  end
41
128
 
42
129
  def async_paged_history(options)
43
- Concurrent::Future.new do
130
+ Concurrent::Future.execute do
44
131
  sync_options = options.dup
45
132
  sync_options[:http_sync] = true
46
- paged_history(sync_options, &block)
133
+ paged_history(sync_options)
134
+ end
135
+ end
136
+
137
+ def async_all_history_messages(options)
138
+ Concurrent::Future.execute do
139
+ sync_options = options.dup
140
+ sync_options[:http_sync] = true
141
+ all_history_messages(sync_options)
47
142
  end
48
143
  end
49
144
 
50
145
  def call_callback(envelopes, callback)
51
- envelopes.flatten!
52
146
  if callback
53
147
  envelopes.each do |envelope|
54
- secure_call callback, envelope
148
+ callback.call envelope
55
149
  end
56
150
  end
57
151
  envelopes
152
+ rescue StandardError => e
153
+ Pubnub.logger.error('Pubnub::Client') { "Error while calling callback #{e.inspect}" }
154
+ end
155
+
156
+ def envelope_with_messages(messages, timetokens)
157
+ Pubnub::Envelope.new(
158
+ event: :history,
159
+ event_options: nil,
160
+ timetoken: nil,
161
+ status: {
162
+ code: 200,
163
+ client_request: nil,
164
+ server_response: nil,
165
+
166
+ category: Pubnub::Constants::STATUS_ACK,
167
+ error: false,
168
+ auto_retried: false,
169
+
170
+ data: nil,
171
+ current_timetoken: nil,
172
+ last_timetoken: nil,
173
+ subscribed_channels: nil,
174
+ subscribed_channel_groups: nil,
175
+ config: nil
176
+ },
177
+ result: {
178
+ code: 200,
179
+ operation: Pubnub::Constants::OPERATION_HISTORY,
180
+ client_request: nil,
181
+ server_response: nil,
182
+ data: { messages: messages, end: timetokens[:end], start: timetokens[:start] }
183
+ }
184
+ )
58
185
  end
59
186
  end
60
187
  end
data/lib/pubnub/client.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'base64'
2
+
1
3
  require 'pubnub/error'
2
4
  require 'pubnub/uuid'
3
5
  require 'pubnub/formatter'
@@ -34,6 +36,8 @@ require 'pubnub/validators/client'
34
36
  require 'pubnub/validators/audit'
35
37
  require 'pubnub/validators/channel_registration'
36
38
  require 'pubnub/validators/grant'
39
+ require 'pubnub/validators/grant_token'
40
+ require 'pubnub/validators/revoke_token'
37
41
  require 'pubnub/validators/heartbeat'
38
42
  require 'pubnub/validators/here_now'
39
43
  require 'pubnub/validators/history'
@@ -67,6 +71,7 @@ require 'pubnub/validators/set_channel_members'
67
71
  require 'pubnub/validators/set_memberships'
68
72
  require 'pubnub/validators/remove_channel_members'
69
73
  require 'pubnub/validators/remove_memberships'
74
+ require 'pubnub/cbor'
70
75
 
71
76
  Dir[File.join(File.dirname(__dir__), 'pubnub', 'events', '*.rb')].each do |file|
72
77
  require file
@@ -319,6 +324,15 @@ module Pubnub
319
324
  @telemetry.await.fetch_average(event).value
320
325
  end
321
326
 
327
+ def parse_token(token)
328
+ token_bytes = Base64.urlsafe_decode64(token)
329
+ Cbor.new.decode(token_bytes.bytes)
330
+ end
331
+
332
+ def set_token(token)
333
+ @env[:token] = token
334
+ end
335
+
322
336
  private
323
337
 
324
338
  def create_state_pools(event)
@@ -370,14 +384,9 @@ module Pubnub
370
384
 
371
385
  def prepare_env
372
386
  assign_defaults
373
- generate_uuid if @env[:uuid].blank?
374
387
  setup_pools
375
388
  end
376
389
 
377
- def generate_uuid
378
- @env[:uuid] = UUID.generate
379
- end
380
-
381
390
  def assign_defaults
382
391
  @env[:origin] = @env[:origins_pool].first if @env[:origins_pool]
383
392
  default_values.each do |k, v|
@@ -57,6 +57,8 @@ module Pubnub
57
57
  OPERATION_CHANNEL_GROUP_REMOVE = :channel_group_remove
58
58
  OPERATION_AUDIT = :audit
59
59
  OPERATION_GRANT = :grant
60
+ OPERATION_GRANT_TOKEN = :grant_token
61
+ OPERATION_REVOKE_TOKEN = :revoke_token
60
62
  OPERATION_REVOKE = :revoke
61
63
  OPERATION_DELETE = :delete
62
64
  OPERATION_LIST_ALL_CHANNEL_GROUPS = :list_all_channel_groups
@@ -86,13 +88,14 @@ module Pubnub
86
88
  OPERATION_SUBSCRIBE, OPERATION_HEARTBEAT, OPERATION_PRESENCE, OPERATION_TIME, OPERATION_HISTORY,
87
89
  OPERATION_HERE_NOW, OPERATION_GLOBAL_HERE_NOW, OPERATION_GET_STATE, OPERATION_LIST_ALL_CHANNEL_GROUPS,
88
90
  OPERATION_LIST_ALL_CHANNELS_IN_CHANNEL_GROUP, OPERATION_CHANNEL_GROUP_ADD, OPERATION_CHANNEL_GROUP_REMOVE,
89
- OPERATION_AUDIT, OPERATION_GRANT, OPERATION_REVOKE, OPERATION_WHERE_NOW, OPERATION_MESSAGE_COUNTS,
90
- OPERATION_ADD_CHANNELS_TO_PUSH, OPERATION_LIST_PUSH_PROVISIONS, OPERATION_REMOVE_CHANNELS_FROM_PUSH,
91
- OPERATION_REMOVE_DEVICE_FROM_PUSH, OPERATION_SIGNAL, OPERATION_SET_UUID_METADATA, OPERATION_GET_UUID_METADATA,
92
- OPERATION_GET_ALL_UUID_METADATA, OPERATION_REMOVE_UUID_METADATA, OPERATION_SET_CHANNEL_METADATA,
93
- OPERATION_GET_CHANNEL_METADATA, OPERATION_GET_ALL_CHANNELS_METADATA, OPERATION_REMOVE_CHANNEL_METADATA,
94
- OPERATION_GET_CHANNEL_MEMBERS, OPERATION_SET_CHANNEL_MEMBERS, OPERATION_REMOVE_CHANNEL_MEMBERS,
95
- OPERATION_GET_MEMBERSHIPS, OPERATION_SET_MEMBERSHIPS, OPERATION_REMOVE_MEMBERSHIPS
91
+ OPERATION_AUDIT, OPERATION_GRANT, OPERATION_GRANT_TOKEN, OPERATION_REVOKE, OPERATION_WHERE_NOW,
92
+ OPERATION_MESSAGE_COUNTS, OPERATION_ADD_CHANNELS_TO_PUSH, OPERATION_LIST_PUSH_PROVISIONS,
93
+ OPERATION_REMOVE_CHANNELS_FROM_PUSH, OPERATION_REMOVE_DEVICE_FROM_PUSH, OPERATION_SIGNAL,
94
+ OPERATION_SET_UUID_METADATA, OPERATION_GET_UUID_METADATA, OPERATION_GET_ALL_UUID_METADATA,
95
+ OPERATION_REMOVE_UUID_METADATA, OPERATION_SET_CHANNEL_METADATA, OPERATION_GET_CHANNEL_METADATA,
96
+ OPERATION_GET_ALL_CHANNELS_METADATA, OPERATION_REMOVE_CHANNEL_METADATA, OPERATION_GET_CHANNEL_MEMBERS,
97
+ OPERATION_SET_CHANNEL_MEMBERS, OPERATION_REMOVE_CHANNEL_MEMBERS, OPERATION_GET_MEMBERSHIPS,
98
+ OPERATION_SET_MEMBERSHIPS, OPERATION_REMOVE_MEMBERSHIPS
96
99
  ].freeze
97
100
 
98
101
  # Announcements
data/lib/pubnub/event.rb CHANGED
@@ -24,8 +24,8 @@ module Pubnub
24
24
  env.delete(:state)
25
25
  create_variables_from_options(env.merge(options))
26
26
  @origin = @app.current_origin
27
- format_channels
28
- format_group
27
+ format_channels if enable_format_channels?
28
+ format_group if enable_format_group?
29
29
  set_timestamp
30
30
  validate!
31
31
  telemetry = @app.telemetry_for(@telemetry_name)
@@ -44,7 +44,7 @@ module Pubnub
44
44
  envelopes
45
45
  end
46
46
 
47
- def send_request(compressed_body = '')
47
+ def send_request(compressed_body = '', header = {})
48
48
  Pubnub.logger.debug('Pubnub::Event') { '#send_request called' }
49
49
 
50
50
  @compressed_body = compressed_body
@@ -54,13 +54,13 @@ module Pubnub
54
54
  telemetry_time_start = ::Time.now.to_f
55
55
  response = case operation_http_method
56
56
  when "get"
57
- sender.get(uri.to_s)
57
+ sender.get(uri.to_s, header: header)
58
58
  when "post"
59
- sender.post(uri.to_s, body: compressed_body)
59
+ sender.post(uri.to_s, body: compressed_body, header: header)
60
60
  when "patch"
61
- sender.patch(uri.to_s, body: compressed_body)
61
+ sender.patch(uri.to_s, body: compressed_body, header: header)
62
62
  else
63
- sender.delete(uri.to_s)
63
+ sender.delete(uri.to_s, header: header)
64
64
  end
65
65
 
66
66
  begin
@@ -102,9 +102,18 @@ module Pubnub
102
102
 
103
103
  private
104
104
 
105
+ def enable_format_channels?
106
+ true
107
+ end
108
+
109
+ def enable_format_group?
110
+ true
111
+ end
112
+
105
113
  def operation_http_method
106
114
  case @event
107
- when Pubnub::Constants::OPERATION_DELETE, Pubnub::Constants::OPERATION_REMOVE_CHANNEL_METADATA, Pubnub::Constants::OPERATION_REMOVE_UUID_METADATA
115
+ when Pubnub::Constants::OPERATION_DELETE, Pubnub::Constants::OPERATION_REMOVE_CHANNEL_METADATA,
116
+ Pubnub::Constants::OPERATION_REMOVE_UUID_METADATA, Pubnub::Constants::OPERATION_REVOKE_TOKEN
108
117
  "delete"
109
118
  when Pubnub::Constants::OPERATION_SET_UUID_METADATA, Pubnub::Constants::OPERATION_SET_CHANNEL_METADATA,
110
119
  Pubnub::Constants::OPERATION_SET_CHANNEL_MEMBERS, Pubnub::Constants::OPERATION_SET_MEMBERSHIPS,
@@ -136,8 +145,9 @@ module Pubnub
136
145
  pnsdk: @app.sdk_version
137
146
  }
138
147
 
148
+ token = @app.env[:token]
139
149
  empty_if_blank = {
140
- auth: @auth_key,
150
+ auth: token ? token : @auth_key,
141
151
  uuid: @app.env[:uuid],
142
152
  @telemetry_name => @current_telemetry
143
153
  }
@@ -164,7 +174,8 @@ module Pubnub
164
174
  end count limit reverse presence_callback store skip_validate
165
175
  state channel_group channel_groups compressed meta customs include_token
166
176
  replicate with_presence cipher_key_selector include_meta join update get
167
- add remove push_token push_gateway environment topic
177
+ add remove push_token push_gateway environment topic authorized_uuid
178
+ token
168
179
  ]
169
180
 
170
181
  options = options.each_with_object({}) { |option, obj| obj[option.first.to_sym] = option.last }
@@ -0,0 +1,172 @@
1
+ module Pubnub
2
+ # Holds grant token functionality
3
+ class GrantToken < SingleEvent
4
+ include Concurrent::Async
5
+ include Pubnub::Validator::GrantToken
6
+
7
+ def initialize(options, app)
8
+ @event = current_operation
9
+ @telemetry_name = :l_pamv3
10
+ @uuids = options[:uuids] || {}
11
+ options[:channels] = options[:channels] || {}
12
+ options[:channel_groups] = options[:channel_groups] || {}
13
+ super
14
+ end
15
+
16
+ def fire
17
+ Pubnub.logger.debug('Pubnub::GrantToken') { "Fired event #{self.class}" }
18
+
19
+ raw_body = {
20
+ ttl: @ttl,
21
+ permissions: {
22
+ meta: @meta,
23
+ uuid: @authorized_uuid,
24
+ resources: prepare_permissions(:resource, @channels, @channel_groups, @uuids),
25
+ patterns: prepare_permissions(:pattern, @channels, @channel_groups, @uuids)
26
+ }.select { |_, v| v }
27
+ }
28
+ body = Formatter.format_message(raw_body, "", false, false)
29
+ response = send_request(body, { "Content-Type": "application/json" })
30
+
31
+ envelopes = fire_callbacks(handle(response, uri))
32
+ finalize_event(envelopes)
33
+ envelopes
34
+ end
35
+
36
+ private
37
+
38
+ def enable_format_channels?
39
+ false
40
+ end
41
+
42
+ def enable_format_group?
43
+ false
44
+ end
45
+
46
+ def current_operation
47
+ Pubnub::Constants::OPERATION_GRANT_TOKEN
48
+ end
49
+
50
+ def prepare_permissions(type, channels, groups, uuids)
51
+ {
52
+ channels: prepare_single_permissions(type, channels),
53
+ groups: prepare_single_permissions(type, groups),
54
+ uuids: prepare_single_permissions(type, uuids)
55
+ }
56
+ end
57
+
58
+ def prepare_single_permissions(type, resources)
59
+ resources
60
+ .select { |_, v| v.type == type }
61
+ .to_h { |k, v| [k, v.calculate_bitmask] }
62
+ end
63
+
64
+ def valid_envelope(parsed_response, req_res_objects)
65
+ Pubnub::Envelope.new(
66
+ event: @event,
67
+ event_options: @given_options,
68
+ timetoken: nil,
69
+ status: {
70
+ code: req_res_objects[:response].code,
71
+ client_request: req_res_objects[:request],
72
+ server_response: req_res_objects[:response],
73
+ category: Pubnub::Constants::STATUS_ACK,
74
+ error: false,
75
+ auto_retried: false,
76
+
77
+ current_timetoken: nil,
78
+ last_timetoken: nil,
79
+ subscribed_channels: nil,
80
+ subscribed_channel_groups: nil,
81
+
82
+ data: nil,
83
+
84
+ config: get_config
85
+
86
+ },
87
+ result: {
88
+ code: req_res_objects[:response].code,
89
+ operation: current_operation,
90
+ client_request: req_res_objects[:request],
91
+ server_response: req_res_objects[:response],
92
+
93
+ data: parsed_response['data']
94
+ }
95
+ )
96
+ end
97
+
98
+ def path
99
+ '/' + [
100
+ 'v3',
101
+ 'pam',
102
+ @subscribe_key,
103
+ 'grant'
104
+ ].join('/')
105
+ end
106
+ end
107
+
108
+ class Permissions
109
+ attr_reader :type
110
+
111
+ class << Permissions
112
+ def pat(read: false, write: false, manage: false, delete: false,
113
+ create: false, get: false, update: false, join: false)
114
+ Permissions.new(
115
+ type: :pattern,
116
+ read: read,
117
+ write: write,
118
+ manage: manage,
119
+ delete: delete,
120
+ create: create,
121
+ get: get,
122
+ update: update,
123
+ join: join
124
+ )
125
+ end
126
+
127
+ def res(read: false, write: false, manage: false, delete: false, create: false, get: false, update: false, join: false)
128
+ Permissions.new(
129
+ type: :resource,
130
+ read: read,
131
+ write: write,
132
+ manage: manage,
133
+ delete: delete,
134
+ create: create,
135
+ get: get,
136
+ update: update,
137
+ join: join
138
+ )
139
+ end
140
+ end
141
+
142
+ def initialize(options)
143
+ @type = options[:type]
144
+ @read = options[:read] || false
145
+ @write = options[:write] || false
146
+ @manage = options[:manage] || false
147
+ @delete = options[:delete] || false
148
+ @create = options[:create] || false
149
+ @get = options[:get] || false
150
+ @update = options[:update] || false
151
+ @join = options[:join] || false
152
+ end
153
+
154
+ def to_s
155
+ "Permissions: {:read => #{@read}, :write => #{@write}, :manage => #{@manage} , :delete => #{@delete}, :create => #{@create}, :get => #{@get}, :update => #{@update}, :join => #{@join}}"
156
+ end
157
+
158
+ def calculate_bitmask
159
+ sum = 0
160
+
161
+ sum |= 1 if @read
162
+ sum |= 2 if @write
163
+ sum |= 4 if @manage
164
+ sum |= 8 if @delete
165
+ sum |= 16 if @create
166
+ sum |= 32 if @get
167
+ sum |= 64 if @update
168
+ sum |= 128 if @join
169
+ sum
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,66 @@
1
+ module Pubnub
2
+ # Holds revoke token functionality
3
+ class RevokeToken < SingleEvent
4
+ include Concurrent::Async
5
+ include Pubnub::Validator::RevokeToken
6
+
7
+ def initialize(options, app)
8
+ @event = :revoke_token
9
+ super
10
+ @token = @token.split(' ')
11
+ .map{ |part| CGI.escape(part) }
12
+ .join("%20")
13
+ end
14
+
15
+ private
16
+
17
+ def current_operation
18
+ Pubnub::Constants::OPERATION_GRANT_TOKEN
19
+ end
20
+
21
+ def valid_envelope(parsed_response, req_res_objects)
22
+ Pubnub::Envelope.new(
23
+ event: @event,
24
+ event_options: @given_options,
25
+ timetoken: nil,
26
+ status: {
27
+ code: req_res_objects[:response].code,
28
+ client_request: req_res_objects[:request],
29
+ server_response: req_res_objects[:response],
30
+ category: Pubnub::Constants::STATUS_ACK,
31
+ error: false,
32
+ auto_retried: false,
33
+
34
+ current_timetoken: nil,
35
+ last_timetoken: nil,
36
+ subscribed_channels: nil,
37
+ subscribed_channel_groups: nil,
38
+
39
+ data: nil,
40
+
41
+ config: get_config
42
+
43
+ },
44
+ result: {
45
+ code: req_res_objects[:response].code,
46
+ operation: current_operation,
47
+ client_request: req_res_objects[:request],
48
+ server_response: req_res_objects[:response],
49
+
50
+ data: parsed_response['data']
51
+ }
52
+ )
53
+ end
54
+
55
+
56
+ def path
57
+ '/' + [
58
+ 'v3',
59
+ 'pam',
60
+ @subscribe_key,
61
+ 'grant',
62
+ @token
63
+ ].join('/')
64
+ end
65
+ end
66
+ end
@@ -11,6 +11,7 @@ module Pubnub
11
11
  validate_origin parameters[:origin], true
12
12
  validate_subscribe_key parameters[:subscribe_key], true
13
13
  validate_publish_key parameters[:publish_key]
14
+ validate_uuid parameters[:uuid]
14
15
  end
15
16
  end
16
17
  end
@@ -52,6 +52,23 @@ module Pubnub
52
52
  )
53
53
  end
54
54
  end
55
+
56
+ # Validates given uuid
57
+ def validate_uuid(uuid)
58
+ if !uuid || uuid.blank?
59
+ raise(
60
+ InitializationError.new,
61
+ 'Missing required :uuid parameter.'
62
+ )
63
+ elsif !([String, Symbol].include?(uuid.class) ||
64
+ uuid.blank?)
65
+ raise(
66
+ InitializationError.new,
67
+ 'UUID parameter is not valid. \
68
+ Should be type of String or Symbol.'
69
+ )
70
+ end
71
+ end
55
72
  end
56
73
  end
57
74
  end
@@ -0,0 +1,51 @@
1
+ # Toplevel Pubnub module.
2
+ module Pubnub
3
+ # Validator module that holds all validators modules
4
+ module Validator
5
+ # Validator for Grant event
6
+ module GrantToken
7
+ include CommonValidator
8
+
9
+ def validate!
10
+ validate_keys!
11
+ validate_ttl!
12
+ validate_permissions!(@uuids, ":uuids")
13
+ validate_permissions!(@channels, ":channels")
14
+ validate_permissions!(@channel_groups, ":uuids")
15
+ end
16
+
17
+ private
18
+
19
+ def validate_keys!
20
+ raise(
21
+ ArgumentError.new(object: self, message: ':subscribe_key is required for grant token event.'),
22
+ ':subscribe_key is required for grant token event.'
23
+ ) if @subscribe_key.nil? || @subscribe_key.empty?
24
+
25
+ raise(
26
+ ArgumentError.new(object: self, message: ':secret_key is required for grant token event.'),
27
+ ':publish_key is required for grant token event.'
28
+ ) if @secret_key.nil? || @secret_key.empty?
29
+ end
30
+
31
+ def validate_ttl!
32
+ return unless !@ttl.nil? && !@ttl.is_a?(Integer)
33
+
34
+ raise(
35
+ ArgumentError.new(object: self, message: ':ttl has to be kind of Integer for grant token event.'),
36
+ ':ttl has to be kind of Integer for grant token event.'
37
+ )
38
+ end
39
+
40
+ def validate_permissions!(arg, name)
41
+ return if arg.nil?
42
+
43
+ raise(
44
+ ArgumentError.new(object: self, message: ":#{name} has to be kind of Hash for grant token event."),
45
+ ":#{name} has to be kind of Hash for grant token event."
46
+ ) unless arg.is_a?(Hash)
47
+ end
48
+ end
49
+ end
50
+ end
51
+