drbservice 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require 'digest/sha2'
5
+ require 'drbservice'
6
+
7
+ # An authentication strategy for DRbService -- set a password via a
8
+ # class method.
9
+ module DRbService::PasswordAuthentication
10
+
11
+ ### Methods added to including classes when PasswordAuthentication is
12
+ ### mixed in.
13
+ module ClassMethods
14
+
15
+ # The SHA2 digest of the service password
16
+ attr_accessor :password_digest
17
+
18
+ ### Set a password for the service. If you don't specify a password, even guarded
19
+ ### methods can be accessed. With a password set, the remote side can still call
20
+ ### unguarded methods, but all other methods will be hidden.
21
+ def service_password( password )
22
+ self.password_digest = Digest::SHA2.hexdigest( password )
23
+ DRbService.log.debug "Setting encrypted password for %p to "
24
+ end
25
+
26
+ end # module ClassMethods
27
+
28
+
29
+ ### Overridden mixin callback -- add the ClassMethods to the including class
30
+ def self::included( klass )
31
+ super
32
+ klass.extend( ClassMethods )
33
+ end
34
+
35
+
36
+ ### Authenticate using the specified +password+, calling the provided block if
37
+ ### authentication succeeds. Raises a SecurityError if authentication fails. If
38
+ ### no password is set, the block is called regardless of what the +password+ is.
39
+ def authenticate( password )
40
+ if digest = self.class.password_digest
41
+ if Digest::SHA2.hexdigest( password ) == digest
42
+ self.log.info "authentication successful"
43
+ @authenticated = true
44
+ yield
45
+ else
46
+ super
47
+ end
48
+ else
49
+ self.log.error "no password set -- authentication will always fail"
50
+ super
51
+ end
52
+ ensure
53
+ @authenticated = false
54
+ end
55
+
56
+ end # DRbService::PasswordAuthentication
57
+
58
+
@@ -0,0 +1,426 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'logger'
4
+ require 'erb'
5
+ require 'bigdecimal'
6
+ require 'date'
7
+
8
+ require 'drbservice'
9
+
10
+
11
+ class DRbService
12
+
13
+ ### A collection of ANSI color utility functions
14
+ module ANSIColorUtilities
15
+
16
+ # Set some ANSI escape code constants (Shamelessly stolen from Perl's
17
+ # Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
18
+ ANSI_ATTRIBUTES = {
19
+ 'clear' => 0,
20
+ 'reset' => 0,
21
+ 'bold' => 1,
22
+ 'dark' => 2,
23
+ 'underline' => 4,
24
+ 'underscore' => 4,
25
+ 'blink' => 5,
26
+ 'reverse' => 7,
27
+ 'concealed' => 8,
28
+
29
+ 'black' => 30, 'on_black' => 40,
30
+ 'red' => 31, 'on_red' => 41,
31
+ 'green' => 32, 'on_green' => 42,
32
+ 'yellow' => 33, 'on_yellow' => 43,
33
+ 'blue' => 34, 'on_blue' => 44,
34
+ 'magenta' => 35, 'on_magenta' => 45,
35
+ 'cyan' => 36, 'on_cyan' => 46,
36
+ 'white' => 37, 'on_white' => 47
37
+ }
38
+
39
+ ###############
40
+ module_function
41
+ ###############
42
+
43
+ ### Create a string that contains the ANSI codes specified and return it
44
+ def ansi_code( *attributes )
45
+ attributes.flatten!
46
+ attributes.collect! {|at| at.to_s }
47
+ return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
48
+ attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
49
+
50
+ if attributes.empty?
51
+ return ''
52
+ else
53
+ return "\e[%sm" % attributes
54
+ end
55
+ end
56
+
57
+
58
+ ### Colorize the given +string+ with the specified +attributes+ and return it, handling
59
+ ### line-endings, color reset, etc.
60
+ def colorize( *args )
61
+ string = ''
62
+
63
+ if block_given?
64
+ string = yield
65
+ else
66
+ string = args.shift
67
+ end
68
+
69
+ ending = string[/(\s)$/] || ''
70
+ string = string.rstrip
71
+
72
+ return ansi_code( args.flatten ) + string + ansi_code( 'reset' ) + ending
73
+ end
74
+
75
+ end # module ANSIColorUtilities
76
+
77
+
78
+ #
79
+ # A alternate formatter for Logger instances.
80
+ #
81
+ # == Usage
82
+ #
83
+ # require 'drbservice/utils'
84
+ # DRbService.logger.formatter = DRbService::LogFormatter.new( DRbService.logger )
85
+ #
86
+ # == Version
87
+ #
88
+ # $Id: utils.rb,v 87bc5aa9e2be 2011/08/29 21:05:42 ged $
89
+ #
90
+ # == Authors
91
+ #
92
+ # * Michael Granger <ged@FaerieMUD.org>
93
+ #
94
+ # :include: LICENSE
95
+ #
96
+ #--
97
+ #
98
+ # Please see the file LICENSE in the 'docs' directory for licensing details.
99
+ #
100
+ class LogFormatter < Logger::Formatter
101
+
102
+ # The format to output unless debugging is turned on
103
+ DEFAULT_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"
104
+
105
+ # The format to output if debugging is turned on
106
+ DEFAULT_DEBUG_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"
107
+
108
+
109
+ ### Initialize the formatter with a reference to the logger so it can check for log level.
110
+ def initialize( logger, format=DEFAULT_FORMAT, debug=DEFAULT_DEBUG_FORMAT ) # :notnew:
111
+ @logger = logger
112
+ @format = format
113
+ @debug_format = debug
114
+
115
+ super()
116
+ end
117
+
118
+ ######
119
+ public
120
+ ######
121
+
122
+ # The Logger object associated with the formatter
123
+ attr_accessor :logger
124
+
125
+ # The logging format string
126
+ attr_accessor :format
127
+
128
+ # The logging format string that's used when outputting in debug mode
129
+ attr_accessor :debug_format
130
+
131
+
132
+ ### Log using either the DEBUG_FORMAT if the associated logger is at ::DEBUG level or
133
+ ### using FORMAT if it's anything less verbose.
134
+ def call( severity, time, progname, msg )
135
+ args = [
136
+ time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
137
+ time.usec, # %2$d
138
+ Process.pid, # %3$d
139
+ Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
140
+ severity, # %5$s
141
+ progname, # %6$s
142
+ msg # %7$s
143
+ ]
144
+
145
+ if @logger.level == Logger::DEBUG
146
+ return self.debug_format % args
147
+ else
148
+ return self.format % args
149
+ end
150
+ end
151
+ end # class LogFormatter
152
+
153
+
154
+ #
155
+ # A ANSI-colorized formatter for Logger instances.
156
+ #
157
+ # == Usage
158
+ #
159
+ # require 'drbservice/utils'
160
+ # DRbService.logger.formatter = DRbService::ColorLogFormatter.new( DRbService.logger )
161
+ #
162
+ # == Version
163
+ #
164
+ # $Id: utils.rb,v 87bc5aa9e2be 2011/08/29 21:05:42 ged $
165
+ #
166
+ # == Authors
167
+ #
168
+ # * Michael Granger <ged@FaerieMUD.org>
169
+ #
170
+ # :include: LICENSE
171
+ #
172
+ #--
173
+ #
174
+ # Please see the file LICENSE in the 'docs' directory for licensing details.
175
+ #
176
+ class ColorLogFormatter < Logger::Formatter
177
+ extend DRbService::ANSIColorUtilities
178
+
179
+ # Color settings
180
+ LEVEL_FORMATS = {
181
+ :debug => colorize( :bold, :black ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"},
182
+ :info => colorize( :normal ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
183
+ :warn => colorize( :bold, :yellow ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
184
+ :error => colorize( :red ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
185
+ :fatal => colorize( :bold, :red, :on_white ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
186
+ }
187
+
188
+
189
+ ### Initialize the formatter with a reference to the logger so it can check for log level.
190
+ def initialize( logger, settings={} ) # :notnew:
191
+ settings = LEVEL_FORMATS.merge( settings )
192
+
193
+ @logger = logger
194
+ @settings = settings
195
+
196
+ super()
197
+ end
198
+
199
+ ######
200
+ public
201
+ ######
202
+
203
+ # The Logger object associated with the formatter
204
+ attr_accessor :logger
205
+
206
+ # The formats, by level
207
+ attr_accessor :settings
208
+
209
+
210
+ ### Log using the format associated with the severity
211
+ def call( severity, time, progname, msg )
212
+ args = [
213
+ time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
214
+ time.usec, # %2$d
215
+ Process.pid, # %3$d
216
+ Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
217
+ severity, # %5$s
218
+ progname, # %6$s
219
+ msg # %7$s
220
+ ]
221
+
222
+ return self.settings[ severity.downcase.to_sym ] % args
223
+ end
224
+ end # class LogFormatter
225
+
226
+
227
+ #
228
+ # An alternate formatter for Logger instances that outputs +div+ HTML
229
+ # fragments.
230
+ #
231
+ # == Usage
232
+ #
233
+ # require 'drbservice/utils'
234
+ # DRbService.logger.formatter = DRbService::HtmlLogFormatter.new( DRbService.logger )
235
+ #
236
+ # == Version
237
+ #
238
+ # $Id: utils.rb,v 87bc5aa9e2be 2011/08/29 21:05:42 ged $
239
+ #
240
+ # == Authors
241
+ #
242
+ # * Michael Granger <ged@FaerieMUD.org>
243
+ #
244
+ # :include: LICENSE
245
+ #
246
+ #--
247
+ #
248
+ # Please see the file LICENSE in the 'docs' directory for licensing details.
249
+ #
250
+ class HtmlLogFormatter < Logger::Formatter
251
+ include ERB::Util # for html_escape()
252
+
253
+ # The default HTML fragment that'll be used as the template for each log message.
254
+ HTML_LOG_FORMAT = %q{
255
+ <div class="log-message %5$s">
256
+ <span class="log-time">%1$s.%2$06d</span>
257
+ [
258
+ <span class="log-pid">%3$d</span>
259
+ /
260
+ <span class="log-tid">%4$s</span>
261
+ ]
262
+ <span class="log-level">%5$s</span>
263
+ :
264
+ <span class="log-name">%6$s</span>
265
+ <span class="log-message-text">%7$s</span>
266
+ </div>
267
+ }
268
+
269
+ ### Override the logging formats with ones that generate HTML fragments
270
+ def initialize( logger, format=HTML_LOG_FORMAT ) # :notnew:
271
+ @logger = logger
272
+ @format = format
273
+ super()
274
+ end
275
+
276
+
277
+ ######
278
+ public
279
+ ######
280
+
281
+ # The HTML fragment that will be used as a format() string for the log
282
+ attr_accessor :format
283
+
284
+
285
+ ### Return a log message composed out of the arguments formatted using the
286
+ ### formatter's format string
287
+ def call( severity, time, progname, msg )
288
+ args = [
289
+ time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
290
+ time.usec, # %2$d
291
+ Process.pid, # %3$d
292
+ Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
293
+ severity.downcase, # %5$s
294
+ progname, # %6$s
295
+ html_escape( msg ).gsub(/\n/, '<br />') # %7$s
296
+ ]
297
+
298
+ return self.format % args
299
+ end
300
+
301
+ end # class HtmlLogFormatter
302
+
303
+
304
+ ### DRbService logging methods and data.
305
+ module Logging
306
+
307
+ # Mapping of symbols to logging levels
308
+ LEVEL = {
309
+ :debug => Logger::DEBUG,
310
+ :info => Logger::INFO,
311
+ :warn => Logger::WARN,
312
+ :error => Logger::ERROR,
313
+ :fatal => Logger::FATAL,
314
+ }
315
+
316
+
317
+ ### Inclusion callback: Add logging methods and instance variables to
318
+ ### the Module +mod+.
319
+ def self::included( mod )
320
+
321
+ # Logging class instance variables
322
+ default_logger = Logger.new( $stderr )
323
+ default_logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
324
+ formatter = DRbService::LogFormatter.new( default_logger )
325
+ default_logger.formatter = formatter
326
+
327
+ mod.instance_variable_set( :@default_logger, default_logger )
328
+ mod.instance_variable_set( :@default_log_formatter, formatter )
329
+ mod.instance_variable_set( :@logger, default_logger )
330
+
331
+ # Accessors
332
+ class << mod
333
+ include DRbService::Logging::ClassMethods
334
+
335
+ # The log formatter that will be used when the logging subsystem is reset
336
+ attr_accessor :default_log_formatter
337
+
338
+ # The logger that will be used when the logging subsystem is reset
339
+ attr_accessor :default_logger
340
+
341
+ # The logger that's currently in effect
342
+ attr_accessor :logger
343
+ alias_method :log, :logger
344
+ alias_method :log=, :logger=
345
+ end
346
+
347
+ end
348
+
349
+
350
+ ### A collection of class methods that will get added as class method to anything that
351
+ ### includes Logging.
352
+ module ClassMethods
353
+
354
+ ### Reset the global logger object to the default
355
+ def reset_logger
356
+ self.logger = self.default_logger
357
+ self.logger.level = Logger::WARN
358
+ self.logger.formatter = self.default_log_formatter
359
+ end
360
+
361
+
362
+ ### Returns +true+ if the global logger has not been set to something other than
363
+ ### the default one.
364
+ def using_default_logger?
365
+ return self.logger == self.default_logger
366
+ end
367
+
368
+
369
+ ### Return the library's version string
370
+ def version_string( include_buildnum=false )
371
+ vstring = "%s %s" % [ self.name, self.const_get(:VERSION) ]
372
+ if include_buildnum
373
+ rev = self.const_get(:REVISION)[/: ([[:xdigit:]]+)/, 1] rescue '0'
374
+ vstring << " (build %s)" % [ rev ]
375
+ end
376
+ return vstring
377
+ end
378
+
379
+ end # module ClassMethods
380
+
381
+
382
+ ### A logging proxy class that wraps calls to the logger into calls that include
383
+ ### the name of the calling class.
384
+ class ClassNameProxy # :nodoc:
385
+
386
+ ### Create a new proxy for the given +klass+.
387
+ def initialize( klass, force_debug=false )
388
+ @classname = klass.name
389
+ @force_debug = force_debug
390
+ end
391
+
392
+ ### Delegate calls the global logger with the class name as the 'progname'
393
+ ### argument.
394
+ def method_missing( sym, msg=nil, &block )
395
+ return super unless LEVEL.key?( sym )
396
+ sym = :debug if @force_debug
397
+ DRbService.logger.add( LEVEL[sym], msg, @classname, &block )
398
+ end
399
+ end # ClassNameProxy
400
+
401
+
402
+ ### Copy constructor -- clear the original's log proxy.
403
+ def initialize_copy( original )
404
+ @log_proxy = @log_debug_proxy = nil
405
+ super
406
+ end
407
+
408
+
409
+ ### Return the proxied logger.
410
+ def log
411
+ @log_proxy ||= ClassNameProxy.new( self.class )
412
+ end
413
+
414
+
415
+ ### Return a proxied "debug" logger that ignores other level specification.
416
+ def log_debug
417
+ @log_debug_proxy ||= ClassNameProxy.new( self.class, true )
418
+ end
419
+
420
+ end # module Logging
421
+
422
+
423
+ end # class DRbService
424
+
425
+ # vim: set nosta noet ts=4 sw=4:
426
+