strelka 0.0.1.pre177 → 0.0.1.pre184
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/ChangeLog +111 -16
- data/Manifest.txt +8 -8
- data/Rakefile +3 -3
- data/bin/leash +51 -28
- data/examples/{auth-demo.rb → apps/auth-demo} +3 -3
- data/examples/{auth-demo2.rb → apps/auth-demo2} +0 -0
- data/examples/{sessions-demo.rb → apps/sessions-demo} +0 -0
- data/examples/config.yml +5 -1
- data/examples/{examples.css → static/examples.css} +0 -0
- data/examples/{examples.html → static/examples.html} +0 -0
- data/examples/{auth-form.tmpl → templates/auth-form.tmpl} +0 -0
- data/examples/{auth-success.tmpl → templates/auth-success.tmpl} +0 -0
- data/examples/{layout.tmpl → templates/layout.tmpl} +0 -0
- data/lib/strelka/app/auth.rb +18 -8
- data/lib/strelka/app/errors.rb +3 -2
- data/lib/strelka/app/filters.rb +2 -0
- data/lib/strelka/app/negotiation.rb +2 -0
- data/lib/strelka/app/parameters.rb +18 -140
- data/lib/strelka/app/plugins.rb +84 -26
- data/lib/strelka/app/restresources.rb +26 -18
- data/lib/strelka/app/routing.rb +8 -2
- data/lib/strelka/app/sessions.rb +7 -0
- data/lib/strelka/app/templating.rb +1 -1
- data/lib/strelka/app.rb +25 -1
- data/lib/strelka/constants.rb +3 -1
- data/lib/strelka/paramvalidator.rb +251 -74
- data/lib/strelka/session/default.rb +1 -1
- data/spec/strelka/app/auth_spec.rb +37 -0
- data/spec/strelka/app/errors_spec.rb +0 -2
- data/spec/strelka/app/filters_spec.rb +1 -1
- data/spec/strelka/app/parameters_spec.rb +4 -92
- data/spec/strelka/app/plugins_spec.rb +64 -2
- data/spec/strelka/app/restresources_spec.rb +3 -0
- data/spec/strelka/app/routing_spec.rb +5 -5
- data/spec/strelka/paramvalidator_spec.rb +294 -385
- data.tar.gz.sig +0 -0
- metadata +126 -46
- metadata.gz.sig +0 -0
@@ -20,49 +20,43 @@ require 'strelka/app' unless defined?( Strelka::App )
|
|
20
20
|
#
|
21
21
|
# require 'strelka/app/formvalidator'
|
22
22
|
#
|
23
|
-
# # Profile specifies validation criteria for input
|
24
|
-
# profile = {
|
25
|
-
# :required => :name,
|
26
|
-
# :optional => [:email, :description],
|
27
|
-
# :filters => [:strip, :squeeze],
|
28
|
-
# :untaint_all_constraints => true,
|
29
|
-
# :descriptions => {
|
30
|
-
# :email => "Customer Email",
|
31
|
-
# :description => "Issue Description",
|
32
|
-
# :name => "Customer Name",
|
33
|
-
# },
|
34
|
-
# :constraints => {
|
35
|
-
# :email => :email,
|
36
|
-
# :name => /^[\x20-\x7f]+$/,
|
37
|
-
# :description => /^[\x20-\x7f]+$/,
|
38
|
-
# },
|
39
|
-
# }
|
40
|
-
#
|
41
|
-
# # Create a validator object and pass in a hash of request parameters and the
|
42
|
-
# # profile hash.
|
43
23
|
# validator = Strelka::ParamValidator.new
|
44
|
-
# validator.validate( req_params, profile )
|
45
24
|
#
|
46
|
-
# #
|
25
|
+
# # Add validation criteria for input parameters
|
26
|
+
# validator.add( :name, /^(?<lastname>\S+), (?<firstname>\S+)$/, "Customer Name" )
|
27
|
+
# validator.add( :email, "Customer Email" )
|
28
|
+
# validator.add( :feedback, :printable, "Customer Feedback" )
|
29
|
+
#
|
30
|
+
# # Untaint all parameter values which match their constraints
|
31
|
+
# validate.untaint_all_constraints = true
|
32
|
+
#
|
33
|
+
# # Now pass in tainted values in a hash (e.g., from an HTML form)
|
34
|
+
# validator.validate( req.params )
|
35
|
+
#
|
36
|
+
# # Now if there weren't any errors, use some form values to fill out the
|
37
|
+
# # success page template
|
47
38
|
# if validator.okay?
|
48
|
-
#
|
39
|
+
# tmpl = template :success
|
40
|
+
# tmpl.firstname = validator[:name][:firstname]
|
41
|
+
# tmpl.lastname = validator[:name][:lastname]
|
42
|
+
# tmpl.email = validator[:email]
|
43
|
+
# tmpl.feedback = validator[:feedback]
|
44
|
+
# return tmpl
|
49
45
|
#
|
50
46
|
# # Otherwise fill in the error template with auto-generated error messages
|
51
47
|
# # and return that instead.
|
52
48
|
# else
|
53
|
-
#
|
54
|
-
#
|
49
|
+
# tmpl = template :feedback_form
|
50
|
+
# tmpl.errors = validator.error_messages
|
51
|
+
# return tmpl
|
55
52
|
# end
|
56
53
|
#
|
57
54
|
class Strelka::ParamValidator < ::FormValidator
|
58
55
|
extend Forwardable
|
59
56
|
include Strelka::Loggable
|
60
57
|
|
61
|
-
|
62
|
-
|
63
|
-
DEFAULT_PROFILE = {
|
64
|
-
:descriptions => {},
|
65
|
-
}
|
58
|
+
# Options that are passed as Symbols to .param
|
59
|
+
FLAGS = [ :required, :untaint ]
|
66
60
|
|
67
61
|
#
|
68
62
|
# RFC822 Email Address Regex
|
@@ -110,6 +104,7 @@ class Strelka::ParamValidator < ::FormValidator
|
|
110
104
|
|
111
105
|
# The Hash of builtin constraints that are validated against a regular
|
112
106
|
# expression.
|
107
|
+
# :TODO: Document that these are the built-in constraints that can be used in a route
|
113
108
|
BUILTIN_CONSTRAINT_PATTERNS = {
|
114
109
|
:boolean => /^(?<boolean>t(?:rue)?|y(?:es)?|[10]|no?|f(?:alse)?)$/i,
|
115
110
|
:integer => /^(?<integer>[\-\+]?\d+)$/,
|
@@ -124,6 +119,11 @@ class Strelka::ParamValidator < ::FormValidator
|
|
124
119
|
:uri => /^(?<uri>#{URI::URI_REF})$/,
|
125
120
|
}
|
126
121
|
|
122
|
+
# Pattern to use to strip binding operators from parameter patterns so they
|
123
|
+
# can be used in the middle of routing Regexps.
|
124
|
+
PARAMETER_PATTERN_STRIP_RE = Regexp.union( '^', '$', '\\A', '\\z', '\\Z' )
|
125
|
+
|
126
|
+
|
127
127
|
|
128
128
|
### Return a Regex for the built-in constraint associated with the given +name+. If
|
129
129
|
### the builtin constraint is not pattern-based, or there is no such constraint,
|
@@ -138,11 +138,19 @@ class Strelka::ParamValidator < ::FormValidator
|
|
138
138
|
#################################################################
|
139
139
|
|
140
140
|
### Create a new Strelka::ParamValidator object.
|
141
|
-
def initialize( profile
|
141
|
+
def initialize( profile={} )
|
142
|
+
@profile = {
|
143
|
+
descriptions: {},
|
144
|
+
required: [],
|
145
|
+
optional: [],
|
146
|
+
descriptions: {},
|
147
|
+
constraints: {},
|
148
|
+
untaint_constraint_fields: [],
|
149
|
+
}.merge( profile )
|
150
|
+
|
142
151
|
@form = {}
|
143
152
|
@raw_form = {}
|
144
|
-
@
|
145
|
-
@invalid_fields = []
|
153
|
+
@invalid_fields = {}
|
146
154
|
@missing_fields = []
|
147
155
|
@unknown_fields = []
|
148
156
|
@required_fields = []
|
@@ -150,18 +158,22 @@ class Strelka::ParamValidator < ::FormValidator
|
|
150
158
|
@optional_fields = []
|
151
159
|
@filters_array = []
|
152
160
|
@untaint_fields = []
|
161
|
+
@untaint_all = false
|
153
162
|
|
154
163
|
@parsed_params = nil
|
155
|
-
|
156
|
-
self.validate( params ) if params
|
157
164
|
end
|
158
165
|
|
159
166
|
|
160
167
|
### Copy constructor.
|
161
168
|
def initialize_copy( original )
|
169
|
+
super
|
170
|
+
|
171
|
+
@profile = original.profile.dup
|
172
|
+
@profile.each_key {|k| @profile[k] = @profile[k].clone }
|
173
|
+
self.log.debug "Copied validator profile: %p" % [ @profile ]
|
174
|
+
|
162
175
|
@form = @form.clone
|
163
176
|
@raw_form = @form.clone
|
164
|
-
@profile = @profile.clone
|
165
177
|
@invalid_fields = @invalid_fields.clone
|
166
178
|
@missing_fields = @missing_fields.clone
|
167
179
|
@unknown_fields = @unknown_fields.clone
|
@@ -170,6 +182,7 @@ class Strelka::ParamValidator < ::FormValidator
|
|
170
182
|
@optional_fields = @optional_fields.clone
|
171
183
|
@filters_array = @filters_array.clone
|
172
184
|
@untaint_fields = @untaint_fields.clone
|
185
|
+
@untaint_all = original.untaint_all?
|
173
186
|
|
174
187
|
@parsed_params = @parsed_params.clone if @parsed_params
|
175
188
|
end
|
@@ -180,12 +193,103 @@ class Strelka::ParamValidator < ::FormValidator
|
|
180
193
|
public
|
181
194
|
######
|
182
195
|
|
196
|
+
# The profile hash
|
197
|
+
attr_reader :profile
|
198
|
+
|
183
199
|
# The raw form data Hash
|
184
200
|
attr_reader :raw_form
|
185
201
|
|
186
202
|
# The validated form data Hash
|
187
203
|
attr_reader :form
|
188
204
|
|
205
|
+
# Global untainting flag
|
206
|
+
attr_accessor :untaint_all
|
207
|
+
alias_method :untaint_all_constraints=, :untaint_all=
|
208
|
+
alias_method :untaint_all?, :untaint_all
|
209
|
+
alias_method :untaint_all_constraints, :untaint_all
|
210
|
+
alias_method :untaint_all_constraints?, :untaint_all
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
### Return the Array of declared parameter validations.
|
215
|
+
def param_names
|
216
|
+
return self.profile[:required] | self.profile[:optional]
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
### Fetch the constraint/s that apply to the parameter with the given
|
221
|
+
### +name+.
|
222
|
+
def constraint_for( name )
|
223
|
+
constraint = self.profile[:constraints][ name.to_sym ] or
|
224
|
+
raise ScriptError, "no parameter %p defined" % [ name ]
|
225
|
+
return constraint
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
### Fetch the constraint/s that apply to the parameter named +name+ as a
|
230
|
+
### Regexp, if possible.
|
231
|
+
def constraint_regexp_for( name )
|
232
|
+
self.log.debug " searching for a constraint for %p" % [ name ]
|
233
|
+
|
234
|
+
# Munge the constraint into a Regexp
|
235
|
+
constraint = self.constraint_for( name )
|
236
|
+
re = case constraint
|
237
|
+
when Regexp
|
238
|
+
self.log.debug " regex constraint is: %p" % [ constraint ]
|
239
|
+
constraint
|
240
|
+
when Array
|
241
|
+
sub_res = constraint.map( &self.method(:extract_route_from_constraint) )
|
242
|
+
Regexp.union( sub_res )
|
243
|
+
when Symbol
|
244
|
+
self.class.pattern_for_constraint( constraint ) or
|
245
|
+
raise ScriptError, "no pattern for built-in %p constraint" % [ constraint ]
|
246
|
+
else
|
247
|
+
raise ScriptError,
|
248
|
+
"can't route on a parameter with a %p constraint %p" % [ constraint.class ]
|
249
|
+
end
|
250
|
+
|
251
|
+
self.log.debug " bounded constraint is: %p" % [ re ]
|
252
|
+
|
253
|
+
# Unbind the pattern from beginning or end of line.
|
254
|
+
# :TODO: This is pretty ugly. Find a better way of modifying the regex.
|
255
|
+
re_str = re.to_s.
|
256
|
+
sub( %r{\(\?[\-mix]+:(.*)\)}, '\\1' ).
|
257
|
+
gsub( PARAMETER_PATTERN_STRIP_RE, '' )
|
258
|
+
self.log.debug " stripped constraint pattern down to: %p" % [ re_str ]
|
259
|
+
|
260
|
+
return Regexp.new( "(?<#{name}>#{re_str})", re.options )
|
261
|
+
end
|
262
|
+
|
263
|
+
|
264
|
+
### :call-seq:
|
265
|
+
### param( name, *flags )
|
266
|
+
### param( name, constraint, *flags )
|
267
|
+
### param( name, description, *flags )
|
268
|
+
### param( name, constraint, description, *flags )
|
269
|
+
###
|
270
|
+
### Add a validation for a parameter with the specified +name+. The +args+ can include
|
271
|
+
### a constraint, a description, and one or more flags.
|
272
|
+
def add( name, *args, &block )
|
273
|
+
name = name.to_sym
|
274
|
+
raise ArgumentError,
|
275
|
+
"parameter %p is already defined; perhaps you meant to use #override?" % [name] if
|
276
|
+
self.param_names.include?( name )
|
277
|
+
|
278
|
+
self.set_param( name, *args, &block )
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
### Replace the existing parameter with the specified +name+. The +args+ replace
|
283
|
+
### the existing description, constraints, and flags. See #add for details.
|
284
|
+
def override( name, *args, &block )
|
285
|
+
name = name.to_sym
|
286
|
+
raise ArgumentError,
|
287
|
+
"no parameter %p defined; perhaps you meant to use #add?" % [name] unless
|
288
|
+
self.param_names.include?( name )
|
289
|
+
|
290
|
+
self.set_param( name, *args, &block )
|
291
|
+
end
|
292
|
+
|
189
293
|
|
190
294
|
### Stringified description of the validator
|
191
295
|
def to_s
|
@@ -198,6 +302,26 @@ class Strelka::ParamValidator < ::FormValidator
|
|
198
302
|
end
|
199
303
|
|
200
304
|
|
305
|
+
### Return a human-readable representation of the validator, suitable for debugging.
|
306
|
+
def inspect
|
307
|
+
required = self.profile[:required].collect do |field|
|
308
|
+
"%s (%p)" % [ field, self.profile[:constraints][field] ]
|
309
|
+
end.join( ',' )
|
310
|
+
optional = self.profile[:optional].collect do |field|
|
311
|
+
"%s (%p)" % [ field, self.profile[:constraints][field] ]
|
312
|
+
end.join( ',' )
|
313
|
+
|
314
|
+
return "#<%p:0x%016x %s, profile: [required: %s, optional: %s] global untaint: %s>" % [
|
315
|
+
self.class,
|
316
|
+
self.object_id / 2,
|
317
|
+
self.to_s,
|
318
|
+
required.empty? ? "(none)" : required,
|
319
|
+
optional.empty? ? "(none)" : optional,
|
320
|
+
self.untaint_all? ? "enabled" : "disabled",
|
321
|
+
]
|
322
|
+
end
|
323
|
+
|
324
|
+
|
201
325
|
### Hash of field descriptions
|
202
326
|
def descriptions
|
203
327
|
return @profile[:descriptions]
|
@@ -212,19 +336,70 @@ class Strelka::ParamValidator < ::FormValidator
|
|
212
336
|
|
213
337
|
### Validate the input in +params+. If the optional +additional_profile+ is
|
214
338
|
### given, merge it with the validator's default profile before validating.
|
215
|
-
def validate( params, additional_profile=nil )
|
339
|
+
def validate( params=nil, additional_profile=nil )
|
340
|
+
params ||= {}
|
341
|
+
|
342
|
+
self.log.info "Validating request params: %p with profile: %p" %
|
343
|
+
[ params, @profile ]
|
216
344
|
@raw_form = params.dup
|
217
345
|
profile = @profile
|
218
346
|
|
219
347
|
if additional_profile
|
220
|
-
self.log.debug "
|
348
|
+
self.log.debug " merging additional profile %p" % [ additional_profile ]
|
221
349
|
profile = @profile.merge( additional_profile )
|
222
350
|
end
|
223
351
|
|
352
|
+
self.log.debug "Calling superclass's validate: %p" % [ self ]
|
224
353
|
super( params, profile )
|
225
354
|
end
|
226
355
|
|
227
356
|
|
357
|
+
protected :convert_profile
|
358
|
+
|
359
|
+
# Load profile with a hash describing valid input.
|
360
|
+
def setup(form_data, profile)
|
361
|
+
@form = form_data
|
362
|
+
@profile = self.convert_profile( @profile )
|
363
|
+
end
|
364
|
+
|
365
|
+
|
366
|
+
### Set the parameter +name+ in the profile to validate using the given +args+,
|
367
|
+
### which are the same as the ones passed to #add and #override.
|
368
|
+
def set_param( name, *args, &block )
|
369
|
+
args.unshift( block ) if block
|
370
|
+
|
371
|
+
# Custom validator -- either a callback or a regex
|
372
|
+
if args.first.is_a?( Regexp ) || args.first.respond_to?( :call )
|
373
|
+
self.profile[:constraints][ name ] = args.shift
|
374
|
+
|
375
|
+
# Builtin match validator, either explicit or implied by the name
|
376
|
+
else
|
377
|
+
constraint = args.shift if args.first.is_a?( Symbol ) && !FLAGS.include?( args.first )
|
378
|
+
constraint ||= name
|
379
|
+
|
380
|
+
raise ArgumentError, "no builtin %p validator" % [ constraint ] unless
|
381
|
+
self.respond_to?( "match_#{constraint}" )
|
382
|
+
self.profile[:constraints][ name ] = constraint
|
383
|
+
end
|
384
|
+
|
385
|
+
self.profile[:descriptions][ name ] = args.shift if args.first.is_a?( String )
|
386
|
+
|
387
|
+
if args.include?( :required )
|
388
|
+
self.profile[:required] |= [ name ]
|
389
|
+
self.profile[:optional].delete( name )
|
390
|
+
else
|
391
|
+
self.profile[:required].delete( name )
|
392
|
+
self.profile[:optional] |= [ name ]
|
393
|
+
end
|
394
|
+
|
395
|
+
if args.include?( :untaint )
|
396
|
+
self.profile[:untaint_constraint_fields] |= [ name ]
|
397
|
+
else
|
398
|
+
self.profile[:untaint_constraint_fields].delete( :name )
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
|
228
403
|
### Overridden to remove the check for extra keys.
|
229
404
|
def check_profile_syntax( profile )
|
230
405
|
end
|
@@ -273,28 +448,21 @@ class Strelka::ParamValidator < ::FormValidator
|
|
273
448
|
### Returns +true+ if the given +field+ is one that should be untainted.
|
274
449
|
def untaint?( field )
|
275
450
|
self.log.debug "Checking to see if %p should be untainted." % [field]
|
276
|
-
rval = (
|
451
|
+
rval = ( self.untaint_all? ||
|
277
452
|
@untaint_fields.include?(field) ||
|
278
453
|
@untaint_fields.include?(field.to_sym) )
|
279
454
|
|
280
455
|
if rval
|
281
456
|
self.log.debug " ...yep it should."
|
282
457
|
else
|
283
|
-
self.log.debug " ...nope; untaint fields is: %p" %
|
458
|
+
self.log.debug " ...nope; untaint_all is: %p, untaint fields is: %p" %
|
459
|
+
[ @untaint_all, @untaint_fields ]
|
284
460
|
end
|
285
461
|
|
286
462
|
return rval
|
287
463
|
end
|
288
464
|
|
289
465
|
|
290
|
-
### Overridden so that the presence of :untaint_constraint_fields doesn't
|
291
|
-
### disable the :untaint_all_constraints flag.
|
292
|
-
def untaint_all_constraints
|
293
|
-
@untaint_all = @profile[:untaint_all_constraints] ? true : false
|
294
|
-
end
|
295
|
-
|
296
|
-
|
297
|
-
|
298
466
|
### Return an array of field names which had some kind of error associated
|
299
467
|
### with them.
|
300
468
|
def error_fields
|
@@ -412,8 +580,12 @@ class Strelka::ParamValidator < ::FormValidator
|
|
412
580
|
end
|
413
581
|
|
414
582
|
|
583
|
+
#########
|
584
|
+
protected
|
585
|
+
#########
|
586
|
+
|
415
587
|
#
|
416
|
-
# :section:
|
588
|
+
# :section: Builtin Match Constraints
|
417
589
|
#
|
418
590
|
|
419
591
|
### Try to match the specified +val+ using the built-in constraint pattern
|
@@ -521,9 +693,14 @@ class Strelka::ParamValidator < ::FormValidator
|
|
521
693
|
end
|
522
694
|
|
523
695
|
|
696
|
+
#
|
697
|
+
# :section: Constraint method
|
698
|
+
#
|
699
|
+
|
524
700
|
### Apply one or more +constraints+ to the field value/s corresponding to
|
525
701
|
### +key+.
|
526
702
|
def do_constraint( key, constraints )
|
703
|
+
self.log.debug "Applying constraints %p to field %p" % [ constraints, key ]
|
527
704
|
constraints.each do |constraint|
|
528
705
|
case constraint
|
529
706
|
when String
|
@@ -640,7 +817,7 @@ class Strelka::ParamValidator < ::FormValidator
|
|
640
817
|
|
641
818
|
### Set the form value for the given +key+. If +value+ is false, add it to
|
642
819
|
### the list of invalid fields with a description derived from the specified
|
643
|
-
### +constraint+.
|
820
|
+
### +constraint+. Called by constraint methods when they succeed.
|
644
821
|
def set_form_value( key, value, constraint )
|
645
822
|
key.untaint
|
646
823
|
|
@@ -680,30 +857,30 @@ class Strelka::ParamValidator < ::FormValidator
|
|
680
857
|
### The formvalidator filters method has a bug where he assumes an array
|
681
858
|
### when it is in fact a string for multiple values (ie anytime you have a
|
682
859
|
### text-area with newlines in it).
|
683
|
-
def filters
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
end
|
860
|
+
# def filters
|
861
|
+
# @filters_array = Array(@profile[:filters]) unless(@filters_array)
|
862
|
+
# @filters_array.each do |filter|
|
863
|
+
#
|
864
|
+
# if respond_to?( "filter_#{filter}" )
|
865
|
+
# @form.keys.each do |field|
|
866
|
+
# # If a key has multiple elements, apply filter to each element
|
867
|
+
# @field_array = Array( @form[field] )
|
868
|
+
#
|
869
|
+
# if @field_array.length > 1
|
870
|
+
# @field_array.each_index do |i|
|
871
|
+
# elem = @field_array[i]
|
872
|
+
# @field_array[i] = self.send("filter_#{filter}", elem)
|
873
|
+
# end
|
874
|
+
# else
|
875
|
+
# if not @form[field].to_s.empty?
|
876
|
+
# @form[field] = self.send("filter_#{filter}", @form[field].to_s)
|
877
|
+
# end
|
878
|
+
# end
|
879
|
+
# end
|
880
|
+
# end
|
881
|
+
# end
|
882
|
+
# @form
|
883
|
+
# end
|
707
884
|
|
708
885
|
|
709
886
|
#######
|
@@ -52,6 +52,7 @@ describe Strelka::App::Auth do
|
|
52
52
|
app = Class.new( Strelka::App ) do
|
53
53
|
plugins :auth
|
54
54
|
end
|
55
|
+
app.install_plugins
|
55
56
|
|
56
57
|
@request_factory.get( '/api/v1/verify' ).should respond_to( :authenticated? )
|
57
58
|
end
|
@@ -83,6 +84,10 @@ describe Strelka::App::Auth do
|
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
87
|
+
after( :each ) do
|
88
|
+
@app = nil
|
89
|
+
end
|
90
|
+
|
86
91
|
|
87
92
|
it "applies auth to every request by default" do
|
88
93
|
app = @app.new
|
@@ -111,6 +116,38 @@ describe Strelka::App::Auth do
|
|
111
116
|
req.authenticated_user.should == 'anonymous'
|
112
117
|
end
|
113
118
|
|
119
|
+
context "that has negative auth criteria for the root" do
|
120
|
+
|
121
|
+
before( :each ) do
|
122
|
+
@app.no_auth_for( '/' )
|
123
|
+
end
|
124
|
+
|
125
|
+
it "knows that it has auth criteria" do
|
126
|
+
@app.should have_auth_criteria()
|
127
|
+
end
|
128
|
+
|
129
|
+
it "doesn't pass a request for the root path through auth" do
|
130
|
+
req = @request_factory.get( '/api/v1/' )
|
131
|
+
|
132
|
+
app = @app.new
|
133
|
+
app.auth_provider.should_not_receive( :authenticate )
|
134
|
+
app.auth_provider.should_not_receive( :authorize )
|
135
|
+
|
136
|
+
app.handle( req )
|
137
|
+
end
|
138
|
+
|
139
|
+
it "passes a request for a path other than the root through auth" do
|
140
|
+
req = @request_factory.get( '/api/v1/console' )
|
141
|
+
|
142
|
+
app = @app.new
|
143
|
+
app.auth_provider.should_receive( :authenticate ).and_return( 'anonymous' )
|
144
|
+
app.auth_provider.should_receive( :authorize ).and_return( true )
|
145
|
+
|
146
|
+
app.handle( req )
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
114
151
|
context "that has negative auth criteria" do
|
115
152
|
|
116
153
|
before( :each ) do
|
@@ -42,14 +42,12 @@ describe Strelka::App::Errors do
|
|
42
42
|
describe "an including App" do
|
43
43
|
|
44
44
|
before( :each ) do
|
45
|
-
Strelka.log.debug "Creating a new Strelka::App"
|
46
45
|
@app = Class.new( Strelka::App ) do
|
47
46
|
plugin :errors, :routing
|
48
47
|
def initialize( appid='params-test', sspec=TEST_SEND_SPEC, rspec=TEST_RECV_SPEC )
|
49
48
|
super
|
50
49
|
end
|
51
50
|
end
|
52
|
-
Strelka.log.debug " new instance is: %p" % [ @app ]
|
53
51
|
end
|
54
52
|
|
55
53
|
it "doesn't alter normal responses" do
|
@@ -52,8 +52,8 @@ describe Strelka::App::Parameters do
|
|
52
52
|
@app = nil
|
53
53
|
end
|
54
54
|
|
55
|
-
it "has a
|
56
|
-
@app.
|
55
|
+
it "has a ParamValidator" do
|
56
|
+
@app.paramvalidator.should be_a( Strelka::ParamValidator )
|
57
57
|
end
|
58
58
|
|
59
59
|
it "can declare a parameter with a validation pattern" do
|
@@ -61,95 +61,9 @@ describe Strelka::App::Parameters do
|
|
61
61
|
param :username, /\w+/i
|
62
62
|
end
|
63
63
|
|
64
|
-
@app.
|
65
|
-
@app.parameters[ :username ].
|
66
|
-
should include( :constraint => /(?<username>(?i-mx:\w+))/ )
|
64
|
+
@app.paramvalidator.param_names.should == [ :username ]
|
67
65
|
end
|
68
66
|
|
69
|
-
it "can declare a parameter with an Array validation" do
|
70
|
-
@app.class_eval do
|
71
|
-
param :username, [:printable, lambda {|str| str.length <= 16 }]
|
72
|
-
end
|
73
|
-
|
74
|
-
@app.parameters.should have( 1 ).member
|
75
|
-
@app.parameters[:username][:constraint][0].should == :printable
|
76
|
-
@app.parameters[:username][:constraint][1].should be_an_instance_of( Proc )
|
77
|
-
end
|
78
|
-
|
79
|
-
it "can declare a parameter with a Hash validation" do
|
80
|
-
@app.class_eval do
|
81
|
-
param :username, {'ambrel' => 'A. Hotchgah'}
|
82
|
-
end
|
83
|
-
|
84
|
-
@app.parameters.should have( 1 ).member
|
85
|
-
@app.parameters[ :username ].
|
86
|
-
should include( :constraint => {'ambrel' => 'A. Hotchgah'} )
|
87
|
-
end
|
88
|
-
|
89
|
-
it "can declare a parameter with a matcher validation" do
|
90
|
-
@app.class_eval do
|
91
|
-
param :host, :hostname
|
92
|
-
end
|
93
|
-
|
94
|
-
@app.parameters.should have( 1 ).member
|
95
|
-
@app.parameters[ :host ].should include( :constraint => :hostname )
|
96
|
-
end
|
97
|
-
|
98
|
-
it "can declare a parameter with a validation pattern and a description" do
|
99
|
-
@app.class_eval do
|
100
|
-
param :username, /\w+/i, "The user's login"
|
101
|
-
end
|
102
|
-
|
103
|
-
@app.parameters.should have( 1 ).member
|
104
|
-
@app.parameters[ :username ].should include( :required => false )
|
105
|
-
@app.parameters[ :username ].should include( :constraint => /(?<username>(?i-mx:\w+))/ )
|
106
|
-
@app.parameters[ :username ].should include( :description => "The user's login" )
|
107
|
-
end
|
108
|
-
|
109
|
-
it "can declare a parameter with an Array validation and a description" do
|
110
|
-
@app.class_eval do
|
111
|
-
param :username, ['johnny5', 'ariel', 'hotah'], "The user's login"
|
112
|
-
end
|
113
|
-
|
114
|
-
@app.parameters.should have( 1 ).member
|
115
|
-
@app.parameters[ :username ].
|
116
|
-
should include( :constraint => ['johnny5', 'ariel', 'hotah'] )
|
117
|
-
@app.parameters[ :username ].should include( :description => "The user's login" )
|
118
|
-
end
|
119
|
-
|
120
|
-
it "can declare a parameter with just a description" do
|
121
|
-
@app.class_eval do
|
122
|
-
param :uuid, "UUID string"
|
123
|
-
end
|
124
|
-
|
125
|
-
@app.parameters.should have( 1 ).member
|
126
|
-
@app.parameters[ :uuid ].should include( :description => "UUID string" )
|
127
|
-
@app.parameters[ :uuid ].should include( :constraint => :uuid )
|
128
|
-
end
|
129
|
-
|
130
|
-
it "can declare a parameter with a validation pattern and a flag" do
|
131
|
-
@app.class_eval do
|
132
|
-
param :username, /\w+/i, :untaint
|
133
|
-
end
|
134
|
-
|
135
|
-
@app.parameters.should have( 1 ).member
|
136
|
-
@app.parameters[ :username ].should include( :required => false )
|
137
|
-
@app.parameters[ :username ].should include( :untaint => true )
|
138
|
-
@app.parameters[ :username ].should include( :constraint => /(?<username>(?i-mx:\w+))/ )
|
139
|
-
@app.parameters[ :username ].should include( :description => nil )
|
140
|
-
end
|
141
|
-
|
142
|
-
it "can declare a parameter with a validation Array and a flag" do
|
143
|
-
@app.class_eval do
|
144
|
-
param :username, ['amhel', 'hotah', 'aurelii'], :required
|
145
|
-
end
|
146
|
-
|
147
|
-
@app.parameters.should have( 1 ).member
|
148
|
-
@app.parameters[ :username ].should include( :required => true )
|
149
|
-
@app.parameters[ :username ].
|
150
|
-
should include( :constraint => ['amhel', 'hotah', 'aurelii'] )
|
151
|
-
@app.parameters[ :username ].should include( :description => nil )
|
152
|
-
end
|
153
67
|
|
154
68
|
it "inherits parameters from its superclass" do
|
155
69
|
@app.class_eval do
|
@@ -157,9 +71,7 @@ describe Strelka::App::Parameters do
|
|
157
71
|
end
|
158
72
|
subapp = Class.new( @app )
|
159
73
|
|
160
|
-
subapp.
|
161
|
-
subapp.parameters[ :username ].
|
162
|
-
should include( :constraint => /(?<username>(?i-mx:\w+))/ )
|
74
|
+
subapp.paramvalidator.param_names.should == [ :username ]
|
163
75
|
end
|
164
76
|
|
165
77
|
describe "instance" do
|