strelka 0.1.0 → 0.2.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 61bf9e26b28c2ed2b22d5b69924c2882ec985a54
4
+ data.tar.gz: 2c112fd724573c6bef02a4d24b8af0cf59af660e
5
+ SHA512:
6
+ metadata.gz: e00fbbbda4e9f473311fe1de9e5d5dd6f0297e15835bfc9b487b932e3e5047abcaa3344ce87f76d1fb2c6008736a23918743375818108165af3f3c483b15b6be
7
+ data.tar.gz: 50452d6a4e88827c1a42f562bd576a38c3d8565eb53e4ff0d243c0ec44e57420ebec3f0a200184e76aaaaff96add79504053e994d76cec0551f9686c03851707
checksums.yaml.gz.sig ADDED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/ChangeLog CHANGED
@@ -1,11 +1,143 @@
1
+ 2013-02-25 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * lib/strelka/paramvalidator.rb:
4
+ Fix API documentation
5
+ [5471a055ac2e] [tip]
6
+
7
+ * lib/strelka/app/restresources.rb:
8
+ Add some documentation to the REST Resources plugin
9
+ [bfbbcdf9ebe8]
10
+
11
+ * lib/strelka/paramvalidator.rb:
12
+ Remove accidentally-committed code.
13
+ [0875b2988d81]
14
+
15
+ 2013-02-22 Michael Granger <ged@FaerieMUD.org>
16
+
17
+ * lib/strelka/httprequest.rb, spec/strelka/httprequest_spec.rb:
18
+ Guard against malformed URI query
19
+ [2e56a22dac4a]
20
+
21
+ * lib/strelka/httpresponse.rb:
22
+ Whitespace fix
23
+ [ebe06cfc1695]
24
+
25
+ 2013-02-06 Michael Granger <ged@FaerieMUD.org>
26
+
27
+ * lib/strelka/app/auth.rb, spec/strelka/app/auth_spec.rb:
28
+ Fix multiple permission criteria in the auth plugin (fixes #2)
29
+ [d661773e0781] [github/master]
30
+
31
+ 2013-02-01 Michael Granger <ged@FaerieMUD.org>
32
+
33
+ * History.rdoc, lib/strelka/app/restresources.rb,
34
+ lib/strelka/paramvalidator.rb,
35
+ spec/strelka/app/restresources_spec.rb,
36
+ spec/strelka/paramvalidator_spec.rb:
37
+ Remove pending status from specs for multiple parameters support
38
+
39
+ This was apparently implemented (by me) in 49716850bd29. Fixes #1.
40
+ [2c41e18bc237]
41
+
42
+ 2013-01-29 Michael Granger <ged@FaerieMUD.org>
43
+
44
+ * lib/strelka/app/parameters.rb, lib/strelka/paramvalidator.rb,
45
+ spec/strelka/app/parameters_spec.rb,
46
+ spec/strelka/paramvalidator_spec.rb:
47
+ Add a paramvalidator constraint for JSON fields
48
+ [ac11b12f9366] [github/no-notes-auto-vivify]
49
+
50
+ 2013-01-25 Michael Granger <ged@FaerieMUD.org>
51
+
52
+ * lib/strelka/httprequest.rb, lib/strelka/httpresponse.rb,
53
+ spec/strelka/app/filters_spec.rb, spec/strelka/httprequest_spec.rb:
54
+ Remove HTTP{Request,Response}#notes multi-level autovivification
55
+ [0dc702f6eacc]
56
+
57
+ * bin/strelka:
58
+ Add support for --requires to bin/strelka
59
+ [c844fb419c83]
60
+
61
+ * lib/strelka.rb, lib/strelka/app/parameters.rb,
62
+ spec/strelka/app/parameters_spec.rb,
63
+ spec/strelka/app/restresources_spec.rb:
64
+ Allow declaration of parameters with block constraints
65
+ [afb6cec9add0]
66
+
67
+ * .rvm.gems, .tm_properties, Rakefile,
68
+ lib/strelka/app/restresources.rb, lib/strelka/paramvalidator.rb,
69
+ spec/strelka/app/restresources_spec.rb:
70
+ Modify the restresources app plugin for new versions of Sequel
71
+ [543c22d3050e]
72
+
73
+ 2013-01-24 Michael Granger <ged@FaerieMUD.org>
74
+
75
+ * lib/strelka/app/routing.rb, spec/strelka/app/routing_spec.rb:
76
+ Fix the routing plugin to super with a block like the other plugins
77
+ [9ac7a036f54a]
78
+
79
+ 2013-01-18 Michael Granger <ged@FaerieMUD.org>
80
+
81
+ * .pryrc:
82
+ Fix the .pryrc for recent versions of pry
83
+ [779190d1cc55]
84
+
85
+ 2013-01-09 Michael Granger <ged@FaerieMUD.org>
86
+
87
+ * .rvm.gems:
88
+ Update rvm gemset file
89
+ [2bedace701fe]
90
+
91
+ 2013-01-02 Michael Granger <ged@FaerieMUD.org>
92
+
93
+ * lib/strelka/paramvalidator.rb:
94
+ Remove spurious return in ParamValidator#[]=
95
+ [39c9459daa02]
96
+
97
+ 2013-01-02 Mahlon E. Smith <mahlon@martini.nu>
98
+
99
+ * lib/strelka/paramvalidator.rb, spec/strelka/paramvalidator_spec.rb:
100
+ Revalidate parameters when using the index operator.
101
+ [1d71e22f5f6e]
102
+
103
+ 2012-12-27 Michael Granger <ged@FaerieMUD.org>
104
+
105
+ * .hgtags:
106
+ Added tag v0.1.0 for changeset 943a0502da20
107
+ [43c3f7dddf0d]
108
+
109
+ * .hgsigs:
110
+ Added signature for changeset a6be71c3d94d
111
+ [943a0502da20] [v0.1.0]
112
+
113
+ * History.rdoc, lib/strelka.rb:
114
+ Bump the minor version, update history.
115
+ [a6be71c3d94d]
116
+
117
+ * spec/strelka/app_spec.rb:
118
+ Fix a spec for newer versions of Mongrel2
119
+ [ee1b3bcf1664]
120
+
1
121
  2012-11-02 Michael Granger <ged@FaerieMUD.org>
2
122
 
123
+ * bin/strelka:
124
+ Add --version to the command line tool
125
+ [4581498edfaa]
126
+
127
+ * lib/strelka/paramvalidator.rb:
128
+ Fix documentation
129
+ [6523f90b76ac]
130
+
131
+ * lib/strelka/app/parameters.rb:
132
+ Remove accidentally-committed require.
133
+ [e98f2b302f1d]
134
+
3
135
  * lib/strelka/app/parameters.rb, lib/strelka/app/restresources.rb,
4
136
  lib/strelka/mixins.rb, lib/strelka/paramvalidator.rb,
5
137
  lib/strelka/plugins.rb, spec/strelka/paramvalidator_spec.rb:
6
138
  Rewrite ParamValidator to simplify, remove dependency on
7
139
  FormValidator.
8
- [49716850bd29] [github/master, tip]
140
+ [49716850bd29]
9
141
 
10
142
  2012-11-02 Mahlon E. Smith <mahlon@martini.nu>
11
143
 
data/History.rdoc CHANGED
@@ -1,3 +1,18 @@
1
+ == v0.2.0 [2013-02-01] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ - Fixes for Ruby 2.0.
4
+ - Fix API documentation
5
+ - Guard against malformed URI query
6
+ - Fix multiple permission criteria in the auth plugin (fixes #2)
7
+ - Add a paramvalidator constraint for JSON fields
8
+ - Remove HTTP{Request,Response}#notes multi-level autovivification
9
+ - Add support for --requires to bin/strelka
10
+ - Allow declaration of parameters with block constraints
11
+ - Modify the restresources app plugin for new versions of Sequel
12
+ - Fix the routing plugin to super with a block like the other plugins
13
+ - Revalidate parameters when using ParamValidator#[].
14
+
15
+
1
16
  == v0.1.0 [2012-11-02] Michael Granger <ged@FaerieMUD.org>
2
17
 
3
18
  - Add --version to the command line tool
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ hoespec = Hoe.spec 'strelka' do
27
27
  self.dependency 'highline', '~> 1.6'
28
28
  self.dependency 'inversion', '~> 0.11'
29
29
  self.dependency 'loggability', '~> 0.4'
30
- self.dependency 'mongrel2', '~> 0.34'
30
+ self.dependency 'mongrel2', '~> 0.35'
31
31
  self.dependency 'pluginfactory', '~> 1.0'
32
32
  self.dependency 'sysexits', '~> 1.1'
33
33
  self.dependency 'trollop', '~> 2.0'
data/bin/strelka CHANGED
@@ -100,11 +100,14 @@ class Strelka::CLICommand
100
100
  collect {|name,lvl| name.to_s }.
101
101
  join( ', ' )
102
102
  command_table = self.make_command_table
103
+ commands = self.available_commands
103
104
 
104
105
  @option_parser = Trollop::Parser.new do
105
106
  banner "Manage Strelka apps"
106
107
  version( Strelka.version_string(true) )
107
108
 
109
+ stop_on( commands )
110
+
108
111
  text ''
109
112
  command_table.each {|line| text(line) }
110
113
  text ''
@@ -113,6 +116,8 @@ class Strelka::CLICommand
113
116
  opt :config, "Specify the config file to load.", :type => :string
114
117
  opt :datadir, "Override the Strelka data directory.", :type => :string,
115
118
  :short => :D
119
+ opt :requires, "Specify additional libraries to require.", :type => :strings,
120
+ :short => :r
116
121
  text ''
117
122
 
118
123
  text 'Other Options:'
@@ -259,6 +264,8 @@ class Strelka::CLICommand
259
264
  def discover_command( *args )
260
265
  header "Searching for Strelka applications..."
261
266
 
267
+ self.load_additional_requires
268
+
262
269
  paths = Strelka::App.discover_paths
263
270
  if paths.empty?
264
271
  message "None found."
@@ -298,6 +305,9 @@ class Strelka::CLICommand
298
305
  apps = Strelka::App.load( path )
299
306
  Strelka.load_config( self.options.config ) if self.options.config
300
307
  self.log.debug " loaded: %p" % [ apps ]
308
+
309
+ self.load_additional_requires
310
+
301
311
  apps.first.run
302
312
  end
303
313
  help :start, "Start a Strelka app"
@@ -325,6 +335,8 @@ class Strelka::CLICommand
325
335
  Strelka::App.load( apppath )
326
336
  end
327
337
 
338
+ self.load_additional_requires
339
+
328
340
  message " dumping config:"
329
341
  $stdout.puts Configurability.default_config.dump
330
342
  end
@@ -385,6 +397,17 @@ class Strelka::CLICommand
385
397
  end
386
398
 
387
399
 
400
+ ### Load any requires added to the command via the '-r' option.
401
+ def load_additional_requires
402
+ return unless self.options.requires
403
+
404
+ self.log.debug " loading additional requires: %p" % [ self.options.requires ]
405
+ self.options.requires.each do |lib|
406
+ require( lib )
407
+ end
408
+ end
409
+
410
+
388
411
  #
389
412
  # Utility methods
390
413
  #
data/lib/strelka.rb CHANGED
@@ -24,10 +24,10 @@ module Strelka
24
24
  log_as :strelka
25
25
 
26
26
  # Library version constant
27
- VERSION = '0.1.0'
27
+ VERSION = '0.2.0'
28
28
 
29
29
  # Version-control revision constant
30
- REVISION = %q$Revision: a6be71c3d94d $
30
+ REVISION = %q$Revision: afb6cec9add0 $
31
31
 
32
32
  require 'strelka/constants'
33
33
  require 'strelka/exceptions'
@@ -286,8 +286,8 @@ module Strelka::App::Auth
286
286
  @positive_auth_criteria = {}
287
287
  @negative_auth_criteria = {}
288
288
 
289
- @positive_perms_criteria = {}
290
- @negative_perms_criteria = {}
289
+ @positive_perms_criteria = []
290
+ @negative_perms_criteria = []
291
291
 
292
292
 
293
293
  ##
@@ -409,17 +409,19 @@ module Strelka::App::Auth
409
409
  ### +pattern+. The +pattern+ is either a String or a Regexp which is tested against
410
410
  ### {the request's #app_path}[rdoc-ref:Strelka::HTTPRequest#app_path]. The +perms+ should
411
411
  ### be Symbols which indicate a set of permission types that must have been granted
412
- ### in order to carry out the request. The block should also return one or more
413
- ### permissions (as Symbols) if the request should undergo authorization, or nil
414
- ### if it should not.
412
+ ### in order to carry out the request. The block, if given, should evaluate to +true+
413
+ ### if the request should undergo authorization, or false if it should not.
415
414
  ### *NOTE:* using this declaration inverts the default security policy of
416
415
  ### restricting access to all requests.
417
416
  def require_perms_for( pattern=nil, *perms, &block )
418
- block ||= Proc.new { perms }
417
+ block ||= Proc.new {
418
+ self.log.debug " using default perms: %p" % [ perms ]
419
+ true
420
+ }
419
421
 
420
422
  pattern.gsub!( %r{^/+|/+$}, '' ) if pattern.respond_to?( :gsub! )
421
423
  self.log.debug " adding require_perms (%p) for %p" % [ perms, pattern ]
422
- self.positive_perms_criteria[ pattern ] = block
424
+ self.positive_perms_criteria << [ pattern, block, perms ]
423
425
  end
424
426
 
425
427
 
@@ -435,7 +437,7 @@ module Strelka::App::Auth
435
437
 
436
438
  pattern.gsub!( %r{^/+|/+$}, '' ) if pattern.respond_to?( :gsub! )
437
439
  self.log.debug " adding no_auth for %p" % [ pattern ]
438
- self.negative_perms_criteria[ pattern ] = block
440
+ self.negative_perms_criteria << [ pattern, block ]
439
441
  end
440
442
 
441
443
  end # module ClassMethods
@@ -502,7 +504,7 @@ module Strelka::App::Auth
502
504
  ### +nil+ if the request didn't require authentication.
503
505
  def provide_authorization( credentials, request )
504
506
  provider = self.auth_provider
505
- perms = self.required_perms_for( request )
507
+ perms = self.perms_required_for( request )
506
508
  self.log.debug "Perms required: %p" % [ perms ]
507
509
  provider.authorize( credentials, request, perms ) unless perms.empty?
508
510
  end
@@ -550,7 +552,7 @@ module Strelka::App::Auth
550
552
 
551
553
  ### Gather the set of permissions that apply to the specified +request+ and return
552
554
  ### them.
553
- def required_perms_for( request )
555
+ def perms_required_for( request )
554
556
  self.log.debug "Gathering required perms for: %s %s" % [ request.verb, request.app_path ]
555
557
 
556
558
  # Return the empty set if any negative auth criteria match
@@ -565,6 +567,7 @@ module Strelka::App::Auth
565
567
  # Apply positive auth criteria
566
568
  return self.union_positive_perms_criteria( request )
567
569
  end
570
+ alias_method :required_perms_for, :perms_required_for
568
571
 
569
572
 
570
573
  #########
@@ -617,8 +620,8 @@ module Strelka::App::Auth
617
620
  perms = []
618
621
 
619
622
  self.log.debug " positive perm criteria: %p" % [ self.class.positive_perms_criteria ]
620
- self.class.positive_perms_criteria.each do |pattern, block|
621
- newperms = self.request_matches_criteria( request, pattern, &block ) or next
623
+ self.class.positive_perms_criteria.each do |pattern, block, newperms|
624
+ next unless self.request_matches_criteria( request, pattern, &block )
622
625
  newperms = Array( newperms )
623
626
  newperms << self.default_permission if newperms.empty?
624
627
 
@@ -93,10 +93,16 @@ module Strelka::App::Parameters
93
93
  ### Declare a parameter with the specified +name+ that will be validated using the given
94
94
  ### +constraint+. The +constraint+ can be any of the types supported by
95
95
  ### Strelka::ParamValidator.
96
- def param( name, *args )
96
+ def param( name, *args, &block )
97
97
  self.log.debug "New param %p" % [ name ]
98
98
  self.log.debug " adding parameter %p to %p" % [ name, self.paramvalidator ]
99
- self.paramvalidator.add( name, *args )
99
+ self.paramvalidator.add( name, *args, &block )
100
+ end
101
+
102
+
103
+ ### Add a 'builtin' constraint type with the specified +name+.
104
+ def add_param_type( name, &block )
105
+
100
106
  end
101
107
 
102
108
 
@@ -43,14 +43,28 @@ require 'strelka/app' unless defined?( Strelka::App )
43
43
  # parameters[Strelka::App::Parameters] plugins, and will load them
44
44
  # automatically if they haven't been already.
45
45
  #
46
- # Stuff left to do:
46
+ # Goals:
47
+ #
48
+ # [√] Composite resources generated from associations
49
+ # [ ] Honor If-unmodified-since and If-match headers
50
+ # [ ] Caching support (ETag, If-modified-since)
51
+ # [ ] Means of tailoring responses for requests for which the response
52
+ # isn't clearly specified in the RFC (DELETE /resource)
53
+ # [ ] Sequel plugin for adding links to serialized representations
54
+ #
55
+ # == Caveats / Known Problems
56
+ #
57
+ # * Dataset methods declared using the 'subset' declaration don't allow the
58
+ # introspection necessary for automatically building routes, so you have
59
+ # to declare them as normal methods in a dataset module:
60
+ #
61
+ # dataset_module do
62
+ # def by_name( string )
63
+ # filter(:name => string)
64
+ # end
65
+ # end
66
+ #
47
67
  #
48
- # * Composite resources generated from associations
49
- # * Honor If-unmodified-since and If-match headers
50
- # * Caching support (ETag, If-modified-since)
51
- # * Means of tailoring responses for requests for which the response
52
- # isn't clearly specified in the RFC (DELETE /resource)
53
- # * Sequel plugin for adding links to serialized representations
54
68
  module Strelka::App::RestResources
55
69
  extend Strelka::Plugin
56
70
 
@@ -238,7 +252,7 @@ module Strelka::App::RestResources
238
252
  # Add validations for limit, offset, and order parameters
239
253
  req.params.add :limit, :integer
240
254
  req.params.add :offset, :integer
241
- req.params.add :order, colre
255
+ req.params.add :order, colre, :multiple
242
256
 
243
257
  finish_with( HTTP::BAD_REQUEST, req.params.error_messages.join("\n") ) unless
244
258
  req.params.okay?
@@ -444,23 +458,14 @@ module Strelka::App::RestResources
444
458
  ### Add routes for any associations +rsrcobj+ has as composite resources.
445
459
  def add_composite_resource_handlers( route_prefix, rsrcobj, options )
446
460
 
447
- # Add a method for each dataset method that only has a single argument
448
- # :TODO: Support multiple args? (customers/by_city_state/{city}/{state})
449
- rsrcobj.dataset_methods.each do |name, proc|
450
- if proc.parameters.length > 1
451
- self.log.debug " skipping dataset method %p: more than 1 argument" % [ name ]
452
- next
453
- end
461
+ # Add methods declared by (user-declared) dataset modules.
462
+ ds_mods = rsrcobj.dataset_method_modules.select do |mod|
463
+ mod.is_a?( Sequel::Model::DatasetModule ) || mod.name.nil?
464
+ end.each
454
465
 
455
- # Use the name of the dataset block's parameter
456
- # :TODO: Handle the case where the parameter name doesn't match a column
457
- # or a parameter-type more gracefully.
458
- unless proc.parameters.empty?
459
- param = proc.parameters.first[1]
460
- route = "%s/%s/:%s" % [ route_prefix, name, param ]
461
- self.log.debug " route for dataset method %s: %s" % [ name, route ]
462
- self.add_dataset_read_handler( route, rsrcobj, name, param, options )
463
- end
466
+ ds_mods.each do |mod|
467
+ self.log.debug " adding dataset methods declared by %p" % [ mod ]
468
+ self.add_dataset_module_routes( route_prefix, rsrcobj, mod, options )
464
469
  end
465
470
 
466
471
  # Add composite service routes for each association
@@ -476,14 +481,44 @@ module Strelka::App::RestResources
476
481
  end
477
482
 
478
483
 
484
+ ### Add routes for the methods declared in the dataset module +mod+.
485
+ def add_dataset_module_routes( route_prefix, rsrcobj, mod, options )
486
+ self.log.debug "Adding dataset module routes."
487
+
488
+ mod.instance_methods.each do |methname|
489
+ meth = mod.instance_method( methname )
490
+ self.log.debug " instance_method: %p" % [ meth ]
491
+
492
+ route = "%s/%s" % [ route_prefix, methname ]
493
+ params = []
494
+
495
+ # Add a route placeholder for each parameter of the dataset method
496
+ meth.parameters.each do |type, param|
497
+ self.log.debug " adding parameter placeholder to the route for %s parameter %p" %
498
+ [ type, param ]
499
+ route << "/:%s" % [ param ]
500
+ params << param
501
+ end
502
+
503
+ self.log.debug " route for dataset method %s: %s" % [ methname, route ]
504
+ self.add_dataset_read_handler( route, rsrcobj, methname, params, options )
505
+ end
506
+
507
+ self.log.debug " done with dataset module routes."
508
+ end
509
+
510
+
479
511
  ### Add a GET route for the dataset method +dsname+ for the given +rsrcobj+ at the
480
512
  ### given +path+.
481
- def add_dataset_read_handler( path, rsrcobj, dsname, param, options )
513
+ def add_dataset_read_handler( path, rsrcobj, dsname, params, options )
482
514
  self.log.debug "Adding dataset method read handler: %s" % [ path ]
483
515
 
484
- config = rsrcobj.db_schema[ param ] or
485
- raise ArgumentError, "no such column %p for %p" % [ param, rsrcobj ]
486
- param( param, config[:type] )
516
+ # Only need to declare a parameter if the dataset method has one
517
+ params.each do |paramname|
518
+ config = rsrcobj.db_schema[ paramname ] or
519
+ raise ArgumentError, "no such column %p for %p" % [ paramname, rsrcobj ]
520
+ param( paramname, config[:type] )
521
+ end
487
522
 
488
523
  self.add_route( :GET, path, options ) do |req|
489
524
  self.log.debug "Resource dataset GET request for dataset %s on %p" %
@@ -491,10 +526,9 @@ module Strelka::App::RestResources
491
526
  finish_with( HTTP::BAD_REQUEST, req.params.error_messages.join("\n") ) unless
492
527
  req.params.okay?
493
528
 
494
- # Get the parameter and make the dataset
495
- res = req.response
496
- arg = req.params[ param ]
497
- dataset = rsrcobj.send( dsname, arg )
529
+ # Get the dataset, either with a parameter or without one
530
+ args = req.params.values_at( *params )
531
+ dataset = rsrcobj.send( dsname, *args )
498
532
  self.log.debug " dataset is: %p" % [ dataset ]
499
533
 
500
534
  # Apply offset and limit if they're present
@@ -507,6 +541,7 @@ module Strelka::App::RestResources
507
541
  # Fetch and return the records as JSON or YAML
508
542
  # :TODO: Handle other mediatypes
509
543
  self.log.debug " returning collection: %s" % [ dataset.sql ]
544
+ res = req.response
510
545
  res.for( :json, :yaml ) { dataset.all }
511
546
  res.for( :text ) { Sequel::PrettyTable.string(dataset) }
512
547