uri_format_validator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,166 @@
1
+ # (c) Copyright 2017 Ribose Inc.
2
+ #
3
+
4
+ require "active_model"
5
+ require "uri"
6
+ require "active_support/core_ext"
7
+ require "net/http"
8
+ require "resolv"
9
+
10
+ module UriFormatValidator
11
+ module Validators
12
+ #
13
+ # TODO: documentation
14
+ #
15
+ class UriFormatValidator < ::ActiveModel::EachValidator
16
+ SCHEMES = %w[
17
+ aaa aaas about acap acct cap cid coap coaps crid data dav dict dns
18
+ example file ftp geo go gopher h323 http https iax icap im imap info ipp
19
+ ipps iris iris.beep iris.lwz iris.xpc iris.xpcs jabber ldap mailto mid
20
+ msrp msrps mtqp mupdate news nfs ni nih nntp opaquelocktoken pkcs11 pop
21
+ pres reload rtsp rtsps rtspu service session shttp sieve sip sips sms
22
+ snmp soap.beep soap.beeps stun stuns tag tel telnet tftp thismessage tip
23
+ tn3270 turn turns tv urn vemmi vnc ws wss xcon xcon-userid xmlrpc.beep
24
+ xmlrpc.beeps xmpp z39.50r z39.50s
25
+ ].freeze
26
+
27
+ # Examples: http://www.rubular.com/r/Xy4iNY2ztf
28
+ RESERVED_DOMAINS = %r{
29
+ (\.(test|example|invalid|localhost)$)|
30
+ ((^|\.)example\.(...?)(\...)?$)
31
+ }x
32
+
33
+ def initialize(options)
34
+ @schemes =
35
+ case options[:scheme]
36
+ when :all then SCHEMES
37
+ when nil then %w[http https]
38
+ else options[:scheme]
39
+ end
40
+
41
+ options[:message] ||= I18n.t("errors.messages.invalid_uri")
42
+ super(options)
43
+ end
44
+
45
+ def validate_each(record, attribute, value)
46
+ success = catch(STOP_VALIDATION) do
47
+ do_checks(value.to_s)
48
+ true
49
+ end
50
+ success || set_failure_message(record, attribute)
51
+ end
52
+
53
+ private
54
+
55
+ STOP_VALIDATION = Object.new.freeze
56
+
57
+ def do_checks(uri_string)
58
+ uri = string_to_uri(uri_string)
59
+ fail_unless uri
60
+
61
+ if accept_relative_uris?
62
+ validate_domain_absense(uri)
63
+ else
64
+ validate_domain(uri_string)
65
+ validate_against_options(uri, :authority, :scheme, :retrievable)
66
+ end
67
+
68
+ validate_against_options(uri, :path, :query, :fragment)
69
+ end
70
+
71
+ # Warning! The +URI+ method behaviour is inconsistent across VMs.
72
+ # For instance, Rubinius allows leading and trailing spaces. Non-nil
73
+ # return value doesn't guarantee that URI is indeed well-formed.
74
+ def string_to_uri(uri_string)
75
+ URI(uri_string)
76
+ rescue URI::InvalidURIError
77
+ nil
78
+ end
79
+
80
+ def set_failure_message(record, attribute)
81
+ record.errors[attribute] << options[:message]
82
+ end
83
+
84
+ def fail_if(condition)
85
+ throw STOP_VALIDATION if condition
86
+ end
87
+
88
+ def fail_unless(condition)
89
+ fail_if !condition
90
+ end
91
+
92
+ def validate_domain(uri)
93
+ fail_unless uri =~ regexp
94
+ end
95
+
96
+ def validate_against_options(uri, *option_keys_list)
97
+ option_keys_list.each do |option_name|
98
+ next unless options.key?(option_name)
99
+ send(:"validate_#{option_name}", options[option_name], uri)
100
+ end
101
+ end
102
+
103
+ def validate_scheme(_option, uri)
104
+ scheme = uri.scheme
105
+ if @schemes.is_a?(Regexp)
106
+ fail_if scheme !~ @schemes
107
+ else
108
+ fail_unless @schemes.include?(scheme)
109
+ end
110
+ end
111
+
112
+ def validate_path(option, uri)
113
+ path = uri.path
114
+ fail_if option == true && path == "/" || path == ""
115
+ fail_if option == false && path != "/" && path != ""
116
+ fail_if option.is_a?(Regexp) && path !~ option
117
+ end
118
+
119
+ def validate_query(option, uri)
120
+ fail_unless uri.query.present? == option
121
+ end
122
+
123
+ def validate_fragment(option, uri)
124
+ fail_unless uri.fragment.present? == option
125
+ end
126
+
127
+ def validate_authority(option, uri)
128
+ fail_if option.is_a?(Regexp) && uri.host !~ option
129
+ fail_if option.is_a?(Array) && !option.include?(uri.host)
130
+
131
+ if option.is_a?(Hash) && option[:allow_reserved] == false
132
+ check_reserved_domains(uri)
133
+ end
134
+ end
135
+
136
+ def validate_retrievable(option, uri)
137
+ fail_unless Reacher.new(uri).retrievable? if option
138
+ end
139
+
140
+ def accept_relative_uris?
141
+ options.key?(:authority) && options[:authority] == false
142
+ end
143
+
144
+ def validate_domain_absense(uri)
145
+ fail_if uri.host.present?
146
+ end
147
+
148
+ def check_reserved_domains(uri)
149
+ fail_if uri.host =~ RESERVED_DOMAINS
150
+ end
151
+
152
+ def regexp
153
+ protocol =
154
+ if @schemes.is_a?(Regexp)
155
+ "(#{@schemes.source})://"
156
+ else
157
+ "(#{@schemes.join('|')})://"
158
+ end
159
+
160
+ %r{^#{
161
+ protocol
162
+ }[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$}iux
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,16 @@
1
+ # (c) Copyright 2017 Ribose Inc.
2
+ #
3
+
4
+ require "uri_format_validator/validators/uri_format_validator"
5
+ require "uri_format_validator/validators/helper_methods"
6
+
7
+ module UriFormatValidator
8
+ module Validators
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ extend HelperMethods
13
+ include HelperMethods
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ # (c) Copyright 2017 Ribose Inc.
2
+ #
3
+
4
+ module UriFormatValidator
5
+ VERSION = "0.1.0".freeze
6
+ end
@@ -0,0 +1,14 @@
1
+ # (c) Copyright 2017 Ribose Inc.
2
+ #
3
+
4
+ require "uri_format_validator/version"
5
+ require "uri_format_validator/localization"
6
+ require "uri_format_validator/reacher"
7
+ require "uri_format_validator/validators"
8
+
9
+ # This is a placeholder...
10
+ module UriFormatValidator
11
+ # Your code goes here...
12
+ end
13
+
14
+ ActiveModel::Validations.include UriFormatValidator::Validators
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "uri_format_validator/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "uri_format_validator"
9
+ spec.version = UriFormatValidator::VERSION
10
+ spec.authors = ["Ribose Inc."]
11
+ spec.email = ["open.source@ribose.com"]
12
+
13
+ spec.summary = "Library for validating urls in Rails"
14
+ spec.description = "Library for validating urls in Rails"
15
+ spec.homepage = "https://github.com/riboseinc/uri_format_validator"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.required_ruby_version = ">= 2.2.2"
26
+
27
+ spec.add_runtime_dependency "activemodel", ">= 4.0.0", "< 6"
28
+
29
+ spec.add_development_dependency "bundler", "~> 1.14"
30
+ spec.add_development_dependency "pry"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rspec", "~> 3.0"
33
+ spec.add_development_dependency "rubocop", "~> 0.49.1"
34
+ spec.add_development_dependency "simplecov"
35
+ spec.add_development_dependency "webmock", "~> 3.0"
36
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uri_format_validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ribose Inc.
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-10-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '6'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 4.0.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '6'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.14'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.14'
47
+ - !ruby/object:Gem::Dependency
48
+ name: pry
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '10.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '10.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.49.1
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 0.49.1
103
+ - !ruby/object:Gem::Dependency
104
+ name: simplecov
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: webmock
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '3.0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '3.0'
131
+ description: Library for validating urls in Rails
132
+ email:
133
+ - open.source@ribose.com
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - ".codeclimate.yml"
139
+ - ".editorconfig"
140
+ - ".gitignore"
141
+ - ".hound.yml"
142
+ - ".rubocop.yml"
143
+ - ".travis.yml"
144
+ - CHANGELOG.adoc
145
+ - CODE_OF_CONDUCT.md
146
+ - Gemfile
147
+ - LICENSE.txt
148
+ - README.adoc
149
+ - ROADMAP.adoc
150
+ - Rakefile
151
+ - bin/console
152
+ - bin/rake
153
+ - bin/rspec
154
+ - bin/rubocop
155
+ - bin/setup
156
+ - examples/basic.rb
157
+ - gemfiles/common.gemfile
158
+ - gemfiles/rails-4.0.gemfile
159
+ - gemfiles/rails-4.1.gemfile
160
+ - gemfiles/rails-4.2.gemfile
161
+ - gemfiles/rails-5.0.gemfile
162
+ - gemfiles/rails-5.1.gemfile
163
+ - gemfiles/rails-head.gemfile
164
+ - lib/uri_format_validator.rb
165
+ - lib/uri_format_validator/locale/en.yml
166
+ - lib/uri_format_validator/locale/pl.yml
167
+ - lib/uri_format_validator/localization.rb
168
+ - lib/uri_format_validator/reacher.rb
169
+ - lib/uri_format_validator/validators.rb
170
+ - lib/uri_format_validator/validators/helper_methods.rb
171
+ - lib/uri_format_validator/validators/uri_format_validator.rb
172
+ - lib/uri_format_validator/version.rb
173
+ - uri_format_validator.gemspec
174
+ homepage: https://github.com/riboseinc/uri_format_validator
175
+ licenses:
176
+ - MIT
177
+ metadata: {}
178
+ post_install_message:
179
+ rdoc_options: []
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: 2.2.2
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ requirements: []
193
+ rubyforge_project:
194
+ rubygems_version: 2.5.2
195
+ signing_key:
196
+ specification_version: 4
197
+ summary: Library for validating urls in Rails
198
+ test_files: []