ruby-jss 2.1.0b5 → 2.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e4edfd42bf486020f780c565948d0b6de6db11413eaaf2f5a486243d8137a76
4
- data.tar.gz: 0c3b1e370c9f1ffdcf97f7174b0dbc508f3c414efc5a86a0b5b09e0c42ba4e3f
3
+ metadata.gz: efe85ea732df2a1ce119273c532084459fdb9ebe6316d62ab7afa533d9c4adc8
4
+ data.tar.gz: e42de1baecb51f2886d704e63818d24063d4332a0b17170c2977aa3e336656a5
5
5
  SHA512:
6
- metadata.gz: 7fd967954cc7642ec10054fff0c2d75f3dd30bce1836baf158a1fb4abe4f5d8a95ca493e9c1ef2b03fe1490874fdbf3f42b81af46389c7a86a6a73bdaeb867c2
7
- data.tar.gz: f806304ae8b9fad9fae2ffc35b77681a26cf2bfd63dc202b5a52f25b43e2e278fda62321f05e0c3f47a6e063238b5eda86ec870814a971fb13e7631ecfa04f5a
6
+ metadata.gz: 6a0874d08b6c7fc3aa93c207c81ab3a09c0b822e5f035ddb5192144d04fbe3a846db6c6528a8150cd81a2ee9f994155d4b7ba396d11ef7ecf565c9330b99aae6
7
+ data.tar.gz: fb3bdf758de69f290974def92a42ff279f1c98611373116304fbe618b0536f59361d892c3444db88c952c2208bb7cfbf0763cba8a959bd84cffb3ca5f8bee8e7
data/CHANGES.md CHANGED
@@ -14,7 +14,19 @@ __Please update all installations of ruby-jss to at least v1.6.0.__
14
14
 
15
15
  Many many thanks to actae0n of Blacksun Hackers Club for reporting this issue and providing examples of how it could be exploited.
16
16
 
17
- ## \[2.1.0] - unreleased
17
+ --------
18
+
19
+ ## \[2.1.1] - 2022-11-07
20
+
21
+ ### Fixed & Deprecated
22
+
23
+ - The classic API no longer includes SHA256 hashes of various passwords - the data value is there, but only contains a string of asterisks. As such, ruby-jss can no longer use those to validate some passwords before trying to use them. The methods doing so are still present, but only return `true`. If an incorrect password is given, the underlying process that uses it will fail on its own.
24
+ These methods will be removed in a future version of ruby-jss:
25
+ - `Jamf::DistributionPoint#check_pw` Used mostly by the `Jamf::DistributionPoint#mount` method
26
+ - `Jamf::Policy.verify_management_password`
27
+
28
+
29
+ ## \[2.1.0] - 2022-10-10
18
30
 
19
31
  ### Added
20
32
 
@@ -34,6 +46,8 @@ Many many thanks to actae0n of Blacksun Hackers Club for reporting this issue an
34
46
  - A few internal rescues of a deprecated exception class
35
47
  - Removed auto-loading of deprecation files; now explicitly loaded.
36
48
  - A few Ruby 2 => Ruby 3 bugs - method params needing double-splats (Thanks to @Timelost for reporting this one)
49
+ - Ensure resource paths don't start with a slash
50
+ - Setting the timeouts on an existing API connection object now works.
37
51
 
38
52
  ## \[2.0.0] - 2022-09-12
39
53
 
data/bin/cgrouper CHANGED
@@ -55,7 +55,7 @@ class App
55
55
  ###
56
56
  ### set up
57
57
  ###
58
- def initialize(**_args)
58
+ def initialize
59
59
  @debug = false
60
60
 
61
61
  # define the options
@@ -207,7 +207,7 @@ class App
207
207
 
208
208
  # smart groups can't have some things done to them
209
209
  if ACTIONS_FOR_STATIC_GROUPS_ONLY.include? @options.action and @group.smart?
210
- raise InvalidTypeError,
210
+ raise InvalidTypeError,
211
211
  "You can't do that to a smart group. Use the JSS WebApp if needed."
212
212
  end
213
213
 
@@ -384,7 +384,6 @@ Notes:
384
384
  return unless @options.action == :create_group or confirm "add computers to group '#{@group.name}'"
385
385
 
386
386
  @options.computers.each do |c|
387
-
388
387
  @group.add_member c
389
388
  rescue JSS::NoSuchItemError
390
389
  puts "#{$!} - skipping"
@@ -404,11 +403,9 @@ Notes:
404
403
  return unless confirm "remove computers from group '#{@group.name}'"
405
404
 
406
405
  @options.computers.each do |c|
407
-
408
406
  @group.remove_member c
409
407
  rescue JSS::NoSuchItemError
410
408
  puts "#{$!} - skipping"
411
-
412
409
  end
413
410
  @group.update
414
411
  end
@@ -459,7 +456,7 @@ end # class App
459
456
 
460
457
  #######################################
461
458
  begin
462
- app = App.new(ARGV)
459
+ app = App.new
463
460
  app.run
464
461
  rescue
465
462
  # handle exceptions not handled elsewhere
data/bin/netseg-update CHANGED
@@ -55,13 +55,13 @@ class App
55
55
 
56
56
  USAGE = "Usage: #{PROG_NAME} [options] [--help] /path/to/file".freeze
57
57
 
58
- POTENTIAL_COLUMNS = %i(name starting ending cidr mask).freeze
58
+ POTENTIAL_COLUMNS = %i[name starting ending cidr mask].freeze
59
59
 
60
60
  DEFAULT_CACHE_FILE = Pathname.new('~/.last_subnet_update').expand_path
61
61
 
62
62
  DEFAULT_DELIMITER = "\t".freeze
63
63
 
64
- DEFAULT_COLUMNS = [:name, :starting, :ending].freeze
64
+ DEFAULT_COLUMNS = %i[name starting ending].freeze
65
65
 
66
66
  DEFAULT_MANUAL_PREFIX = 'Manual-'.freeze
67
67
 
@@ -84,7 +84,7 @@ class App
84
84
 
85
85
  attr_reader :debug
86
86
 
87
- def initialize(_args)
87
+ def initialize
88
88
  @getpass = $stdin.tty? ? :prompt : :stdin
89
89
  set_defaults
90
90
  parse_cli
@@ -183,7 +183,7 @@ Options:
183
183
  -V, --no-verify-cert - Allow self-signed, unverified SSL certificate
184
184
  -T, --timeout secs - specify the JSS API timeout
185
185
  -N, --no-op - Don't make any changes in the JSS, just report what would
186
- have be changed.
186
+ have been changed.
187
187
  -H, --help - show this help
188
188
  --debug - show the ruby backtrace when errors occur
189
189
 
@@ -254,6 +254,7 @@ Notes:
254
254
  lines.each do |line|
255
255
  parsed_line = parse_a_data_line line
256
256
  next unless parsed_line
257
+
257
258
  name = parsed_line.delete :name
258
259
  parsed_data[name] = parsed_line
259
260
  end
@@ -273,6 +274,7 @@ Notes:
273
274
  @columns.include?(:ending) || \
274
275
  @columns.include?(:cidr) || \
275
276
  @columns.include?(:mask)
277
+
276
278
  @use_cidr = (@columns.include?(:cidr) || @columns.include?(:mask))
277
279
  end
278
280
 
@@ -296,11 +298,13 @@ Notes:
296
298
  # read in the file
297
299
  @raw_data = @file.read
298
300
  return true unless @cache_file.exist?
301
+
299
302
  @raw_data != @cache_file.read
300
303
  end
301
304
 
302
305
  def cache_latest_data
303
306
  return if @noop
307
+
304
308
  @cache_file.jss_save @raw_data
305
309
  end
306
310
 
@@ -375,7 +379,7 @@ end # app
375
379
  # create the app and go
376
380
  begin
377
381
  debug = ARGV.include? '--debug'
378
- app = App.new(ARGV)
382
+ app = App.new
379
383
  app.run
380
384
  rescue
381
385
  # handle exceptions not handled elsewhere
@@ -440,7 +440,7 @@ module Jamf
440
440
  cnx = api if api
441
441
 
442
442
  id = valid_id ident, cnx: cnx
443
- raise "No computer matches identifier: #{ident}" unless id
443
+ raise Jamf::NoSuchItemError, "No computer matches identifier: #{ident}" unless id
444
444
 
445
445
  end_date ||= start_date
446
446
  start_date = Jamf.parse_time start_date
@@ -259,8 +259,8 @@ module Jamf
259
259
  attr_reader :ssh_password_sha256
260
260
 
261
261
  def initialize(**args)
262
- super
263
-
262
+ super
263
+
264
264
  @ip_address = @init_data[:ip_address]
265
265
  @local_path = @init_data[:local_path]
266
266
  @enable_load_balancing = @init_data[:enable_load_balancing]
@@ -294,44 +294,28 @@ module Jamf
294
294
 
295
295
  @port = @init_data[:ssh_password]
296
296
 
297
- # Note, as of Casper 9.3:
298
- # :management_password_md5=>"xxxxx"
299
- # and
300
- # :management_password_sha256=> "xxxxxxxxxx"
301
- # Are the read/write password
302
- #
303
- # An empty passwd is
304
- # MD5 = d41d8cd98f00b204e9800998ecf8427e
305
- # SHA256 = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
306
- #
307
- # Seemms the read-only pw isn't available in the API
308
-
309
297
  # if we mount for fileservice, where's the mountpoint?
310
298
  @mountpoint = DEFAULT_MOUNTPOINT_DIR + "#{DEFAULT_MOUNTPOINT_PREFIX}#{@id}"
311
299
  end # init
312
300
 
313
- # Check the validity of a password.
301
+ # @deprecated The API no longer sends SHA256 hashed password data, and instead
302
+ # only has a string of asterisks, meaning we can no longer use it to validate
303
+ # passwords before attempting to use them. Instead, the processes that use
304
+ # them, e.g. mounting a Dist. Point, will fail on their own if the pw is not
305
+ # valid.
314
306
  #
315
- # @param user[Symbol] one of :ro, :rw, :ssh, :http
307
+ # This method remains defined for backward-compatibility with any existing
308
+ # code that calls it. but it will always return true. It will be removed in
309
+ # a future version
316
310
  #
317
- # @param pw[String] the password to check for the given user
311
+ # @param user[Symbol] ignored
318
312
  #
319
- # @return [Boolean,Nil] was the password correct?
320
- # nil is returned if there is no password set in the JSS.
313
+ # @param pw[String] ignored
321
314
  #
322
- def check_pw(user, pw)
323
- raise Jamf::InvalidDataError, 'The first parameter must be one of :ro, :rw, :ssh, :http' unless %i[ro rw ssh http].include? user
324
-
325
- sha256 = case user
326
- when :rw then @read_write_password_sha256
327
- when :ro then @read_only_password_sha256
328
- when :http then @http_password_sha256
329
- when :ssh then @ssh_password_sha256
330
- end # case
331
-
332
- return nil if sha256 == EMPTY_PW_256
333
-
334
- sha256 == Digest::SHA2.new(256).update(pw).to_s
315
+ # @return [TrueClass] Allow the process calling this to continue.
316
+ #
317
+ def check_pw(_user = nil, _pw = nil)
318
+ true
335
319
  end
336
320
 
337
321
  # Check to see if this dist point is reachable for downloads (read-only)
@@ -350,7 +334,6 @@ module Jamf
350
334
  def reachable_for_download?(pw = '', check_http = true)
351
335
  return :http if check_http && http_reachable?(pw)
352
336
  return :mountable if mounted?
353
- return false unless check_pw :ro, pw
354
337
 
355
338
  begin
356
339
  mount pw, :ro
@@ -371,7 +354,6 @@ module Jamf
371
354
  #
372
355
  def reachable_for_upload?(pw)
373
356
  return :mountable if mounted?
374
- return false unless check_pw :rw, pw
375
357
 
376
358
  begin
377
359
  mount pw, :rw
@@ -413,12 +395,6 @@ module Jamf
413
395
  pw
414
396
  end
415
397
 
416
- pwok = check_pw(access, password)
417
- unless pwok
418
- msg = pwok.nil? ? "No #{access} password set in the JSS" : "Incorrect password for #{access} account"
419
- raise Jamf::InvalidDataError, msg
420
- end
421
-
422
398
  username = access == :ro ? @read_only_username : @read_write_username
423
399
 
424
400
  safe_pw = CGI.escape password.to_s
@@ -481,7 +457,7 @@ module Jamf
481
457
  private
482
458
 
483
459
  # can the dp be reached for http downloads?
484
- def http_reachable?(pw)
460
+ def http_reachable?(pw = nil)
485
461
  return false unless http_downloads_enabled
486
462
 
487
463
  url =
@@ -154,7 +154,7 @@ module Jamf
154
154
  # when fetching a specific version, this is a valid version
155
155
  UNKNOWN_VERSION_ID = 'Unknown'.freeze
156
156
 
157
- REPORTS_RSRC_BASE = '/patchreports/patchsoftwaretitleid'.freeze
157
+ REPORTS_RSRC_BASE = 'patchreports/patchsoftwaretitleid'.freeze
158
158
 
159
159
  # Class Methods
160
160
  #######################################
@@ -233,7 +233,7 @@ module Jamf
233
233
  all(refresh, cnx: cnx).map { |i| i[:source_name_id] }
234
234
  end
235
235
 
236
- # Get a patch report for a softwaretitle, withouth fetching an instance.
236
+ # Get a patch report for a softwaretitle, without fetching an instance.
237
237
  # Defaults to reporting all versions. Specifiying a version will be faster.
238
238
  #
239
239
  # The Hash returned has 3 keys:
@@ -269,6 +269,7 @@ module Jamf
269
269
 
270
270
  # TODO: remove this and adjust parsing when jamf fixes the JSON
271
271
  raw_report = XMLWorkaround.data_via_xml(rsrc, PATCH_REPORT_DATA_MAP, cnx)[:patch_report]
272
+
272
273
  report = {}
273
274
  report[:total_computers] = raw_report[:total_computers]
274
275
  report[:total_versions] = raw_report[:total_versions]
@@ -312,7 +313,7 @@ module Jamf
312
313
  # so all other lookup values have to be converted to ID before
313
314
  # the call to super
314
315
  #
315
- def self.fetch(identifier = nil, **params)
316
+ def self.fetch(identifier = nil, **params)
316
317
  # default connection if unspecified
317
318
  cnx = params.delete :cnx
318
319
  cnx ||= params.delete :api # backward compatibility, deprecated
@@ -472,7 +473,6 @@ module Jamf
472
473
  # wrapper to fetch versions after creating
473
474
  def create
474
475
  super
475
-
476
476
  end
477
477
 
478
478
  # wrapper to clear @changed_pkgs after updating
@@ -166,7 +166,7 @@ module Jamf
166
166
  selected: 'Currently Selected Startup Disk (No Bless)',
167
167
  netboot: 'NetBoot',
168
168
  os_installer: 'inPlaceOSUpgradeDirectory'
169
- }.freeze # Note: any other value in :specify_startup is a path to some other drive to boot from, e.g. /Volumes/Foo
169
+ }.freeze # NOTE: any other value in :specify_startup is a path to some other drive to boot from, e.g. /Volumes/Foo
170
170
 
171
171
  ACCOUNT_ACTIONS = {
172
172
  create: 'Create',
@@ -200,9 +200,9 @@ module Jamf
200
200
  }.freeze
201
201
 
202
202
  DISK_ENCRYPTION_ACTIONS = {
203
- apply: "apply",
204
- remediate: "remediate",
205
- none: "none"
203
+ apply: 'apply',
204
+ remediate: 'remediate',
205
+ none: 'none'
206
206
  }
207
207
 
208
208
  PRINTER_ACTIONS = {
@@ -751,7 +751,7 @@ module Jamf
751
751
  @management_account = amaint[:management_account]
752
752
  @accounts = amaint[:accounts]
753
753
 
754
- @packages = @init_data[:package_configuration][:packages] ? @init_data[:package_configuration][:packages] : []
754
+ @packages = @init_data[:package_configuration][:packages] || []
755
755
 
756
756
  @scripts = @init_data[:scripts]
757
757
 
@@ -815,6 +815,7 @@ module Jamf
815
815
  #
816
816
  def enabled=(new_val)
817
817
  return if @enabled == new_val
818
+
818
819
  @enabled = Jamf::Validate.boolean new_val
819
820
  @need_to_update = true
820
821
  end
@@ -868,9 +869,7 @@ module Jamf
868
869
 
869
870
  # if the event is not 'none' and attempts is <= 0,
870
871
  # set events to 1, or the API won't accept it
871
- unless evt == RETRY_EVENTS[:none]
872
- @retry_attempts = 1 unless @retry_attempts.positive?
873
- end
872
+ @retry_attempts = 1 if !(evt == RETRY_EVENTS[:none]) && !@retry_attempts.positive?
874
873
 
875
874
  @retry_event = evt
876
875
  @need_to_update = true
@@ -934,6 +933,7 @@ module Jamf
934
933
  #
935
934
  def target_drive=(path_to_drive)
936
935
  raise Jamf::InvalidDataError, 'Path to target drive must be absolute' unless path_to_drive.to_s.start_with? '/'
936
+
937
937
  @target_drive = path_to_drive.to_s
938
938
  @need_to_update = true
939
939
  end
@@ -946,6 +946,7 @@ module Jamf
946
946
  #
947
947
  def offline=(new_val)
948
948
  raise Jamf::InvalidDataError, 'New value must be boolean true or false' unless Jamf::TRUE_FALSE.include? new_val
949
+
949
950
  @offline = new_val
950
951
  @need_to_update = true
951
952
  end
@@ -960,6 +961,7 @@ module Jamf
960
961
  #
961
962
  def set_trigger_event(type, new_val)
962
963
  raise Jamf::InvalidDataError, "Trigger type must be one of #{TRIGGER_EVENTS.keys.join(', ')}" unless TRIGGER_EVENTS.key?(type)
964
+
963
965
  if type == :custom
964
966
  raise Jamf::InvalidDataError, 'Custom triggers must be Strings' unless new_val.is_a? String
965
967
  else
@@ -977,6 +979,7 @@ module Jamf
977
979
  #
978
980
  def server_side_activation=(activation)
979
981
  raise Jamf::InvalidDataError, 'Activation must be a Time' unless activation.is_a? Time
982
+
980
983
  @server_side_limitations[:activation] = activation
981
984
  @need_to_update = true
982
985
  end
@@ -989,6 +992,7 @@ module Jamf
989
992
  #
990
993
  def server_side_expiration=(expiration)
991
994
  raise Jamf::InvalidDataError, 'Expiration must be a Time' unless expiration.is_a? Time
995
+
992
996
  @server_side_limitations[:expiration] = expiration
993
997
  @need_to_update = true
994
998
  end
@@ -999,6 +1003,7 @@ module Jamf
999
1003
  #
1000
1004
  def verify_startup_disk=(bool)
1001
1005
  return if @verify_startup_disk == bool
1006
+
1002
1007
  @verify_startup_disk = Jamf::Validate.boolean bool
1003
1008
  @need_to_update = true
1004
1009
  end
@@ -1007,6 +1012,7 @@ module Jamf
1007
1012
  #
1008
1013
  def permissions_repair=(bool)
1009
1014
  return if @permissions_repair == bool
1015
+
1010
1016
  @permissions_repair = Jamf::Validate.boolean bool
1011
1017
  @need_to_update = true
1012
1018
  end
@@ -1015,6 +1021,7 @@ module Jamf
1015
1021
  #
1016
1022
  def recon=(bool)
1017
1023
  return if @recon == bool
1024
+
1018
1025
  @recon = Jamf::Validate.boolean bool
1019
1026
  @need_to_update = true
1020
1027
  end
@@ -1024,6 +1031,7 @@ module Jamf
1024
1031
  #
1025
1032
  def fix_byhost=(bool)
1026
1033
  return if @fix_byhost == bool
1034
+
1027
1035
  @fix_byhost = Jamf::Validate.boolean bool
1028
1036
  @need_to_update = true
1029
1037
  end
@@ -1032,6 +1040,7 @@ module Jamf
1032
1040
  #
1033
1041
  def reset_name=(bool)
1034
1042
  return if @reset_name == bool
1043
+
1035
1044
  @reset_name = Jamf::Validate.boolean bool
1036
1045
  @need_to_update = true
1037
1046
  end
@@ -1040,6 +1049,7 @@ module Jamf
1040
1049
  #
1041
1050
  def flush_system_cache=(bool)
1042
1051
  return if @flush_system_cache == bool
1052
+
1043
1053
  @flush_system_cache = Jamf::Validate.boolean bool
1044
1054
  @need_to_update = true
1045
1055
  end # see attr_reader :recon
@@ -1048,6 +1058,7 @@ module Jamf
1048
1058
  #
1049
1059
  def install_cached_pkgs=(bool)
1050
1060
  return if @install_cached_pkgs == bool
1061
+
1051
1062
  @install_cached_pkgs = Jamf::Validate.boolean bool
1052
1063
  @need_to_update = true
1053
1064
  end
@@ -1056,6 +1067,7 @@ module Jamf
1056
1067
  #
1057
1068
  def flush_user_cache=(bool)
1058
1069
  return if @flush_user_cache == bool
1070
+
1059
1071
  @flush_user_cache = Jamf::Validate.boolean bool
1060
1072
  @need_to_update = true
1061
1073
  end
@@ -1071,6 +1083,7 @@ module Jamf
1071
1083
  #
1072
1084
  def no_user_logged_in=(no_user_option)
1073
1085
  raise Jamf::InvalidDataError, "no_user_logged_in options: #{NO_USER_LOGGED_IN.join(', ')}" unless NO_USER_LOGGED_IN.include? no_user_option
1086
+
1074
1087
  @reboot_options[:no_user_logged_in] = no_user_option
1075
1088
  @need_to_update = true
1076
1089
  end
@@ -1083,6 +1096,7 @@ module Jamf
1083
1096
  #
1084
1097
  def user_logged_in=(logged_in_option)
1085
1098
  raise Jamf::InvalidDataError, "user_logged_in options: #{USER_LOGGED_IN.join(', ')}" unless USER_LOGGED_IN.include? logged_in_option
1099
+
1086
1100
  @reboot_options[:user_logged_in] = logged_in_option
1087
1101
  @need_to_update = true
1088
1102
  end
@@ -1095,6 +1109,7 @@ module Jamf
1095
1109
  #
1096
1110
  def reboot_message=(message)
1097
1111
  raise Jamf::InvalidDataError, 'Reboot message must be a String' unless message.is_a? String
1112
+
1098
1113
  @reboot_options[:message] = message
1099
1114
  @need_to_update = true
1100
1115
  end
@@ -1107,6 +1122,7 @@ module Jamf
1107
1122
  # @return [void] description of returned object
1108
1123
  def user_message_start=(message)
1109
1124
  raise Jamf::InvalidDataError, 'User message must be a String' unless message.is_a? String
1125
+
1110
1126
  @user_message_start = message
1111
1127
  @need_to_update = true
1112
1128
  end
@@ -1118,6 +1134,7 @@ module Jamf
1118
1134
  # @return [void] description of returned object
1119
1135
  def user_message_end=(message)
1120
1136
  raise Jamf::InvalidDataError, 'User message must be a String' unless message.is_a? String
1137
+
1121
1138
  @user_message_finish = message
1122
1139
  @need_to_update = true
1123
1140
  end
@@ -1133,6 +1150,7 @@ module Jamf
1133
1150
  #
1134
1151
  def startup_disk=(startup_disk_option)
1135
1152
  raise Jamf::InvalidDataError, "#{startup_disk_option} is not a valid Startup Disk" unless startup_disk_option.is_a? String
1153
+
1136
1154
  @reboot_options[:startup_disk] = 'Specify Local Startup Disk'
1137
1155
  self.specify_startup = startup_disk_option
1138
1156
  @need_to_update = true
@@ -1147,6 +1165,7 @@ module Jamf
1147
1165
  #
1148
1166
  def specify_startup=(startup_volume)
1149
1167
  raise Jamf::InvalidDataError, "#{startup_volume} is not a valid Startup Disk" unless startup_volume.is_a? String
1168
+
1150
1169
  @reboot_options[:specify_startup] = startup_volume
1151
1170
  @need_to_update = true
1152
1171
  end
@@ -1172,6 +1191,7 @@ module Jamf
1172
1191
  #
1173
1192
  def minutes_until_reboot=(minutes)
1174
1193
  raise Jamf::InvalidDataError, 'Minutes until reboot must be an Integer' unless minutes.is_a? Integer
1194
+
1175
1195
  @reboot_options[:minutes_until_reboot] = minutes
1176
1196
  @need_to_update = true
1177
1197
  end
@@ -1185,6 +1205,7 @@ module Jamf
1185
1205
  #
1186
1206
  def file_vault_2_reboot=(fv_bool)
1187
1207
  raise Jamf::InvalidDataError, 'FileVault 2 Reboot must be a Boolean' unless fv_bool.jss_boolean?
1208
+
1188
1209
  @reboot_options[:file_vault_2_reboot] = fv_bool
1189
1210
  @need_to_update = true
1190
1211
  end
@@ -1206,6 +1227,7 @@ module Jamf
1206
1227
  #
1207
1228
  def run_command=(command)
1208
1229
  raise Jamf::InvalidDataError, 'Command to run must be a String' unless command.is_a? String
1230
+
1209
1231
  @files_processes[:run_command] = command
1210
1232
  @need_to_update = true
1211
1233
  end
@@ -1262,7 +1284,7 @@ module Jamf
1262
1284
  #
1263
1285
  def search_by_path
1264
1286
  if @files_processes[:search_by_path].nil?
1265
- return nil
1287
+ nil
1266
1288
  else
1267
1289
  Pathname.new @files_processes[:search_by_path]
1268
1290
  end
@@ -1289,6 +1311,7 @@ module Jamf
1289
1311
  #
1290
1312
  def set_search_by_path(path, delete = false)
1291
1313
  raise Jamf::InvalidDataError, 'Path to search for must be a String or a Pathname' unless path.is_a?(String) || path.is_a?(Pathname)
1314
+
1292
1315
  @files_processes[:search_by_path] = path.to_s
1293
1316
  @files_processes[:delete_file] = delete ? true : false
1294
1317
  @need_to_update = true
@@ -1308,6 +1331,7 @@ module Jamf
1308
1331
  #
1309
1332
  def spotlight_search=(term)
1310
1333
  raise Jamf::InvalidDataError, 'Spotlight search term must be a String' unless term.is_a? String
1334
+
1311
1335
  @files_processes[:spotlight_search] = term
1312
1336
  @need_to_update = true
1313
1337
  end
@@ -1326,6 +1350,7 @@ module Jamf
1326
1350
  #
1327
1351
  def locate_file=(term)
1328
1352
  raise Jamf::InvalidDataError, 'Term to locate must be a String' unless term.is_a? String
1353
+
1329
1354
  @files_processes[:locate_file] = term
1330
1355
  @need_to_update = true
1331
1356
  end
@@ -1571,7 +1596,6 @@ module Jamf
1571
1596
  @directory_bindings
1572
1597
  end
1573
1598
 
1574
-
1575
1599
  # Remove a directory binding from this policy by name or id
1576
1600
  #
1577
1601
  # @param identifier [String,Integer] the name or id of the directory binding to remove
@@ -1596,7 +1620,6 @@ module Jamf
1596
1620
  @dock_items.map { |p| p[:name] }
1597
1621
  end
1598
1622
 
1599
-
1600
1623
  ###### Printers
1601
1624
 
1602
1625
  # Add a specific printer object to the policy.
@@ -1661,7 +1684,7 @@ module Jamf
1661
1684
 
1662
1685
  name = Jamf::DockItem.map_all_ids_to(:name, cnx: @cnx)[id]
1663
1686
 
1664
- @dock_items << {id: id, name: name, action: DOCK_ITEM_ACTIONS[action]}
1687
+ @dock_items << { id: id, name: name, action: DOCK_ITEM_ACTIONS[action] }
1665
1688
 
1666
1689
  @need_to_update = true
1667
1690
  @dock_items
@@ -1677,24 +1700,18 @@ module Jamf
1677
1700
 
1678
1701
  # @return [Array] the id's of the printers handled by the policy
1679
1702
  def printer_ids
1680
- begin
1681
- @printers.map { |p| p[:id] }
1682
- rescue TypeError
1683
- return []
1684
- end
1703
+ @printers.map { |p| p[:id] }
1704
+ rescue TypeError
1705
+ []
1685
1706
  end
1686
1707
 
1687
1708
  # @return [Array] the names of the printers handled by the policy
1688
1709
  def printer_names
1689
- begin
1690
- @printers.map { |p| p[:name] }
1691
- rescue TypeError
1692
- return []
1693
- end
1710
+ @printers.map { |p| p[:name] }
1711
+ rescue TypeError
1712
+ []
1694
1713
  end
1695
1714
 
1696
-
1697
-
1698
1715
  ###### Disk Encryption
1699
1716
 
1700
1717
  # Sets the Disk Encryption application to "Remediate" and sets the remediation key type to individual.
@@ -1703,12 +1720,12 @@ module Jamf
1703
1720
  #
1704
1721
  # @return [Void]
1705
1722
  #
1706
- def reissue_key()
1723
+ def reissue_key
1707
1724
  if @disk_encryption[:action] != DISK_ENCRYPTION_ACTIONS[:remediate]
1708
1725
  # Setting New Action
1709
1726
  hash = {
1710
1727
  action: DISK_ENCRYPTION_ACTIONS[:remediate],
1711
- remediate_key_type: "Individual"
1728
+ remediate_key_type: 'Individual'
1712
1729
  }
1713
1730
 
1714
1731
  @disk_encryption = hash
@@ -1716,12 +1733,10 @@ module Jamf
1716
1733
 
1717
1734
  else
1718
1735
  # Update
1719
- return
1736
+ nil
1720
1737
  end
1721
-
1722
1738
  end
1723
1739
 
1724
-
1725
1740
  # Sets the Disk Encryption application to "Apply" and sets the correct disk encryption configuration ID using either the name or id.
1726
1741
  #
1727
1742
  # @author Tyler Morgan
@@ -1729,7 +1744,6 @@ module Jamf
1729
1744
  # @return [Void]
1730
1745
  #
1731
1746
  def apply_encryption_configuration(identifier)
1732
-
1733
1747
  id = Jamf::DiskEncryptionConfiguration.valid_id identifier
1734
1748
 
1735
1749
  return if id.nil?
@@ -1744,14 +1758,13 @@ module Jamf
1744
1758
  @need_to_update = true
1745
1759
  end
1746
1760
 
1747
-
1748
1761
  # Removes the Disk Encryption settings associated with this specific policy.
1749
1762
  #
1750
1763
  # @author Tyler Morgan
1751
1764
  #
1752
1765
  # @return [Void]
1753
1766
  #
1754
- def remove_encryption_configuration()
1767
+ def remove_encryption_configuration
1755
1768
  hash = {
1756
1769
  action: DISK_ENCRYPTION_ACTIONS[:none]
1757
1770
  }
@@ -1774,16 +1787,16 @@ module Jamf
1774
1787
 
1775
1788
  management_data = {}
1776
1789
 
1777
- if action == :change_pw || action == :reset_pw
1778
- raise Jamf::MissingDataError, ":password must be provided when changing management account password" if opts[:password].nil?
1790
+ if %i[change_pw reset_pw].include?(action)
1791
+ raise Jamf::MissingDataError, ':password must be provided when changing management account password' if opts[:password].nil?
1779
1792
 
1780
1793
  management_data = {
1781
1794
  action: MGMT_ACCOUNT_ACTIONS[action],
1782
1795
  managed_password: opts[:password]
1783
1796
  }
1784
- elsif action == :reset_random || action == :generate_pw
1785
- raise Jamf::MissingDataError, ":password_length must be provided when setting a random password" if opts[:password_length].nil?
1786
- raise Jamf::InvalidDataError, ":password_length must be an Integer" unless opts[:password_length].is_a? Integer
1797
+ elsif %i[reset_random generate_pw].include?(action)
1798
+ raise Jamf::MissingDataError, ':password_length must be provided when setting a random password' if opts[:password_length].nil?
1799
+ raise Jamf::InvalidDataError, ':password_length must be an Integer' unless opts[:password_length].is_a? Integer
1787
1800
 
1788
1801
  management_data = {
1789
1802
  action: MGMT_ACCOUNT_ACTIONS[action],
@@ -1800,21 +1813,23 @@ module Jamf
1800
1813
  @need_to_update = true
1801
1814
 
1802
1815
  @management_account
1803
-
1804
1816
  end
1805
1817
 
1806
- # Check if management password matches provided password
1818
+ # @deprecated The API no longer sends SHA256 hashed password data, and instead
1819
+ # only has a string of asterisks, meaning we can no longer use it to validate
1820
+ # passwords before attempting to use them. Instead, the processes that use
1821
+ # the password will fail on their own if the pw is not valid.
1807
1822
  #
1808
- # @param password[String] the password that is SHA256'ed to compare to the one from the API.
1823
+ # This method remains defined for backward-compatibility with any existing
1824
+ # code that calls it. but it will always return true. Itwill be removed in
1825
+ # a future version
1809
1826
  #
1810
- # @return [Boolean] The result of the comparison of the management password and provided text.
1827
+ # @param password[String] ignored
1811
1828
  #
1812
- def verify_management_password(password)
1813
- raise Jamf::InvalidDataError, "Management password must be a string." unless password.is_a? String
1814
-
1815
- raise Jamf::UnsupportedError, "'#{@management_account[:action].to_s}' does not support management passwords." unless @management_account[:action] == MGMT_ACCOUNT_ACTIONS[:change_pw] || @management_account[:action] == MGMT_ACCOUNT_ACTIONS[:reset_pw]
1816
-
1817
- return Digest::SHA256.hexdigest(password).to_s == @management_account[:managed_password_sha256].to_s
1829
+ # @return [TrueClass] Allow the process calling this to continue.
1830
+ #
1831
+ def verify_management_password(_password = nil)
1832
+ true
1818
1833
  end
1819
1834
 
1820
1835
  ###### Actions
@@ -1829,8 +1844,10 @@ module Jamf
1829
1844
  #
1830
1845
  def run(show_output = false)
1831
1846
  return nil unless enabled?
1847
+
1832
1848
  output = Jamf::Client.run_jamf('policy', "-id #{id}", show_output)
1833
1849
  return nil if output.include? 'No policies were found for the ID'
1850
+
1834
1851
  $CHILD_STATUS.exitstatus.zero? ? true : false
1835
1852
  end
1836
1853
  alias execute run
@@ -1944,6 +1961,7 @@ module Jamf
1944
1961
 
1945
1962
  id = Jamf::Script.valid_id identifier, cnx: @cnx
1946
1963
  raise Jamf::NoSuchItemError, "No script matches '#{identifier}'" unless id
1964
+
1947
1965
  id
1948
1966
  end
1949
1967
 
@@ -1963,12 +1981,13 @@ module Jamf
1963
1981
  else Jamf::Validate.integer(opts[:position])
1964
1982
  end
1965
1983
 
1966
- # if the given position is past the end, set it to -1 (the end)
1967
- opts[:position] = -1 if opts[:position] > @directory_bindings.size
1984
+ # if the given position is past the end, set it to -1 (the end)
1985
+ opts[:position] = -1 if opts[:position] > @directory_bindings.size
1986
+
1987
+ id = Jamf::DirectoryBinding.valid_id identifier, cnx: @cnx
1988
+ raise Jamf::NoSuchItemError, "No directory binding matches '#{identifier}'" unless id
1968
1989
 
1969
- id = Jamf::DirectoryBinding.valid_id identifier, cnx: @cnx
1970
- raise Jamf::NoSuchItemError, "No directory binding matches '#{identifier}'" unless id
1971
- id
1990
+ id
1972
1991
  end
1973
1992
 
1974
1993
  # Raises an error if the printer being added isn't valid, additionally checks the options and sets defaults where possible.
@@ -1994,14 +2013,17 @@ module Jamf
1994
2013
  raise Jamf::MissingDataError, "action must be provided, must be one of :#{PRINTER_ACTIONS.keys.join(':,')}." if opts[:action].nil?
1995
2014
  raise Jamf::InvalidDataError, "action must be one of :#{PRINTER_ACTIONS.keys.join(',:')}." unless PRINTER_ACTIONS.keys.include? opts[:action]
1996
2015
 
1997
-
1998
2016
  # Checks if the make_default option is valid, and sets the default if needed.
1999
- raise Jamf::InvalidDataError, "make_default must be either true or false." unless opts[:make_default].is_a?(TrueClass) || opts[:make_default].is_a?(FalseClass) || opts[:make_default].nil?
2017
+ unless opts[:make_default].is_a?(TrueClass) || opts[:make_default].is_a?(FalseClass) || opts[:make_default].nil?
2018
+ raise Jamf::InvalidDataError,
2019
+ 'make_default must be either true or false.'
2020
+ end
2000
2021
 
2001
2022
  opts[:make_default] = false if opts[:make_default].nil?
2002
2023
 
2003
2024
  id = Jamf::Printer.valid_id identifier, cnx: @cnx
2004
2025
  raise Jamf::NoSuchItemError, "No printer matches '#{identifier}'" unless id
2026
+
2005
2027
  id
2006
2028
  end
2007
2029
 
@@ -2081,7 +2103,7 @@ module Jamf
2081
2103
 
2082
2104
  disk_encryption = obj.add_element 'disk_encryption'
2083
2105
 
2084
- @disk_encryption.each do |k,v|
2106
+ @disk_encryption.each do |k, v|
2085
2107
  disk_encryption.add_element(k.to_s).text = v.to_s
2086
2108
  end
2087
2109
 
@@ -150,7 +150,8 @@ module Jamf
150
150
  element ? element.text.to_f : model
151
151
  when nil
152
152
  return nil unless element
153
- element.text.downcase == TRUE_STRING ? true : false
153
+
154
+ element.text.downcase == TRUE_STRING
154
155
  when Array
155
156
  element ? elem_as_array(model.first, element) : []
156
157
  when Hash
@@ -176,6 +177,7 @@ module Jamf
176
177
  return unless size_elems.count == 1
177
178
  return if size_elem.has_elements?
178
179
  return unless size_elem.text.jss_integer?
180
+
179
181
  elem.delete_element size_elem
180
182
  end
181
183
 
@@ -74,15 +74,15 @@ module Jamf
74
74
  attr_reader :sticky_session
75
75
  alias sticky_session? sticky_session
76
76
  alias sticky? sticky_session
77
-
77
+
78
78
  # @return [String, nil] The current sticky_session cookie. nil unless
79
79
  # sticky_session is set to true, either as a param to 'connect' or via
80
80
  # #sticky_session=
81
81
  #
82
- # When set via .connect, the cookie is gleaned from the token creation
82
+ # When set via .connect, the cookie is gleaned from the token creation
83
83
  # reponse. When set via #sticky_session=, a HEAD request is made, and the
84
84
  # cookie will be in the response.
85
- #
85
+ #
86
86
  # Only valid when the connection is to a Jamf Cloud server.
87
87
  attr_reader :sticky_session_cookie
88
88
 
@@ -100,7 +100,7 @@ module Jamf
100
100
 
101
101
  # convert boolean-y to boolean
102
102
  value = value ? true : false
103
-
103
+
104
104
  return if @sticky_session == value
105
105
 
106
106
  if value
@@ -125,8 +125,8 @@ module Jamf
125
125
  #
126
126
  def timeout=(new_timeout)
127
127
  @timeout = new_timeout.to_i
128
- @c_cnx&.options[:timeout] = @timeout
129
- @jp_cnx&.options[:timeout] = @timeout
128
+ @c_cnx.options.timeout = @timeout if @c_cnx
129
+ @jp_cnx.options.timeout = @timeout if @jp_cnx
130
130
  end
131
131
 
132
132
  # Reset the open-connection timeout for the rest connection
@@ -137,8 +137,8 @@ module Jamf
137
137
  #
138
138
  def open_timeout=(new_timeout)
139
139
  @open_timeout = new_timeout.to_i
140
- @c_cnx&.options[:open_timeout] = @open_timeout
141
- @jp_cnx&.options[:open_timeout] = @open_timeout
140
+ @c_cnx.options.open_timeout = @open_timeout if @c_cnx
141
+ @jp_cnx.options.open_timeout = @open_timeout if @jp_cnx
142
142
  end
143
143
 
144
144
  # @return [URI::HTTPS] the base URL to the server
@@ -59,6 +59,8 @@ module Jamf
59
59
  # @return [Hash,String] the result of the get
60
60
  #
61
61
  def c_get(rsrc, format = :json, raw_json: false)
62
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
63
+
62
64
  validate_connected @c_cnx
63
65
  raise Jamf::InvalidDataError, 'format must be :json or :xml' unless Jamf::Connection::GET_FORMATS.include?(format)
64
66
 
@@ -92,6 +94,8 @@ module Jamf
92
94
  def c_post(rsrc, xml)
93
95
  validate_connected @c_cnx
94
96
 
97
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
98
+
95
99
  # convert CRs & to &#13;
96
100
  xml&.gsub!(/\r/, '&#13;')
97
101
 
@@ -125,6 +129,8 @@ module Jamf
125
129
  def c_put(rsrc, xml)
126
130
  validate_connected @c_cnx
127
131
 
132
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
133
+
128
134
  # convert CRs & to &#13;
129
135
  xml.gsub!(/\r/, '&#13;')
130
136
 
@@ -157,6 +163,8 @@ module Jamf
157
163
  validate_connected @c_cnx
158
164
  raise MissingDataError, 'Missing :rsrc' if rsrc.nil?
159
165
 
166
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
167
+
160
168
  # delete the resource
161
169
  resp =
162
170
  @c_cnx.delete(rsrc) do |req|
@@ -188,6 +196,7 @@ module Jamf
188
196
  #
189
197
  def upload(rsrc, local_file)
190
198
  validate_connected @c_cnx
199
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
191
200
 
192
201
  # the upload file object for faraday
193
202
  local_file = Pathname.new local_file
@@ -223,7 +232,7 @@ module Jamf
223
232
 
224
233
  cnx.options[:timeout] = @timeout
225
234
  cnx.options[:open_timeout] = @open_timeout
226
-
235
+
227
236
  cnx.request :multipart
228
237
  cnx.request :url_encoded
229
238
 
@@ -87,6 +87,8 @@ module Jamf
87
87
  MIME_JSON = 'application/json'.freeze
88
88
  MIME_XML = 'application/xml'.freeze
89
89
 
90
+ SLASH = '/'
91
+
90
92
  # Only these variables are displayed with PrettyPrint
91
93
  # This avoids, especially, the caches, which are available
92
94
  # as attr_readers
@@ -53,11 +53,12 @@ module Jamf
53
53
 
54
54
  # @param rsrc[String] the resource to get
55
55
  # (the part of the API url after the '/api/' )
56
-
56
+
57
57
  # @return [Hash] the result of the get
58
58
  #######################################################
59
59
  def jp_get(rsrc)
60
60
  validate_connected @jp_cnx
61
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
61
62
  resp = @jp_cnx.get(rsrc) do |req|
62
63
  # Modify the request here if needed.
63
64
  # puts "JPAPI Cookie is: #{req.headers['Cookie']}"
@@ -82,6 +83,7 @@ module Jamf
82
83
  #######################################################
83
84
  def jp_post(rsrc, data)
84
85
  validate_connected @jp_cnx
86
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
85
87
  resp = @jp_cnx.post(rsrc) do |req|
86
88
  req.body = data
87
89
  end
@@ -104,6 +106,7 @@ module Jamf
104
106
  #######################################################
105
107
  def jp_put(rsrc, data)
106
108
  validate_connected @jp_cnx
109
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
107
110
  resp = @jp_cnx.put(rsrc) do |req|
108
111
  req.body = data
109
112
  end
@@ -126,6 +129,7 @@ module Jamf
126
129
  #######################################################
127
130
  def jp_patch(rsrc, data)
128
131
  validate_connected @jp_cnx
132
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
129
133
  resp = @jp_cnx.patch(rsrc) do |req|
130
134
  req.body = data
131
135
  end
@@ -146,6 +150,7 @@ module Jamf
146
150
  #######################################################
147
151
  def jp_delete(rsrc)
148
152
  validate_connected @jp_cnx
153
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
149
154
  resp = @jp_cnx.delete rsrc
150
155
  @last_http_response = resp
151
156
  return resp.body if resp.success?
@@ -159,6 +164,7 @@ module Jamf
159
164
  # a temporary Faraday connection object
160
165
  #######################################################
161
166
  def jp_download(rsrc)
167
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
162
168
  temp_cnx = create_jp_connection(parse_json: false)
163
169
  resp = temp_cnx.get rsrc
164
170
  @last_http_response = resp
data/lib/jamf/version.rb CHANGED
@@ -27,6 +27,6 @@
27
27
  module Jamf
28
28
 
29
29
  ### The version of ruby-jss
30
- VERSION = '2.1.0b5'.freeze
30
+ VERSION = '2.1.1'.freeze
31
31
 
32
32
  end # module
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-jss
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0b5
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Lasell
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-09-23 00:00:00.000000000 Z
13
+ date: 2022-11-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: CFPropertyList
@@ -824,9 +824,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
824
824
  version: 2.6.3
825
825
  required_rubygems_version: !ruby/object:Gem::Requirement
826
826
  requirements:
827
- - - ">"
827
+ - - ">="
828
828
  - !ruby/object:Gem::Version
829
- version: 1.3.1
829
+ version: '0'
830
830
  requirements: []
831
831
  rubygems_version: 3.0.3.1
832
832
  signing_key: