faye-authentication 0.3.0 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c557cbf72df6369ab2dcc5ad4ca635cc06220ad
4
- data.tar.gz: ce322da963e471760990647799e6ac430a56bd4e
3
+ metadata.gz: 9a617e82b1d7184dc0ce7016b8736c6e412500f3
4
+ data.tar.gz: 640960f50c1a742c704bd4ded7930817caf22ee4
5
5
  SHA512:
6
- metadata.gz: 15b99a92f41c1ff17cafd508ff2ebd55710ea52b20b828f00adcce50cefe9822e302d0fb41e7e40bb005bb7ba122ccdad9c640434701a0f988eb9b809e33a1c1
7
- data.tar.gz: e470c75679e72fa27515ace5f16bf844e36fba64f4d7ed89ee5466d2a7e6c88f083c58d9c478aa16cd1a836f09e7da8b7aa6ba273b0d1d749501363f3d8e6274
6
+ metadata.gz: c130a9cef8388dcc2666842339aea83206c3500e155c45b67ab5751ba29a339a8786e95c54cf754aeb8362d78cca94d120f8d2a3151bece77ee44c47e4121609
7
+ data.tar.gz: 09ef066a4f2cbaddb41ac92175a0dbe58e9c3d6e8e78cb21c775bf9300a0f8026eea4cf0d89dc0b5a5a09bbaba1aa7f0c7b1d91549ad5db5a3209d8f220dff25
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
+ ## 0.4.0
2
+ - Channels beginning by ``/public/`` do not require authentication anymore,
3
+ However, globbing with public channels still require authentication.
4
+
1
5
  ## 0.3.0
2
- - Rename ``Faye::Authentication::Extension`` to ``Faye::Authentication::ServerExtension``
3
- - Add extension for faye Ruby Client : ``Faye::Authentication::ClientExtension``
6
+ - Rename ``Faye::Authentication::Extension`` to ``Faye::Authentication::ServerExtension``
7
+ - Add extension for faye Ruby Client : ``Faye::Authentication::ClientExtension``
4
8
 
5
9
  ## 0.2.0
6
10
 
data/README.md CHANGED
@@ -38,6 +38,18 @@ Or install it yourself as:
38
38
 
39
39
  ## Usage
40
40
 
41
+ ### Channels requiring authentication
42
+
43
+ All channels require authentication, except channels beginning by ``/public/``
44
+
45
+ However, globbing, even on ``/public/`` channels will require authentication.
46
+
47
+ Example :
48
+
49
+ - ``/public/foo`` does not require authentication
50
+ - ``/public/bar/*`` requires authentication
51
+
52
+
41
53
  ### Authentication endpoint requirements
42
54
 
43
55
  The endpoint will receive a POST request, and shall return a JSON hash with a ``signature`` key.
@@ -42,16 +42,25 @@ FayeAuthentication.prototype.signMessage = function(message, callback) {
42
42
  }
43
43
 
44
44
  FayeAuthentication.prototype.outgoing = function(message, callback) {
45
- if (message.channel == '/meta/subscribe') {
45
+ if (this.authentication_required(message))
46
46
  this.signMessage(message, callback);
47
- }
48
- else if (!/^\/meta\/(.*)/.test(message.channel)) { // Publish
49
- this.signMessage(message, callback);
50
- }
51
47
  else
52
48
  callback(message);
53
49
  };
54
50
 
51
+ FayeAuthentication.prototype.authentication_required = function(message) {
52
+ var subscription_or_channel = message.subscription || message.channel
53
+ return (!this.public_channel(subscription_or_channel) && (message.channel == '/meta/subscribe' || message.channel.lastIndexOf('/meta/', 0) !== 0))
54
+ };
55
+
56
+ FayeAuthentication.prototype.public_channel = function(channel) {
57
+ if (channel.lastIndexOf('/public/', 0) === 0) {
58
+ return (channel.indexOf('*') == -1);
59
+ } else {
60
+ return (false);
61
+ }
62
+ };
63
+
55
64
  FayeAuthentication.prototype.incoming = function(message, callback) {
56
65
  var outbox_message = this._outbox[message.id];
57
66
  if (outbox_message && message.error) {
@@ -8,7 +8,7 @@ module Faye
8
8
  end
9
9
 
10
10
  def outgoing(message, callback)
11
- if message['channel'] == '/meta/subscribe' || !(message['channel'] =~ /^\/meta\/.*/)
11
+ if Faye::Authentication.authentication_required?(message)
12
12
  message['signature'] = Faye::Authentication.sign({channel: message['subscription'] || message['channel'], clientId: message['clientId']}, @secret, @options)
13
13
  end
14
14
  callback.call(message)
@@ -10,7 +10,7 @@ module Faye
10
10
  end
11
11
 
12
12
  def incoming(message, callback)
13
- if message['channel'] == '/meta/subscribe' || !(message['channel'] =~ /^\/meta\/.*/)
13
+ if Faye::Authentication.authentication_required?(message)
14
14
  begin
15
15
  Faye::Authentication.validate(message['signature'],
16
16
  message['subscription'] || message['channel'],
@@ -1,5 +1,5 @@
1
1
  module Faye
2
2
  module Authentication
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
@@ -31,5 +31,15 @@ module Faye
31
31
  raise PayloadError unless channel == payload['channel'] && clientId == payload['clientId']
32
32
  true
33
33
  end
34
+
35
+ def self.authentication_required?(message)
36
+ subscription_or_channel = message['subscription'] || message['channel']
37
+ !public_channel?(subscription_or_channel) && (message['channel'] == '/meta/subscribe' || (!(message['channel'].start_with?('/meta/'))))
38
+ end
39
+
40
+ def self.public_channel?(channel)
41
+ channel.start_with?('/public/') and not channel.include?('*')
42
+ end
43
+
34
44
  end
35
45
  end
@@ -17,8 +17,8 @@ describe('faye-authentication', function() {
17
17
  describe('extension', function() {
18
18
  beforeEach(function() {
19
19
  jasmine.Ajax.install();
20
- this.auth = new FayeAuthentication();
21
20
  this.client = new Faye.Client('http://localhost:9296/faye');
21
+ this.auth = new FayeAuthentication(this.client);
22
22
  this.client.addExtension(this.auth);
23
23
  });
24
24
 
@@ -118,35 +118,25 @@ describe('faye-authentication', function() {
118
118
  }, 500);
119
119
  });
120
120
 
121
- it('should make only one ajax call when dealing with one channel', function(done) {
122
- this.client.subscribe('/foobar');
123
- this.client.publish('/foobar', {text: 'hallo'});
124
- this.client.publish('/foobar', {text: 'hallo'});
125
121
 
126
- setTimeout(function() {
127
- expect(jasmine.Ajax.requests.count()).toBe(2); // Handshake + auth
128
- done();
129
- }, 500);
130
-
131
- })
132
-
133
- it('should make two ajax calls when dealing with two channels', function(done) {
134
- this.client.subscribe('/foo');
135
- this.client.publish('/foo', {text: 'hallo'});
136
- this.client.publish('/foo', {text: 'hallo'});
122
+ it('does not add the signature to a public message', function(done) {
123
+ var self = this;
137
124
 
138
- this.client.subscribe('/bar');
139
- this.client.publish('/bar', {text: 'hallo'});
140
- this.client.publish('/bar', {text: 'hallo'});
125
+ this.client.handshake(function() {
126
+ self.client._transport = self.fake_transport
127
+ self.client.publish('/public/foo', {text: 'hallo'});
128
+ }, this.client);
141
129
 
142
130
  setTimeout(function() {
143
- expect(jasmine.Ajax.requests.count()).toBe(3); // Handshake + auth * 2
131
+ var calls = self.fake_transport.send.calls.all();
132
+ var last_call = calls[calls.length - 1];
133
+ var message = last_call.args[0].message;
134
+ expect(message.channel).toBe('/public/foo');
135
+ expect(message.signature).toBe(undefined);
144
136
  done();
145
137
  }, 500);
146
138
  });
147
- });
148
139
 
140
+ });
149
141
  });
150
-
151
-
152
- })
142
+ });
@@ -59,6 +59,33 @@ describe('Faye extension', function() {
59
59
  });
60
60
  });
61
61
 
62
+ it('should make only one ajax call when dealing with one channel', function(done) {
63
+ this.client.subscribe('/foobar');
64
+ this.client.publish('/foobar', {text: 'hallo'});
65
+ this.client.publish('/foobar', {text: 'hallo'});
66
+
67
+ setTimeout(function() {
68
+ expect(jasmine.Ajax.requests.count()).toBe(2); // Handshake + auth * 1
69
+ done();
70
+ }, 500);
71
+
72
+ })
73
+
74
+ it('should make two ajax calls when dealing with two channels', function(done) {
75
+ this.client.subscribe('/foobar');
76
+ this.client.publish('/foobar', {text: 'hallo'});
77
+ this.client.publish('/foobar', {text: 'hallo'});
78
+
79
+ this.client.subscribe('/bar');
80
+ this.client.publish('/bar', {text: 'hallo'});
81
+ this.client.publish('/bar', {text: 'hallo'});
82
+
83
+ setTimeout(function() {
84
+ expect(jasmine.Ajax.requests.count()).toBe(3); // Handshake + auth * 2
85
+ done();
86
+ }, 500);
87
+ });
88
+
62
89
  it('tries to get a new signature immediately when the used signature is bad or expired', function(done) {
63
90
  jasmine.Ajax.stubRequest('/faye/auth').andReturn({
64
91
  'responseText': '{"signature": "bad"}'
@@ -6,32 +6,65 @@ describe Faye::Authentication::ServerExtension do
6
6
  let(:secret) { 'macaroni' }
7
7
  let(:extension) { Faye::Authentication::ServerExtension.new(secret) }
8
8
 
9
- it 'does not add an eror if the message is correctly signed' do
10
- message = {'channel' => '/foo/bar', 'clientId' => '42', 'text' => 'whatever'}
11
- signature = Faye::Authentication.sign(message, secret)
12
- message['signature'] = signature
9
+ describe '#incoming' do
10
+ shared_examples 'signature_has_error' do
11
+ it 'adds an error' do
12
+ subject
13
+ expect(@result).to have_key('error')
14
+ end
15
+ end
13
16
 
14
- result = nil
17
+ shared_examples 'signature_has_no_error' do
18
+ it 'adds no error' do
19
+ subject
20
+ expect(@result).to_not have_key('error')
21
+ end
22
+ end
15
23
 
16
- extension.incoming(message, ->(m) { result = m });
24
+ shared_examples 'authentication_actions' do
25
+ context 'not signed' do
26
+ context '/public' do
27
+ context 'no globbing' do
28
+ let(:channel) { '/public/foo' }
29
+ it_should_behave_like 'signature_has_no_error'
30
+ end
17
31
 
18
- expect(result).to_not have_key('error')
19
- end
32
+ context 'globbing' do
33
+ let(:channel) { '/public/foo/*'}
34
+ it_should_behave_like 'signature_has_error'
35
+ end
36
+ end
20
37
 
21
- it 'adds an eror if the message is not signed' do
22
- message = {'channel' => '/foo/bar', 'clientId' => '42', 'text' => 'whatever'}
23
- result = nil
24
- extension.incoming(message, ->(m) { result = m });
38
+ context 'not public' do
39
+ context 'not signed' do
40
+ let(:channel) { '/whatever' }
41
+ it_should_behave_like 'signature_has_error'
42
+ end
25
43
 
26
- expect(result).to have_key('error')
27
- end
44
+ context 'signed' do
45
+ let(:channel) { '/foo/bar' }
46
+ before { message['signature'] = Faye::Authentication.sign(message.merge({'channel' => channel}), secret) }
47
+ it_should_behave_like 'signature_has_no_error'
48
+ end
49
+
50
+ end
51
+ end
52
+ end
28
53
 
29
- it 'adds an error if the signature is incorrect' do
30
- message = {'channel' => '/foo/bar', 'clientId' => '42', 'text' => 'whatever', 'signature' => 'hello'}
31
- result = nil
32
- extension.incoming(message, ->(m) { result = m });
54
+ let(:message) { {'channel' => channel, 'clientId' => '42', 'text' => 'whatever'} }
55
+ subject do
56
+ extension.incoming(message, ->(m) { @result = m });
57
+ end
33
58
 
34
- expect(result).to have_key('error')
59
+ context 'publish' do
60
+ it_should_behave_like 'authentication_actions'
61
+ end
62
+
63
+ context 'subscribe' do
64
+ before { message['channel'] = '/meta/subscribe'}
65
+ before { message['subscription'] = channel}
66
+ it_should_behave_like 'authentication_actions'
67
+ end
35
68
  end
36
69
 
37
70
  ['/meta/handshake', '/meta/connect', '/meta/unsubscribe', '/meta/disconnect'].each do |channel|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faye-authentication
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrien Siami
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-17 00:00:00.000000000 Z
11
+ date: 2014-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt