Module: FlossFunding::Validators
- Defined in:
- lib/floss_funding/validators.rb
Constant Summary collapse
- MAX_LEN =
512- URL_KEYS =
%w[ funding_uri funding_subscription_uri funding_donation_uri homepage ].freeze
Class Method Summary collapse
-
.deep_sanitize(obj, path, invalids) ⇒ Object
-
.reject_string_for_key?(key, value) ⇒ Boolean
-
.sanitize_config(data) ⇒ Object
Deeply sanitize configuration Hash values.
-
.string_too_long?(value) ⇒ Boolean
Returns true if value is a String and longer than MAX_LEN.
-
.valid_url?(value) ⇒ Boolean
Minimal WHATWG-like validation suitable for our needs without extra deps.
Class Method Details
.deep_sanitize(obj, path, invalids) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/floss_funding/validators.rb', line 51 def deep_sanitize(obj, path, invalids) case obj when Hash out = {} obj.each do |k, v| key = k.to_s new_path = path + [key] if v.is_a?(String) if reject_string_for_key?(key, v) invalids << new_path.join(".") next end out[key] = [v] else val = deep_sanitize(v, new_path, invalids) out[key] = val unless val.nil? || (val.respond_to?(:empty?) && val.empty?) end end out when Array arr = [] obj.each_with_index do |v, idx| new_path = path.dup # arrays are not included in attribute name for logging granularity add [idx] case v when String key = path.last if reject_string_for_key?(key, v) invalids << (path.empty? ? "[#{idx}]" : (path.join(".") + "[#{idx}]")) next end arr << v when Hash, Array val = deep_sanitize(v, new_path, invalids) arr << val unless val.nil? || (val.respond_to?(:empty?) && val.empty?) else arr << v end end arr when String if reject_string_for_key?(path.last, obj) invalids << path.join(".") nil else obj end else obj end end |
.reject_string_for_key?(key, value) ⇒ Boolean
103 104 105 106 107 108 |
# File 'lib/floss_funding/validators.rb', line 103 def reject_string_for_key?(key, value) return true if string_too_long?(value) urlish = URL_KEYS.include?(key.to_s) || key.to_s.end_with?("_uri", "_url") return true if urlish && !valid_url?(value) false end |
.sanitize_config(data) ⇒ Object
Deeply sanitize configuration Hash values.
- All strings longer than MAX_LEN are removed
- Keys that look like URLs (URL_KEYS or end with _uri/_url) must pass valid_url?
Returns [sanitized_hash, invalid_paths]
invalid_paths: array of strings like “authors[2]” or “funding_uri”
45 46 47 48 49 |
# File 'lib/floss_funding/validators.rb', line 45 def sanitize_config(data) invalids = [] sanitized = deep_sanitize(data, [], invalids) [sanitized, invalids] end |
.string_too_long?(value) ⇒ Boolean
Returns true if value is a String and longer than MAX_LEN
19 20 21 |
# File 'lib/floss_funding/validators.rb', line 19 def string_too_long?(value) value.is_a?(String) && value.length > MAX_LEN end |
.valid_url?(value) ⇒ Boolean
Minimal WHATWG-like validation suitable for our needs without extra deps.
- Accept only http/https
- Must have a host
- Full string length <= 512
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/floss_funding/validators.rb', line 27 def valid_url?(value) return false unless value.is_a?(String) return false if value.length > MAX_LEN begin u = URI.parse(value) return false unless %w[http https].include?(u.scheme) return false if u.host.nil? || u.host.empty? true rescue URI::InvalidURIError, ArgumentError false end end |