pubnub-ruby 0.0.9 → 3.3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,53 @@
1
+ class PubnubCrypto
2
+ require 'yajl'
3
+
4
+ def initialize(cipher_key)
5
+ @alg = "AES-256-CBC"
6
+ sha256_key = Digest::SHA256.hexdigest(cipher_key)
7
+ @key = sha256_key.slice(0,32)
8
+
9
+ #puts("\nraw sha cipher_key is: #{cipher_key}")
10
+ #puts("raw sha cipher_key is: #{sha256_key}")
11
+ #puts("padded cipher_key is: #{@key}\n")
12
+
13
+ @iv = '0123456789012345'
14
+ end
15
+
16
+
17
+ def encrypt(message)
18
+
19
+ aes = OpenSSL::Cipher::Cipher.new(@alg)
20
+ aes.encrypt
21
+ aes.key = @key
22
+ aes.iv = @iv
23
+
24
+ json_message = Yajl.dump(message)
25
+ cipher = aes.update(json_message)
26
+ cipher << aes.final
27
+
28
+ Base64.strict_encode64(cipher)
29
+
30
+ end
31
+
32
+
33
+ def decrypt(cipher_text)
34
+ decode_cipher = OpenSSL::Cipher::Cipher.new(@alg)
35
+ decode_cipher.decrypt
36
+ decode_cipher.key = @key
37
+ decode_cipher.iv = @iv
38
+
39
+ plain_text = ""
40
+
41
+ begin
42
+ undecoded_text = Base64.decode64(cipher_text)
43
+ plain_text = decode_cipher.update(undecoded_text)
44
+ plain_text << decode_cipher.final
45
+ rescue => e
46
+
47
+ return "DECRYPTION_ERROR"
48
+
49
+ end
50
+
51
+ return Yajl.load(plain_text)
52
+ end
53
+ end
@@ -0,0 +1,37 @@
1
+ require 'eventmachine'
2
+
3
+ class PubnubDeferrable < EM::Protocols::HttpClient2
4
+
5
+ include EM::Deferrable
6
+
7
+ attr_accessor :start_time, :end_time, :elapsed_time, :pubnub_request
8
+
9
+ def initialize
10
+ super
11
+ end
12
+
13
+ def post_init
14
+ #puts("deferrable says my query is: #{pubnub_request.query}")
15
+ super
16
+ end
17
+
18
+ def connection_completed
19
+ @start_time = Time.now
20
+ #puts("\n--- #{@start_time}: Connected with string: #{self.pubnub_request.query}")
21
+ super
22
+ end
23
+
24
+ def unbind
25
+ @end_time = Time.now
26
+
27
+ if @start_time == nil
28
+ @start_time = Time.now
29
+ end
30
+
31
+ #puts("-- #{@end_time}: Disconnected.")
32
+ #puts("--- Elapsed connection time: #{@end_time - @start_time}s")
33
+ super
34
+ end
35
+
36
+
37
+ end
@@ -0,0 +1,287 @@
1
+ class PubnubRequest
2
+ attr_accessor :cipher_key, :host, :query, :response, :timetoken, :url, :operation, :callback, :publish_key, :subscribe_key, :secret_key, :channel, :jsonp, :message, :ssl, :port
3
+ attr_accessor :history_limit, :history_count, :history_start, :history_end, :history_reverse, :session_uuid
4
+
5
+ class RequestError < RuntimeError;
6
+ end
7
+
8
+ def initialize(args = {})
9
+ args = HashWithIndifferentAccess.new(args)
10
+
11
+ @operation = args[:operation].to_s
12
+ @callback = args[:callback]
13
+ @cipher_key = args[:cipher_key]
14
+ @session_uuid = args[:session_uuid]
15
+ @publish_key = args[:publish_key]
16
+ @subscribe_key = args[:subscribe_key]
17
+ @channel = args[:channel]
18
+ @jsonp = args[:jsonp].present? ? "1" : "0"
19
+ @message = args[:message]
20
+ @secret_key = args[:secret_key] || "0"
21
+ @timetoken = args[:timetoken] || "0"
22
+ @ssl = args[:ssl]
23
+
24
+ @port = args[:port]
25
+ @url = args[:url]
26
+ @host = args[:host]
27
+ @query = args[:query]
28
+ end
29
+
30
+ def op_exception
31
+ if @operation.present?
32
+ ("Pubnub::" + @operation.to_s.capitalize + "Error").constantize
33
+ else
34
+ PubnubRequest::RequestError
35
+ end
36
+ end
37
+
38
+ def ==(another)
39
+ self.operation == another.operation && self.callback == another.callback &&
40
+ self.channel == another.channel && self.message == another.message
41
+ end
42
+
43
+ def set_channel(options)
44
+ options = HashWithIndifferentAccess.new(options)
45
+
46
+ if options[:channel].blank?
47
+ raise(op_exception, "channel is a required parameter.")
48
+ else
49
+ self.channel = options[:channel].to_s
50
+ self
51
+ end
52
+ end
53
+
54
+ def set_callback(options)
55
+ options = HashWithIndifferentAccess.new(options)
56
+
57
+ if options[:callback].blank?
58
+ raise(op_exception, "callback is a required parameter.")
59
+ elsif !options[:callback].try(:respond_to?, "call")
60
+ raise(op_exception, "callback is invalid.")
61
+ else
62
+ self.callback = options[:callback]
63
+ self
64
+ end
65
+ end
66
+
67
+
68
+ def set_cipher_key(options, self_cipher_key)
69
+ options = HashWithIndifferentAccess.new(options)
70
+
71
+ if self_cipher_key.present? && options['cipher_key'].present?
72
+ raise(op_exception, "existing cipher_key #{self_cipher_key} cannot be overridden at publish-time.")
73
+
74
+ elsif (self_cipher_key.present? && options[:cipher_key].blank?) || (self_cipher_key.blank? && options[:cipher_key].present?)
75
+
76
+ this_cipher_key = self_cipher_key || options[:cipher_key]
77
+ raise(Pubnub::PublishError, "secret key must be a string.") if this_cipher_key.class != String
78
+ self.cipher_key = this_cipher_key
79
+ end
80
+ end
81
+
82
+ def set_secret_key(options, self_secret_key)
83
+ options = HashWithIndifferentAccess.new(options)
84
+
85
+ if self_secret_key.present? && options['secret_key'].present?
86
+ raise(Pubnub::PublishError, "existing secret_key #{self_secret_key} cannot be overridden at publish-time.")
87
+
88
+ elsif (self_secret_key.present? && options[:secret_key].blank?) || (self_secret_key.blank? && options[:secret_key].present?)
89
+
90
+ my_secret_key = self_secret_key || options[:secret_key]
91
+ raise(Pubnub::PublishError, "secret key must be a string.") if my_secret_key.class != String
92
+
93
+ signature = "{ @publish_key, @subscribe_key, @secret_key, channel, message}"
94
+ digest = OpenSSL::Digest.new("sha256")
95
+ key = [my_secret_key]
96
+ hmac = OpenSSL::HMAC.hexdigest(digest, key.pack("H*"), signature)
97
+ self.secret_key = hmac
98
+ else
99
+ self.secret_key = "0"
100
+ end
101
+ end
102
+
103
+ def set_message(options, self_cipher_key)
104
+ options = HashWithIndifferentAccess.new(options)
105
+
106
+ if options[:message].blank? && options[:message] != ""
107
+ raise(op_exception, "message is a required parameter.")
108
+ else
109
+ my_cipher_key = options[:cipher_key] || self_cipher_key
110
+
111
+ if my_cipher_key.present?
112
+ self.message = Yajl.dump(aes_encrypt(my_cipher_key, options, self))
113
+ else
114
+ self.message = Yajl.dump(options[:message])
115
+ end
116
+ end
117
+ end
118
+
119
+ def set_publish_key(options, self_publish_key)
120
+ options = HashWithIndifferentAccess.new(options)
121
+
122
+ if options[:publish_key].blank? && self_publish_key.blank?
123
+ raise(Pubnub::PublishError, "publish_key is a required parameter.")
124
+ elsif self_publish_key.present? && options['publish_key'].present?
125
+ raise(Pubnub::PublishError, "existing publish_key #{self_publish_key} cannot be overridden at publish-time.")
126
+ else
127
+ self.publish_key = (self_publish_key || options[:publish_key]).to_s
128
+ end
129
+ end
130
+
131
+ def set_subscribe_key(options, self_subscribe_key)
132
+ options = HashWithIndifferentAccess.new(options)
133
+
134
+ if options[:subscribe_key].blank? && self_subscribe_key.blank?
135
+ raise(op_exception, "subscribe_key is a required parameter.")
136
+ elsif self_subscribe_key.present? && options['subscribe_key'].present?
137
+ raise(op_exception, "existing subscribe_key #{self_subscribe_key} cannot be overridden at subscribe-time.")
138
+ else
139
+ self.subscribe_key = (self_subscribe_key || options[:subscribe_key]).to_s
140
+ end
141
+ end
142
+
143
+ def package_response!(response_data)
144
+ self.response = response_data.respond_to?(:content) ? Yajl.load(response_data.content) : Yajl.load(response_data)
145
+ self.timetoken = self.response[1] unless self.operation == "time"
146
+
147
+ if self.cipher_key.present? && %w(subscribe history detailed_history).include?(self.operation)
148
+
149
+ myarr = Array.new
150
+ pc = PubnubCrypto.new(@cipher_key)
151
+
152
+ case @operation
153
+ when "publish"
154
+ iterate = self.response.first
155
+ when "subscribe"
156
+ iterate = self.response.first
157
+ when "history"
158
+ iterate = self.response
159
+ when "detailed_history"
160
+ iterate = self.response.first
161
+
162
+ else
163
+ raise(RequestError, "Don't know how to iterate on this operation.")
164
+ end
165
+
166
+ iterate.each do |message|
167
+ message = pc.decrypt(message)
168
+ myarr.push(message)
169
+ end
170
+
171
+ if %w(publish subscribe).include?(@operation)
172
+ self.response[0] = myarr
173
+ elsif @operation == "detailed_history"
174
+ json_response_data = Yajl.load(response_data)
175
+ self.response = [myarr, json_response_data[1], json_response_data[2]]
176
+ else
177
+ self.response = myarr
178
+ end
179
+
180
+ end
181
+ end
182
+
183
+ def format_url!(override_timetoken = nil)
184
+
185
+ raise(Pubnub::PublishError, "Missing .operation in PubnubRequest object") if self.operation.blank?
186
+
187
+ if @ssl.present?
188
+ origin = 'https://' + Pubnub::ORIGIN_HOST
189
+ @port = 443
190
+ else
191
+ origin = 'http://' + Pubnub::ORIGIN_HOST
192
+ @port = 80
193
+ end
194
+
195
+ if override_timetoken.present?
196
+ self.timetoken = override_timetoken.to_s
197
+ end
198
+
199
+ case self.operation.to_s
200
+ when "publish"
201
+ url_array = [self.operation.to_s, self.publish_key.to_s, self.subscribe_key.to_s,
202
+ self.secret_key.to_s, self.channel.to_s, "0", self.message]
203
+
204
+ when "subscribe"
205
+ url_array = [self.operation.to_s, self.subscribe_key.to_s, self.channel.to_s, "0", @timetoken]
206
+
207
+ when "presence"
208
+ url_array = ["subscribe", self.subscribe_key.to_s, ((self.channel.to_s) + "-pnpres"), "0", @timetoken]
209
+
210
+ when "time"
211
+ url_array = [self.operation.to_s, "0"]
212
+
213
+ when "history"
214
+ url_array = [self.operation.to_s, self.subscribe_key.to_s, self.channel.to_s, "0", self.history_limit.to_s]
215
+
216
+ when "detailed_history"
217
+ url_array = ["v2", "history", "sub-key", self.subscribe_key.to_s, "channel", self.channel.to_s]
218
+
219
+ when "here_now"
220
+ url_array = ["v2", "presence", "sub-key", self.subscribe_key.to_s, "channel", self.channel.to_s]
221
+
222
+ else
223
+
224
+ raise(PubnubRequest::RequestError, "I can't create that URL for you due to unknown operation type.")
225
+ end
226
+
227
+ self.url = origin + encode_URL(url_array)
228
+
229
+ uri = URI.parse(self.url)
230
+
231
+ self.host = uri.host
232
+ url_params = ""
233
+
234
+ if %w(subscribe presence).include?(@operation)
235
+ uri.query = uri.query.blank? ? "uuid=#{@session_uuid}" : (uri.query + "uuid=#{@session_uuid}")
236
+
237
+ elsif @operation == "detailed_history"
238
+ url_sep = "?"
239
+
240
+ if @history_count || @history_start || @history_end || @history_reverse
241
+
242
+ if @history_count
243
+ url_params += url_sep + "count=" + @history_count.to_s
244
+ url_sep = "&"
245
+ end
246
+
247
+ if @history_start
248
+ url_params += url_sep + "start=" + @history_start.to_s
249
+ url_sep = "&"
250
+ end
251
+
252
+ if @history_end
253
+ url_params += url_sep + "end=" + @history_end.to_s
254
+ url_sep = "&"
255
+ end
256
+
257
+ if @history_reverse
258
+ url_params += url_sep + "reverse=true"
259
+ url_sep = "&"
260
+ end
261
+ end
262
+ end
263
+
264
+ self.query = uri.path + (uri.query.present? ? ("?" + uri.query) : "") + url_params
265
+ self.url += url_params
266
+ self
267
+
268
+ end
269
+
270
+ def aes_encrypt(cipher_key, options, publish_request)
271
+ options = HashWithIndifferentAccess.new(options)
272
+
273
+ pc = PubnubCrypto.new(cipher_key)
274
+ publish_request.message = pc.encrypt(options[:message])
275
+
276
+ end
277
+
278
+ def encode_URL(request)
279
+ ## Construct Request URL
280
+ url = '/' + request.map { |bit| bit.split('').map { |ch|
281
+ ' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.index(ch) ?
282
+ '%' + ch.unpack('H2')[0].to_s.upcase : URI.encode(ch)
283
+ }.join('') }.join('/')
284
+ return url
285
+ end
286
+
287
+ end
metadata CHANGED
@@ -1,84 +1,113 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: pubnub-ruby
3
- version: !ruby/object:Gem::Version
4
- hash: 13
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.3.0.1
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 9
10
- version: 0.0.9
11
6
  platform: ruby
12
- authors:
13
- - Luke Carpenter
7
+ authors:
8
+ - PubNub
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-05-28 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: json
12
+ date: 2012-09-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
22
23
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: eventmachine
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.12.9
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.12.9
46
+ - !ruby/object:Gem::Dependency
47
+ name: uuid
48
+ requirement: !ruby/object:Gem::Requirement
24
49
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.3.5
32
54
  type: :runtime
33
- version_requirements: *id001
34
- description: Simply Pubnub.rb in gem format, :require => "pubnub" - ask @rubynerd for upgrades
35
- email: orlyowlizere@gmail.com
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: yajl-ruby
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Ruby anywhere in the world in 250ms with PubNub!
79
+ email: support@pubnub.com
36
80
  executables: []
37
-
38
81
  extensions: []
39
-
40
- extra_rdoc_files:
41
- - README
42
- files:
43
- - examples/history-example.rb
44
- - examples/publish-example.rb
45
- - examples/subscribe-example.rb
46
- - lib/pubnub-ruby.rb
82
+ extra_rdoc_files: []
83
+ files:
47
84
  - lib/pubnub.rb
48
- - tests/unit-test.rb
49
- - README
50
- homepage: http://github.com/rubynerd/pubnub
51
- licenses:
85
+ - lib/pubnub_crypto.rb
86
+ - lib/pubnub_deferrable.rb
87
+ - lib/pubnub_request.rb
88
+ homepage: http://github.com/pubnub/pubnub-api
89
+ licenses:
52
90
  - MIT
53
91
  post_install_message:
54
92
  rdoc_options: []
55
-
56
- require_paths:
93
+ require_paths:
57
94
  - lib
58
- required_ruby_version: !ruby/object:Gem::Requirement
95
+ required_ruby_version: !ruby/object:Gem::Requirement
59
96
  none: false
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- hash: 3
64
- segments:
65
- - 0
66
- version: "0"
67
- required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
102
  none: false
69
- requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- hash: 3
73
- segments:
74
- - 0
75
- version: "0"
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
76
107
  requirements: []
77
-
78
108
  rubyforge_project:
79
- rubygems_version: 1.8.5
109
+ rubygems_version: 1.8.24
80
110
  signing_key:
81
111
  specification_version: 3
82
- summary: PubNub unofficial gem
112
+ summary: PubNub Official Ruby gem
83
113
  test_files: []
84
-