pubnub-ruby 0.0.9 → 3.3.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-