faye-authentication 0.2.0 → 0.3.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: 184e59a30a70d8300c56d55355689fc266f4c1d8
4
- data.tar.gz: e27e148c68384f0f1f8d74cec6e7bbd92769dd51
3
+ metadata.gz: 5c557cbf72df6369ab2dcc5ad4ca635cc06220ad
4
+ data.tar.gz: ce322da963e471760990647799e6ac430a56bd4e
5
5
  SHA512:
6
- metadata.gz: 62c1b8a62630230868e2f748219970745e72a868dcafdc3de4112c82f25a25e4ee0f7de829caa7b7e85fdf017040287b13d7ce6b47495a9475f3aa6f772a0c81
7
- data.tar.gz: 8dd4d44413f43949c21512b3932f3f06659ee1ff5193eed99c5ef75cba04218b68dfafcb33042b9af251d1169bf984538d6e29e4b2b4e255e3d4c735e37060f3
6
+ metadata.gz: 15b99a92f41c1ff17cafd508ff2ebd55710ea52b20b828f00adcce50cefe9822e302d0fb41e7e40bb005bb7ba122ccdad9c640434701a0f988eb9b809e33a1c1
7
+ data.tar.gz: e470c75679e72fa27515ace5f16bf844e36fba64f4d7ed89ee5466d2a7e6c88f083c58d9c478aa16cd1a836f09e7da8b7aa6ba273b0d1d749501363f3d8e6274
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
1
  --color
2
- --warnings
3
2
  --require spec_helper
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
+ ## 0.3.0
2
+ - Rename ``Faye::Authentication::Extension`` to ``Faye::Authentication::ServerExtension``
3
+ - Add extension for faye Ruby Client : ``Faye::Authentication::ClientExtension``
4
+
1
5
  ## 0.2.0
2
6
 
3
7
  - Use JWT instead of HMAC for signing the messages
4
8
  - Allow expiration of the signature
5
- - The client javascript extension now takes the faye client as its frst parameter
9
+ - The client javascript extension now takes the faye client as its first parameter
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in faye-authentication.gemspec
4
+ group :development do
5
+ gem 'rspec-eventmachine', '~> 0.1', github: 'jcoglan/rspec-eventmachine'
6
+ end
4
7
  gemspec
data/README.md CHANGED
@@ -18,6 +18,7 @@ is incorrect or not present.
18
18
  Currently Implemented :
19
19
  - Javascript Client Extention (JQuery needed)
20
20
  - Ruby Faye Server Extension
21
+ - Ruby Faye Client Extension
21
22
  - Ruby utils to signing messages in your webapp
22
23
  - **Want another one ? Pull requests are welcome.**
23
24
 
@@ -92,22 +93,31 @@ If you wish to change the endpoint, you can supply it as the second argument of
92
93
 
93
94
  client.addExtension(new FayeAuthentication(client, '/my_custom_auth_endpoint'));
94
95
 
95
- ### Faye server extension
96
+ ### Ruby Faye server extension
96
97
 
97
98
  Instanciate the extension with your secret key and add it to the server :
98
99
 
99
100
  ````ruby
100
101
  server = Faye::RackAdapter.new(:mount => '/faye', :timeout => 15)
101
- server.add_extension Faye::Authentication::Extension.new('your shared secret key')
102
+ server.add_extension Faye::Authentication::ServerExtension.new('your shared secret key')
102
103
  ````
103
104
 
104
- Faye::Authentication::Extension expect that :
105
+ Faye::Authentication::ServerExtension expect that :
105
106
  - a ``signature`` is present in the message for publish/subscribe request
106
107
  - this signature is a valid JWT token
107
108
  - the JWT payload contains "channel", "clientId" and a expiration timestamp "exp" that is not in the past.
108
109
 
109
110
  Otherwise Faye Server will refuse the message.
110
111
 
112
+ ### Ruby Faye client extension
113
+
114
+ This extension allows the ruby ``Faye::Client`` to auto-sign its messages before sending them to the server.
115
+
116
+ ````ruby
117
+ client = Faye::Client.new('http://localhost:9292/faye')
118
+ client.add_extension Faye::Authentication::ClientExtension.new('your shared secret key')
119
+ ````
120
+
111
121
  ## Contributing
112
122
 
113
123
  1. Fork it ( https://github.com/dimelo/faye-authentication/fork )
@@ -1,6 +1,7 @@
1
1
  require 'jwt'
2
2
  require 'faye/authentication/version'
3
- require 'faye/authentication/extension'
3
+ require 'faye/authentication/server_extension'
4
+ require 'faye/authentication/client_extension'
4
5
  require 'faye/authentication/http_client'
5
6
  require 'faye/authentication/engine'
6
7
 
@@ -10,7 +11,7 @@ module Faye
10
11
  class ExpiredError < AuthError; end
11
12
  class PayloadError < AuthError; end
12
13
 
13
- # Return jwt signature, pass hash of payload including channel and client_id
14
+ # Return jwt signature, pass hash of payload including channel and client_id
14
15
  def self.sign(payload, secret, options = {})
15
16
  options = {expires_at: Time.now + 12*3600, algorithm: 'HS256'}.merge(options)
16
17
  JWT.encode(payload.merge(exp: options[:expires_at].to_i), secret, options[:algorithm])
@@ -0,0 +1,19 @@
1
+ module Faye
2
+ module Authentication
3
+ class ClientExtension
4
+
5
+ def initialize(secret, options = {})
6
+ @secret = secret
7
+ @options = options
8
+ end
9
+
10
+ def outgoing(message, callback)
11
+ if message['channel'] == '/meta/subscribe' || !(message['channel'] =~ /^\/meta\/.*/)
12
+ message['signature'] = Faye::Authentication.sign({channel: message['subscription'] || message['channel'], clientId: message['clientId']}, @secret, @options)
13
+ end
14
+ callback.call(message)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -2,7 +2,7 @@ require 'faye'
2
2
 
3
3
  module Faye
4
4
  module Authentication
5
- class Extension
5
+ class ServerExtension
6
6
  include Faye::Logging
7
7
 
8
8
  def initialize(secret)
@@ -12,8 +12,8 @@ module Faye
12
12
  def incoming(message, callback)
13
13
  if message['channel'] == '/meta/subscribe' || !(message['channel'] =~ /^\/meta\/.*/)
14
14
  begin
15
- Faye::Authentication.validate(message['signature'],
16
- message['subscription'] || message['channel'],
15
+ Faye::Authentication.validate(message['signature'],
16
+ message['subscription'] || message['channel'],
17
17
  message['clientId'],
18
18
  @secret)
19
19
  debug("Authentication sucessful")
@@ -1,5 +1,5 @@
1
1
  module Faye
2
2
  module Authentication
3
- VERSION = "0.2.0"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -21,7 +21,7 @@ fork do
21
21
  faye = Faye::RackAdapter.new(:mount => '/faye')
22
22
  #require 'logger'
23
23
  #Faye.logger = Logger.new(STDOUT)
24
- faye.add_extension Faye::Authentication::Extension.new(FAYE_SECRET_KEY)
24
+ faye.add_extension Faye::Authentication::ServerExtension.new(FAYE_SECRET_KEY)
25
25
  Rack::Handler::Thin.run faye, :Port => 9296
26
26
  end.tap do |id|
27
27
  parent = $$
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+ require 'rspec/em'
3
+ require 'faye/authentication'
4
+
5
+ ClientSteps = RSpec::EM.async_steps do
6
+ def client(name, channels, enable_extension = false, &callback)
7
+ @clients ||= {}
8
+ @inboxes ||= {}
9
+ @errors ||= {}
10
+ @clients[name] = Faye::Client.new('http://127.0.0.1:9876/faye')
11
+ @clients[name].add_extension(Faye::Authentication::ClientExtension.new('macaroni')) if enable_extension
12
+ @inboxes[name] = {}
13
+ @errors[name] ||= []
14
+
15
+ n = channels.size
16
+ return @clients[name].connect(&callback) if n.zero?
17
+
18
+ channels.each do |channel|
19
+ subscription = @clients[name].subscribe(channel) do |message|
20
+ @inboxes[name][channel] ||= []
21
+ @inboxes[name][channel] << message
22
+ end
23
+ subscription.errback do |e|
24
+ n -= 1
25
+ @errors[name] << e.message
26
+ callback.call if n.zero?
27
+ end
28
+ subscription.callback do
29
+ n -= 1
30
+ callback.call if n.zero?
31
+ end
32
+ end
33
+ end
34
+
35
+ def publish(name, channel, message, &callback)
36
+ @clients[name].publish(channel, message)
37
+ EM.add_timer(0.1, &callback)
38
+ end
39
+
40
+ def check_inbox(name, channel, messages, &callback)
41
+ inbox = @inboxes[name][channel] || []
42
+ expect(inbox).to eq(messages)
43
+ callback.call
44
+ end
45
+
46
+ def check_errors(name, errors, &callback)
47
+ expect(@errors[name]).to eq(errors)
48
+ callback.call
49
+ end
50
+
51
+ def launch_server(&callback)
52
+ Faye::WebSocket.load_adapter('thin')
53
+ app = Faye::RackAdapter.new(:mount => '/faye', :timeout => 25)
54
+ app.add_extension(Faye::Authentication::ServerExtension.new('macaroni'))
55
+ Thin::Logging.silent = true
56
+ Thin::Server.start('127.0.0.1', 9876, app)
57
+ callback.call
58
+ end
59
+ end
60
+
61
+ describe Faye::Authentication::ClientExtension do
62
+
63
+ include ClientSteps
64
+
65
+ before(:each) { launch_server }
66
+
67
+ context 'without extension' do
68
+
69
+ before(:each) do
70
+ client 'foo', ['/foo']
71
+ end
72
+
73
+ it 'fails to deliver the message' do
74
+ check_inbox 'foo', '/foo', []
75
+ check_errors 'foo', ['Invalid signature']
76
+ end
77
+
78
+ end
79
+
80
+ context 'with extension' do
81
+
82
+ before(:each) do
83
+ client 'foo', ['/foo'], true
84
+ client 'bar', ['/foo'], true
85
+ end
86
+
87
+ it 'succeeds to deliver the message' do
88
+ publish 'foo', '/foo', 'Hello'
89
+ check_inbox 'foo', '/foo', ['Hello']
90
+ check_errors 'foo', []
91
+ end
92
+
93
+ end
94
+
95
+ end
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
- require 'faye/authentication/extension'
2
+ require 'faye/authentication/server_extension'
3
3
 
4
- describe Faye::Authentication::Extension do
4
+ describe Faye::Authentication::ServerExtension do
5
5
 
6
6
  let(:secret) { 'macaroni' }
7
- let(:extension) { Faye::Authentication::Extension.new(secret) }
7
+ let(:extension) { Faye::Authentication::ServerExtension.new(secret) }
8
8
 
9
9
  it 'does not add an eror if the message is correctly signed' do
10
10
  message = {'channel' => '/foo/bar', 'clientId' => '42', 'text' => 'whatever'}
data/spec/spec_helper.rb CHANGED
@@ -18,6 +18,7 @@
18
18
  require 'webmock/rspec'
19
19
 
20
20
  RSpec.configure do |config|
21
+ WebMock.disable_net_connect!(:allow_localhost => true)
21
22
  # The settings below are suggested to provide a good initial experience
22
23
  # with RSpec, but feel free to customize to your heart's content.
23
24
  =begin
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.2.0
4
+ version: 0.3.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-06 00:00:00.000000000 Z
11
+ date: 2014-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
@@ -154,17 +154,19 @@ files:
154
154
  - app/assets/javascripts/faye-authentication.js
155
155
  - faye-authentication.gemspec
156
156
  - lib/faye/authentication.rb
157
+ - lib/faye/authentication/client_extension.rb
157
158
  - lib/faye/authentication/engine.rb
158
- - lib/faye/authentication/extension.rb
159
159
  - lib/faye/authentication/http_client.rb
160
+ - lib/faye/authentication/server_extension.rb
160
161
  - lib/faye/authentication/version.rb
161
162
  - spec/javascripts/faye-authentication_spec.js
162
163
  - spec/javascripts/faye-extension_spec.js
163
164
  - spec/javascripts/helpers/.gitkeep
164
165
  - spec/javascripts/support/jasmine.yml
165
166
  - spec/javascripts/support/jasmine_helper.rb
166
- - spec/lib/faye/authentication/extension_spec.rb
167
+ - spec/lib/faye/authentication/client_extension_spec.rb
167
168
  - spec/lib/faye/authentication/http_client_spec.rb
169
+ - spec/lib/faye/authentication/server_extension_spec.rb
168
170
  - spec/lib/faye/authentication_spec.rb
169
171
  - spec/spec_helper.rb
170
172
  - spec/utils/javascripts/core.js
@@ -204,8 +206,9 @@ test_files:
204
206
  - spec/javascripts/helpers/.gitkeep
205
207
  - spec/javascripts/support/jasmine.yml
206
208
  - spec/javascripts/support/jasmine_helper.rb
207
- - spec/lib/faye/authentication/extension_spec.rb
209
+ - spec/lib/faye/authentication/client_extension_spec.rb
208
210
  - spec/lib/faye/authentication/http_client_spec.rb
211
+ - spec/lib/faye/authentication/server_extension_spec.rb
209
212
  - spec/lib/faye/authentication_spec.rb
210
213
  - spec/spec_helper.rb
211
214
  - spec/utils/javascripts/core.js