ruby-jss 1.2.4a4 → 1.3.3

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.
Files changed (248) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +185 -1
  3. data/README.md +3 -1
  4. data/bin/cgrouper +1 -1
  5. data/bin/jamfHelperBackgrounder +1 -1
  6. data/bin/netseg-update +1 -1
  7. data/data/ruby-jss.conf.example +1 -1
  8. data/lib/jamf.rb +1 -1
  9. data/lib/jamf/api/abstract_classes/advanced_search.rb +1 -1
  10. data/lib/jamf/api/abstract_classes/collection_resource.rb +31 -26
  11. data/lib/jamf/api/abstract_classes/generic_reference.rb +1 -1
  12. data/lib/jamf/api/abstract_classes/json_object.rb +15 -5
  13. data/lib/jamf/api/abstract_classes/prestage.rb +2 -2
  14. data/lib/jamf/api/abstract_classes/prestage_skip_setup_items.rb +1 -1
  15. data/lib/jamf/api/abstract_classes/resource.rb +1 -1
  16. data/lib/jamf/api/abstract_classes/singleton_resource.rb +1 -1
  17. data/lib/jamf/api/attribute_classes/ip_address.rb +1 -1
  18. data/lib/jamf/api/attribute_classes/timestamp.rb +1 -1
  19. data/lib/jamf/api/connection.rb +106 -60
  20. data/lib/jamf/api/connection/api_error.rb +1 -1
  21. data/lib/jamf/api/connection/api_error_styleguide.rb +1 -1
  22. data/lib/jamf/api/connection/token.rb +80 -13
  23. data/lib/jamf/api/json_objects/account_prefs.rb +1 -1
  24. data/lib/jamf/api/json_objects/android_details.rb +1 -1
  25. data/lib/jamf/api/json_objects/appletv_details.rb +1 -1
  26. data/lib/jamf/api/json_objects/attachment.rb +1 -1
  27. data/lib/jamf/api/json_objects/cellular_network.rb +1 -1
  28. data/lib/jamf/api/json_objects/change_log_entry.rb +1 -1
  29. data/lib/jamf/api/json_objects/computer_prestage_skip_setup_items.rb +1 -1
  30. data/lib/jamf/api/json_objects/country.rb +1 -1
  31. data/lib/jamf/api/json_objects/criterion.rb +1 -1
  32. data/lib/jamf/api/json_objects/device_enrollment_device.rb +1 -1
  33. data/lib/jamf/api/json_objects/device_enrollment_sync_status.rb +1 -1
  34. data/lib/jamf/api/json_objects/extension_attribute_value.rb +1 -1
  35. data/lib/jamf/api/json_objects/installed_application.rb +1 -1
  36. data/lib/jamf/api/json_objects/installed_certificate.rb +1 -1
  37. data/lib/jamf/api/json_objects/installed_configuration_profile.rb +1 -1
  38. data/lib/jamf/api/json_objects/installed_ebook.rb +1 -1
  39. data/lib/jamf/api/json_objects/installed_provisioning_profile.rb +1 -1
  40. data/lib/jamf/api/json_objects/inventory_preload_extension_attribute.rb +1 -1
  41. data/lib/jamf/api/json_objects/ios_details.rb +1 -1
  42. data/lib/jamf/api/json_objects/location.rb +1 -1
  43. data/lib/jamf/api/json_objects/md_prestage_name.rb +1 -1
  44. data/lib/jamf/api/json_objects/md_prestage_names.rb +1 -1
  45. data/lib/jamf/api/json_objects/md_prestage_skip_setup_items.rb +1 -1
  46. data/lib/jamf/api/json_objects/mobile_device_details.rb +1 -1
  47. data/lib/jamf/api/json_objects/mobile_device_security.rb +1 -1
  48. data/lib/jamf/api/json_objects/prestage_assignment.rb +1 -1
  49. data/lib/jamf/api/json_objects/prestage_location.rb +1 -1
  50. data/lib/jamf/api/json_objects/prestage_purchasing_data.rb +1 -1
  51. data/lib/jamf/api/json_objects/prestage_scope.rb +1 -1
  52. data/lib/jamf/api/json_objects/prestage_sync_status.rb +1 -1
  53. data/lib/jamf/api/json_objects/purchasing_data.rb +1 -1
  54. data/lib/jamf/api/mixins/abstract.rb +1 -1
  55. data/lib/jamf/api/mixins/bulk_deletable.rb +1 -1
  56. data/lib/jamf/api/mixins/change_log.rb +1 -1
  57. data/lib/jamf/api/mixins/extendable.rb +1 -1
  58. data/lib/jamf/api/mixins/immutable.rb +1 -1
  59. data/lib/jamf/api/mixins/locatable.rb +1 -1
  60. data/lib/jamf/api/mixins/lockable.rb +1 -1
  61. data/lib/jamf/api/mixins/referable.rb +1 -1
  62. data/lib/jamf/api/mixins/searchable.rb +1 -1
  63. data/lib/jamf/api/mixins/uncreatable.rb +1 -1
  64. data/lib/jamf/api/mixins/undeletable.rb +1 -1
  65. data/lib/jamf/api/resources/collection_resources/account.rb +1 -1
  66. data/lib/jamf/api/resources/collection_resources/advanced_mobile_device_search.rb +1 -1
  67. data/lib/jamf/api/resources/collection_resources/advanced_user_search.rb +1 -1
  68. data/lib/jamf/api/resources/collection_resources/building.rb +1 -1
  69. data/lib/jamf/api/resources/collection_resources/category.rb +1 -1
  70. data/lib/jamf/api/resources/collection_resources/computer.rb +1 -1
  71. data/lib/jamf/api/resources/collection_resources/computer_prestage.rb +1 -1
  72. data/lib/jamf/api/resources/collection_resources/department.rb +1 -1
  73. data/lib/jamf/api/resources/collection_resources/device_enrollment.rb +1 -1
  74. data/lib/jamf/api/resources/collection_resources/extension_attribute.rb +1 -1
  75. data/lib/jamf/api/resources/collection_resources/inventory_preload_record.rb +9 -2
  76. data/lib/jamf/api/resources/collection_resources/mobile_device.rb +1 -1
  77. data/lib/jamf/api/resources/collection_resources/mobile_device_prestage.rb +1 -1
  78. data/lib/jamf/api/resources/collection_resources/script.rb +1 -1
  79. data/lib/jamf/api/resources/collection_resources/site.rb +1 -1
  80. data/lib/jamf/api/resources/collection_resources/time_zone.rb +1 -1
  81. data/lib/jamf/api/resources/singleton_resources/app_store_country_codes.rb +1 -1
  82. data/lib/jamf/api/resources/singleton_resources/authorization.rb +1 -1
  83. data/lib/jamf/api/resources/singleton_resources/client_checkin_settings.rb +1 -1
  84. data/lib/jamf/api/resources/singleton_resources/reenrollment_settings.rb +1 -1
  85. data/lib/jamf/client.rb +1 -1
  86. data/lib/jamf/client/jamf_binary.rb +1 -1
  87. data/lib/jamf/client/jamf_helper.rb +1 -1
  88. data/lib/jamf/client/management_action.rb +1 -1
  89. data/lib/jamf/compatibility.rb +1 -1
  90. data/lib/jamf/composer.rb +1 -1
  91. data/lib/jamf/configuration.rb +8 -10
  92. data/lib/jamf/exceptions.rb +6 -1
  93. data/lib/jamf/ruby_extensions.rb +2 -1
  94. data/lib/jamf/ruby_extensions/array.rb +2 -2
  95. data/lib/jamf/ruby_extensions/array/predicates.rb +1 -1
  96. data/lib/jamf/ruby_extensions/array/utils.rb +4 -4
  97. data/lib/jamf/ruby_extensions/dig.rb +52 -0
  98. data/lib/jamf/ruby_extensions/filetest.rb +1 -1
  99. data/lib/jamf/ruby_extensions/filetest/predicates.rb +1 -1
  100. data/lib/jamf/ruby_extensions/hash.rb +1 -1
  101. data/lib/jamf/ruby_extensions/hash/backports.rb +2 -2
  102. data/lib/jamf/ruby_extensions/ipaddr.rb +1 -1
  103. data/lib/jamf/ruby_extensions/ipaddr/utils.rb +1 -1
  104. data/lib/jamf/ruby_extensions/object.rb +1 -1
  105. data/lib/jamf/ruby_extensions/object/predicates.rb +1 -1
  106. data/lib/jamf/ruby_extensions/pathname.rb +1 -1
  107. data/lib/jamf/ruby_extensions/pathname/predicates.rb +1 -1
  108. data/lib/jamf/ruby_extensions/pathname/utils.rb +1 -1
  109. data/lib/jamf/ruby_extensions/string.rb +1 -1
  110. data/lib/jamf/ruby_extensions/string/backports.rb +1 -1
  111. data/lib/jamf/ruby_extensions/string/conversions.rb +1 -1
  112. data/lib/jamf/ruby_extensions/string/predicates.rb +14 -4
  113. data/lib/jamf/utility.rb +1 -1
  114. data/lib/jamf/validate.rb +1 -1
  115. data/lib/jamf/version.rb +2 -2
  116. data/lib/jpapi.rb +1 -1
  117. data/lib/jss-api.rb +1 -1
  118. data/lib/jss.rb +5 -2
  119. data/lib/jss/api_connection.rb +3 -30
  120. data/lib/jss/api_object.rb +16 -3
  121. data/lib/jss/api_object/account.rb +1 -1
  122. data/lib/jss/api_object/advanced_search.rb +1 -1
  123. data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +1 -1
  124. data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +1 -1
  125. data/lib/jss/api_object/advanced_search/advanced_user_search.rb +1 -1
  126. data/lib/jss/api_object/building.rb +1 -1
  127. data/lib/jss/api_object/categorizable.rb +1 -1
  128. data/lib/jss/api_object/category.rb +1 -1
  129. data/lib/jss/api_object/computer.rb +12 -6
  130. data/lib/jss/api_object/computer/application_installs.rb +1 -1
  131. data/lib/jss/api_object/computer_invitation.rb +1 -1
  132. data/lib/jss/api_object/configuration_profile.rb +4 -2
  133. data/lib/jss/api_object/configuration_profile/mobile_device_configuration_profile.rb +1 -1
  134. data/lib/jss/api_object/configuration_profile/osx_configuration_profile.rb +1 -1
  135. data/lib/jss/api_object/creatable.rb +1 -1
  136. data/lib/jss/api_object/criteriable.rb +10 -5
  137. data/lib/jss/api_object/criteriable/criteria.rb +26 -10
  138. data/lib/jss/api_object/criteriable/criterion.rb +1 -1
  139. data/lib/jss/api_object/department.rb +1 -1
  140. data/lib/jss/api_object/directory_binding.rb +273 -0
  141. data/lib/jss/api_object/directory_binding_type.rb +90 -0
  142. data/lib/jss/api_object/directory_binding_type/active_directory.rb +502 -0
  143. data/lib/jss/api_object/directory_binding_type/admitmac.rb +525 -0
  144. data/lib/jss/api_object/directory_binding_type/centrify.rb +212 -0
  145. data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
  146. data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
  147. data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
  148. data/lib/jss/api_object/distribution_point.rb +96 -36
  149. data/lib/jss/api_object/dock_item.rb +137 -0
  150. data/lib/jss/api_object/ebook.rb +1 -1
  151. data/lib/jss/api_object/extendable.rb +67 -28
  152. data/lib/jss/api_object/extension_attribute.rb +1 -1
  153. data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +1 -1
  154. data/lib/jss/api_object/extension_attribute/mobile_device_extension_attribute.rb +1 -1
  155. data/lib/jss/api_object/extension_attribute/user_extension_attribute.rb +1 -1
  156. data/lib/jss/api_object/group.rb +1 -1
  157. data/lib/jss/api_object/group/computer_group.rb +1 -1
  158. data/lib/jss/api_object/group/mobile_device_group.rb +1 -1
  159. data/lib/jss/api_object/group/user_group.rb +1 -1
  160. data/lib/jss/api_object/ibeacon.rb +1 -1
  161. data/lib/jss/api_object/ldap_server.rb +1 -1
  162. data/lib/jss/api_object/locatable.rb +1 -1
  163. data/lib/jss/api_object/mac_application.rb +1 -1
  164. data/lib/jss/api_object/management_history.rb +23 -22
  165. data/lib/jss/api_object/management_history/audit_event.rb +1 -1
  166. data/lib/jss/api_object/management_history/casper_imaging_log.rb +1 -1
  167. data/lib/jss/api_object/management_history/casper_remote_log.rb +1 -1
  168. data/lib/jss/api_object/management_history/computer_usage_log.rb +1 -1
  169. data/lib/jss/api_object/management_history/ebook.rb +1 -1
  170. data/lib/jss/api_object/management_history/hashlike.rb +1 -1
  171. data/lib/jss/api_object/management_history/mac_app_store_app.rb +1 -1
  172. data/lib/jss/api_object/management_history/mdm_command.rb +1 -1
  173. data/lib/jss/api_object/management_history/mobile_device_app.rb +1 -1
  174. data/lib/jss/api_object/management_history/policy_log.rb +1 -1
  175. data/lib/jss/api_object/management_history/screen_sharing_log.rb +1 -1
  176. data/lib/jss/api_object/management_history/user_location_change.rb +1 -1
  177. data/lib/jss/api_object/matchable.rb +1 -1
  178. data/lib/jss/api_object/mdm.rb +1 -1
  179. data/lib/jss/api_object/mobile_device.rb +29 -6
  180. data/lib/jss/api_object/mobile_device_application.rb +13 -1
  181. data/lib/jss/api_object/netboot_server.rb +1 -1
  182. data/lib/jss/api_object/network_segment.rb +153 -59
  183. data/lib/jss/api_object/package.rb +106 -41
  184. data/lib/jss/api_object/patch_policy.rb +1 -1
  185. data/lib/jss/api_object/patch_source.rb +1 -1
  186. data/lib/jss/api_object/patch_source/patch_external_source.rb +1 -1
  187. data/lib/jss/api_object/patch_source/patch_internal_source.rb +1 -1
  188. data/lib/jss/api_object/patch_title.rb +1 -1
  189. data/lib/jss/api_object/patch_title/version.rb +1 -1
  190. data/lib/jss/api_object/peripheral.rb +1 -1
  191. data/lib/jss/api_object/peripheral_type.rb +1 -1
  192. data/lib/jss/api_object/policy.rb +380 -5
  193. data/lib/jss/api_object/printer.rb +440 -0
  194. data/lib/jss/api_object/purchasable.rb +1 -1
  195. data/lib/jss/api_object/removable_macaddr.rb +1 -1
  196. data/lib/jss/api_object/restricted_software.rb +1 -1
  197. data/lib/jss/api_object/scopable.rb +1 -1
  198. data/lib/jss/api_object/scopable/scope.rb +257 -37
  199. data/lib/jss/api_object/script.rb +1 -1
  200. data/lib/jss/api_object/self_servable.rb +7 -7
  201. data/lib/jss/api_object/self_servable/icon.rb +1 -1
  202. data/lib/jss/api_object/sitable.rb +6 -2
  203. data/lib/jss/api_object/site.rb +1 -1
  204. data/lib/jss/api_object/software_update_server.rb +1 -1
  205. data/lib/jss/api_object/updatable.rb +1 -1
  206. data/lib/jss/api_object/uploadable.rb +1 -1
  207. data/lib/jss/api_object/user.rb +5 -3
  208. data/lib/jss/api_object/vppable.rb +1 -1
  209. data/lib/jss/api_object/webhook.rb +1 -1
  210. data/lib/jss/client.rb +1 -1
  211. data/lib/jss/client/jamf_binary.rb +1 -1
  212. data/lib/jss/client/jamf_helper.rb +1 -1
  213. data/lib/jss/client/management_action.rb +1 -1
  214. data/lib/jss/compatibility.rb +1 -1
  215. data/lib/jss/composer.rb +2 -2
  216. data/lib/jss/configuration.rb +1 -1
  217. data/lib/jss/db_connection.rb +1 -1
  218. data/lib/jss/exceptions.rb +1 -1
  219. data/lib/jss/ruby_extensions.rb +1 -1
  220. data/lib/jss/ruby_extensions/array.rb +1 -1
  221. data/lib/jss/ruby_extensions/filetest.rb +1 -1
  222. data/lib/jss/ruby_extensions/hash.rb +1 -1
  223. data/lib/jss/ruby_extensions/ipaddr.rb +1 -1
  224. data/lib/jss/ruby_extensions/pathname.rb +1 -1
  225. data/lib/jss/ruby_extensions/string.rb +1 -1
  226. data/lib/jss/ruby_extensions/string/backports.rb +1 -1
  227. data/lib/jss/ruby_extensions/string/conversions.rb +1 -1
  228. data/lib/jss/ruby_extensions/string/predicates.rb +14 -4
  229. data/lib/jss/ruby_extensions/time.rb +1 -1
  230. data/lib/jss/server.rb +1 -1
  231. data/lib/jss/utility.rb +9 -23
  232. data/lib/jss/validate.rb +1 -1
  233. data/lib/jss/version.rb +2 -2
  234. data/lib/jss/xml_workaround.rb +1 -1
  235. data/lib/ruby-jss.rb +1 -1
  236. data/test/bin/runtests +1 -1
  237. data/test/lib/testhelper.rb +1 -1
  238. data/test/lib/testhelper/auth.rb +1 -1
  239. data/test/lib/testhelper/patch_mgmt.rb +1 -1
  240. data/test/specs/api_connection_spec.rb +1 -1
  241. data/test/specs/patch01_source_spec.rb +1 -1
  242. data/test/specs/patch02_internal_source_spec.rb +1 -1
  243. data/test/specs/patch03_external_source_spec.rb +1 -1
  244. data/test/specs/patch04_titles_spec.rb +1 -1
  245. data/test/specs/patch05_policies_spec.rb +1 -1
  246. data/test/specs/patch06_cleanup_spec.rb +1 -1
  247. data/test/specs/policy_spec.rb +1 -1
  248. metadata +15 -4
@@ -1,4 +1,4 @@
1
- ### Copyright 2019 Pixar
1
+ ### Copyright 2020 Pixar
2
2
 
3
3
  ###
4
4
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
@@ -1,4 +1,4 @@
1
- ### Copyright 2019 Pixar
1
+ ### Copyright 2020 Pixar
2
2
 
3
3
  ###
4
4
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Pixar
1
+ # Copyright 2020 Pixar
2
2
 
3
3
  # Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  # with the following modification; you may not use this file except in
@@ -41,6 +41,85 @@ module JSS
41
41
  # This class provides methods for adding, removing, or fully replacing the
42
42
  # various items in scope's realms: targets, limitations, and exclusions.
43
43
  #
44
+ # IMPORTANT:
45
+ # The classic API has bugs regarding the use of Users, UserGroups,
46
+ # LDAP/Local Users, & LDAP User Groups in scopes. Here's a discussion
47
+ # of those bugs and how ruby-jss handles them.
48
+ #
49
+ # Targets/Inclusions
50
+ # - 'Users' can only be JSS::Users - No LDAP
51
+ # - BUG: They do not appear in API data (XML or JSON) and are
52
+ # NOT SUPPORTED in ruby-jss.
53
+ # - You must use the Web UI to work with them in a Scope.
54
+ # - 'User Groups' can only be JSS::UserGroups - No LDAP
55
+ # - BUG: They do not appear in API data (XML or JSON) and are
56
+ # NOT SUPPORTED in ruby-jss.
57
+ # - You must use the Web UI to work with them in a Scope.
58
+ #
59
+ # Limitations
60
+ # - 'LDAP/Local Users' can be any string
61
+ # - The Web UI accepts any string, even if no matching Local or LDAP user.
62
+ # - The data shows up in API data in scope=>limitations=>users
63
+ # by name only (the string provided), no IDs
64
+ # - 'LDAP User Groups' can only be LDAP groups that actually exist
65
+ # - The Web UI won't let you add a group that doesn't exist in ldap
66
+ # - The data shows up in API data in scope=>limitations=>user_groups
67
+ # by name and LDAP ID (which may be empty)
68
+ # - The data ALSO shows up in API data in scope=>limit_to_users=>user_groups
69
+ # by name only, no LDAP IDs. ruby-jss ignores this and looks at
70
+ # scope=>limitations=>user_groups
71
+ #
72
+ # Exclusions, combines the behavior of Inclusions & Limitations
73
+ # - 'Users' can only be JSS::Users - No LDAP
74
+ # - BUG: They do not appear in API data (XML or JSON) and are
75
+ # NOT SUPPORTED in ruby-jss.
76
+ # - You must use the Web UI to work with them in a Scope.
77
+ # - 'User Groups' can only be JSS::UserGroups - No LDAP
78
+ # - BUG: They do not appear in API data (XML or JSON) and are
79
+ # NOT SUPPORTED in ruby-jss.
80
+ # - You must use the Web UI to work with them in a Scope.
81
+ # - 'LDAP/Local Users' can be any string
82
+ # - The Web UI accepts any string, even if no matching Local or LDAP user.
83
+ # - The data shows up in API data in scope=>exclusions=>users
84
+ # by name only (the string provided), no IDs
85
+ # - 'LDAP User Groups' can only be LDAP groups that actually exist
86
+ # - The Web UI won't let you add a group that doesn't exist in ldap
87
+ # - The data shows up in API data in scope=>exclusions=>user_groups
88
+ # by name and LDAP ID (which may be empty)
89
+ #
90
+ #
91
+ # How ruby-jss handles this:
92
+ #
93
+ # - Methods #set_targets and #add_target will not accept the keys
94
+ # :user, :users, :user_group, :user_groups.
95
+ #
96
+ # - Method #remove_target will ignore them.
97
+ #
98
+ # - Methods #set_limitations, #add_limitation & #remove_limitation will accept:
99
+ # - :user, :ldap_user, or :jamf_ldap_user (and their plurals) for working
100
+ # with 'LDAP/Local Users'. When setting or adding, the provided
101
+ # string(s) must exist as either a JSS::User or an LDAP user
102
+ # - :user_group or :ldap_user_group (and their plurals) for working with
103
+ # 'LDAP User Groups'. When setting or adding, the provided string
104
+ # must exist as a group in LDAP.
105
+ #
106
+ # - Methods #set_exclusions, #add_exclusion & #remove_exclusion will accept:
107
+ # - :user, :ldap_user, or :jamf_ldap_user (and their plurals) for working
108
+ # with 'LDAP/Local Users'. When setting or adding, the provided string(s)
109
+ # must exist as either a JSS::User or an LDAP user.
110
+ # - :user_group or :ldap_user_group (and their plurals) for working with
111
+ # 'LDAP User Groups''. When setting or adding, the provided string
112
+ # must exist as a group in LDAP.
113
+ #
114
+ # Internally in the Scope instance:
115
+ #
116
+ # - The limitations and exclusions that match the WebUI's 'LDAP/Local Users'
117
+ # are in @limitations[:jamf_ldap_users] and @exclusions[:jamf_ldap_users]
118
+ #
119
+ # - The limitations and exclusions that match the WebUI's 'LDAP User Groups'
120
+ # are in @limitations[:ldap_user_groups] and @exclusions[:ldap_user_groups]
121
+ #
122
+ #
44
123
  # @see JSS::Scopable
45
124
  #
46
125
  class Scope
@@ -50,6 +129,8 @@ module JSS
50
129
 
51
130
  # These are the classes that Scopes can use for defining a scope,
52
131
  # keyed by appropriate symbols.
132
+ # NOTE: All the user and group ones don't actually refer to
133
+ # JSS::User or JSS::UserGroup. See IMPORTANT discussion above.
53
134
  SCOPING_CLASSES = {
54
135
  computers: JSS::Computer,
55
136
  computer: JSS::Computer,
@@ -65,16 +146,37 @@ module JSS
65
146
  department: JSS::Department,
66
147
  network_segments: JSS::NetworkSegment,
67
148
  network_segment: JSS::NetworkSegment,
68
- users: JSS::User,
69
- user: JSS::User,
70
- user_groups: JSS::UserGroup,
71
- user_group: JSS::UserGroup
149
+ ibeacon: JSS::IBeacon,
150
+ ibeacons: JSS::IBeacon,
151
+ user: nil,
152
+ users: nil,
153
+ ldap_user: nil,
154
+ ldap_users: nil,
155
+ jamf_ldap_user: nil,
156
+ jamf_ldap_users: nil,
157
+ user_group: nil,
158
+ user_groups: nil,
159
+ ldap_user_group: nil,
160
+ ldap_user_groups: nil
72
161
  }.freeze
73
162
 
74
- # Some things get checked in LDAP as well as the JSS
75
- LDAP_USER_KEYS = %i[user users].freeze
76
- LDAP_GROUP_KEYS = %i[user_groups user_group].freeze
77
- CHECK_LDAP_KEYS = LDAP_USER_KEYS + LDAP_GROUP_KEYS
163
+ # These keys always mean :jamf_ldap_users
164
+ LDAP_JAMF_USER_KEYS = %i[
165
+ user
166
+ users
167
+ ldap_user
168
+ ldap_users
169
+ jamf_ldap_user
170
+ jamf_ldap_users
171
+ ].freeze
172
+
173
+ # These keys always mean :ldap_user_groups
174
+ LDAP_GROUP_KEYS = %i[
175
+ user_group
176
+ user_groups
177
+ ldap_user_group
178
+ ldap_user_groups
179
+ ].freeze
78
180
 
79
181
  # This hash maps the availble Scope Target keys from SCOPING_CLASSES to
80
182
  # their corresponding target group keys from SCOPING_CLASSES.
@@ -88,7 +190,16 @@ module JSS
88
190
  INCLUSIONS = %i[buildings departments].freeze
89
191
 
90
192
  # These can limit the inclusion list
91
- LIMITATIONS = %i[network_segments users user_groups].freeze
193
+ # These are the keys that come from the API
194
+ # the :users key from the API is what we call :jamf_ldap_users
195
+ # and the :user_groups key from the API we call :ldap_user_groups
196
+ # See the IMPORTANT discussion above.
197
+ LIMITATIONS = %i[
198
+ ibeacons
199
+ network_segments
200
+ jamf_ldap_users
201
+ ldap_user_groups
202
+ ].freeze
92
203
 
93
204
  # any of them can be excluded
94
205
  EXCLUSIONS = INCLUSIONS + LIMITATIONS
@@ -179,7 +290,9 @@ module JSS
179
290
  #
180
291
  def initialize(target_key, raw_scope = nil)
181
292
  raw_scope ||= DEFAULT_SCOPE.dup
182
- raise JSS::InvalidDataError, "The target class of a Scope must be one of the symbols :#{TARGETS_AND_GROUPS.keys.join(', :')}" unless TARGETS_AND_GROUPS.key?(target_key)
293
+ unless TARGETS_AND_GROUPS.key?(target_key)
294
+ raise JSS::InvalidDataError, "The target class of a Scope must be one of the symbols :#{TARGETS_AND_GROUPS.keys.join(', :')}"
295
+ end
183
296
 
184
297
  @target_key = target_key
185
298
  @target_class = SCOPING_CLASSES[@target_key]
@@ -197,24 +310,64 @@ module JSS
197
310
  @inclusions = {}
198
311
  @inclusion_keys.each do |k|
199
312
  raw_scope[k] ||= []
200
- @inclusions[k] = raw_scope[k].compact.map { |n| n[:id].to_i }
313
+ @inclusions[k] = raw_scope[k].compact.map { |n| n[:id].to_i }
201
314
  end # @inclusion_keys.each do |k|
202
315
 
316
+ # the :users key from the API is what we call :jamf_ldap_users
317
+ # and the :user_groups key from the API we call :ldap_user_groups
318
+ # See the IMPORTANT discussion above.
203
319
  @limitations = {}
204
320
  if raw_scope[:limitations]
321
+
205
322
  LIMITATIONS.each do |k|
206
- raw_scope[:limitations][k] ||= []
207
- @limitations[k] = raw_scope[:limitations][k].compact.map { |n| n[:id].to_i }
323
+ # :jamf_ldap_users comes from :users in the API data
324
+ if k == :jamf_ldap_users
325
+ api_data = raw_scope[:limitations][:users]
326
+ api_data ||= []
327
+ @limitations[k] = api_data.compact.map { |n| n[:name].to_s }
328
+
329
+ # :ldap_user_groups comes from :user_groups in the API data
330
+ elsif k == :ldap_user_groups
331
+ api_data = raw_scope[:limitations][:user_groups]
332
+ api_data ||= []
333
+ @limitations[k] = api_data.compact.map { |n| n[:name].to_s }
334
+
335
+ # others handled normally.
336
+ else
337
+ api_data = raw_scope[:limitations][k]
338
+ api_data ||= []
339
+ @limitations[k] = api_data.compact.map { |n| n[:id].to_i }
340
+ end
208
341
  end # LIMITATIONS.each do |k|
209
342
  end # if raw_scope[:limitations]
210
343
 
344
+ # the :users key from the API is what we call :jamf_ldap_users
345
+ # and the :user_groups key from the API we call :ldap_user_groups
346
+ # See the IMPORTANT discussion above.
211
347
  @exclusions = {}
212
348
  if raw_scope[:exclusions]
349
+
213
350
  @exclusion_keys.each do |k|
214
- raw_scope[:exclusions][k] ||= []
215
- @exclusions[k] = raw_scope[:exclusions][k].compact.map { |n| n[:id].to_i }
216
- end
217
- end
351
+ # :jamf_ldap_users comes from :users in the API data
352
+ if k == :jamf_ldap_users
353
+ api_data = raw_scope[:exclusions][:users]
354
+ api_data ||= []
355
+ @exclusions[k] = api_data.compact.map { |n| n[:name].to_s }
356
+
357
+ # :ldap_user_groups comes from :user_groups in the API data
358
+ elsif k == :ldap_user_groups
359
+ api_data = raw_scope[:exclusions][:user_groups]
360
+ api_data ||= []
361
+ @exclusions[k] = api_data.compact.map { |n| n[:name].to_s }
362
+
363
+ # others handled normally.
364
+ else
365
+ api_data = raw_scope[:exclusions][k]
366
+ api_data ||= []
367
+ @exclusions[k] = api_data.compact.map { |n| n[:id].to_i }
368
+ end # if ...elsif... else
369
+ end # @exclusion_keys.each
370
+ end # if raw_scope[:exclusions]
218
371
 
219
372
  @container = nil
220
373
  end # init
@@ -266,10 +419,12 @@ module JSS
266
419
  # check the idents
267
420
  list.map! do |ident|
268
421
  item_id = validate_item(:target, key, ident)
422
+
269
423
  if @exclusions[key] && @exclusions[key].include?(item_id)
270
424
  raise JSS::AlreadyExistsError, \
271
- "Can't set #{key} target to '#{ident}' because it's already an explicit exclusion."
425
+ "Can't set #{key} target to '#{ident}' because it's already an explicit exclusion."
272
426
  end
427
+
273
428
  item_id
274
429
  end # each
275
430
 
@@ -303,7 +458,7 @@ module JSS
303
458
  def add_target(key, item)
304
459
  key = pluralize_key(key)
305
460
  item_id = validate_item(:target, key, item)
306
- return if @inclusions[key] && @inclusions[key].include?(item_id)
461
+ return if @inclusions[key] && @exclusions[key].include?(item_id)
307
462
 
308
463
  raise JSS::AlreadyExistsError, "Can't set #{key} target to '#{item}' because it's already an explicit exclusion." if @exclusions[key] && @exclusions[key].include?(item_id)
309
464
 
@@ -328,7 +483,8 @@ module JSS
328
483
  key = pluralize_key(key)
329
484
  item_id = validate_item :target, key, item, error_if_not_found: false
330
485
  return unless item_id
331
- return unless @inclusions[key] && @inclusions[key].include?(item_id)
486
+ return unless @inclusions[key] && @exclusions[key].include?(item_id)
487
+
332
488
  @inclusions[key].delete item_id
333
489
  @container.should_update if @container
334
490
  end
@@ -357,7 +513,10 @@ module JSS
357
513
  # check the idents
358
514
  list.map! do |ident|
359
515
  item_id = validate_item(:limitation, key, ident)
360
- raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." if @exclusions[key] && @exclusions[key].include?(item_id)
516
+ if @exclusions[key] && @exclusions[key].include?(item_id)
517
+ raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion."
518
+ end
519
+
361
520
  item_id
362
521
  end # each
363
522
 
@@ -386,9 +545,11 @@ module JSS
386
545
  def add_limitation(key, item)
387
546
  key = pluralize_key(key)
388
547
  item_id = validate_item(:limitation, key, item)
389
- return nil if @limitations[key] && @limitations[key].include?(item_id)
548
+ return nil if @limitations[key] && @exclusions[key].include?(item_id)
390
549
 
391
- raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." if @exclusions[key] && @exclusions[key].include?(item_id)
550
+ if @exclusions[key] && @exclusions[key].include?(item_id)
551
+ raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion."
552
+ end
392
553
 
393
554
  @limitations[key] << item_id
394
555
  @container.should_update if @container
@@ -411,7 +572,8 @@ module JSS
411
572
  key = pluralize_key(key)
412
573
  item_id = validate_item :limitation, key, item, error_if_not_found: false
413
574
  return unless item_id
414
- return unless @limitations[key] && @limitations[key].include?(item_id)
575
+ return unless @limitations[key] && @exclusions[key].include?(item_id)
576
+
415
577
  @limitations[key].delete item_id
416
578
  @container.should_update if @container
417
579
  end ###
@@ -439,9 +601,11 @@ module JSS
439
601
  item_id = validate_item(:exclusion, key, ident)
440
602
  case key
441
603
  when *@inclusion_keys
442
- raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{ident}' because it's already explicitly included." if @inclusions[key] && @inclusions[key].include?(item_id)
604
+ raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{ident}' because it's already explicitly included." if @inclusions[key] && @exclusions[key].include?(item_id)
443
605
  when *LIMITATIONS
444
- raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{ident}' because it's already an explicit limitation." if @limitations[key] && @limitations[key].include?(item_id)
606
+ if @limitations[key] && @exclusions[key].include?(item_id)
607
+ raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{ident}' because it's already an explicit limitation."
608
+ end
445
609
  end
446
610
  item_id
447
611
  end # each
@@ -469,7 +633,9 @@ module JSS
469
633
  key = pluralize_key(key)
470
634
  item_id = validate_item(:exclusion, key, item)
471
635
  return if @exclusions[key] && @exclusions[key].include?(item_id)
636
+
472
637
  raise JSS::AlreadyExistsError, "Can't exclude #{key} scope to '#{item}' because it's already explicitly included." if @inclusions[key] && @inclusions[key].include?(item)
638
+
473
639
  raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{item}' because it's already an explicit limitation." if @limitations[key] && @limitations[key].include?(item)
474
640
 
475
641
  @exclusions[key] << item_id
@@ -491,6 +657,7 @@ module JSS
491
657
  key = pluralize_key(key)
492
658
  item_id = validate_item :exclusion, key, item, error_if_not_found: false
493
659
  return unless @exclusions[key] && @exclusions[key].include?(item_id)
660
+
494
661
  @exclusions[key].delete item_id
495
662
  @container.should_update if @container
496
663
  end
@@ -508,24 +675,52 @@ module JSS
508
675
  @inclusions.each do |klass, list|
509
676
  list.compact!
510
677
  list.delete 0
511
- list_as_hash = list.map { |i| { id: i } }
512
- scope << SCOPING_CLASSES[klass].xml_list(list_as_hash, :id)
678
+ list_as_hashes = list.map { |i| { id: i } }
679
+ scope << SCOPING_CLASSES[klass].xml_list(list_as_hashes, :id)
513
680
  end
514
681
 
515
682
  limitations = scope.add_element('limitations')
516
683
  @limitations.each do |klass, list|
517
684
  list.compact!
518
685
  list.delete 0
519
- list_as_hash = list.map { |i| { id: i } }
520
- limitations << SCOPING_CLASSES[klass].xml_list(list_as_hash, :id)
686
+ if klass == :jamf_ldap_users
687
+ users_xml = limitations.add_element 'users'
688
+ list.each do |name|
689
+ user_xml = users_xml.add_element 'user'
690
+ user_xml.add_element('name').text = name
691
+ end
692
+ elsif klass == :ldap_user_groups
693
+ user_groups_xml = limitations.add_element 'user_groups'
694
+ list.each do |name|
695
+ user_group_xml = user_groups_xml.add_element 'user_group'
696
+ user_group_xml.add_element('name').text = name
697
+ end
698
+ else
699
+ list_as_hashes = list.map { |i| { id: i } }
700
+ limitations << SCOPING_CLASSES[klass].xml_list(list_as_hashes, :id)
701
+ end
521
702
  end
522
703
 
523
704
  exclusions = scope.add_element('exclusions')
524
705
  @exclusions.each do |klass, list|
525
706
  list.compact!
526
707
  list.delete 0
527
- list_as_hash = list.map { |i| { id: i } }
528
- exclusions << SCOPING_CLASSES[klass].xml_list(list_as_hash, :id)
708
+ if klass == :jamf_ldap_users
709
+ users_xml = exclusions.add_element 'users'
710
+ list.each do |name|
711
+ user_xml = users_xml.add_element 'user'
712
+ user_xml.add_element('name').text = name
713
+ end
714
+ elsif klass == :ldap_user_groups
715
+ user_groups_xml = exclusions.add_element 'user_groups'
716
+ list.each do |name|
717
+ user_group_xml = user_groups_xml.add_element 'user_group'
718
+ user_group_xml.add_element('name').text = name
719
+ end
720
+ else
721
+ list_as_hashes = list.map { |i| { id: i } }
722
+ exclusions << SCOPING_CLASSES[klass].xml_list(list_as_hashes, :id)
723
+ end
529
724
  end
530
725
  scope
531
726
  end # scope_xml
@@ -551,6 +746,7 @@ module JSS
551
746
  private
552
747
 
553
748
  # look up a valid id or nil, for use in a scope type
749
+ # Raise an error if not found, unless error_if_not_found is falsey
554
750
  #
555
751
  # @param realm [Symbol] How is this key being used in the scope?
556
752
  # :target, :limitation, or :exclusion
@@ -561,7 +757,9 @@ module JSS
561
757
  # @param ident [String, Integer] A unique identifier for the item being
562
758
  # validated, jss id, name, serial number, etc.
563
759
  #
564
- # @return [Integer, nil] the valid id for the item, or nil if not found
760
+ # @param error_if_not_found [Boolean] raise an error if no match for the ident
761
+ #
762
+ # @return [Integer, String, nil] the valid id or string for the item, or nil if not found
565
763
  #
566
764
  def validate_item(realm, key, ident, error_if_not_found: true)
567
765
  # which keys allowed depends on how the item is used...
@@ -573,20 +771,42 @@ module JSS
573
771
  else
574
772
  raise ArgumentError, 'Unknown realm, must be :target, :limitation, or :exclusion'
575
773
  end
774
+
576
775
  key = pluralize_key(key)
776
+
577
777
  raise JSS::InvalidDataError, "#{realm} key must be one of :#{possible_keys.join(', :')}" \
578
778
  unless possible_keys.include? key
579
779
 
580
- # return nil or a valid id
581
- id = SCOPING_CLASSES[key].valid_id ident
780
+ id = nil
781
+
782
+ # id will be a string
783
+ if key == :jamf_ldap_users
784
+ id = ident if JSS::User.all_names(:refresh).include?(ident) || JSS::LDAPServer.user_in_ldap?(ident)
785
+
786
+ # id will be a string
787
+ elsif key == :ldap_user_groups
788
+ id = ident if JSS::LDAPServer.group_in_ldap? ident
789
+
790
+ # id will be an integer
791
+ else
792
+ id = SCOPING_CLASSES[key].valid_id ident
793
+ end
794
+
582
795
  raise JSS::NoSuchItemError, "No existing #{key} matching '#{ident}'" if error_if_not_found && id.nil?
796
+
583
797
  id
584
798
  end # validate_item(type, key, ident)
585
799
 
586
800
  # the symbols used in the API data are plural, e.g. 'network_segments'
587
801
  # this will pluralize them, allowing us to use singulars as well.
588
802
  def pluralize_key(key)
589
- key.to_s.end_with?(ESS) ? key : "#{key}s".to_sym
803
+ if LDAP_JAMF_USER_KEYS.include? key
804
+ :jamf_ldap_users
805
+ elsif LDAP_GROUP_KEYS.include? key
806
+ :ldap_user_groups
807
+ else
808
+ key.to_s.end_with?(ESS) ? key : "#{key}s".to_sym
809
+ end
590
810
  end
591
811
 
592
812
  end # class Scope