Module: Jamf::Validate

Defined in:
lib/jamf/validate.rb

Overview

A collection of methods for validating values. Mostly for ensuring the validity of data being set as attributes of APIObject subclass instances.

Some of these methods can take multiple input types, such as a String or an Array. 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. an Array, even if given a String)

Constant Summary collapse

MAC_ADDR_RE =

The regular expression that matches a valid MAC address.

/^[a-f0-9]{2}(:[a-f0-9]{2}){5}$/i.freeze
TRUE_FALSE =
[true, false].freeze
SCRIPT_SHEBANG =
'#!'.freeze

Class Method Summary collapse

Class Method Details

.boolean(val, msg = 'Value must be true or false, or equivalent string or symbol') ⇒ Boolean

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

Parameters:

  • val (Boolean, String, Symbol)

    The value to validate

  • msg (String) (defaults to: 'Value must be true or false, or equivalent string or symbol')

    A custom error message when the value is invalid

Returns:

  • (Boolean)

    the valid boolean

Raises:



149
150
151
152
153
154
155
# File 'lib/jamf/validate.rb', line 149

def self.boolean(val, msg = 'Value must be true or false, or equivalent string or symbol')
  return val if TRUE_FALSE.include? val
  return true if val.to_s =~ /^(t(rue)?|y(es)?)$/i
  return false if val.to_s =~ /^(f(alse)?|no?)$/i

  raise Jamf::InvalidDataError, msg
end

.doesnt_exist(val, klass, identifier, msg = nil, cnx: Jamf.cnx) ⇒ Object

Validate that a value doesn’t already exist for a given identifier of a given CollectionResource class

e.g. when klass = Jamf::Computer, identifier = :name, and val = ‘foo’ will raise an error when a computer named ‘foo’ already exists

Otherwise returns val.

Parameters:

  • val (Object)

    The value to check for uniqueness

  • klass (Jamf::CollectionResource)

    A descendent of Jamf::CollectionResource, e.g. Jamf::Computer

  • identifier (Symbol)

    One of the values of klass.identifiers

  • msg (String) (defaults to: nil)

    A custom error message when the value is invalid

  • cnx (Jamf::Connection) (defaults to: Jamf.cnx)

    The api connection to use for validation

Returns:

  • (Object)

    the validated unique value

Raises:



126
127
128
129
130
131
132
133
134
# File 'lib/jamf/validate.rb', line 126

def self.doesnt_exist(val, klass, identifier, msg = nil, cnx: Jamf.cnx)
  msg ||= "A #{klass} already exists with #{identifier} '#{val}'"

  raise Jamf::InvalidDataError, "No identifier '#{identifier}' for #{klass}" unless klass.identifiers.include? identifier

  return val unless klass.send("all_#{identifier}s", :refresh, cnx: cnx).include? val

  raise Jamf::AlreadyExistsError, msg
end

.float(val, msg = 'Value must be a Floating Point number') ⇒ Float

Confirm that a value is a Float or a String representation of a Float. Return the Float, or raise an error

Parameters:

  • val (Object)

    the value to validate

  • msg (String) (defaults to: 'Value must be a Floating Point number')

    A custom error message when the value is invalid

Returns:

  • (Float)

    the valid float

Raises:



204
205
206
207
208
209
# File 'lib/jamf/validate.rb', line 204

def self.float(val, msg = 'Value must be a Floating Point number')
  val = val.to_f if val.is_a?(String) && val.j_float?
  raise Jamf::InvalidDataError, msg unless val.is_a? Float

  val
end

.in_enum(val, enum) ⇒ Symbol

Does a value exist in a given enum array?

Parameters:

  • klass (<JSONObject] A class descended from JSONObject)

    lass [<JSONObject] A class descended from JSONObject

  • attr_name (Symbol)

    The attribute to validate

Returns:

  • (Symbol)

    The valid attribute

Raises:



100
101
102
103
104
# File 'lib/jamf/validate.rb', line 100

def self.in_enum(val, enum)
  raise Jamf::InvalidDataError, "Value must be one of: #{enum.join ', '}" unless enum.include? val

  val
end

.integer(val, msg = 'Value must be an Integer') ⇒ Integer

Confirm that a value is an Integer or a String representation of an Integer. Return the integer, or raise an error

Parameters:

  • val (Object)

    the value to validate

  • msg (String) (defaults to: 'Value must be an Integer')

    A custom error message when the value is invalid

Returns:

  • (Integer)

    the valid integer

Raises:



188
189
190
191
192
193
# File 'lib/jamf/validate.rb', line 188

def self.integer(val, msg = 'Value must be an Integer')
  val = val.to_i if val.is_a?(String) && val.j_integer?
  raise Jamf::InvalidDataError, msg unless val.is_a? Integer

  val
end

.ip_address(val, msg = nil) ⇒ String

Validate the format and content of an IPv4 address

Parameters:

  • val (String)

    The value to validate

  • msg (String) (defaults to: nil)

    A custom error message when the value is invalid

Returns:

  • (String)

    The valid value

Raises:



65
66
67
68
69
70
71
72
73
74
# File 'lib/jamf/validate.rb', line 65

def self.ip_address(val, msg = nil)
  msg ||= "Not a valid IPv4 address: '#{val}'"
  ok = true
  parts = val.strip.split '.'
  ok = false unless parts.size == 4
  parts.each { |p| ok = false unless p.j_integer? && p.to_i < 256 && p.to_i >= 0 }
  raise Jamf::InvalidDataError, msg unless ok

  val
end

.j_id(val, msg = 'Value must be an Integer or an Integer in a String, e.g. "42"') ⇒ String

Confirm that a value provided is an integer or a string version of an integer, and return the string version

The JPAPI specs say that all IDs are integers in strings tho, the endpoints are still implementing that in different versions.

Parameters:

  • val (Object)

    the value to validate

  • msg (String) (defaults to: 'Value must be an Integer or an Integer in a String, e.g. "42"')

    A custom error message when the value is invalid

Returns:

  • (String)

    the valid integer-in-a-string

Raises:



169
170
171
172
173
174
175
176
177
# File 'lib/jamf/validate.rb', line 169

def self.j_id(val, msg = 'Value must be an Integer or an Integer in a String, e.g. "42"')
  case val
  when Integer
    return val.to_s
  when String
    return val if val.j_integer?
  end
  raise Jamf::InvalidDataError, msg
end

.json_attribute_name(klass, attr_name) ⇒ Symbol

Does a given JSONObject class have a given JSON attribute?

Parameters:

  • klass (<JSONObject] A class descended from JSONObject)

    lass [<JSONObject] A class descended from JSONObject

  • attr_name (Symbol)

    The attribute to validate

Returns:

  • (Symbol)

    The valid attribute

Raises:



84
85
86
87
88
89
90
# File 'lib/jamf/validate.rb', line 84

def self.json_attribute_name(klass, attr_name)
  raise "#{klass} is not a descendent of JSONObject" unless klass < Jamf::JSONObject

  raise Jamf::NoSuchItemError, "No attribute #{attr_name} for class #{klass}" unless klass::OBJECT_MODEL.key? attrib

  attr_name
end

.mac_address(val, msg = nil) ⇒ String

Validate the format and content of a MAC address

Parameters:

  • val (String)

    The value to validate

  • msg (String) (defaults to: nil)

    A custom error message when the value is invalid

Returns:

  • (String)

    The valid value

Raises:



50
51
52
53
54
55
# File 'lib/jamf/validate.rb', line 50

def self.mac_address(val, msg = nil)
  msg ||= "Not a valid MAC address: '#{val}'"
  raise Jamf::InvalidDataError, msg unless val =~ MAC_ADDR_RE

  val
end

.non_empty_string(val, msg = 'value must be a non-empty String') ⇒ String

validate that the given value is a non-empty string Symbols are accepted and returned as strings

Parameters:

  • val (Object)

    the thing to validate

  • msg (String) (defaults to: 'value must be a non-empty String')

    A custom error message when the value is invalid

Returns:

  • (String)

    the valid non-empty string

Raises:



238
239
240
241
242
243
# File 'lib/jamf/validate.rb', line 238

def self.non_empty_string(val, msg = 'value must be a non-empty String')
  val = val.to_s if val.is_a? Symbol
  raise Jamf::InvalidDataError, msg unless val.is_a?(String) && !val.empty?

  val
end

.script_contents(val, msg = "value must be a String starting with '#!'") ⇒ String

validate that the given value is a string that starts with #!

Parameters:

  • val (Object)

    the thing to validate

  • msg (String) (defaults to: "value must be a String starting with '#!'")

    A custom error message when the value is invalid

Returns:

  • (String)

    the validated string

Raises:



255
256
257
258
259
# File 'lib/jamf/validate.rb', line 255

def self.script_contents(val, msg = "value must be a String starting with '#!'")
  raise Jamf::InvalidDataError, msg unless val.is_a?(String) && val.start_with?(SCRIPT_SHEBANG)

  val
end

.string(val, msg = 'Value must be a String') ⇒ String

Confirm that a value is a string, symbol, or nil, all of which will be returned as a string

Parameters:

  • val (Object)

    the value to validate

  • msg (String) (defaults to: 'Value must be a String')

    A custom error message when the value is invalid

Returns:

  • (String)

    the valid String

Raises:



220
221
222
223
224
225
226
227
# File 'lib/jamf/validate.rb', line 220

def self.string(val, msg = 'Value must be a String')
  return Jamf::BLANK if val.nil?

  val = val.to_s if val.is_a? Symbol
  raise Jamf::InvalidDataError, msg unless val.is_a? String

  val
end