module Jamf::OAPIValidate
A collection of methods implementing data constraints as defined in the OAPI3 standard. See
swagger.io/docs/specification/data-models/data-types/
This module is extended into Jamf::Validate
, where these become module methods
As with that module: Some of these methods can take multiple input types, such as a String
or an number. All of them will either raise an exception if the value isn’t valid, or will return a standardized form of the input (e.g. a number, even if given a String
)
IMPORTANT - This module MUST be extended into Jamf::Validate
.
Public Instance Methods
Confirm that the given value is a boolean value, accepting strings and symbols and returning real booleans as needed Accepts: true, false, ‘true’, ‘false’, ‘yes’, ‘no’, ‘t’,‘f’, ‘y’, or ‘n’ as strings or symbols, case insensitive
TODO: use this throughout ruby-jss
@param val [Boolean,String,Symbol] The value to validate
@param msg A custom error message when the value is invalid
@return [Boolean] the valid boolean
# File lib/jamf/oapi_validate.rb 184 def boolean(val, attr_name: nil, msg: nil) 185 return val if Jamf::TRUE_FALSE.include? val 186 return true if val.to_s =~ /^(t(rue)?|y(es)?)$/i 187 return false if val.to_s =~ /^(f(alse)?|no?)$/i 188 189 raise_invalid_data_error(msg || "#{attr_name} value must be boolean true or false, or an equivalent string or symbol") 190 end
validate that a value is of a specific class
@param val [Object] The value to validate
@param klass [Class, Symbol] The class which the val must be an instance of
@param msg A custom error message when the value is invalid
@return [Object] the valid value
# File lib/jamf/oapi_validate.rb 161 def class_instance(val, klass:, attr_name: nil, msg: nil) 162 return val if val.instance_of? klass 163 164 # try to instantiate the class with the value. It should raise an error 165 # if not good 166 klass.new val 167 rescue => e 168 raise_invalid_data_error(msg || "#{attr_name} value must be a #{klass}, or #{klass}.new must accept it as the only parameter, but #{klass}.new raised: #{e.class}: #{e}") 169 end
Confirm that a value is a Float or a string representation of a Float Return the Float, or raise an error
@param val the value to validate
@param msg A custom error message when the value is invalid
@return [Float]
# File lib/jamf/oapi_validate.rb 243 def float(val, attr_name: nil, msg: nil) 244 val = val.to_f if val.is_a?(Integer) 245 val = val.to_f if val.is_a?(String) && (val.j_float? || val.j_integer?) 246 return val if val.is_a? Float 247 248 raise_invalid_data_error(msg || "#{attr_name} value must be an floating point number") 249 end
run all the possible validations on an integer
# File lib/jamf/oapi_validate.rb 111 def fully_validate_integer(val, attr_def:, attr_name: nil) 112 val = integer val, attr_name: attr_name 113 validate_numeric_constraints(val, attr_def: attr_def, attr_name: attr_name) 114 end
run all the possible validations on a ‘number’
# File lib/jamf/oapi_validate.rb 117 def fully_validate_number(val, attr_def:, attr_name: nil) 118 val = 119 if %w[float double].include? attr_def[:format] 120 float val, attr_name: attr_name 121 else 122 number val, attr_name: attr_name 123 end 124 validate_numeric_constraints(val, attr_def: attr_def, attr_name: attr_name) 125 end
run all the possible validations on a string
# File lib/jamf/oapi_validate.rb 100 def fully_validate_string(val, attr_def:, attr_name: nil) 101 val = string val, attr_name: attr_name 102 103 min_length val, min: attr_def[:min_length], attr_name: attr_name if attr_def[:min_length] 104 max_length val, max: attr_def[:max_length], attr_name: attr_name if attr_def[:max_length] 105 matches_pattern val, attr_def[:pattern], attr_name: attr_name if attr_def[:pattern] 106 107 val 108 end
Does a value exist in a given enum array?
@param val [Object] The thing that must be in the enum
@param enum [Array] the enum of allowed values
@param msg A custom error message when the value is invalid
@return [Object] The valid object
# File lib/jamf/oapi_validate.rb 478 def in_enum(val, enum:, attr_name: nil, msg: nil) 479 return val if enum.include? val 480 481 raise_invalid_data_error(msg || "#{attr_name} value must be one of: #{enum.join ', '}") 482 end
Confirm that a value is an integer or a string representation of an integer. Return the integer, or raise an error
@param val the value to validate
@param msg A custom error message when the value is invalid
@return [Integer]
# File lib/jamf/oapi_validate.rb 227 def integer(val, attr_name: nil, msg: nil) 228 val = val.to_i if val.is_a?(String) && val.j_integer? 229 return val if val.is_a? Integer 230 231 raise_invalid_data_error(msg || "#{attr_name} value must be an integer") 232 end
Does a string match a given regular expression?
@param val [String] The value to match
@param pattern [pattern] the regular expression
@param msg A custom error message when the value is invalid
@return [Object] The valid object
# File lib/jamf/oapi_validate.rb 494 def matches_pattern(val, pattern:, attr_name: nil, msg: nil) 495 return val if val =~ pattern 496 497 raise_invalid_data_error(msg || "#{attr_name} value does not match RegExp: #{pattern}") 498 end
validate that the given value contains no more than some maximum number of items
While this is intended for Arrays, it will work for any object that responds to size
@param val [Object] the value to validate
@param max [Object] the maximum number of items allowed
@param msg [String] A custom error message when the value is invalid
@return [String] the valid value
# File lib/jamf/oapi_validate.rb 432 def max_items(val, max:, attr_name: nil, msg: nil) 433 raise ArgumentError, 'max must be a number' unless max.is_a?(Numeric) 434 return val if val.size <= max 435 436 raise_invalid_data_error(msg || "#{attr_name} value must contain no more than #{max} items") 437 end
validate that the given value’s length is less than or equal to some maximum
While this is intended for Strings, it will work for any object that responds to length
@param val [Object] the value to validate
@param max [Object] the maximum length allowed
@param msg [String] A custom error message when the value is invalid
@return [String] the valid value
# File lib/jamf/oapi_validate.rb 392 def max_length(val, max:, attr_name: nil, msg: nil) 393 raise ArgumentError, 'max must be a number' unless max.is_a?(Numeric) 394 return val if val.length <= max 395 396 raise_invalid_data_error(msg || "length of #{attr_name} value must be <= #{max}") 397 end
validate that the given value is less than or equal to some maximum
While intended for Numbers, this will work for any Comparable objects
If exclusive, the max value is excluded from the range and the value must be less than the max.
@param val [Object] the thing to validate
@param max A value that the val must be less than or equal to
@param exclusuve [Boolean] Should the max be excluded from the valid range?
true: val must be < max, false: val must be <= max
@param msg A custom error message when the value is invalid
@return [String] the valid value
# File lib/jamf/oapi_validate.rb 330 def maximum(val, max:, attr_name: nil, exclusive: false, msg: nil) 331 if exclusive 332 return val if val < max 333 elsif val <= max 334 return val 335 end 336 raise_invalid_data_error(msg || "#{attr_name} value must be <= #{max}") 337 end
validate that the given value contains at least some minimum number of items
While this is intended for Arrays, it will work for any object that responds to size
@param val [Object] the value to validate
@param min [Object] the minimum number of items allowed
@param msg [String] A custom error message when the value is invalid
@return [String] the valid value
# File lib/jamf/oapi_validate.rb 412 def min_items(val, min:, attr_name: nil, msg: nil) 413 raise ArgumentError, 'min must be a number' unless min.is_a?(Numeric) 414 return val if val.size >= min 415 416 raise_invalid_data_error(msg || "#{attr_name} value must contain at least #{min} items") 417 end
validate that the given value’s length is greater than or equal to some minimum
While this is intended for Strings, it will work for any object that responds to length
@param val [Object] the value to validate
@param min [Object] The minimum length allowed
@param msg [String] A custom error message when the value is invalid
@return [String] the valid value
# File lib/jamf/oapi_validate.rb 372 def min_length(val, min:, attr_name: nil, msg: nil) 373 raise ArgumentError, 'min must be a number' unless min.is_a?(Numeric) 374 return val if val.length >= min 375 376 raise_invalid_data_error(msg || "length of #{attr_name} value must be >= #{min}") 377 end
validate that the given value is greater than or equal to some minimum
If exclusive, the min value is excluded from the range and the value must be greater than the min.
While intended for Numbers, this will work for any Comparable objects
@param val [Object] the thing to validate
@param min [Object] A value that the val must be greater than or equal to
@param exclusuve [Boolean] Should the min be excluded from the valid range?
true: val must be > min, false: val must be >= min
@param msg [String] A custom error message when the value is invalid
@return [String] the valid value
# File lib/jamf/oapi_validate.rb 303 def minimum(val, min:, attr_name: nil, exclusive: false, msg: nil) 304 if exclusive 305 return val if val > min 306 elsif val >= min 307 return val 308 end 309 raise_invalid_data_error(msg || "#{attr_name} value must be >= #{min}") 310 end
Validate
that a given number is multiple of some other given number
@param val [Number] the number to validate
@param multiplier [Number] the number what the val must be a multiple of.
this must be positive.
@param msg A custom error message when the value is invalid
@return [String] the valid value
# File lib/jamf/oapi_validate.rb 350 def multiple_of(val, multiplier:, attr_name: nil, msg: nil) 351 raise ArgumentError, 'multiplier must be a positive number' unless multiplier.is_a?(Numeric) && multiplier.positive? 352 raise Jamf::InvalidDataError, 'Value must be a number' unless val.is_a?(Numeric) 353 354 return val if (val % multiplier).zero? 355 356 raise_invalid_data_error(msg || "#{attr_name} value must be a multiple of #{multiplier}") 357 end
validate that a value is not nil
@param val the value to validate
@param msg A custom error message when the value is invalid
@return [Object] the valid value
# File lib/jamf/oapi_validate.rb 462 def not_nil(val, attr_name: nil, msg: nil) 463 return val unless val.nil? 464 465 raise_invalid_data_error(msg || "#{attr_name} value may not be nil") 466 end
Confirm that a value is an number or a string representation of an number. Return the number, or raise an error
@param val the value to validate
@param msg A custom error message when the value is invalid
@return [Integer]
# File lib/jamf/oapi_validate.rb 201 def number(val, attr_name: nil, msg: nil) 202 if val.ia_a?(Integer) || val.is_a?(Float) 203 return val 204 205 elsif val.is_a?(String) 206 207 if val.j_integer? 208 return val.to_i 209 elsif val.j_float? 210 return val.to_f 211 end 212 213 end 214 215 raise_invalid_data_error(msg || "#{attr_name} value must be a number") 216 end
Validate
that a value is valid based on its definition in an objects OAPI_PROPERTIES constant.
@param val [Object] The value to validate
@param klass [Class, Symbol] The class which the val must be
@param msg A custom error message when the value is invalid
@return [Boolean] the valid boolean
# File lib/jamf/oapi_validate.rb 56 def oapi_attr(val, attr_def:, attr_name: nil) 57 # check that the new val is not nil unless nil is OK 58 val = not_nil(val, attr_name: attr_name) unless attr_def[:nil_ok] 59 60 # if the new val is nil here, then nil is OK andd we shouldn't 61 # check anything else 62 return val if val.nil? 63 64 val = 65 case attr_def[:class] 66 when :j_id 67 Jamf::Validate.j_id value, attr_name: attr_name 68 69 when Class 70 class_instance val, klass: attr_def[:class], attr_name: attr_name 71 72 when :boolean 73 boolean val, attr_name: attr_name 74 75 when :string 76 fully_validate_string(val, attr_def: attr_def, attr_name: attr_name) 77 78 when :integer 79 fully_validate_integer(val, attr_def: attr_def, attr_name: attr_name) 80 81 when :number 82 fully_validate_number(val, attr_def: attr_def, attr_name: attr_name) 83 84 when :hash 85 hash val, attr_name: attr_name 86 87 end # case 88 89 # Now that the val is in whatever correct format after the above tests, 90 # we test for enum membership if needed 91 # otherwise, just return the val 92 if attr_def[:enum] 93 in_enum val, enum: attr_def[:enum], attr_name: attr_name 94 else 95 val 96 end 97 end
Confirm that a value is a Hash
Return the Hash
, or raise an error
@param val the value to validate
@param msg A custom error message when the value is invalid
@return [Hash]
# File lib/jamf/oapi_validate.rb 260 def object(val, attr_name: nil, msg: nil) 261 return val if val.is_a? Hash 262 263 raise_invalid_data_error(msg || "#{attr_name} value must be a Hash") 264 end
Confirm that a value is a String
Return the String
, or raise an error
@param val the value to validate
@param msg A custom error message when the value is invalid
@param to_s: [Boolean] If true, this method always succeds and returns
the result of calling #to_s on the value
@return [Hash]
# File lib/jamf/oapi_validate.rb 278 def string(val, attr_name: nil, msg: nil, to_s: false) 279 val = val.to_s if to_s 280 return val if val.is_a? String 281 282 raise_invalid_data_error(msg || "#{attr_name} value must be a String") 283 end
validate that an array has only unique items, no duplicate values
@param val [Array] The array to validate
@param msg [String] A custom error message when the value is invalid
@param return [Array] the valid array
# File lib/jamf/oapi_validate.rb 447 def unique_array(val, attr_name: nil, msg: nil) 448 raise ArgumentError, 'Value must be an Array' unless val.is_a?(Array) 449 return val if val.uniq.size == val.size 450 451 raise_invalid_data_error(msg || "#{attr_name} value must contain only unique items") 452 end
run the array constraint validations for an array value. The individual array items must already be validated
# File lib/jamf/oapi_validate.rb 143 def validate_array_constraints(val, attr_def:, attr_name: nil) 144 min_items val, min: attr_def[:minItems], attr_name: attr_name if attr_def[:minItems] 145 max_items val, max: attr_def[:maxItems], attr_name: attr_name if attr_def[:maxItems] 146 unique_array val, attr_name: attr_name if attr_def[:uniqueItems] 147 148 val 149 end
run the numeric constraint validations for any numeric value The number itself must already be validated
# File lib/jamf/oapi_validate.rb 129 def validate_numeric_constraints(val, attr_def:, attr_name: nil) 130 ex_min = attr_def[:exclusive_minimum] 131 ex_max = attr_def[:exclusive_maximum] 132 mult_of = attr_def[:multiple_of] 133 134 minimum val, min: attr_def[:minimum], exclusive: ex_min, attr_name: attr_name if attr_def[:minimum] 135 maximum val, max: attr_def[:maximum], exclusive: ex_max, attr_name: attr_name if attr_def[:maximum] 136 multiple_of val, multiplier: mult_of, attr_name: attr_name if mult_of 137 138 val 139 end