sinatra-params-validator 0.0.1

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/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+
3
+ gem 'rack', '1.5.2'
4
+ gem 'sinatra', '1.4.2'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 tsov, lube8uy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,116 @@
1
+ # sinatra-params-validator
2
+ ========================
3
+
4
+ ## Description
5
+
6
+ This sinatra module validates the incoming parameter and lets you configure the pattern.
7
+ Once it's registered with your sinatra app, it will act as a before filter, that validates your parameters.
8
+ You can configure it with the newly available sinatra method `validation_required`.
9
+
10
+ ## Sinatra Module
11
+
12
+ Configure your routes to require parameters and validate their values. If the
13
+ validator finds errors, it will execute sinatras halt method, which will prevent
14
+ invocation of your sinatra code block, and set the response status to 400. The missing
15
+ or invalid parameters can be found in the environment variable, like in the example
16
+ below. That means you can customize your own error responses, for example by catching the errors
17
+ with some middleware.
18
+
19
+ ### Examples
20
+
21
+ ```ruby
22
+ require 'sinatra'
23
+
24
+ class App < Sinatra::Base
25
+ register Rack::Validator::Sinatra
26
+
27
+ helpers do
28
+ def missing_parameters
29
+ @env['validator.missing']
30
+ end
31
+
32
+ def invalid_parameters
33
+ @env['validator.invalid']
34
+ end
35
+
36
+ def messages
37
+ @env['validator.messages']
38
+ end
39
+ end
40
+
41
+ after do
42
+ puts missing_parameters
43
+ puts invalid_parameters
44
+ puts messages
45
+ puts params
46
+ end
47
+
48
+ validation_required :GET, '/', :params => [
49
+ { :name => :name, :required => true },
50
+ { :name => :email, :type => :email, :required => true },
51
+ { :name => :age, :range => [ 0, 120 ], :default => 1000 },
52
+ { :name => :latitude, :type => :float, :default => 0.0 },
53
+ { :name => :longitude, :type => :float, :default => 0.0 },
54
+ { :name => :message },
55
+ { :name => :price, :matches => /^[\d]*.[\d]{2}$/ }
56
+ ]
57
+
58
+ get '/' do
59
+
60
+ end
61
+
62
+ validation_required :POST, '/group', :params => [
63
+ { :name => :name, :required => true }
64
+ ]
65
+
66
+ post '/group' do
67
+
68
+ end
69
+
70
+ end
71
+ ```
72
+
73
+ Try it out yourself and run this in the root directory `rackup example/app.rb`.
74
+
75
+ ## Validator class
76
+
77
+ A class with several methods to validate and clean data from sinatra params holder.
78
+ Can be used for an adopter for other libraries/frameworks, like rails.
79
+
80
+ ### Examples
81
+
82
+ Initialize class in lazy mode, this means that once a validation fail the following ones are not executed:
83
+
84
+ ```ruby
85
+ validator = Rack::Validator.new(params)
86
+ #required_3 is not present
87
+ validator.required [:required_1, :required_2, :required_3]
88
+ validator.trim
89
+ validator.downcase [:required_2, :other_param]
90
+ validator.is_in_range 3, 32, :required_1
91
+ validator.is_email :contact
92
+ validator.matches /[a-z]{2}_[A-Z]{2}|[a-z]{2}/i, :locale
93
+
94
+ if validator.has_errors?
95
+ p validator.messages.join('|')
96
+ #Inputs "required_3 is required"
97
+ end
98
+ ```
99
+
100
+ If you want to get all the errors at the end of the validation calls pass false as second parameter in the constructor:
101
+ validator = Rack::Validator.new(params, true)
102
+
103
+ Available methods:
104
+
105
+ * trim
106
+ * downcase
107
+ * required
108
+ * is_integer
109
+ * is_float
110
+ * is_greater_equal_than
111
+ * is_in_range
112
+ * is_less_equal_than
113
+ * is_email
114
+ * matches
115
+
116
+ To see more examples check tests/params_validator_spec.rb
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,234 @@
1
+ require 'rack'
2
+
3
+ module Rack
4
+ class Validator
5
+
6
+ attr_reader :invalid_params
7
+ attr_reader :missing_params
8
+ attr_reader :messages
9
+ attr_accessor :lazy_mode
10
+
11
+ def initialize(params, lazy_mode = true)
12
+ @params = params
13
+ @invalid_params = []
14
+ @missing_params = []
15
+ @messages = []
16
+ @lazy_mode = lazy_mode
17
+ end
18
+
19
+ def has_errors?
20
+ @invalid_params.length > 0 or @missing_params.length > 0
21
+ end
22
+
23
+ def trim
24
+ @params.each_key { |k| @params[k] = @params[k].strip if @params[k]}
25
+ end
26
+
27
+ def downcase(keys)
28
+ keys.each { |k| @params[k.to_s] = @params[k.to_s].to_s.downcase if @params[k.to_s]}
29
+ end
30
+
31
+ def required(keys)
32
+ if lazy_check_disabled
33
+ keys.each { |k|
34
+ k = k.to_s
35
+ unless @params.has_key?(k)
36
+ @invalid_params.push(k)
37
+ @missing_params.push(k)
38
+ @messages.push("#{k} is required")
39
+ end
40
+ }
41
+ end
42
+ end
43
+
44
+ def is_integer(key)
45
+ if lazy_check_disabled
46
+ key = key.to_s
47
+ value = @params[key]
48
+ unless is_valid_integer(value)
49
+ @invalid_params.push(key)
50
+ @messages.push("#{key} is not an integer")
51
+ end
52
+ end
53
+ end
54
+
55
+ def is_float(key)
56
+ if lazy_check_disabled
57
+ key = key.to_s
58
+ value = @params[key]
59
+ unless is_valid_float(value)
60
+ @invalid_params.push(key)
61
+ @messages.push("#{key} is not a float")
62
+ end
63
+ end
64
+ end
65
+
66
+ def is_greater_equal_than(min, key)
67
+ if lazy_check_disabled
68
+ key = key.to_s
69
+ if !is_valid_float(@params[key])
70
+ if !@params[key] || @params[key].length < min
71
+ @invalid_params.push(key)
72
+ @messages.push("#{key} length is less than #{min}")
73
+ end
74
+ else
75
+ value = is_valid_integer(@params[key]) ? @params[key].to_i : @params[key].to_f
76
+ if !value || value < min
77
+ @invalid_params.push(key)
78
+ @messages.push("#{key} is less than #{min}")
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def is_in_range(min, max, key)
85
+ if lazy_check_disabled
86
+ key = key.to_s
87
+ unless is_valid_float(@params[key])
88
+ if !@params[key] || @params[key].length < min || @params[key].length > max
89
+ @invalid_params.push(key)
90
+ @messages.push("#{key} length is not in range #{min},#{max}")
91
+ end
92
+ else
93
+ value = is_valid_integer(@params[key]) ? @params[key].to_i : @params[key].to_f
94
+ if !value || value < min || value > max
95
+ @invalid_params.push(key)
96
+ @messages.push("#{key} is not in range #{min},#{max}")
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ def is_less_equal_than(max, key)
103
+ if lazy_check_disabled
104
+ key = key.to_s
105
+ unless is_valid_float(@params[key])
106
+ if !@params[key] || @params[key].length > max
107
+ @invalid_params.push(key)
108
+ @messages.push("#{key} length is greater than #{max}")
109
+ end
110
+ else
111
+ value = is_valid_integer(@params[key]) ? @params[key].to_i : @params[key].to_f
112
+ if !value || value > max
113
+ @invalid_params.push(key)
114
+ @messages.push("#{key} is greater than #{max}")
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ def is_email(key)
121
+ if lazy_check_disabled
122
+ key = key.to_s
123
+ unless @params[key].to_s[/^\S+@\S+\.\S+$/]
124
+ @invalid_params.push(key)
125
+ @messages.push("#{key} is not a valid email")
126
+ end
127
+ end
128
+ end
129
+
130
+ def matches(regexp, key)
131
+ if lazy_check_disabled
132
+ key = key.to_s
133
+ unless @params[key] =~ regexp
134
+ @invalid_params.push(key)
135
+ @messages.push("#{key} is not a valid expression")
136
+ end
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ def lazy_check_disabled
143
+ return !@lazy_mode || !has_errors?
144
+ end
145
+
146
+ def is_valid_integer(value)
147
+ key = key.to_s
148
+ value.to_i.to_s == value.to_s
149
+ end
150
+
151
+ def is_valid_float(value)
152
+ key = key.to_s
153
+ value.to_f.to_s == value.to_s || is_valid_integer(value)
154
+ end
155
+
156
+ module Sinatra
157
+
158
+ def validation_required(method, path, options = { })
159
+ before path do
160
+ validate_parameters(options) if same_method? method
161
+ end
162
+ end
163
+
164
+ module Helpers
165
+ def same_method?(method)
166
+ @env['REQUEST_METHOD'] == method.to_s
167
+ end
168
+
169
+ # TODO: Needs a general cleanup!!!
170
+ def validate_parameters(options)
171
+ validator = Rack::Validator.new params, false
172
+ required_params = [ ]
173
+ integer_params = [ ]
174
+ float_params = [ ]
175
+ email_params = [ ]
176
+ range_params = [ ]
177
+ matches_params = [ ]
178
+ default_params = [ ]
179
+
180
+ options[:params].each do |param|
181
+ required_params << (param[:name]) if param[:required]
182
+ integer_params << (param) if param[:type] == :integer
183
+ float_params << (param) if param[:type] == :float
184
+ email_params << (param) if param[:type] == :email
185
+ range_params << (param) if param[:range]
186
+ matches_params << (param) if param[:matches]
187
+ default_params << (param) if param[:default]
188
+ end
189
+
190
+ validator.required required_params
191
+ integer_params.each do |param|
192
+ validator.is_integer param[:name] unless params[param[:name].to_s].nil?
193
+ end
194
+ float_params.each do |param|
195
+ validator.is_float param[:name] unless params[param[:name].to_s].nil?
196
+ end
197
+ email_params.each do |param|
198
+ validator.is_email param[:name] unless params[param[:name].to_s].nil?
199
+ end
200
+ range_params.each do |param|
201
+ validator.is_in_range param[:range].first, param[:range].last, param[:name] unless params[param[:name].to_s].nil?
202
+ end
203
+ matches_params.each do |param|
204
+ validator.matches param[:matches], param[:name] unless params[param[:name].to_s].nil?
205
+ end
206
+
207
+ default_params.each do |param|
208
+ if params[param[:name].to_s].nil?
209
+ params[param[:name].to_s] = param[:default]
210
+ validator.invalid_params.delete param[:name]
211
+ validator.missing_params.delete param[:name]
212
+ end
213
+ end
214
+
215
+ if validator.has_errors?
216
+ @env['validator.missing'] = validator.missing_params
217
+ @env['validator.invalid'] = validator.invalid_params
218
+ @env['validator.messages'] = validator.messages
219
+ halt missing_params!
220
+ end
221
+ end
222
+
223
+ def missing_params!
224
+ @response.status = 400
225
+ end
226
+ end
227
+
228
+ def self.registered(base)
229
+ base.helpers Helpers
230
+ end
231
+
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,14 @@
1
+ $: << File.dirname(__FILE__) + "/lib"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "sinatra-params-validator"
5
+ spec.version = IO.read("VERSION")
6
+ spec.authors = ["tsov", "lube8buy"]
7
+ spec.email = "tsov@me.com"
8
+ spec.homepage = "http://github.com/tsov/#{spec.name}"
9
+ spec.summary = "A Sinatra Module to validate incoming parameters"
10
+ spec.description = "This sinatra module validates the incoming parameter and lets you configure the pattern."
11
+
12
+ spec.files = Dir["lib/**/*", "VERSION", "LICENSE", "README.md", "Gemfile", "*.gemspec"]
13
+ spec.license = "MIT"
14
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-params-validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - tsov
9
+ - lube8buy
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-05-30 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: This sinatra module validates the incoming parameter and lets you configure
16
+ the pattern.
17
+ email: tsov@me.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/rack/validator/sinatra.rb
23
+ - VERSION
24
+ - LICENSE
25
+ - README.md
26
+ - Gemfile
27
+ - sinatra-params-validator.gemspec
28
+ homepage: http://github.com/tsov/sinatra-params-validator
29
+ licenses:
30
+ - MIT
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 1.8.24
50
+ signing_key:
51
+ specification_version: 3
52
+ summary: A Sinatra Module to validate incoming parameters
53
+ test_files: []
54
+ has_rdoc: