socky-authenticator 0.5.0.beta4 → 0.5.0.beta5
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.
- data/README.md +1 -1
- data/lib/socky/authenticator.rb +55 -32
- data/lib/socky/authenticator/version.rb +5 -0
- data/socky-authenticator.gemspec +1 -1
- data/spec/authenticator_spec.rb +22 -24
- metadata +44 -50
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')
|
data/lib/socky/authenticator.rb
CHANGED
@@ -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
|
-
|
11
|
-
|
12
|
-
|
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(
|
19
|
-
self.new(
|
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(
|
26
|
-
@
|
27
|
-
raise ArgumentError, 'Expected hash or JSON' unless @
|
28
|
-
@secret = secret || self.class.secret
|
29
|
-
@
|
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.
|
36
|
-
raise ArgumentError, '
|
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,
|
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
|
-
@
|
62
|
+
@params[:connection_id] || @params['connection_id']
|
63
63
|
end
|
64
64
|
|
65
|
-
def
|
66
|
-
@
|
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
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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 @
|
82
|
+
@user_data ||= case (@params[:data] || @params['data'])
|
83
83
|
when NilClass then nil
|
84
|
-
when String then @
|
85
|
-
else @
|
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.
|
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
|
data/socky-authenticator.gemspec
CHANGED
data/spec/authenticator_spec.rb
CHANGED
@@ -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('@
|
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('@
|
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
|
-
|
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(:
|
34
|
-
its(:rights) { should eql(
|
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.
|
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.
|
54
|
-
subject.
|
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.
|
60
|
-
subject.rights.should
|
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.
|
69
|
-
subject.rights.should eql(
|
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.
|
74
|
-
subject.rights.should eql(
|
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.
|
79
|
-
subject.rights.should eql(
|
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
|
-
|
83
|
+
subject { Socky::Authenticator.new(default_params.merge(:channel => 'presence-channel')) }
|
86
84
|
|
87
|
-
its(:
|
88
|
-
its(:rights) { should eql(
|
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
|
-
|
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
|
-
|
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
|
-
|
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:
|
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
|
-
|
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:
|
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
|
-
|
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:
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '2.0'
|
47
45
|
type: :development
|
48
|
-
|
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:
|
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.
|
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
|