drbservice 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/spec
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+
6
+ basedir = Pathname( __FILE__ ).dirname.parent.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'digest/sha2'
14
+
15
+ require 'rspec'
16
+ require 'spec/lib/helpers'
17
+
18
+ require 'drbservice'
19
+ require 'drbservice/passwordauth'
20
+
21
+
22
+ describe DRbService::PasswordAuthentication do
23
+ include DRbService::SpecHelpers
24
+
25
+ TEST_PASSWORD = 'hungerlumpkins'
26
+
27
+ before( :all ) do
28
+ setup_logging( :fatal )
29
+ end
30
+
31
+ after( :all ) do
32
+ reset_logging()
33
+ end
34
+
35
+
36
+ describe "mixed into a DRbService" do
37
+
38
+ it "provides a declarative to set a password for the service" do
39
+ serviceclass = Class.new( DRbService ) do
40
+ include DRbService::PasswordAuthentication
41
+ def do_some_stuff; return "Yep."; end
42
+ service_password TEST_PASSWORD
43
+ end
44
+ serviceclass.password_digest.should == Digest::SHA2.hexdigest( TEST_PASSWORD )
45
+ end
46
+
47
+ describe "without a password set" do
48
+
49
+ before( :all ) do
50
+ @serviceclass = Class.new( DRbService ) do
51
+ def do_some_guarded_stuff; return "Ronk."; end
52
+ unguarded do
53
+ def do_some_unguarded_stuff; return "Adonk."; end
54
+ end
55
+ end
56
+ end
57
+
58
+ before( :each ) do
59
+ @serviceobj = @serviceclass.new
60
+ end
61
+
62
+
63
+ it "raises an exception without calling the block on any authentication" do
64
+ block_called = false
65
+ expect {
66
+ @serviceobj.authenticate( '' ) do
67
+ block_called = true
68
+ end
69
+ }.should raise_exception( SecurityError, /authentication failure/i )
70
+ block_called.should == false
71
+ end
72
+
73
+ it "doesn't allow access to guarded methods" do
74
+ expect {
75
+ @serviceobj.do_some_guarded_stuff
76
+ }.to raise_exception( SecurityError, /not authenticated/i )
77
+ end
78
+
79
+ it "allows access to unguarded methods" do
80
+ @serviceobj.do_some_unguarded_stuff.should == 'Adonk.'
81
+ end
82
+
83
+ end
84
+
85
+
86
+ describe "instances with a password set" do
87
+
88
+ before( :each ) do
89
+ @serviceclass = Class.new( DRbService ) do
90
+ include DRbService::PasswordAuthentication
91
+ service_password TEST_PASSWORD
92
+ def do_some_guarded_stuff; return "Ronk."; end
93
+ unguarded do
94
+ def do_some_unguarded_stuff; return "Adonk."; end
95
+ end
96
+ end
97
+ end
98
+
99
+ before( :each ) do
100
+ @serviceobj = @serviceclass.new
101
+ end
102
+
103
+
104
+ it "raises an exception without calling the block on failed authentication" do
105
+ block_called = false
106
+ expect {
107
+ @serviceobj.authenticate( '' ) do
108
+ block_called = true
109
+ end
110
+ }.should raise_exception( SecurityError, /authentication failure/i )
111
+ block_called.should == false
112
+ end
113
+
114
+ it "doesn't allow access to guarded methods before authenticating" do
115
+ expect {
116
+ @serviceobj.do_some_guarded_stuff
117
+ }.to raise_exception( SecurityError, /not authenticated/i )
118
+ end
119
+
120
+ it "allows access to guarded methods after authenticating successfully" do
121
+ @serviceobj.authenticate( TEST_PASSWORD ) do
122
+ @serviceobj.do_some_guarded_stuff.should == 'Ronk.'
123
+ end
124
+ end
125
+
126
+ it "allows access to unguarded methods before authenticating" do
127
+ @serviceobj.do_some_unguarded_stuff.should == 'Adonk.'
128
+ end
129
+
130
+ it "allows access to unguarded methods after authenticating" do
131
+ @serviceobj.authenticate( TEST_PASSWORD ) do
132
+ @serviceobj.do_some_unguarded_stuff.should == 'Adonk.'
133
+ end
134
+ end
135
+
136
+ end
137
+
138
+ end
139
+
140
+ end
141
+
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/spec
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+
6
+ basedir = Pathname( __FILE__ ).dirname.parent
7
+ libdir = basedir + 'lib'
8
+
9
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
+ }
12
+
13
+ require 'rspec'
14
+ require 'spec/lib/helpers'
15
+
16
+ require 'uri'
17
+ require 'drbservice'
18
+
19
+
20
+ describe DRbService do
21
+ include DRbService::SpecHelpers
22
+
23
+ SERVICE_URI = URI( "drbssl://localhost:8484" )
24
+
25
+ before( :all ) do
26
+ setup_logging( :fatal )
27
+ end
28
+
29
+ after( :all ) do
30
+ reset_logging()
31
+ end
32
+
33
+
34
+ it "is always an 'undumped' service object" do
35
+ testclass = Class.new( DRbService )
36
+ testclass.should include( DRbUndumped )
37
+ end
38
+
39
+ it "doesn't allow instances to be created of itself" do
40
+ expect {
41
+ DRbService.new
42
+ }.should raise_exception( ScriptError, /can't instantiate/ )
43
+ end
44
+
45
+ it "obscures instance methods declared by subclasses by default" do
46
+ testclass = Class.new( DRbService ) do
47
+ def do_some_stuff; return "Yep."; end
48
+ end
49
+ testclass.new.should_not respond_to( :do_some_stuff )
50
+ end
51
+
52
+
53
+ it "provides an 'unguarded' declarative to define instance methods that can " +
54
+ "be used without authentication" do
55
+ testclass = Class.new( DRbService ) do
56
+ unguarded do
57
+ def do_some_stuff; return "Yep."; end
58
+ end
59
+ end
60
+ testclass.new.should respond_to( :do_some_stuff )
61
+ end
62
+
63
+
64
+ describe "subclass" do
65
+
66
+ it "is an 'undumped' service objects" do
67
+ serviceclass = Class.new( DRbService )
68
+ serviceclass.should include( DRbUndumped )
69
+ end
70
+
71
+ it "obscures instance methods by default" do
72
+ serviceclass = Class.new( DRbService ) do
73
+ def do_some_stuff; return "Yep."; end
74
+ end
75
+ serviceclass.new.should_not respond_to( :do_some_stuff )
76
+ end
77
+
78
+
79
+ it "can use an 'unguarded' declarative to define instance methods that can " +
80
+ "be used without authentication" do
81
+ serviceclass = Class.new( DRbService ) do
82
+ unguarded do
83
+ def do_some_stuff; return "Yep."; end
84
+ end
85
+ end
86
+ serviceclass.new.should respond_to( :do_some_stuff )
87
+ end
88
+
89
+
90
+ it "has a .start class method that does the necessary DRb setup and runs the service" do
91
+ serviceclass = Class.new( DRbService )
92
+ drbserver = mock( "drb server" )
93
+ thread = mock( "drb service thread" )
94
+
95
+ File.should_receive( :read ).with( 'service-cert.pem' ).
96
+ and_return( :cert_data )
97
+ OpenSSL::X509::Certificate.should_receive( :new ).with( :cert_data ).
98
+ and_return( :ssl_cert )
99
+ File.should_receive( :read ).with( 'service-key.pem' ).
100
+ and_return( :key_data )
101
+ OpenSSL::PKey::RSA.should_receive( :new ).with( :key_data ).
102
+ and_return( :ssl_key )
103
+
104
+ expected_config = {
105
+ :SSLCertificate => :ssl_cert,
106
+ :SSLPrivateKey => :ssl_key,
107
+ :safe_level => 1,
108
+ :verbose => true,
109
+ }
110
+
111
+ DRb::DRbServer.should_receive( :new ).
112
+ with( SERVICE_URI.to_s, an_instance_of(serviceclass), expected_config ).
113
+ and_return( drbserver )
114
+ drbserver.should_receive( :thread ).and_return( thread )
115
+ thread.should_receive( :join )
116
+
117
+ serviceclass.start( :ip => SERVICE_URI.host, :port => SERVICE_URI.port )
118
+ end
119
+
120
+
121
+ describe "instances without an authentication strategy mixed in" do
122
+
123
+ before( :all ) do
124
+ @serviceclass = Class.new( DRbService ) do
125
+ def do_some_guarded_stuff; return "Ronk."; end
126
+
127
+ unguarded do
128
+ def make_authenticated
129
+ self.log.debug "Making it authenticated!"
130
+ @authenticated = true
131
+ end
132
+ def do_some_unguarded_stuff; return "Adonk."; end
133
+ end
134
+ end
135
+ end
136
+
137
+ before( :each ) do
138
+ @serviceobj = @serviceclass.new
139
+ end
140
+
141
+
142
+ it "raises an exception when #authenticate is called" do
143
+ expect {
144
+ @serviceobj.authenticate( '' )
145
+ }.to raise_exception( SecurityError, /authentication failure/i )
146
+ end
147
+
148
+ it "allows access to unguarded methods without authenticating" do
149
+ @serviceobj.do_some_unguarded_stuff.should == 'Adonk.'
150
+ end
151
+
152
+ it "knows whether the user is authenticated or not" do
153
+ @serviceobj.should_not be_authenticated()
154
+ @serviceobj.make_authenticated
155
+ @serviceobj.should be_authenticated()
156
+ end
157
+
158
+ it "knows whether the user is authorized or not; in the base class authentication " +
159
+ "is sufficient for authorization as well" do
160
+ @serviceobj.should_not be_authorized()
161
+ @serviceobj.make_authenticated
162
+ @serviceobj.should be_authorized()
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+ end
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname.new( __FILE__ ).dirname.parent
7
+
8
+ libdir = basedir + "lib"
9
+
10
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
11
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
12
+ }
13
+
14
+ require 'uri'
15
+ require 'yaml'
16
+ require 'drbservice'
17
+
18
+
19
+ module DRbService::TestConstants
20
+
21
+ VALID_SERVICE_URISTRING = "drbauthssl://localhost:8484"
22
+ VALID_SERVICE_URI = URI( VALID_SERVICE_URISTRING )
23
+
24
+ end # module DRbService::TestConstants
25
+
26
+
27
+ ### RSpec helper functions.
28
+ module DRbService::SpecHelpers
29
+
30
+ ### Make an easily-comparable version vector out of +ver+ and return it.
31
+ def vvec( ver )
32
+ return ver.split('.').collect {|char| char.to_i }.pack('N*')
33
+ end
34
+
35
+
36
+ class ArrayLogger
37
+ ### Create a new ArrayLogger that will append content to +array+.
38
+ def initialize( array )
39
+ @array = array
40
+ end
41
+
42
+ ### Write the specified +message+ to the array.
43
+ def write( message )
44
+ @array << message
45
+ end
46
+
47
+ ### No-op -- this is here just so Logger doesn't complain
48
+ def close; end
49
+
50
+ end # class ArrayLogger
51
+
52
+
53
+ unless defined?( LEVEL )
54
+ LEVEL = {
55
+ :debug => Logger::DEBUG,
56
+ :info => Logger::INFO,
57
+ :warn => Logger::WARN,
58
+ :error => Logger::ERROR,
59
+ :fatal => Logger::FATAL,
60
+ }
61
+ end
62
+
63
+ ###############
64
+ module_function
65
+ ###############
66
+
67
+ ### Reset the logging subsystem to its default state.
68
+ def reset_logging
69
+ DRbService.reset_logger
70
+ end
71
+
72
+
73
+ ### Alter the output of the default log formatter to be pretty in SpecMate output
74
+ def setup_logging( level=Logger::FATAL )
75
+
76
+ # Turn symbol-style level config into Logger's expected Fixnum level
77
+ if DRbService::Logging::LEVEL.key?( level )
78
+ level = DRbService::Logging::LEVEL[ level ]
79
+ end
80
+
81
+ logger = Logger.new( $stderr )
82
+ DRbService.logger = logger
83
+ DRbService.logger.level = level
84
+
85
+ # Only do this when executing from a spec in TextMate
86
+ if ENV['HTML_LOGGING'] || (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/)
87
+ Thread.current['logger-output'] = []
88
+ logdevice = ArrayLogger.new( Thread.current['logger-output'] )
89
+ DRbService.logger = Logger.new( logdevice )
90
+ # DRbService.logger.level = level
91
+ DRbService.logger.formatter = DRbService::HtmlLogFormatter.new( logger )
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ ### Mock with Rspec
98
+ RSpec.configure do |c|
99
+ include DRbService::SpecHelpers,
100
+ DRbService::TestConstants
101
+
102
+ c.mock_with :rspec
103
+
104
+ c.filter_run_excluding( :ruby_1_9_only => true ) unless vvec( RUBY_VERSION ) >= vvec('1.9.0')
105
+ end
106
+
107
+ # vim: set nosta noet ts=4 sw=4:
108
+
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: drbservice
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.4
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Granger
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - ! '-----BEGIN CERTIFICATE-----
13
+
14
+ MIIDLDCCAhSgAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQwwCgYDVQQDDANnZWQx
15
+
16
+ FzAVBgoJkiaJk/IsZAEZFgdfYWVyaWVfMRMwEQYKCZImiZPyLGQBGRYDb3JnMB4X
17
+
18
+ DTEwMDkxNjE0NDg1MVoXDTExMDkxNjE0NDg1MVowPDEMMAoGA1UEAwwDZ2VkMRcw
19
+
20
+ FQYKCZImiZPyLGQBGRYHX2FlcmllXzETMBEGCgmSJomT8ixkARkWA29yZzCCASIw
21
+
22
+ DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALy//BFxC1f/cPSnwtJBWoFiFrir
23
+
24
+ h7RicI+joq/ocVXQqI4TDWPyF/8tqkvt+rD99X9qs2YeR8CU/YiIpLWrQOYST70J
25
+
26
+ vDn7Uvhb2muFVqq6+vobeTkILBEO6pionWDG8jSbo3qKm1RjKJDwg9p4wNKhPuu8
27
+
28
+ KGue/BFb67KflqyApPmPeb3Vdd9clspzqeFqp7cUBMEpFS6LWxy4Gk+qvFFJBJLB
29
+
30
+ BUHE/LZVJMVzfpC5Uq+QmY7B+FH/QqNndn3tOHgsPadLTNimuB1sCuL1a4z3Pepd
31
+
32
+ TeLBEFmEao5Dk3K/Q8o8vlbIB/jBDTUx6Djbgxw77909x6gI9doU4LD5XMcCAwEA
33
+
34
+ AaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJeoGkOr9l4B
35
+
36
+ +saMkW/ZXT4UeSvVMA0GCSqGSIb3DQEBBQUAA4IBAQBG2KObvYI2eHyyBUJSJ3jN
37
+
38
+ vEnU3d60znAXbrSd2qb3r1lY1EPDD3bcy0MggCfGdg3Xu54z21oqyIdk8uGtWBPL
39
+
40
+ HIa9EgfFGSUEgvcIvaYqiN4jTUtidfEFw+Ltjs8AP9gWgSIYS6Gr38V0WGFFNzIH
41
+
42
+ aOD2wmu9oo/RffW4hS/8GuvfMzcw7CQ355wFR4KB/nyze+EsZ1Y5DerCAagMVuDQ
43
+
44
+ U0BLmWDFzPGGWlPeQCrYHCr+AcJz+NRnaHCKLZdSKj/RHuTOt+gblRex8FAh8NeA
45
+
46
+ cmlhXe46pZNJgWKbxZah85jIjx95hR8vOI+NAM5iH9kOqK13DrxacTKPhqj5PjwF
47
+
48
+ -----END CERTIFICATE-----
49
+
50
+ '
51
+ date: 2011-08-29 00:00:00.000000000Z
52
+ dependencies:
53
+ - !ruby/object:Gem::Dependency
54
+ name: hoe-mercurial
55
+ requirement: &70270604159400 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ version: 1.2.1
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: *70270604159400
64
+ - !ruby/object:Gem::Dependency
65
+ name: hoe-highline
66
+ requirement: &70270604158900 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ~>
70
+ - !ruby/object:Gem::Version
71
+ version: 0.0.1
72
+ type: :development
73
+ prerelease: false
74
+ version_requirements: *70270604158900
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: &70270604158380 !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '2.6'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: *70270604158380
86
+ - !ruby/object:Gem::Dependency
87
+ name: hoe
88
+ requirement: &70270604157920 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '2.10'
94
+ type: :development
95
+ prerelease: false
96
+ version_requirements: *70270604157920
97
+ description: ! "DRbService is a framework we use at LAIKA for creating authenticated\nSSL-encrypted
98
+ DRb services that provide access to privileged operations\nwithout the need to give
99
+ shell access to everyone.\n\nThere are a few examples in the `examples/` directory
100
+ of the gem, which\nare stripped-down versions of the services we actually use.\n\nThe
101
+ current implementation is kind of a hack, but I intend to \neventually finish a
102
+ DRb protocol that does the same thing in a more\nelegant, less-hackish way, as well
103
+ as a tool that can generate \na new service along with support files for one of
104
+ several different \nruntime environments.\n\nIf you're curious, see the `drb/authsslprotocol.rb`
105
+ file for the \nprotocol. This will replace the current method-hiding code in \n`drbservice.rb`,
106
+ but existing services should be able to switch over\nquite easily. Or that's the
107
+ intention."
108
+ email:
109
+ - ged@FaerieMUD.org
110
+ executables: []
111
+ extensions: []
112
+ extra_rdoc_files:
113
+ - Manifest.txt
114
+ - README.rdoc
115
+ - History.rdoc
116
+ files:
117
+ - ChangeLog
118
+ - History.rdoc
119
+ - LICENSE
120
+ - Manifest.txt
121
+ - README.rdoc
122
+ - Rakefile
123
+ - examples/homedirservice.rb
124
+ - examples/rubyversion.rb
125
+ - lib/drb/authsslprotocol.rb
126
+ - lib/drbservice.rb
127
+ - lib/drbservice/ldapauth.rb
128
+ - lib/drbservice/passwordauth.rb
129
+ - lib/drbservice/utils.rb
130
+ - spec/drb/authsslprotocol_spec.rb
131
+ - spec/drbservice/ldapauth_spec.rb
132
+ - spec/drbservice/passwordauth_spec.rb
133
+ - spec/drbservice_spec.rb
134
+ - spec/lib/helpers.rb
135
+ - .gemtest
136
+ homepage: https://bitbucket.org/ged/drbservice
137
+ licenses:
138
+ - BSD
139
+ post_install_message: ! "\n\nThis library isn't really ready for production use yet,
140
+ but\nfeel free to experiment with it.\n\n\t"
141
+ rdoc_options:
142
+ - --main
143
+ - README.rdoc
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: 1.8.7
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubyforge_project: drbservice
160
+ rubygems_version: 1.8.8
161
+ signing_key:
162
+ specification_version: 3
163
+ summary: DRbService is a framework we use at LAIKA for creating authenticated SSL-encrypted
164
+ DRb services that provide access to privileged operations without the need to give
165
+ shell access to everyone
166
+ test_files: []