socky-authenticator 0.5.0.beta4 → 0.5.0.beta5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -36,4 +36,4 @@ Otherwise you will need to provide secret each time when authenticating data.
36
36
 
37
37
  Except of that you can enable or disable authenticaton of user rights - if disabled(default) then user will not be able to change their rights. Full version of authenticator call will look like that:
38
38
 
39
- Socky::Authenticator.authenticate(<data>, allow_changing_rights, secret)
39
+ Socky::Authenticator.authenticate(<data>, :allow_changing_rights => true, :secret => 'mysecret')
@@ -4,36 +4,35 @@ require 'hmac-sha2'
4
4
 
5
5
  module Socky
6
6
  class Authenticator
7
- VERSION = '0.5.0.beta4'
8
-
9
7
  DEFAULT_RIGHTS = {
10
- 'read' => true,
11
- 'write' => false,
12
- 'hide' => false
8
+ :read => true,
9
+ :write => false,
10
+ :hide => false
13
11
  }
14
12
 
15
13
  class << self
16
14
  attr_accessor :secret
17
15
 
18
- def authenticate(args = {}, allow_changing_rights = false, secret = nil)
19
- self.new(args, allow_changing_rights, secret).result
16
+ def authenticate(params, opts = {})
17
+ self.new(params, opts).result
20
18
  end
21
19
  end
22
20
 
23
- attr_accessor :secret, :salt
21
+ attr_accessor :secret, :salt, :method
24
22
 
25
- def initialize(args = {}, allow_changing_rights = false, secret = nil)
26
- @args = (args.is_a?(String) ? JSON.parse(args) : args) rescue nil
27
- raise ArgumentError, 'Expected hash or JSON' unless @args.kind_of?(Hash)
28
- @secret = secret || self.class.secret
29
- @allow_changing_rights = allow_changing_rights
23
+ def initialize(params, opts = {})
24
+ @params = (params.is_a?(String) ? JSON.parse(params) : params) rescue nil
25
+ raise ArgumentError, 'Expected hash or JSON' unless @params.kind_of?(Hash)
26
+ @secret = opts[:secret] || opts['secret'] || self.class.secret
27
+ @method = opts[:method] || opts['method'] || :websocket
28
+ @allow_changing_rights = opts[:allow_changing_rights] || false
30
29
  end
31
30
 
32
31
  def result
33
32
  raise ArgumentError, 'set Authenticator.secret first' unless self.secret
34
33
  raise ArgumentError, 'expected connection_id' unless self.connection_id
35
- raise ArgumentError, 'expected channel' unless self.channel_name
36
- raise ArgumentError, 'user are not allowed to change channel rights' unless self.rights
34
+ raise ArgumentError, 'expected channel' unless self.channel
35
+ raise ArgumentError, 'expected event' unless self.method != :http || self.event
37
36
 
38
37
  r = { 'auth' => auth }
39
38
  r.merge!('data' => user_data) unless user_data.nil?
@@ -49,7 +48,8 @@ module Socky
49
48
  end
50
49
 
51
50
  def string_to_sign
52
- args = [salt, connection_id, channel_name, rights]
51
+ args = [salt, connection_id, channel]
52
+ args << (@method == :websocket ? rights_string : event.to_s)
53
53
  args << user_data unless user_data.nil?
54
54
  args.collect(&:to_s).join(":")
55
55
  end
@@ -59,35 +59,58 @@ module Socky
59
59
  end
60
60
 
61
61
  def connection_id
62
- @args['connection_id']
62
+ @params[:connection_id] || @params['connection_id']
63
63
  end
64
64
 
65
- def channel_name
66
- @args['channel']
65
+ def channel
66
+ @params[:channel] || @params['channel']
67
67
  end
68
68
 
69
+ def event
70
+ @params[:event] || @params['event']
71
+ end
72
+
69
73
  def rights
70
- return @rights if defined?(@rights)
71
- r = DEFAULT_RIGHTS.merge(@args)
72
-
73
- # Return nil if user is trying to change rights when this option is disabled
74
- return nil if !@allow_changing_rights && DEFAULT_RIGHTS.any?{ |right,val| r[right] != val }
75
-
76
- @rights = ['read', 'write', 'hide'].collect do |right|
77
- r[right] && !(right == 'hide' && !self.presence?) ? '1' : '0'
78
- end.join
74
+ {
75
+ :read => read_right,
76
+ :write => write_right,
77
+ :hide => hide_right
78
+ }
79
79
  end
80
80
 
81
81
  def user_data
82
- @user_data ||= case @args['data']
82
+ @user_data ||= case (@params[:data] || @params['data'])
83
83
  when NilClass then nil
84
- when String then @args['data']
85
- else @args['data'].to_json
84
+ when String then @params['data']
85
+ else @params['data'].to_json
86
86
  end
87
87
  end
88
88
 
89
89
  def presence?
90
- self.channel_name.is_a?(String) && !!self.channel_name.match(/\Apresence-/)
90
+ self.channel.is_a?(String) && !!self.channel.match(/\Apresence-/)
91
+ end
92
+
93
+ private
94
+
95
+ def read_right
96
+ return DEFAULT_RIGHTS[:read] unless @allow_changing_rights
97
+ [ @params[:read], @params['read'], DEFAULT_RIGHTS[:read] ].reject(&:nil?).first
98
+ end
99
+
100
+ def write_right
101
+ return DEFAULT_RIGHTS[:write] unless @allow_changing_rights
102
+ [ @params[:write], @params['write'], DEFAULT_RIGHTS[:write] ].reject(&:nil?).first
103
+ end
104
+
105
+ def hide_right
106
+ return DEFAULT_RIGHTS[:hide] unless self.presence? && @allow_changing_rights
107
+ [ @params[:hide], @params['hide'], DEFAULT_RIGHTS[:hide] ].reject(&:nil?).first
108
+ end
109
+
110
+ def rights_string
111
+ [ rights[:read], rights[:write], rights[:hide] ].collect do |right|
112
+ right ? '1' : '0'
113
+ end.join
91
114
  end
92
115
 
93
116
  end
@@ -0,0 +1,5 @@
1
+ module Socky
2
+ class Authenticator
3
+ VERSION = '0.5.0.beta5'
4
+ end
5
+ end
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
- require "socky/authenticator"
3
+ require "socky/authenticator/version"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "socky-authenticator"
@@ -11,12 +11,12 @@ describe Socky::Authenticator do
11
11
 
12
12
  it "should allow passing Hash" do
13
13
  subject = Socky::Authenticator.new('some' => 'data')
14
- subject.instance_variable_get('@args').should eql('some' => 'data')
14
+ subject.instance_variable_get('@params').should eql('some' => 'data')
15
15
  end
16
16
 
17
17
  it "should allow passing JSON-encoded Hash" do
18
18
  subject = Socky::Authenticator.new('{"some":"data"}')
19
- subject.instance_variable_get('@args').should eql('some' => 'data')
19
+ subject.instance_variable_get('@params').should eql('some' => 'data')
20
20
  end
21
21
 
22
22
  it "should raise on JSON-encoded non-Hash" do
@@ -24,14 +24,15 @@ describe Socky::Authenticator do
24
24
  end
25
25
 
26
26
  context "instance" do
27
- subject { Socky::Authenticator.new('connection_id' => '1234ABCD', 'channel' => 'some_channel') }
27
+ let(:default_params) { {:connection_id => '1234ABCD', :channel => 'some_channel'} }
28
+ subject { Socky::Authenticator.new(default_params) }
28
29
  # Set salt to constant to make tests non-random
29
30
  before { subject.salt = 'somerandomstring' }
30
31
 
31
32
  its(:salt) { should eql('somerandomstring') }
32
33
  its(:connection_id) { should eql('1234ABCD') }
33
- its(:channel_name) { should eql('some_channel') }
34
- its(:rights) { should eql('100') }
34
+ its(:channel) { should eql('some_channel') }
35
+ its(:rights) { should eql(:read => true, :write => false, :hide => false) }
35
36
  its(:presence?) { should eql(false) }
36
37
  its(:string_to_sign) { should eql('somerandomstring:1234ABCD:some_channel:100') }
37
38
  its(:signature) { should eql('28f138d68b1d4971d85355a5aa5a301be9084176b6ae1bbe2399de990de2039d') }
@@ -44,48 +45,45 @@ describe Socky::Authenticator do
44
45
  end
45
46
 
46
47
  it "should raise if connection_id is nil" do
47
- subject.instance_variable_get('@args').delete('connection_id')
48
+ subject = Socky::Authenticator.new(default_params.reject{|k,v| k == :connection_id})
48
49
  subject.connection_id.should be_nil
49
50
  lambda { subject.result }.should raise_error ArgumentError, 'expected connection_id'
50
51
  end
51
52
 
52
53
  it "should raise if channel is nil" do
53
- subject.instance_variable_get('@args').delete('channel')
54
- subject.channel_name.should be_nil
54
+ subject = Socky::Authenticator.new(default_params.reject{|k,v| k == :channel})
55
+ subject.channel.should be_nil
55
56
  lambda { subject.result }.should raise_error ArgumentError, 'expected channel'
56
57
  end
57
58
 
58
59
  it "should not allow to changing rights at default" do
59
- subject.instance_variable_get('@args').merge!('write' => true)
60
- subject.rights.should be_nil
61
- lambda { subject.result }.should raise_error ArgumentError, 'user are not allowed to change channel rights'
60
+ subject = Socky::Authenticator.new(default_params.merge(:read => false, :write => true, :hide => true))
61
+ subject.rights.should eql(:read => true, :write => false, :hide => false)
62
62
  end
63
63
 
64
64
  context "with changing rights enables" do
65
- before { subject.instance_variable_set('@allow_changing_rights', true) }
66
-
67
65
  it "should allow changing 'read' to false" do
68
- subject.instance_variable_get('@args').merge!('read' => false)
69
- subject.rights.should eql('000')
66
+ subject = Socky::Authenticator.new(default_params.merge(:read => false), :allow_changing_rights => true)
67
+ subject.rights[:read].should eql(false)
70
68
  end
71
69
 
72
70
  it "should allow changing 'write' to true" do
73
- subject.instance_variable_get('@args').merge!('write' => true)
74
- subject.rights.should eql('110')
71
+ subject = Socky::Authenticator.new(default_params.merge(:write => true), :allow_changing_rights => true)
72
+ subject.rights[:write].should eql(true)
75
73
  end
76
74
 
77
75
  it "should not allow changing 'hide' to true" do
78
- subject.instance_variable_get('@args').merge!('hide' => true)
79
- subject.rights.should eql('100')
76
+ subject = Socky::Authenticator.new(default_params.merge(:hide => true), :allow_changing_rights => true)
77
+ subject.rights[:hide].should eql(false)
80
78
  end
81
79
 
82
80
  end
83
81
 
84
82
  context "presence channel" do
85
- before { subject.instance_variable_get('@args').merge!('channel' => 'presence-channel') }
83
+ subject { Socky::Authenticator.new(default_params.merge(:channel => 'presence-channel')) }
86
84
 
87
- its(:channel_name) { should eql('presence-channel') }
88
- its(:rights) { should eql('100') }
85
+ its(:channel) { should eql('presence-channel') }
86
+ its(:rights) { should eql(:read => true, :write => false, :hide => false) }
89
87
  its(:presence?) { should eql(true) }
90
88
  its(:user_data) { should eql(nil) }
91
89
  its(:string_to_sign) { should eql('somerandomstring:1234ABCD:presence-channel:100') }
@@ -94,7 +92,7 @@ describe Socky::Authenticator do
94
92
  its(:result) { should eql('auth' => 'somerandomstring:f0332936d0c3e59e2d9840d0c0b538ad88fba467ba546d8f9f91bc8d3cd95a1c') }
95
93
 
96
94
  context "with hash user data provided" do
97
- before { subject.instance_variable_get('@args').merge!('data' => { 'some' => 'data' }) }
95
+ subject { Socky::Authenticator.new(default_params.merge(:channel => 'presence-channel', 'data' => { 'some' => 'data' })) }
98
96
 
99
97
  its(:user_data) { should eql('{"some":"data"}') }
100
98
  its(:string_to_sign) { should eql('somerandomstring:1234ABCD:presence-channel:100:{"some":"data"}') }
@@ -104,7 +102,7 @@ describe Socky::Authenticator do
104
102
  end
105
103
 
106
104
  context "with string user data provided" do
107
- before { subject.instance_variable_get('@args').merge!('data' => '{"some":"data"}') }
105
+ subject { Socky::Authenticator.new(default_params.merge(:channel => 'presence-channel', 'data' => '{"some":"data"}')) }
108
106
 
109
107
  its(:user_data) { should eql('{"some":"data"}') }
110
108
  its(:string_to_sign) { should eql('somerandomstring:1234ABCD:presence-channel:100:{"some":"data"}') }
metadata CHANGED
@@ -1,98 +1,92 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: socky-authenticator
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0.beta5
4
5
  prerelease: 6
5
- version: 0.5.0.beta4
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Bernard Potocki
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-04-16 00:00:00 +02:00
12
+ date: 2011-07-30 00:00:00.000000000 +02:00
14
13
  default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
17
16
  name: json
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &70200339058460 !ruby/object:Gem::Requirement
20
18
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: "0"
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
25
23
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: ruby-hmac
29
24
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: *70200339058460
26
+ - !ruby/object:Gem::Dependency
27
+ name: ruby-hmac
28
+ requirement: &70200339057920 !ruby/object:Gem::Requirement
31
29
  none: false
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: "0"
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
36
34
  type: :runtime
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: rspec
40
35
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
36
+ version_requirements: *70200339057920
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ requirement: &70200339057300 !ruby/object:Gem::Requirement
42
40
  none: false
43
- requirements:
41
+ requirements:
44
42
  - - ~>
45
- - !ruby/object:Gem::Version
46
- version: "2.0"
43
+ - !ruby/object:Gem::Version
44
+ version: '2.0'
47
45
  type: :development
48
- version_requirements: *id003
46
+ prerelease: false
47
+ version_requirements: *70200339057300
49
48
  description: Socky is a WebSocket-based framework for realtime web applications.
50
- email:
49
+ email:
51
50
  - bernard.potocki@imanel.org
52
51
  executables: []
53
-
54
52
  extensions: []
55
-
56
53
  extra_rdoc_files: []
57
-
58
- files:
54
+ files:
59
55
  - .gitignore
60
56
  - Gemfile
61
57
  - README.md
62
58
  - Rakefile
63
59
  - example/config.ru
64
60
  - lib/socky/authenticator.rb
61
+ - lib/socky/authenticator/version.rb
65
62
  - socky-authenticator.gemspec
66
63
  - spec/authenticator_spec.rb
67
64
  - spec/spec_helper.rb
68
65
  has_rdoc: true
69
66
  homepage: http://socky.org
70
67
  licenses: []
71
-
72
68
  post_install_message:
73
69
  rdoc_options: []
74
-
75
- require_paths:
70
+ require_paths:
76
71
  - lib
77
- required_ruby_version: !ruby/object:Gem::Requirement
72
+ required_ruby_version: !ruby/object:Gem::Requirement
78
73
  none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: "0"
83
- required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
79
  none: false
85
- requirements:
86
- - - ">"
87
- - !ruby/object:Gem::Version
80
+ requirements:
81
+ - - ! '>'
82
+ - !ruby/object:Gem::Version
88
83
  version: 1.3.1
89
84
  requirements: []
90
-
91
85
  rubyforge_project:
92
- rubygems_version: 1.6.1
86
+ rubygems_version: 1.6.2
93
87
  signing_key:
94
88
  specification_version: 3
95
89
  summary: Socky - Authentication Module
96
- test_files:
90
+ test_files:
97
91
  - spec/authenticator_spec.rb
98
92
  - spec/spec_helper.rb