rrba 1.0.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.
@@ -0,0 +1,3 @@
1
+ class rrba
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # Error -- rrba -- 04.02.2005 -- rwaltert@ywesee.com
3
+
4
+ module RRBA
5
+ class AuthenticationError < RuntimeError; end
6
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # Server -- rrba -- 10.11.2004 -- hwyss@ywesee.com
3
+
4
+ require 'rrba/user'
5
+ require 'rrba/error'
6
+ require 'openssl'
7
+ require 'digest/md5'
8
+
9
+ module RRBA
10
+ class Server
11
+ attr_writer :root, :anonymous
12
+ def initialize
13
+ @users = []
14
+ end
15
+ def add_user(user)
16
+ id = user.unique_id
17
+ if(@users.any? { |usr| usr.unique_id == id })
18
+ raise "Duplicate ID #{id}"
19
+ end
20
+ @users.push(user).last
21
+ end
22
+ def authenticate(id=nil, &block)
23
+ challenge = Digest::MD5.hexdigest(rand(2**32).to_s)[0,20]
24
+ signature = block.call(challenge)
25
+ if(@anonymous && signature == :anonymous)
26
+ return @anonymous.new_session
27
+ end
28
+ if(@root && @root.authenticate(challenge, signature))
29
+ return @root.new_session
30
+ end
31
+ begin
32
+ if(id)
33
+ if((user = user(id)) \
34
+ && user.authenticate(challenge, signature))
35
+ return user.new_session
36
+ end
37
+ else
38
+ @users.each { |user|
39
+ if(user.authenticate(challenge, signature))
40
+ return user.new_session
41
+ end
42
+ }
43
+ end
44
+ rescue RuntimeError
45
+ end
46
+ raise AuthenticationError, 'Authentication failed'
47
+ end
48
+ def user(id)
49
+ @users.select { |user|
50
+ user.unique_id == id
51
+ }.first or raise "Unknown User: #{id}"
52
+ end
53
+ def unique_ids
54
+ @users.collect { |user|
55
+ user.unique_id
56
+ }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ # User -- rrba -- 01.11.2004 -- hwyss@ywesee.com
3
+
4
+ module RRBA
5
+ class User
6
+ attr_reader :name, :email, :short_name, :unique_id, :public_key
7
+ def initialize(unique_id)
8
+ @unique_id = unique_id or raise "Invalid ID #{unique_id}"
9
+ end
10
+ def authenticate(challenge, signature)
11
+ # enable lazy initializing
12
+ # (for subclasses that can be persisted)
13
+ public_key.sysverify(challenge, signature)
14
+ end
15
+ def email=(email)
16
+ email = email.to_s.strip
17
+ raise "Invalid Email #{email}" if(email.empty?)
18
+ @email = email
19
+ end
20
+ def name=(name)
21
+ name = name.to_s.strip
22
+ raise "Invalid Username #{name}" if(name.empty?)
23
+ @name = name
24
+ end
25
+ def new_session
26
+ raise NotImplementedError,
27
+ "no predefined behavior for RRBA::User#new_session"
28
+ end
29
+ def public_key=(key)
30
+ @public_key = key.public_key
31
+ end
32
+ def short_name=(short_name)
33
+ short_name = short_name.to_s.strip
34
+ raise "Invalid Short Name #{short_name}" if(short_name.empty?)
35
+ @short_name = short_name
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,149 @@
1
+ # Ruby/Mock version 1.0
2
+ #
3
+ # A class for conveniently building mock objects in RUnit test cases.
4
+ # Copyright (c) 2001 Nat Pryce, all rights reserved
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the Free Software
17
+ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
+
19
+ require 'runit/error'
20
+
21
+
22
+ class Mock
23
+ # Creates a new, named mock object. The name is reported in exceptions
24
+ # thrown by the mock object when method invocations are incorrect.
25
+ #
26
+ def initialize( mock_name = self.to_s )
27
+ @mock_calls = []
28
+ @next_call = 0
29
+ @name = mock_name
30
+ end
31
+
32
+ # Mock the next method call to be made to this mock object.
33
+ #
34
+ # A mock method is defined by the method name (a symbol) and a block
35
+ # that defines the arity of the method and the mocked behaviour for
36
+ # this call. The mocked behaviour should assert preconditions and
37
+ # return a value. Mocked behaviour should rarely be any more complex
38
+ # than that. If it is, that's probably an indication that the tests
39
+ # need some restructuring or that the tested code needs refactoring.
40
+ #
41
+ # If no block is given and preconditions have been defined for the named
42
+ # method, a block is created for the mocked methodthat has the same arity
43
+ # as the precondition and returns self.
44
+ #
45
+ def __next( name, &test )
46
+ if test == nil
47
+ if respond_to?( Mock.__pre(name) )
48
+ test = proc { |*args| self }
49
+ else
50
+ raise "no block given for mocked method #{name}"
51
+ end
52
+ end
53
+ @mock_calls.push( [name,test] )
54
+ end
55
+
56
+ # Call this at the end of a test to ensure that all scheduled calls
57
+ # have been made to the mock
58
+ #
59
+ def __verify
60
+ if @next_call != @mock_calls.length
61
+ raise RUNIT::AssertionFailedError,
62
+ "not all expected method calls were made to #{@name}",
63
+ caller
64
+ end
65
+ end
66
+
67
+
68
+ private
69
+ # Dispatches aribtrary method calls to the next mocked behaviour
70
+ #
71
+ def method_missing( name, *args )
72
+ __mock_call( name, args, (block_given? ? proc : nil) )
73
+ end
74
+
75
+ # Implements a method call using the next mocked behaviour and asserts
76
+ # that the expected method is called with the expected number of
77
+ # arguments.
78
+ #
79
+ def __mock_call( name, args, block )
80
+ if @next_call >= @mock_calls.length
81
+ raise RUNIT::AssertionFailedError,
82
+ "unexpected call to #{name} method of #{@name}",
83
+ caller(2)
84
+ end
85
+
86
+ expected_name,body = @mock_calls[@next_call]
87
+ @next_call += 1
88
+
89
+ if name != expected_name
90
+ raise RUNIT::AssertionFailedError,
91
+ "wrong method called on #{@name}; " +
92
+ "expected #{expected_name}, was #{name}",
93
+ caller(2)
94
+ end
95
+
96
+ args_length = args.length + (block ? 1 : 0)
97
+
98
+ if body.arity < 0
99
+ if (body.arity+1).abs > args_length
100
+ raise RUNIT::AssertionFailedError,
101
+ "too few arguments to #{name} method of #{@name}; " +
102
+ "require #{(body.arity+1).abs}, got #{args.length}",
103
+ caller(2)
104
+ end
105
+ else
106
+ if body.arity != args_length
107
+ raise RUNIT::AssertionFailedError,
108
+ "wrong number of arguments to " +
109
+ "#{name} method of #{@name}; " +
110
+ "require #{body.arity}, got #{args.length}",
111
+ caller(2)
112
+ end
113
+ end
114
+
115
+ if respond_to? Mock.__pre(name)
116
+ if block
117
+ precondition_ok = __send__( Mock.__pre(name), *args, &block )
118
+ else
119
+ precondition_ok = __send__( Mock.__pre(name), *args )
120
+ end
121
+
122
+ if not precondition_ok
123
+ raise RUNIT::AssertionFailedError,
124
+ "precondition of #{name} method violated",
125
+ caller(2)
126
+ end
127
+ end
128
+
129
+ if block
130
+ instance_eval { body.call( block, *args ) }
131
+ else
132
+ instance_eval { body.call( *args ) }
133
+ end
134
+ end
135
+
136
+ # The name of a precondition for a method
137
+ def Mock.__pre( method )
138
+ "__pre_#{method.to_i}".intern
139
+ end
140
+
141
+
142
+ def Mock.method_added( name )
143
+ unless(/^__pre_/.match(name.to_s))
144
+ pre = self.__pre(name)
145
+ alias_method( pre, name )
146
+ undef_method(name)
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # -- rdpm -- 21.01.2005 -- hwyss@ywesee.com
3
+
4
+ require 'odba'
5
+
6
+ module ODBA
7
+ module Persistable
8
+ attr_reader :odba_store_called
9
+ def odba_store
10
+ @odba_store_called = true
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # suite.rb -- rrba -- 20.11.2002 -- hwyss@ywesee.com
3
+
4
+ $: << File.expand_path(File.dirname(__FILE__))
5
+
6
+ Dir.foreach(File.dirname(__FILE__)) { |file|
7
+ require file if /^test_.*\.rb$/o.match(file)
8
+ }
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env ruby
2
+ # TestServer -- rdpm -- 10.11.2004 -- hwyss@ywesee.com
3
+
4
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
5
+ $: << File.dirname(__FILE__)
6
+
7
+ require 'test/unit'
8
+ require 'mock'
9
+ require 'fileutils'
10
+ require 'rrba/server'
11
+
12
+ module RRBA
13
+ class TestServer < Test::Unit::TestCase
14
+ def setup
15
+ @server = Server.new
16
+ @datadir = File.expand_path('data', File.dirname(__FILE__))
17
+ end
18
+ def test_add_user
19
+ user = User.new(345)
20
+ users = @server.instance_variable_get('@users')
21
+ @server.add_user(user)
22
+ assert_equal(user, @server.user(345))
23
+ end
24
+ def test_add_user__duplicate_id
25
+ user = User.new(345)
26
+ users = @server.instance_variable_get('@users')
27
+ @server.add_user(user)
28
+ assert_equal(user, @server.user(345))
29
+ assert_equal(345, user.unique_id)
30
+ user = User.new(345)
31
+ assert_raises(RuntimeError) {
32
+ @server.add_user(user)
33
+ }
34
+ end
35
+ def test_authenticate__failure
36
+ user1 = Mock.new('User1')
37
+ user2 = Mock.new('User2')
38
+ user3 = Mock.new('User3')
39
+ user1.__next(:authenticate) { |chal, sig|
40
+ assert_equal(20, chal.size)
41
+ assert_equal('client-signature', sig)
42
+ false
43
+ }
44
+ user2.__next(:authenticate) { |chal, sig|
45
+ assert_equal(20, chal.size)
46
+ assert_equal('client-signature', sig)
47
+ false
48
+ }
49
+ user3.__next(:authenticate) { |chal, sig|
50
+ assert_equal(20, chal.size)
51
+ assert_equal('client-signature', sig)
52
+ false
53
+ }
54
+ users = [
55
+ user1,
56
+ user2,
57
+ user3,
58
+ ]
59
+ @server.instance_variable_set('@users', users)
60
+ user = nil
61
+ assert_raises(AuthenticationError) {
62
+ user = @server.authenticate { |challenge|
63
+ assert_equal(20, challenge.size)
64
+ 'client-signature'
65
+ }
66
+ }
67
+ assert_nil(user)
68
+ end
69
+ def test_authenticate__success
70
+ user1 = Mock.new('User1')
71
+ user2 = Mock.new('User2')
72
+ user3 = Mock.new('User3')
73
+ user1.__next(:authenticate) { |challenge, sig|
74
+ assert_equal('client-signature', sig)
75
+ false
76
+ }
77
+ user2.__next(:authenticate) { |challenge, sig|
78
+ assert_equal('client-signature', sig)
79
+ true
80
+ }
81
+ user3.__next(:authenticate) { |challenge, sig|
82
+ assert_equal('client-signature', sig)
83
+ false
84
+ }
85
+ users = [
86
+ user1,
87
+ user2,
88
+ user3,
89
+ ]
90
+ session = Mock.new('Session')
91
+ user2.__next(:new_session) { session }
92
+ @server.instance_variable_set('@users', users)
93
+ sess = @server.authenticate { |challenge, sig|
94
+ assert_equal(20, challenge.size)
95
+ 'client-signature'
96
+ }
97
+ assert_equal(session, sess)
98
+ user2.__verify
99
+ end
100
+ def test_authenticate__root
101
+ root = Mock.new('Root')
102
+ user2 = Mock.new('User2')
103
+ user3 = Mock.new('User3')
104
+ root.__next(:authenticate) { |challenge, sig|
105
+ assert_equal('client-signature', sig)
106
+ true
107
+ }
108
+ users = [
109
+ user2,
110
+ user3,
111
+ ]
112
+ session = Mock.new('Session')
113
+ root.__next(:new_session) { session }
114
+ @server.instance_variable_set('@root', root)
115
+ @server.instance_variable_set('@users', users)
116
+ sess = @server.authenticate { |challenge, sig|
117
+ 'client-signature'
118
+ }
119
+ assert_equal(session, sess)
120
+ root.__verify
121
+ end
122
+ def test_authenticate__anonymous
123
+ root = Mock.new('Root')
124
+ user2 = Mock.new('User2')
125
+ user3 = Mock.new('User3')
126
+ anonymous = Mock.new('Anonymous')
127
+ users = [
128
+ user2,
129
+ user3,
130
+ ]
131
+ session = Mock.new('Session')
132
+ anonymous.__next(:new_session) { session }
133
+ @server.root = root
134
+ @server.anonymous = anonymous
135
+ @server.instance_variable_set('@users', users)
136
+ sess = @server.authenticate { |challenge, sig|
137
+ :anonymous
138
+ }
139
+ assert_equal(session, sess)
140
+ root.__verify
141
+ end
142
+ def test_authenticate__by_id
143
+ user1 = Mock.new('User1')
144
+ user2 = Mock.new('User2')
145
+ user3 = Mock.new('User3')
146
+ user1.__next(:unique_id) { 'user1' }
147
+ user2.__next(:unique_id) { 'user2' }
148
+ user3.__next(:unique_id) { 'user3' }
149
+ user2.__next(:authenticate) { |challenge, sig|
150
+ assert_equal('client-signature', sig)
151
+ true
152
+ }
153
+ users = [
154
+ user1,
155
+ user2,
156
+ user3,
157
+ ]
158
+ session = Mock.new('Session')
159
+ user2.__next(:new_session) { session }
160
+ @server.instance_variable_set('@users', users)
161
+ sess = @server.authenticate('user2') { |challenge, sig|
162
+ assert_equal(20, challenge.size)
163
+ 'client-signature'
164
+ }
165
+ assert_equal(session, sess)
166
+ user2.__verify
167
+ end
168
+ def test_unique_ids
169
+ user = Mock.new('user')
170
+ user2 = Mock.new('user2')
171
+ user.__next(:unique_id) { 'rwaltert' }
172
+ user2.__next(:unique_id) { 'hwyss' }
173
+ users = [user, user2]
174
+ @server.instance_variable_set('@users', users)
175
+ assert_equal(["rwaltert", 'hwyss'], @server.unique_ids)
176
+ end
177
+ end
178
+ end