pusher 1.3.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/client_spec.rb CHANGED
@@ -1,7 +1,12 @@
1
- require 'spec_helper'
1
+ require 'base64'
2
2
 
3
+ require 'rbnacl'
3
4
  require 'em-http'
4
5
 
6
+ require 'spec_helper'
7
+
8
+ encryption_master_key = RbNaCl::Random.random_bytes(32)
9
+
5
10
  describe Pusher do
6
11
  # The behaviour should be the same when using the Client object, or the
7
12
  # 'global' client delegated through the Pusher class
@@ -12,11 +17,11 @@ describe Pusher do
12
17
 
13
18
  describe 'default configuration' do
14
19
  it 'should be preconfigured for api host' do
15
- expect(@client.host).to eq('api.pusherapp.com')
20
+ expect(@client.host).to eq('api-mt1.pusher.com')
16
21
  end
17
22
 
18
- it 'should be preconfigured for port 80' do
19
- expect(@client.port).to eq(80)
23
+ it 'should be preconfigured for port 443' do
24
+ expect(@client.port).to eq(443)
20
25
  end
21
26
 
22
27
  it 'should use standard logger if no other logger if defined' do
@@ -74,6 +79,16 @@ describe Pusher do
74
79
  expect(@client.host).to eq('api-eu.pusher.com')
75
80
  end
76
81
 
82
+ it 'should handle nil gracefully' do
83
+ @client.cluster = nil
84
+ expect(@client.host).to eq('api-mt1.pusher.com')
85
+ end
86
+
87
+ it 'should handle empty string' do
88
+ @client.cluster = ""
89
+ expect(@client.host).to eq('api-mt1.pusher.com')
90
+ end
91
+
77
92
  it 'should be overridden by host if it comes after' do
78
93
  @client.cluster = 'eu'
79
94
  @client.host = 'api.staging.pusher.com'
@@ -101,26 +116,26 @@ describe Pusher do
101
116
  end
102
117
 
103
118
  describe 'configuring TLS' do
104
- it 'should set port and scheme if "use_tls" enabled' do
119
+ it 'should set port and scheme if "use_tls" disabled' do
105
120
  client = Pusher::Client.new({
106
- :use_tls => true,
121
+ :use_tls => false,
107
122
  })
108
- expect(client.scheme).to eq('https')
109
- expect(client.port).to eq(443)
123
+ expect(client.scheme).to eq('http')
124
+ expect(client.port).to eq(80)
110
125
  end
111
126
 
112
- it 'should set port and scheme if "encrypted" enabled' do
127
+ it 'should set port and scheme if "encrypted" disabled' do
113
128
  client = Pusher::Client.new({
114
- :encrypted => true,
129
+ :encrypted => false,
115
130
  })
116
- expect(client.scheme).to eq('https')
117
- expect(client.port).to eq(443)
131
+ expect(client.scheme).to eq('http')
132
+ expect(client.port).to eq(80)
118
133
  end
119
134
 
120
- it 'should use non-TLS port and scheme if "encrypted" or "use_tls" are not set' do
135
+ it 'should use TLS port and scheme if "encrypted" or "use_tls" are not set' do
121
136
  client = Pusher::Client.new
122
- expect(client.scheme).to eq('http')
123
- expect(client.port).to eq(80)
137
+ expect(client.scheme).to eq('https')
138
+ expect(client.port).to eq(443)
124
139
  end
125
140
 
126
141
  it 'should override port if "use_tls" option set but a different port is specified' do
@@ -132,6 +147,15 @@ describe Pusher do
132
147
  expect(client.port).to eq(8443)
133
148
  end
134
149
 
150
+ it 'should override port if "use_tls" option set but a different port is specified' do
151
+ client = Pusher::Client.new({
152
+ :use_tls => false,
153
+ :port => 8000
154
+ })
155
+ expect(client.scheme).to eq('http')
156
+ expect(client.port).to eq(8000)
157
+ end
158
+
135
159
  end
136
160
 
137
161
  describe 'configuring a http proxy' do
@@ -171,11 +195,22 @@ describe Pusher do
171
195
  end
172
196
  end
173
197
 
198
+ describe 'can set encryption_master_key_base64' do
199
+ it "sets encryption_master_key" do
200
+ @client.encryption_master_key_base64 =
201
+ Base64.strict_encode64(encryption_master_key)
202
+
203
+ expect(@client.encryption_master_key).to eq(encryption_master_key)
204
+ end
205
+ end
206
+
174
207
  describe 'when configured' do
175
208
  before :each do
176
209
  @client.app_id = '20'
177
210
  @client.key = '12345678900000001'
178
211
  @client.secret = '12345678900000001'
212
+ @client.encryption_master_key_base64 =
213
+ Base64.strict_encode64(encryption_master_key)
179
214
  end
180
215
 
181
216
  describe '#[]' do
@@ -260,6 +295,19 @@ describe Pusher do
260
295
  })
261
296
  end
262
297
 
298
+ it 'should include a shared_secret if the private-encrypted channel' do
299
+ allow(MultiJson).to receive(:encode).with(@custom_data).and_return 'a json string'
300
+ @client.instance_variable_set(:@encryption_master_key, '3W1pfB/Etr+ZIlfMWwZP3gz8jEeCt4s2pe6Vpr+2c3M=')
301
+
302
+ response = @client.authenticate('private-encrypted-test_channel', '1.1', @custom_data)
303
+
304
+ expect(response).to eq({
305
+ :auth => "12345678900000001:#{hmac(@client.secret, "1.1:private-encrypted-test_channel:a json string")}",
306
+ :shared_secret => "o0L3QnIovCeRC8KTD8KBRlmi31dGzHVS2M93uryqDdw=",
307
+ :channel_data => 'a json string'
308
+ })
309
+ end
310
+
263
311
  end
264
312
 
265
313
  describe '#trigger' do
@@ -321,6 +369,46 @@ describe Pusher do
321
369
  }
322
370
  end
323
371
  end
372
+
373
+ it "should fail to publish to encrypted channels when missing key" do
374
+ @client.encryption_master_key_base64 = nil
375
+ expect {
376
+ @client.trigger('private-encrypted-channel', 'event', {'some' => 'data'})
377
+ }.to raise_error(Pusher::ConfigurationError)
378
+ expect(WebMock).not_to have_requested(:post, @api_path)
379
+ end
380
+
381
+ it "should fail to publish to multiple channels if one is encrypted" do
382
+ expect {
383
+ @client.trigger(
384
+ ['private-encrypted-channel', 'some-other-channel'],
385
+ 'event',
386
+ {'some' => 'data'},
387
+ )
388
+ }.to raise_error(Pusher::Error)
389
+ expect(WebMock).not_to have_requested(:post, @api_path)
390
+ end
391
+
392
+ it "should encrypt publishes to encrypted channels" do
393
+ @client.trigger(
394
+ 'private-encrypted-channel',
395
+ 'event',
396
+ {'some' => 'data'},
397
+ )
398
+
399
+ expect(WebMock).to have_requested(:post, @api_path).with { |req|
400
+ data = MultiJson.decode(MultiJson.decode(req.body)["data"])
401
+
402
+ key = RbNaCl::Hash.sha256(
403
+ 'private-encrypted-channel' + encryption_master_key
404
+ )
405
+
406
+ expect(MultiJson.decode(RbNaCl::SecretBox.new(key).decrypt(
407
+ Base64.strict_decode64(data["nonce"]),
408
+ Base64.strict_decode64(data["ciphertext"]),
409
+ ))).to eq({ 'some' => 'data' })
410
+ }
411
+ end
324
412
  end
325
413
 
326
414
  describe '#trigger_batch' do
@@ -352,6 +440,55 @@ describe Pusher do
352
440
  )
353
441
  }
354
442
  end
443
+
444
+ it "should fail to publish to encrypted channels when missing key" do
445
+ @client.encryption_master_key_base64 = nil
446
+ expect {
447
+ @client.trigger_batch(
448
+ {
449
+ channel: 'private-encrypted-channel',
450
+ name: 'event',
451
+ data: {'some' => 'data'},
452
+ },
453
+ {channel: 'mychannel', name: 'event', data: 'already encoded'},
454
+ )
455
+ }.to raise_error(Pusher::ConfigurationError)
456
+ expect(WebMock).not_to have_requested(:post, @api_path)
457
+ end
458
+
459
+ it "should encrypt publishes to encrypted channels" do
460
+ @client.trigger_batch(
461
+ {
462
+ channel: 'private-encrypted-channel',
463
+ name: 'event',
464
+ data: {'some' => 'data'},
465
+ },
466
+ {channel: 'mychannel', name: 'event', data: 'already encoded'},
467
+ )
468
+
469
+ expect(WebMock).to have_requested(:post, @api_path).with { |req|
470
+ batch = MultiJson.decode(req.body)["batch"]
471
+ expect(batch.length).to eq(2)
472
+
473
+ expect(batch[0]["channel"]).to eq("private-encrypted-channel")
474
+ expect(batch[0]["name"]).to eq("event")
475
+
476
+ data = MultiJson.decode(batch[0]["data"])
477
+
478
+ key = RbNaCl::Hash.sha256(
479
+ 'private-encrypted-channel' + encryption_master_key
480
+ )
481
+
482
+ expect(MultiJson.decode(RbNaCl::SecretBox.new(key).decrypt(
483
+ Base64.strict_decode64(data["nonce"]),
484
+ Base64.strict_decode64(data["ciphertext"]),
485
+ ))).to eq({ 'some' => 'data' })
486
+
487
+ expect(batch[1]["channel"]).to eq("mychannel")
488
+ expect(batch[1]["name"]).to eq("event")
489
+ expect(batch[1]["data"]).to eq("already encoded")
490
+ }
491
+ end
355
492
  end
356
493
 
357
494
  describe '#trigger_async' do
@@ -400,22 +537,22 @@ describe Pusher do
400
537
  [:get, :post].each do |verb|
401
538
  describe "##{verb}" do
402
539
  before :each do
403
- @url_regexp = %r{api.pusherapp.com}
540
+ @url_regexp = %r{api-mt1.pusher.com}
404
541
  stub_request(verb, @url_regexp).
405
542
  to_return(:status => 200, :body => "{}")
406
543
  end
407
544
 
408
545
  let(:call_api) { @client.send(verb, '/path') }
409
546
 
410
- it "should use http by default" do
547
+ it "should use https by default" do
411
548
  call_api
412
- expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
549
+ expect(WebMock).to have_requested(verb, %r{https://api-mt1.pusher.com/apps/20/path})
413
550
  end
414
551
 
415
552
  it "should use https if configured" do
416
- @client.encrypted = true
553
+ @client.encrypted = false
417
554
  call_api
418
- expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
555
+ expect(WebMock).to have_requested(verb, %r{http://api-mt1.pusher.com})
419
556
  end
420
557
 
421
558
  it "should format the respose hash with symbols at first level" do
@@ -480,7 +617,7 @@ describe Pusher do
480
617
  [[:get, :get_async], [:post, :post_async]].each do |verb, method|
481
618
  describe "##{method}" do
482
619
  before :each do
483
- @url_regexp = %r{api.pusherapp.com}
620
+ @url_regexp = %r{api-mt1.pusher.com}
484
621
  stub_request(verb, @url_regexp).
485
622
  to_return(:status => 200, :body => "{}")
486
623
  end
@@ -494,15 +631,15 @@ describe Pusher do
494
631
  }
495
632
  }
496
633
 
497
- it "should use http by default" do
634
+ it "should use https by default" do
498
635
  call_api
499
- expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
636
+ expect(WebMock).to have_requested(verb, %r{https://api-mt1.pusher.com/apps/20/path})
500
637
  end
501
638
 
502
- it "should use https if configured" do
503
- @client.encrypted = true
639
+ it "should use http if configured" do
640
+ @client.encrypted = false
504
641
  call_api
505
- expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
642
+ expect(WebMock).to have_requested(verb, %r{http://api-mt1.pusher.com})
506
643
  end
507
644
 
508
645
  # Note that the raw httpclient connection object is returned and
@@ -522,27 +659,27 @@ describe Pusher do
522
659
  [[:get, :get_async], [:post, :post_async]].each do |verb, method|
523
660
  describe "##{method}" do
524
661
  before :each do
525
- @url_regexp = %r{api.pusherapp.com}
662
+ @url_regexp = %r{api-mt1.pusher.com}
526
663
  stub_request(verb, @url_regexp).
527
664
  to_return(:status => 200, :body => "{}")
528
665
  end
529
666
 
530
667
  let(:call_api) { @client.send(method, '/path') }
531
668
 
532
- it "should use http by default" do
669
+ it "should use https by default" do
533
670
  EM.run {
534
671
  call_api.callback {
535
- expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
672
+ expect(WebMock).to have_requested(verb, %r{https://api-mt1.pusher.com/apps/20/path})
536
673
  EM.stop
537
674
  }
538
675
  }
539
676
  end
540
677
 
541
- it "should use https if configured" do
678
+ it "should use http if configured" do
542
679
  EM.run {
543
- @client.encrypted = true
680
+ @client.encrypted = false
544
681
  call_api.callback {
545
- expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
682
+ expect(WebMock).to have_requested(verb, %r{http://api-mt1.pusher.com})
546
683
  EM.stop
547
684
  }
548
685
  }
@@ -579,70 +716,6 @@ describe Pusher do
579
716
  end
580
717
  end
581
718
  end
582
-
583
- describe "native notifications" do
584
- before :each do
585
- @client.app_id = "20"
586
- @client.key = "testytest"
587
- @client.secret = "mysupersecretkey"
588
- end
589
-
590
- it "should configure a native notification client using the pusher client object" do
591
- expect(@client.notification_client).to_not be(nil)
592
- end
593
-
594
- it "should use the default host if not provided" do
595
- expect(@client.notification_host).to eq("nativepush-cluster1.pusher.com")
596
- end
597
-
598
- it "should use a newly provided host" do
599
- @client.notification_host = "test.com"
600
- expect(@client.notification_host).to eq("test.com")
601
- end
602
-
603
- it "should set the native notification client host to the same one" do
604
- expect(@client.notification_host).to eq(@client.notification_client.host)
605
- end
606
-
607
- it "should raise an error if no interest is provided" do
608
- payload = {
609
- gcm: {
610
- notification: {
611
- title: "Hello",
612
- icon: "icon",
613
- }
614
- }
615
- }
616
-
617
- expect { @client.notify([], payload) }.to raise_error(Pusher::Error)
618
- end
619
-
620
- it "should send a request to the notifications endpoint" do
621
- notification_host_regexp = %r{nativepush-cluster1.pusher.com}
622
- payload = {
623
- interests: ["test"],
624
- gcm: {
625
- notification: {
626
- title: "Hello",
627
- icon: "icon",
628
- }
629
- }
630
- }
631
-
632
- stub_request(
633
- :post,
634
- notification_host_regexp,
635
- ).with(
636
- body: MultiJson.encode(payload)
637
- ).to_return({
638
- :status => 200,
639
- :body => MultiJson.encode({ :foo => "bar" })
640
- })
641
-
642
- res = @client.notify(["test"], payload)
643
- expect(res).to eq({foo: "bar"})
644
- end
645
- end
646
719
  end
647
720
 
648
721
  describe 'configuring cluster' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pusher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pusher
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-02 00:00:00.000000000 Z
11
+ date: 2021-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1.15'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '1.15'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pusher-signature
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,112 +44,126 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.7'
47
+ version: '2.8'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.7'
54
+ version: '2.8'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.0'
61
+ version: '3.9'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.0'
68
+ version: '3.9'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: webmock
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '3.9'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '3.9'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: em-http-request
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 1.1.0
89
+ version: '1.1'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 1.1.0
96
+ version: '1.1'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: addressable
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '='
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 2.4.0
103
+ version: '2.7'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '='
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 2.4.0
110
+ version: '2.7'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rake
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 10.4.2
117
+ version: '13.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 10.4.2
124
+ version: '13.0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rack
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 1.6.4
131
+ version: '2.2'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 1.6.4
138
+ version: '2.2'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: json
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 1.8.3
145
+ version: '2.3'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '2.3'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rbnacl
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '7.1'
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: 1.8.3
166
+ version: '7.1'
153
167
  description: 'Wrapper for Pusher Channels REST api: : https://pusher.com/channels'
154
168
  email:
155
169
  - support@pusher.com
@@ -157,24 +171,28 @@ executables: []
157
171
  extensions: []
158
172
  extra_rdoc_files: []
159
173
  files:
160
- - ".document"
161
- - ".gemtest"
174
+ - ".github/stale.yml"
175
+ - ".github/workflows/gh-release.yml"
176
+ - ".github/workflows/publish.yml"
177
+ - ".github/workflows/release.yml"
178
+ - ".github/workflows/test.yml"
162
179
  - ".gitignore"
163
- - ".travis.yml"
164
180
  - CHANGELOG.md
165
181
  - Gemfile
166
182
  - LICENSE
167
183
  - README.md
168
184
  - Rakefile
169
185
  - examples/async_message.rb
186
+ - examples/presence_channels/presence_channels.rb
187
+ - examples/presence_channels/public/presence_channels.html
170
188
  - lib/pusher.rb
171
189
  - lib/pusher/channel.rb
172
190
  - lib/pusher/client.rb
173
- - lib/pusher/native_notification/client.rb
174
191
  - lib/pusher/request.rb
175
192
  - lib/pusher/resource.rb
176
193
  - lib/pusher/version.rb
177
194
  - lib/pusher/webhook.rb
195
+ - pull_request_template.md
178
196
  - pusher.gemspec
179
197
  - spec/channel_spec.rb
180
198
  - spec/client_spec.rb
@@ -184,7 +202,7 @@ homepage: http://github.com/pusher/pusher-http-ruby
184
202
  licenses:
185
203
  - MIT
186
204
  metadata: {}
187
- post_install_message:
205
+ post_install_message:
188
206
  rdoc_options: []
189
207
  require_paths:
190
208
  - lib
@@ -192,20 +210,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
210
  requirements:
193
211
  - - ">="
194
212
  - !ruby/object:Gem::Version
195
- version: '0'
213
+ version: '2.6'
196
214
  required_rubygems_version: !ruby/object:Gem::Requirement
197
215
  requirements:
198
216
  - - ">="
199
217
  - !ruby/object:Gem::Version
200
218
  version: '0'
201
219
  requirements: []
202
- rubyforge_project:
203
- rubygems_version: 2.5.2.2
204
- signing_key:
220
+ rubygems_version: 3.1.2
221
+ signing_key:
205
222
  specification_version: 4
206
223
  summary: Pusher Channels API client
207
- test_files:
208
- - spec/channel_spec.rb
209
- - spec/client_spec.rb
210
- - spec/spec_helper.rb
211
- - spec/web_hook_spec.rb
224
+ test_files: []