ruby-jss 1.2.10 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby-jss might be problematic. Click here for more details.

Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +92 -1
  3. data/lib/jamf/api/abstract_classes/json_object.rb +1 -1
  4. data/lib/jamf/api/abstract_classes/prestage.rb +1 -1
  5. data/lib/jamf/api/connection.rb +7 -3
  6. data/lib/jamf/configuration.rb +7 -9
  7. data/lib/jamf/ruby_extensions.rb +1 -0
  8. data/lib/jamf/ruby_extensions/array.rb +1 -1
  9. data/lib/jamf/ruby_extensions/array/utils.rb +3 -3
  10. data/lib/jamf/ruby_extensions/dig.rb +52 -0
  11. data/lib/jss.rb +2 -0
  12. data/lib/jss/api_connection.rb +2 -29
  13. data/lib/jss/api_object.rb +15 -2
  14. data/lib/jss/api_object/directory_binding.rb +273 -0
  15. data/lib/jss/api_object/directory_binding_type.rb +90 -0
  16. data/lib/jss/api_object/directory_binding_type/active_directory.rb +502 -0
  17. data/lib/jss/api_object/directory_binding_type/admitmac.rb +525 -0
  18. data/lib/jss/api_object/directory_binding_type/centrify.rb +212 -0
  19. data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
  20. data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
  21. data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
  22. data/lib/jss/api_object/distribution_point.rb +95 -35
  23. data/lib/jss/api_object/dock_item.rb +137 -0
  24. data/lib/jss/api_object/mobile_device_application.rb +12 -0
  25. data/lib/jss/api_object/network_segment.rb +152 -58
  26. data/lib/jss/api_object/package.rb +106 -41
  27. data/lib/jss/api_object/policy.rb +379 -4
  28. data/lib/jss/api_object/printer.rb +440 -0
  29. data/lib/jss/api_object/scopable/scope.rb +24 -24
  30. data/lib/jss/composer.rb +1 -1
  31. data/lib/jss/utility.rb +8 -22
  32. data/lib/jss/version.rb +1 -1
  33. metadata +13 -2
@@ -174,7 +174,9 @@ module JSS
174
174
  change_pw: 'specified',
175
175
  generate_pw: 'random',
176
176
  enable_fv2: 'fileVaultEnable',
177
- disable_fv2: 'fileVaultDisable'
177
+ disable_fv2: 'fileVaultDisable',
178
+ reset_random: 'resetRandom',
179
+ reset_pw: 'reset'
178
180
  }.freeze
179
181
 
180
182
  PACKAGE_ACTIONS = {
@@ -191,6 +193,12 @@ module JSS
191
193
  after: 'After'
192
194
  }.freeze
193
195
 
196
+ DISK_ENCRYPTION_ACTIONS = {
197
+ apply: "apply",
198
+ remediate: "remediate",
199
+ none: "none"
200
+ }
201
+
194
202
  PRINTER_ACTIONS = {
195
203
  map: 'install',
196
204
  unmap: 'uninstall'
@@ -541,6 +549,7 @@ module JSS
541
549
 
542
550
  # @return [String] the message shown the user at policy end
543
551
  attr_reader :user_message_finish
552
+ alias user_message_end user_message_finish
544
553
 
545
554
  # @return [Hash]
546
555
  #
@@ -670,6 +679,7 @@ module JSS
670
679
  @disk_encryption = @init_data[:disk_encryption]
671
680
 
672
681
  @printers = @init_data[:printers]
682
+ @printers.shift
673
683
 
674
684
  # Not in jss yet
675
685
  end
@@ -914,6 +924,30 @@ module JSS
914
924
  end
915
925
  alias message= reboot_message=
916
926
 
927
+ # Set User Start Message
928
+ #
929
+ # @param user_message[String] Text of User Message
930
+ #
931
+ # @return [void] description of returned object
932
+ def user_message_start=(message)
933
+ raise JSS::InvalidDataError, 'User message must be a String' unless message.is_a? String
934
+ @user_message_start = message
935
+ @need_to_update = true
936
+ end
937
+
938
+ # Set User Finish Message
939
+ #
940
+ # @param user_message[String] Text of User Message
941
+ #
942
+ # @return [void] description of returned object
943
+ def user_message_end=(message)
944
+ raise JSS::InvalidDataError, 'User message must be a String' unless message.is_a? String
945
+ @user_message_finish = message
946
+ @need_to_update = true
947
+ end
948
+
949
+ alias user_message_finish= user_message_end=
950
+
917
951
  # Set Startup Disk
918
952
  # Only Supports 'Specify Local Startup Disk' at the moment
919
953
  #
@@ -1180,7 +1214,7 @@ module JSS
1180
1214
 
1181
1215
  # Remove a package from this policy by name or id
1182
1216
  #
1183
- # @param identfier [String,Integer] the name or id of the package to remove
1217
+ # @param identifier [String,Integer] the name or id of the package to remove
1184
1218
  #
1185
1219
  # @return [Array, nil] the new packages array or nil if no change
1186
1220
  #
@@ -1270,7 +1304,7 @@ module JSS
1270
1304
 
1271
1305
  # Remove a script from this policy by name or id
1272
1306
  #
1273
- # @param identfier [String,Integer] the name or id of the script to remove
1307
+ # @param identifier [String,Integer] the name or id of the script to remove
1274
1308
  #
1275
1309
  # @return [Array, nil] the new scripts array or nil if no change
1276
1310
  #
@@ -1292,6 +1326,49 @@ module JSS
1292
1326
  @directory_bindings.map { |p| p[:name] }
1293
1327
  end
1294
1328
 
1329
+ # Add a Directory Bidning to the list of directory_bindings handled by this policy.
1330
+ # If the directory binding already exists in the policy, nil is returned and
1331
+ # no changes are made.
1332
+ #
1333
+ # @param [String,Integer] identifier the name or id of the directory binding to add to this policy
1334
+ #
1335
+ # @param position [Symbol, Integer] where to add this directory binding among the list of
1336
+ # directory_bindings. Zero-based, :start and 0 are the same, as are :end and -1.
1337
+ # Defaults to :end
1338
+ #
1339
+ # @return [Array, nil] the new @directory_bindings array, nil if directory_binding was already in the policy
1340
+ #
1341
+ def add_directory_binding(identifier, **opts)
1342
+ id = validate_directory_binding_opts identifier, opts
1343
+
1344
+ return nil if @directory_bindings.map { |s| s[:id] }.include? id
1345
+
1346
+ name = JSS::DirectoryBinding.map_all_ids_to(:name, api: @api)[id]
1347
+
1348
+ directory_binding_data = {
1349
+ id: id,
1350
+ name: name
1351
+ }
1352
+
1353
+ @directory_bindings.insert opts[:position], directory_binding_data
1354
+
1355
+ @need_to_update = true
1356
+ @directory_bindings
1357
+ end
1358
+
1359
+
1360
+ # Remove a directory binding from this policy by name or id
1361
+ #
1362
+ # @param identifier [String,Integer] the name or id of the directory binding to remove
1363
+ #
1364
+ # @return [Array, nil] the new directory bindings array or nil if no change
1365
+ #
1366
+ def remove_directory_binding(identifier)
1367
+ removed = @directory_bindings.delete_if { |s| s[:id] == identifier || s[:name] == identifier }
1368
+ @need_to_update = true if removed
1369
+ removed
1370
+ end
1371
+
1295
1372
  ###### Dock items
1296
1373
 
1297
1374
  # @return [Array] the id's of the dock_items handled by the policy
@@ -1304,6 +1381,86 @@ module JSS
1304
1381
  @dock_items.map { |p| p[:name] }
1305
1382
  end
1306
1383
 
1384
+
1385
+ ###### Printers
1386
+
1387
+ # Add a specific printer object to the policy.
1388
+ #
1389
+ # @author Tyler Morgan
1390
+ #
1391
+ # @param newvalue [String,Integer] The name or the id of the printer to be added to this policy.
1392
+ #
1393
+ # @param position [Symbol, Integer] where to add this printer object among the list of printer
1394
+ # objects. Zero-based, :start and 0 are the same, as are :end and -1.
1395
+ # Defaults to :end
1396
+ #
1397
+ # @param action [Symbol] One of the PRINTER_ACTIONS symbols. What you want done with the printer object upon policy execution.
1398
+ #
1399
+ # @param make_default [TrueClass,FalseClass] Should this printer object be set to default.
1400
+ # Defaults to false
1401
+ #
1402
+ # @return [String] The new printers array or nil if the printer was already in the policy
1403
+ def add_printer(identifier, **opts)
1404
+ id = validate_printer_opts identifier, opts
1405
+
1406
+ return nil if @printers.map { |p| p[:id] }.include? id
1407
+
1408
+ name = JSS::Printer.map_all_ids_to(:name, api: @api)[id]
1409
+
1410
+ printer_data = {
1411
+ id: id,
1412
+ name: name,
1413
+ action: PRINTER_ACTIONS[opts[:action]],
1414
+ make_default: opts[:make_default]
1415
+ }
1416
+
1417
+ @printers.insert opts[:position], printer_data
1418
+
1419
+ @need_to_update = true
1420
+ @printers
1421
+ end
1422
+
1423
+
1424
+ # Remove a specific printer object from the policy.
1425
+ #
1426
+ # @author Tyler Morgan
1427
+ #
1428
+ # @param identifier [String,Integer] The name or id of the printer to be removed.
1429
+ #
1430
+ # @return [Array, nil] The new printers array or nil if no change.
1431
+ def remove_printer(identifier)
1432
+ removed = @printers.delete_if { |p| p[:id] == identifier || p[:name] == identifier }
1433
+
1434
+ @need_to_update = true
1435
+ removed
1436
+ end
1437
+
1438
+ # Add a dock item to the policy
1439
+ def add_dock_item(identifier, action)
1440
+ id = JSS::DockItem.valid_id identifier, api: @api
1441
+
1442
+ raise JSS::NoSuchItemError, "No Dock Item matches '#{identifier}'" unless id
1443
+
1444
+ raise JSS::InvalidDataError, "Action must be one of: :#{DOCK_ITEM_ACTIONS.keys.join ', :'}" unless DOCK_ITEM_ACTIONS.include? action
1445
+
1446
+ return nil if @dock_items.map { |d| d[:id] }.include? id
1447
+
1448
+ name = JSS::DockItem.map_all_ids_to(:name, api: @api)[id]
1449
+
1450
+ @dock_items << {id: id, name: name, action: DOCK_ITEM_ACTIONS[action]}
1451
+
1452
+ @need_to_update = true
1453
+ @dock_items
1454
+ end
1455
+
1456
+ # Remove a dock item from the policy
1457
+ def remove_dock_item(identifier)
1458
+ # TODO: Add validation against JSS::DockItem
1459
+ removed = @dock_items.delete_if { |d| d[:id] == identifier || d[:name] == identifier }
1460
+ @need_to_update = true if removed
1461
+ removed
1462
+ end
1463
+
1307
1464
  # @return [Array] the id's of the printers handled by the policy
1308
1465
  def printer_ids
1309
1466
  begin
@@ -1312,7 +1469,7 @@ module JSS
1312
1469
  return []
1313
1470
  end
1314
1471
  end
1315
-
1472
+
1316
1473
  # @return [Array] the names of the printers handled by the policy
1317
1474
  def printer_names
1318
1475
  begin
@@ -1322,6 +1479,130 @@ module JSS
1322
1479
  end
1323
1480
  end
1324
1481
 
1482
+
1483
+
1484
+ ###### Disk Encryption
1485
+
1486
+ # Sets the Disk Encryption application to "Remediate" and sets the remediation key type to individual.
1487
+ #
1488
+ # @author Tyler Morgan
1489
+ #
1490
+ # @return [Void]
1491
+ #
1492
+ def reissue_key()
1493
+ if @disk_encryption[:action] != DISK_ENCRYPTION_ACTIONS[:remediate]
1494
+ # Setting New Action
1495
+ hash = {
1496
+ action: DISK_ENCRYPTION_ACTIONS[:remediate],
1497
+ remediate_key_type: "Individual"
1498
+ }
1499
+
1500
+ @disk_encryption = hash
1501
+ @need_to_update = true
1502
+
1503
+ else
1504
+ # Update
1505
+ return
1506
+ end
1507
+
1508
+ end
1509
+
1510
+
1511
+ # Sets the Disk Encryption application to "Apply" and sets the correct disk encryption configuration ID using either the name or id.
1512
+ #
1513
+ # @author Tyler Morgan
1514
+ #
1515
+ # @return [Void]
1516
+ #
1517
+ def apply_encryption_configuration(identifier)
1518
+
1519
+ id = JSS::DiskEncryptionConfiguration.valid_id identifier
1520
+
1521
+ return if id.nil?
1522
+
1523
+ hash = {
1524
+ action: DISK_ENCRYPTION_ACTIONS[:apply],
1525
+ disk_encryption_configuration_id: id,
1526
+ auth_restart: false
1527
+ }
1528
+
1529
+ @disk_encryption = hash
1530
+ @need_to_update = true
1531
+ end
1532
+
1533
+
1534
+ # Removes the Disk Encryption settings associated with this specific policy.
1535
+ #
1536
+ # @author Tyler Morgan
1537
+ #
1538
+ # @return [Void]
1539
+ #
1540
+ def remove_encryption_configuration()
1541
+ hash = {
1542
+ action: DISK_ENCRYPTION_ACTIONS[:none]
1543
+ }
1544
+
1545
+ @disk_encryption = hash
1546
+ @need_to_update = true
1547
+ end
1548
+
1549
+ # Interact with management account settings
1550
+ #
1551
+ # @param action [Key] one of the MGMT_ACCOUNT_ACTIONS keys
1552
+ #
1553
+ # @return The current specified management settings.
1554
+ #
1555
+ # Reference: https://developer.jamf.com/documentation#resources-with-passwords
1556
+ #
1557
+ def set_management_account(action, **opts)
1558
+ # TODO: Add proper error handling
1559
+ raise JSS::InvalidDataError, "Action must be one of: :#{MGMT_ACCOUNT_ACTIONS.keys.join ', :'}" unless MGMT_ACCOUNT_ACTIONS.include? action
1560
+
1561
+ management_data = {}
1562
+
1563
+ if action == :change_pw || action == :reset_pw
1564
+ raise JSS::MissingDataError, ":password must be provided when changing management account password" if opts[:password].nil?
1565
+
1566
+ management_data = {
1567
+ action: MGMT_ACCOUNT_ACTIONS[action],
1568
+ managed_password: opts[:password]
1569
+ }
1570
+ elsif action == :reset_random || action == :generate_pw
1571
+ raise JSS::MissingDataError, ":password_length must be provided when setting a random password" if opts[:password_length].nil?
1572
+ raise JSS::InvalidDataError, ":password_length must be an Integer" unless opts[:password_length].is_a? Integer
1573
+
1574
+ management_data = {
1575
+ action: MGMT_ACCOUNT_ACTIONS[action],
1576
+ managed_password_length: opts[:password_length]
1577
+ }
1578
+ else
1579
+ management_data = {
1580
+ action: MGMT_ACCOUNT_ACTIONS[action]
1581
+ }
1582
+ end
1583
+
1584
+ @management_account = management_data
1585
+
1586
+ @need_to_update = true
1587
+
1588
+ @management_account
1589
+
1590
+ end
1591
+
1592
+ # Check if management password matches provided password
1593
+ #
1594
+ # @param password[String] the password that is SHA256'ed to compare to the one from the API.
1595
+ #
1596
+ # @return [Boolean] The result of the comparison of the management password and provided text.
1597
+ #
1598
+ def verify_management_password(password)
1599
+ raise JSS::InvalidDataError, "Management password must be a string." unless password.is_a? String
1600
+
1601
+ raise JSS::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]
1602
+
1603
+ return Digest::SHA256.hexdigest(password).to_s == @management_account[:managed_password_sha256].to_s
1604
+ end
1605
+
1325
1606
  ###### Actions
1326
1607
 
1327
1608
  # Try to execute this policy on this machine.
@@ -1439,6 +1720,64 @@ module JSS
1439
1720
  id
1440
1721
  end
1441
1722
 
1723
+ # raise an error if the directory binding being added isn't valid
1724
+ #
1725
+ # @see #add_directory_binding
1726
+ #
1727
+ # @return [Integer, nil] the valid id for the package
1728
+ #
1729
+ def validate_directory_binding_opts(identifier, opts)
1730
+ opts[:position] ||= -1
1731
+
1732
+ opts[:position] =
1733
+ case opts[:position]
1734
+ when :start then 0
1735
+ when :end then -1
1736
+ else JSS::Validate.integer(opts[:position])
1737
+ end
1738
+
1739
+ # if the given position is past the end, set it to -1 (the end)
1740
+ opts[:position] = -1 if opts[:position] > @directory_bindings.size
1741
+
1742
+ id = JSS::DirectoryBinding.valid_id identifier, api: @api
1743
+ raise JSS::NoSuchItemError, "No directory binding matches '#{identifier}'" unless id
1744
+ id
1745
+ end
1746
+
1747
+ # Raises an error if the printer being added isn't valid, additionally checks the options and sets defaults where possible.
1748
+ #
1749
+ # @see #add_printer
1750
+ #
1751
+ # @return [Integer, nil] the valid id for the package
1752
+ #
1753
+ def validate_printer_opts(identifier, opts)
1754
+ opts[:position] ||= -1
1755
+
1756
+ opts[:position] =
1757
+ case opts[:position]
1758
+ when :start then 0
1759
+ when :end then -1
1760
+ else JSS::Validate.integer(opts[:position])
1761
+ end
1762
+
1763
+ # If the given position is past the end, set it to -1 (the end)
1764
+ opts[:position] = -1 if opts[:position] > @printers.size
1765
+
1766
+ # Checks if action to be done with the printer object is provided and valid.
1767
+ raise JSS::MissingDataError, "action must be provided, must be one of :#{PRINTER_ACTIONS.keys.join(':,')}." if opts[:action].nil?
1768
+ raise JSS::InvalidDataError, "action must be one of :#{PRINTER_ACTIONS.keys.join(',:')}." unless PRINTER_ACTIONS.keys.include? opts[:action]
1769
+
1770
+
1771
+ # Checks if the make_default option is valid, and sets the default if needed.
1772
+ raise JSS::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?
1773
+
1774
+ opts[:make_default] = false if opts[:make_default].nil?
1775
+
1776
+ id = JSS::Printer.valid_id identifier, api: @api
1777
+ raise JSS::NoSuchItemError, "No printer matches '#{identifier}'" unless id
1778
+ id
1779
+ end
1780
+
1442
1781
  def rest_xml
1443
1782
  doc = REXML::Document.new APIConnection::XML_HEADER
1444
1783
  obj = doc.add_element RSRC_OBJECT_KEY.to_s
@@ -1475,6 +1814,22 @@ module JSS
1475
1814
  maint.add_element('user_cache').text = @user_cache.to_s
1476
1815
  maint.add_element('verify').text = @verify_startup_disk.to_s
1477
1816
 
1817
+ acct_maint = obj.add_element 'account_maintenance'
1818
+
1819
+ mgmt_acct = acct_maint.add_element 'management_account'
1820
+ JSS.hash_to_rexml_array(@management_account).each { |x| mgmt_acct << x }
1821
+
1822
+ directory_bindings = acct_maint.add_element 'directory_bindings'
1823
+ @directory_bindings.each do |b|
1824
+ directory_binding = directory_bindings.add_element 'binding'
1825
+ dbdeets = JSS.hash_to_rexml_array b
1826
+ dbdeets.each { |d| directory_binding << d }
1827
+ end
1828
+
1829
+ user_interaction = obj.add_element 'user_interaction'
1830
+ user_interaction.add_element('message_start').text = @user_message_start.to_s
1831
+ user_interaction.add_element('message_finish').text = @user_message_finish.to_s
1832
+
1478
1833
  files_processes = obj.add_element 'files_processes'
1479
1834
  JSS.hash_to_rexml_array(@files_processes).each { |f| files_processes << f }
1480
1835
 
@@ -1493,6 +1848,26 @@ module JSS
1493
1848
  sdeets.each { |d| script << d }
1494
1849
  end
1495
1850
 
1851
+ disk_encryption = obj.add_element 'disk_encryption'
1852
+
1853
+ @disk_encryption.each do |k,v|
1854
+ disk_encryption.add_element(k.to_s).text = v.to_s
1855
+ end
1856
+
1857
+ printers = obj.add_element 'printers'
1858
+ @printers.each do |pr|
1859
+ printer = printers.add_element 'printer'
1860
+ pdeets = JSS.hash_to_rexml_array pr
1861
+ pdeets.each { |d| printer << d }
1862
+ end
1863
+
1864
+ dock_items = obj.add_element 'dock_items'
1865
+ @dock_items.each do |d|
1866
+ dock_item = dock_items.add_element 'dock_item'
1867
+ ddeets = JSS.hash_to_rexml_array d
1868
+ ddeets.each { |de| dock_item << de }
1869
+ end
1870
+
1496
1871
  add_self_service_xml doc
1497
1872
  add_site_to_xml doc
1498
1873