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.
- checksums.yaml +4 -4
- data/CHANGES.md +185 -1
- data/README.md +3 -1
- data/bin/cgrouper +1 -1
- data/bin/jamfHelperBackgrounder +1 -1
- data/bin/netseg-update +1 -1
- data/data/ruby-jss.conf.example +1 -1
- data/lib/jamf.rb +1 -1
- data/lib/jamf/api/abstract_classes/advanced_search.rb +1 -1
- data/lib/jamf/api/abstract_classes/collection_resource.rb +31 -26
- data/lib/jamf/api/abstract_classes/generic_reference.rb +1 -1
- data/lib/jamf/api/abstract_classes/json_object.rb +15 -5
- data/lib/jamf/api/abstract_classes/prestage.rb +2 -2
- data/lib/jamf/api/abstract_classes/prestage_skip_setup_items.rb +1 -1
- data/lib/jamf/api/abstract_classes/resource.rb +1 -1
- data/lib/jamf/api/abstract_classes/singleton_resource.rb +1 -1
- data/lib/jamf/api/attribute_classes/ip_address.rb +1 -1
- data/lib/jamf/api/attribute_classes/timestamp.rb +1 -1
- data/lib/jamf/api/connection.rb +106 -60
- data/lib/jamf/api/connection/api_error.rb +1 -1
- data/lib/jamf/api/connection/api_error_styleguide.rb +1 -1
- data/lib/jamf/api/connection/token.rb +80 -13
- data/lib/jamf/api/json_objects/account_prefs.rb +1 -1
- data/lib/jamf/api/json_objects/android_details.rb +1 -1
- data/lib/jamf/api/json_objects/appletv_details.rb +1 -1
- data/lib/jamf/api/json_objects/attachment.rb +1 -1
- data/lib/jamf/api/json_objects/cellular_network.rb +1 -1
- data/lib/jamf/api/json_objects/change_log_entry.rb +1 -1
- data/lib/jamf/api/json_objects/computer_prestage_skip_setup_items.rb +1 -1
- data/lib/jamf/api/json_objects/country.rb +1 -1
- data/lib/jamf/api/json_objects/criterion.rb +1 -1
- data/lib/jamf/api/json_objects/device_enrollment_device.rb +1 -1
- data/lib/jamf/api/json_objects/device_enrollment_sync_status.rb +1 -1
- data/lib/jamf/api/json_objects/extension_attribute_value.rb +1 -1
- data/lib/jamf/api/json_objects/installed_application.rb +1 -1
- data/lib/jamf/api/json_objects/installed_certificate.rb +1 -1
- data/lib/jamf/api/json_objects/installed_configuration_profile.rb +1 -1
- data/lib/jamf/api/json_objects/installed_ebook.rb +1 -1
- data/lib/jamf/api/json_objects/installed_provisioning_profile.rb +1 -1
- data/lib/jamf/api/json_objects/inventory_preload_extension_attribute.rb +1 -1
- data/lib/jamf/api/json_objects/ios_details.rb +1 -1
- data/lib/jamf/api/json_objects/location.rb +1 -1
- data/lib/jamf/api/json_objects/md_prestage_name.rb +1 -1
- data/lib/jamf/api/json_objects/md_prestage_names.rb +1 -1
- data/lib/jamf/api/json_objects/md_prestage_skip_setup_items.rb +1 -1
- data/lib/jamf/api/json_objects/mobile_device_details.rb +1 -1
- data/lib/jamf/api/json_objects/mobile_device_security.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_assignment.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_location.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_purchasing_data.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_scope.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_sync_status.rb +1 -1
- data/lib/jamf/api/json_objects/purchasing_data.rb +1 -1
- data/lib/jamf/api/mixins/abstract.rb +1 -1
- data/lib/jamf/api/mixins/bulk_deletable.rb +1 -1
- data/lib/jamf/api/mixins/change_log.rb +1 -1
- data/lib/jamf/api/mixins/extendable.rb +1 -1
- data/lib/jamf/api/mixins/immutable.rb +1 -1
- data/lib/jamf/api/mixins/locatable.rb +1 -1
- data/lib/jamf/api/mixins/lockable.rb +1 -1
- data/lib/jamf/api/mixins/referable.rb +1 -1
- data/lib/jamf/api/mixins/searchable.rb +1 -1
- data/lib/jamf/api/mixins/uncreatable.rb +1 -1
- data/lib/jamf/api/mixins/undeletable.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/account.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/advanced_mobile_device_search.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/advanced_user_search.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/building.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/category.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/computer.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/computer_prestage.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/department.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/device_enrollment.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/extension_attribute.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/inventory_preload_record.rb +9 -2
- data/lib/jamf/api/resources/collection_resources/mobile_device.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/mobile_device_prestage.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/script.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/site.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/time_zone.rb +1 -1
- data/lib/jamf/api/resources/singleton_resources/app_store_country_codes.rb +1 -1
- data/lib/jamf/api/resources/singleton_resources/authorization.rb +1 -1
- data/lib/jamf/api/resources/singleton_resources/client_checkin_settings.rb +1 -1
- data/lib/jamf/api/resources/singleton_resources/reenrollment_settings.rb +1 -1
- data/lib/jamf/client.rb +1 -1
- data/lib/jamf/client/jamf_binary.rb +1 -1
- data/lib/jamf/client/jamf_helper.rb +1 -1
- data/lib/jamf/client/management_action.rb +1 -1
- data/lib/jamf/compatibility.rb +1 -1
- data/lib/jamf/composer.rb +1 -1
- data/lib/jamf/configuration.rb +8 -10
- data/lib/jamf/exceptions.rb +6 -1
- data/lib/jamf/ruby_extensions.rb +2 -1
- data/lib/jamf/ruby_extensions/array.rb +2 -2
- data/lib/jamf/ruby_extensions/array/predicates.rb +1 -1
- data/lib/jamf/ruby_extensions/array/utils.rb +4 -4
- data/lib/jamf/ruby_extensions/dig.rb +52 -0
- data/lib/jamf/ruby_extensions/filetest.rb +1 -1
- data/lib/jamf/ruby_extensions/filetest/predicates.rb +1 -1
- data/lib/jamf/ruby_extensions/hash.rb +1 -1
- data/lib/jamf/ruby_extensions/hash/backports.rb +2 -2
- data/lib/jamf/ruby_extensions/ipaddr.rb +1 -1
- data/lib/jamf/ruby_extensions/ipaddr/utils.rb +1 -1
- data/lib/jamf/ruby_extensions/object.rb +1 -1
- data/lib/jamf/ruby_extensions/object/predicates.rb +1 -1
- data/lib/jamf/ruby_extensions/pathname.rb +1 -1
- data/lib/jamf/ruby_extensions/pathname/predicates.rb +1 -1
- data/lib/jamf/ruby_extensions/pathname/utils.rb +1 -1
- data/lib/jamf/ruby_extensions/string.rb +1 -1
- data/lib/jamf/ruby_extensions/string/backports.rb +1 -1
- data/lib/jamf/ruby_extensions/string/conversions.rb +1 -1
- data/lib/jamf/ruby_extensions/string/predicates.rb +14 -4
- data/lib/jamf/utility.rb +1 -1
- data/lib/jamf/validate.rb +1 -1
- data/lib/jamf/version.rb +2 -2
- data/lib/jpapi.rb +1 -1
- data/lib/jss-api.rb +1 -1
- data/lib/jss.rb +5 -2
- data/lib/jss/api_connection.rb +3 -30
- data/lib/jss/api_object.rb +16 -3
- data/lib/jss/api_object/account.rb +1 -1
- data/lib/jss/api_object/advanced_search.rb +1 -1
- data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +1 -1
- data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +1 -1
- data/lib/jss/api_object/advanced_search/advanced_user_search.rb +1 -1
- data/lib/jss/api_object/building.rb +1 -1
- data/lib/jss/api_object/categorizable.rb +1 -1
- data/lib/jss/api_object/category.rb +1 -1
- data/lib/jss/api_object/computer.rb +12 -6
- data/lib/jss/api_object/computer/application_installs.rb +1 -1
- data/lib/jss/api_object/computer_invitation.rb +1 -1
- data/lib/jss/api_object/configuration_profile.rb +4 -2
- data/lib/jss/api_object/configuration_profile/mobile_device_configuration_profile.rb +1 -1
- data/lib/jss/api_object/configuration_profile/osx_configuration_profile.rb +1 -1
- data/lib/jss/api_object/creatable.rb +1 -1
- data/lib/jss/api_object/criteriable.rb +10 -5
- data/lib/jss/api_object/criteriable/criteria.rb +26 -10
- data/lib/jss/api_object/criteriable/criterion.rb +1 -1
- data/lib/jss/api_object/department.rb +1 -1
- data/lib/jss/api_object/directory_binding.rb +273 -0
- data/lib/jss/api_object/directory_binding_type.rb +90 -0
- data/lib/jss/api_object/directory_binding_type/active_directory.rb +502 -0
- data/lib/jss/api_object/directory_binding_type/admitmac.rb +525 -0
- data/lib/jss/api_object/directory_binding_type/centrify.rb +212 -0
- data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
- data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
- data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
- data/lib/jss/api_object/distribution_point.rb +96 -36
- data/lib/jss/api_object/dock_item.rb +137 -0
- data/lib/jss/api_object/ebook.rb +1 -1
- data/lib/jss/api_object/extendable.rb +67 -28
- data/lib/jss/api_object/extension_attribute.rb +1 -1
- data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +1 -1
- data/lib/jss/api_object/extension_attribute/mobile_device_extension_attribute.rb +1 -1
- data/lib/jss/api_object/extension_attribute/user_extension_attribute.rb +1 -1
- data/lib/jss/api_object/group.rb +1 -1
- data/lib/jss/api_object/group/computer_group.rb +1 -1
- data/lib/jss/api_object/group/mobile_device_group.rb +1 -1
- data/lib/jss/api_object/group/user_group.rb +1 -1
- data/lib/jss/api_object/ibeacon.rb +1 -1
- data/lib/jss/api_object/ldap_server.rb +1 -1
- data/lib/jss/api_object/locatable.rb +1 -1
- data/lib/jss/api_object/mac_application.rb +1 -1
- data/lib/jss/api_object/management_history.rb +23 -22
- data/lib/jss/api_object/management_history/audit_event.rb +1 -1
- data/lib/jss/api_object/management_history/casper_imaging_log.rb +1 -1
- data/lib/jss/api_object/management_history/casper_remote_log.rb +1 -1
- data/lib/jss/api_object/management_history/computer_usage_log.rb +1 -1
- data/lib/jss/api_object/management_history/ebook.rb +1 -1
- data/lib/jss/api_object/management_history/hashlike.rb +1 -1
- data/lib/jss/api_object/management_history/mac_app_store_app.rb +1 -1
- data/lib/jss/api_object/management_history/mdm_command.rb +1 -1
- data/lib/jss/api_object/management_history/mobile_device_app.rb +1 -1
- data/lib/jss/api_object/management_history/policy_log.rb +1 -1
- data/lib/jss/api_object/management_history/screen_sharing_log.rb +1 -1
- data/lib/jss/api_object/management_history/user_location_change.rb +1 -1
- data/lib/jss/api_object/matchable.rb +1 -1
- data/lib/jss/api_object/mdm.rb +1 -1
- data/lib/jss/api_object/mobile_device.rb +29 -6
- data/lib/jss/api_object/mobile_device_application.rb +13 -1
- data/lib/jss/api_object/netboot_server.rb +1 -1
- data/lib/jss/api_object/network_segment.rb +153 -59
- data/lib/jss/api_object/package.rb +106 -41
- data/lib/jss/api_object/patch_policy.rb +1 -1
- data/lib/jss/api_object/patch_source.rb +1 -1
- data/lib/jss/api_object/patch_source/patch_external_source.rb +1 -1
- data/lib/jss/api_object/patch_source/patch_internal_source.rb +1 -1
- data/lib/jss/api_object/patch_title.rb +1 -1
- data/lib/jss/api_object/patch_title/version.rb +1 -1
- data/lib/jss/api_object/peripheral.rb +1 -1
- data/lib/jss/api_object/peripheral_type.rb +1 -1
- data/lib/jss/api_object/policy.rb +380 -5
- data/lib/jss/api_object/printer.rb +440 -0
- data/lib/jss/api_object/purchasable.rb +1 -1
- data/lib/jss/api_object/removable_macaddr.rb +1 -1
- data/lib/jss/api_object/restricted_software.rb +1 -1
- data/lib/jss/api_object/scopable.rb +1 -1
- data/lib/jss/api_object/scopable/scope.rb +257 -37
- data/lib/jss/api_object/script.rb +1 -1
- data/lib/jss/api_object/self_servable.rb +7 -7
- data/lib/jss/api_object/self_servable/icon.rb +1 -1
- data/lib/jss/api_object/sitable.rb +6 -2
- data/lib/jss/api_object/site.rb +1 -1
- data/lib/jss/api_object/software_update_server.rb +1 -1
- data/lib/jss/api_object/updatable.rb +1 -1
- data/lib/jss/api_object/uploadable.rb +1 -1
- data/lib/jss/api_object/user.rb +5 -3
- data/lib/jss/api_object/vppable.rb +1 -1
- data/lib/jss/api_object/webhook.rb +1 -1
- data/lib/jss/client.rb +1 -1
- data/lib/jss/client/jamf_binary.rb +1 -1
- data/lib/jss/client/jamf_helper.rb +1 -1
- data/lib/jss/client/management_action.rb +1 -1
- data/lib/jss/compatibility.rb +1 -1
- data/lib/jss/composer.rb +2 -2
- data/lib/jss/configuration.rb +1 -1
- data/lib/jss/db_connection.rb +1 -1
- data/lib/jss/exceptions.rb +1 -1
- data/lib/jss/ruby_extensions.rb +1 -1
- data/lib/jss/ruby_extensions/array.rb +1 -1
- data/lib/jss/ruby_extensions/filetest.rb +1 -1
- data/lib/jss/ruby_extensions/hash.rb +1 -1
- data/lib/jss/ruby_extensions/ipaddr.rb +1 -1
- data/lib/jss/ruby_extensions/pathname.rb +1 -1
- data/lib/jss/ruby_extensions/string.rb +1 -1
- data/lib/jss/ruby_extensions/string/backports.rb +1 -1
- data/lib/jss/ruby_extensions/string/conversions.rb +1 -1
- data/lib/jss/ruby_extensions/string/predicates.rb +14 -4
- data/lib/jss/ruby_extensions/time.rb +1 -1
- data/lib/jss/server.rb +1 -1
- data/lib/jss/utility.rb +9 -23
- data/lib/jss/validate.rb +1 -1
- data/lib/jss/version.rb +2 -2
- data/lib/jss/xml_workaround.rb +1 -1
- data/lib/ruby-jss.rb +1 -1
- data/test/bin/runtests +1 -1
- data/test/lib/testhelper.rb +1 -1
- data/test/lib/testhelper/auth.rb +1 -1
- data/test/lib/testhelper/patch_mgmt.rb +1 -1
- data/test/specs/api_connection_spec.rb +1 -1
- data/test/specs/patch01_source_spec.rb +1 -1
- data/test/specs/patch02_internal_source_spec.rb +1 -1
- data/test/specs/patch03_external_source_spec.rb +1 -1
- data/test/specs/patch04_titles_spec.rb +1 -1
- data/test/specs/patch05_policies_spec.rb +1 -1
- data/test/specs/patch06_cleanup_spec.rb +1 -1
- data/test/specs/policy_spec.rb +1 -1
- metadata +15 -4
data/lib/jamf/api/connection.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2020 Pixar
|
|
2
2
|
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "Apache License")
|
|
@@ -48,7 +48,7 @@ module Jamf
|
|
|
48
48
|
RSRC_BASE = 'uapi'.freeze
|
|
49
49
|
|
|
50
50
|
# The API version must be this or higher
|
|
51
|
-
|
|
51
|
+
MIN_JAMF_VERSION = Gem::Version.new('10.15.0')
|
|
52
52
|
|
|
53
53
|
HTTPS_SCHEME = 'https'.freeze
|
|
54
54
|
|
|
@@ -111,6 +111,7 @@ module Jamf
|
|
|
111
111
|
@login_time
|
|
112
112
|
@keep_alive
|
|
113
113
|
@token_refresh
|
|
114
|
+
@pw_fallback
|
|
114
115
|
].freeze
|
|
115
116
|
|
|
116
117
|
# Attributes
|
|
@@ -140,6 +141,10 @@ module Jamf
|
|
|
140
141
|
# @return [String, nil]
|
|
141
142
|
attr_reader :base_url
|
|
142
143
|
|
|
144
|
+
# @return [Boolean] if token refresh/keepaliave fails, try to get a new one
|
|
145
|
+
# with the passwd used with .connect. Defaults to true
|
|
146
|
+
attr_reader :pw_fallback
|
|
147
|
+
|
|
143
148
|
# @return [Boolean]
|
|
144
149
|
attr_reader :connected
|
|
145
150
|
alias connected? connected
|
|
@@ -227,14 +232,13 @@ module Jamf
|
|
|
227
232
|
# ### Tokens
|
|
228
233
|
# Instead of a user and password, you may specify a valid 'token:', either:
|
|
229
234
|
#
|
|
230
|
-
# A Jamf::Connection::Token object, which
|
|
235
|
+
# A Jamf::Connection::Token object, which can be extracted from an active
|
|
231
236
|
# Jamf::Connection via its #token method
|
|
232
237
|
#
|
|
233
238
|
# or
|
|
234
239
|
#
|
|
235
240
|
# A token string e.g. "eyJhdXR...6EKoo" from any source can also be used.
|
|
236
241
|
#
|
|
237
|
-
#
|
|
238
242
|
# Any values available via Jamf.config will be used if they are not provided
|
|
239
243
|
# in the parameters.
|
|
240
244
|
#
|
|
@@ -251,6 +255,19 @@ module Jamf
|
|
|
251
255
|
#
|
|
252
256
|
# @param token: [Jamf::Connection::Token, String] An existing, valid token.
|
|
253
257
|
# When used, there's no need to provide user: or pw:.
|
|
258
|
+
# NOTE if using pw_fallback:true (the default) while providing a token
|
|
259
|
+
# you will also need to provide the password for the token user in the pw:
|
|
260
|
+
# parameter, or be prompted for it. If you don't have the pw for the
|
|
261
|
+
# token user, be sure to set pw_fallback to false.
|
|
262
|
+
#
|
|
263
|
+
# @param token_refresh: [Integer] Refresh the token this many seconds before
|
|
264
|
+
# it expires. Must be >= DFT_TOKEN_REFRESH
|
|
265
|
+
#
|
|
266
|
+
# @pararm pw_fallback: [Boolean] Default is true. Use the password provided
|
|
267
|
+
# to refresh the token if regular refresh doesn't work (e.g. token is expired).
|
|
268
|
+
# NOTE: This causes the password to be kept in memory. If you don't want
|
|
269
|
+
# this, explicitly set pw_fallback to false, however long-running processes
|
|
270
|
+
# may lose connection if token refresh fails for any reason.
|
|
254
271
|
#
|
|
255
272
|
# @param open_timeout: [Integer] The number of seconds for initial contact
|
|
256
273
|
# with the host.
|
|
@@ -268,7 +285,8 @@ module Jamf
|
|
|
268
285
|
# This sets all the instance vars to nil, and flushes/creates the caches
|
|
269
286
|
disconnect
|
|
270
287
|
|
|
271
|
-
#
|
|
288
|
+
# If there's a Token object in :token, this sets @token,
|
|
289
|
+
# and adds host, port, user from that token
|
|
272
290
|
parse_token params
|
|
273
291
|
|
|
274
292
|
# Get host, port, user and pw from a URL, add to params if needed
|
|
@@ -277,6 +295,8 @@ module Jamf
|
|
|
277
295
|
# apply defaults from config, client, and then this class.
|
|
278
296
|
apply_connection_defaults params
|
|
279
297
|
|
|
298
|
+
# Once we're here, all params have been parsed & defaulted into the
|
|
299
|
+
# params hash, so
|
|
280
300
|
# make sure we have the minimum needed params for a connection
|
|
281
301
|
verify_basic_params params
|
|
282
302
|
|
|
@@ -285,15 +305,20 @@ module Jamf
|
|
|
285
305
|
|
|
286
306
|
# if no @token already, get one from from
|
|
287
307
|
# either a token string or a pw
|
|
288
|
-
@token
|
|
308
|
+
unless @token
|
|
289
309
|
if params[:token].is_a? String
|
|
290
|
-
|
|
310
|
+
@token = token_from :token_string, params[:token]
|
|
291
311
|
# get the user from the token
|
|
292
|
-
@user =
|
|
293
|
-
|
|
312
|
+
@user = @toke.user
|
|
313
|
+
# if @pw_fallback, the pw must be acquired, since it isn't in
|
|
314
|
+
# the token
|
|
315
|
+
@pw = acquire_password(params[:pw]) if @pw_fallback
|
|
294
316
|
else
|
|
295
|
-
|
|
317
|
+
pw = acquire_password(params[:pw])
|
|
318
|
+
@token = token_from :pw, pw
|
|
319
|
+
@pw = pw if @pw_fallback
|
|
296
320
|
end
|
|
321
|
+
end
|
|
297
322
|
|
|
298
323
|
# Now get some values from our token
|
|
299
324
|
@base_url = @token.base_url
|
|
@@ -303,43 +328,49 @@ module Jamf
|
|
|
303
328
|
@rest_cnx = create_connection
|
|
304
329
|
|
|
305
330
|
# make sure versions are good
|
|
306
|
-
|
|
331
|
+
validate_jamf_version
|
|
307
332
|
|
|
308
333
|
@connected = true
|
|
309
334
|
|
|
310
335
|
# start keepalive if needed
|
|
311
|
-
@keep_alive = params[:keep_alive].nil? ? false : params[:keep_alive]
|
|
312
336
|
start_keep_alive if @keep_alive
|
|
313
337
|
|
|
314
338
|
# return our string output
|
|
315
339
|
to_s
|
|
316
340
|
end # connect
|
|
317
341
|
|
|
342
|
+
# reset all values to nil or empty
|
|
318
343
|
def disconnect
|
|
319
|
-
# reset everything except the timeouts
|
|
320
|
-
stop_keep_alive
|
|
321
|
-
|
|
322
344
|
@connected = false
|
|
323
345
|
@name = NOT_CONNECTED
|
|
324
346
|
@login_time = nil
|
|
347
|
+
|
|
348
|
+
stop_keep_alive
|
|
349
|
+
|
|
325
350
|
@host = nil
|
|
326
351
|
@port = nil
|
|
327
352
|
@user = nil
|
|
328
|
-
@
|
|
353
|
+
@timeout = nil
|
|
354
|
+
@open_timeout = nil
|
|
329
355
|
@base_url = nil
|
|
356
|
+
@token = nil
|
|
330
357
|
@rest_cnx = nil
|
|
331
358
|
@ssl_options = {}
|
|
332
359
|
@keep_alive = nil
|
|
360
|
+
@token_refresh = nil
|
|
361
|
+
@pw_fallback = nil
|
|
362
|
+
@pw = nil
|
|
333
363
|
|
|
334
364
|
flushcache
|
|
335
365
|
end
|
|
336
366
|
|
|
337
|
-
# Same as disconnect, but invalidates the token
|
|
367
|
+
# Same as disconnect, but invalidates the token on the server first
|
|
338
368
|
def logout
|
|
339
369
|
@token.destroy
|
|
340
370
|
disconnect
|
|
341
371
|
end
|
|
342
372
|
|
|
373
|
+
# Get a resource
|
|
343
374
|
def get(rsrc)
|
|
344
375
|
validate_connected
|
|
345
376
|
resp = @rest_cnx.get rsrc
|
|
@@ -423,7 +454,9 @@ module Jamf
|
|
|
423
454
|
|
|
424
455
|
# Are we keeping the connection alive?
|
|
425
456
|
def keep_alive?
|
|
426
|
-
@keep_alive_thread
|
|
457
|
+
return false unless @keep_alive_thread
|
|
458
|
+
|
|
459
|
+
@keep_alive_thread.alive?
|
|
427
460
|
end
|
|
428
461
|
|
|
429
462
|
# @return [Jamf::Timestamp, nil]
|
|
@@ -461,8 +494,12 @@ module Jamf
|
|
|
461
494
|
@token_refresh = secs
|
|
462
495
|
end
|
|
463
496
|
|
|
464
|
-
def
|
|
465
|
-
@token.
|
|
497
|
+
def jamf_version
|
|
498
|
+
@token.jamf_version
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
def jamf_build
|
|
502
|
+
@token.jamf_build
|
|
466
503
|
end
|
|
467
504
|
|
|
468
505
|
# Flush the collection and/or ea cache for the given class,
|
|
@@ -503,11 +540,11 @@ module Jamf
|
|
|
503
540
|
end
|
|
504
541
|
|
|
505
542
|
# raise exception if API version is too low.
|
|
506
|
-
def
|
|
507
|
-
vers =
|
|
508
|
-
return if Gem::Version.new(vers) >=
|
|
543
|
+
def validate_jamf_version
|
|
544
|
+
vers = jamf_version
|
|
545
|
+
return if Gem::Version.new(vers) >= MIN_JAMF_VERSION
|
|
509
546
|
|
|
510
|
-
raise Jamf::InvalidConnectionError, "API version '#{vers}' too low, must be >= '#{
|
|
547
|
+
raise Jamf::InvalidConnectionError, "API version '#{vers}' too low, must be >= '#{MIN_JAMF_VERSION}'"
|
|
511
548
|
end
|
|
512
549
|
|
|
513
550
|
##### Parse Params
|
|
@@ -537,7 +574,7 @@ module Jamf
|
|
|
537
574
|
raise "Cannot use token: it expires in less than #{TOKEN_REUSE_MIN_LIFE} seconds" if token.secs_remaining < TOKEN_REUSE_MIN_LIFE
|
|
538
575
|
end
|
|
539
576
|
|
|
540
|
-
# Get host, port, user and pw from a URL,
|
|
577
|
+
# Get host, port, user and pw from a URL, overriding any already in the params
|
|
541
578
|
#
|
|
542
579
|
# @return [String, nil] the pw if present
|
|
543
580
|
#
|
|
@@ -547,27 +584,29 @@ module Jamf
|
|
|
547
584
|
url = URI.parse url.to_s
|
|
548
585
|
raise ArgumentError, 'Invalid url, scheme must be https' unless url.scheme == HTTPS_SCHEME
|
|
549
586
|
|
|
550
|
-
params[:host]
|
|
551
|
-
params[:port]
|
|
552
|
-
params[:user]
|
|
553
|
-
params[:pw]
|
|
587
|
+
params[:host] = url.host
|
|
588
|
+
params[:port] = url.port
|
|
589
|
+
params[:user] = url.user if url.user
|
|
590
|
+
params[:pw] = url.password if url.password
|
|
554
591
|
end
|
|
555
592
|
|
|
556
|
-
# Apply defaults
|
|
557
|
-
#
|
|
593
|
+
# Apply defaults to the unset params for the #connect method
|
|
594
|
+
# First apply them from from the Jamf.config,
|
|
595
|
+
# then from the Jamf::Client (read from the jamf binary config),
|
|
558
596
|
# then from the Jamf module defaults
|
|
559
|
-
# to the unset params for the #connect method
|
|
560
597
|
#
|
|
561
598
|
# @param params[Hash] The params for #connect
|
|
562
599
|
#
|
|
563
600
|
# @return [Hash] The params with defaults applied
|
|
564
601
|
#
|
|
565
602
|
def apply_connection_defaults(params)
|
|
566
|
-
#
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
#
|
|
570
|
-
|
|
603
|
+
# must have a host, but accept legacy :server as well as :host
|
|
604
|
+
params[:host] ||= params[:server]
|
|
605
|
+
|
|
606
|
+
# if we have no port set by this point, set to cloud port
|
|
607
|
+
# if host is a cloud host. But leave port nil for other hosts
|
|
608
|
+
# (will be set via client defaults or module defaults)
|
|
609
|
+
params[:port] ||= JAMFCLOUD_PORT if params[:host].to_s.end_with?(JAMFCLOUD_DOMAIN)
|
|
571
610
|
|
|
572
611
|
apply_defaults_from_config(params)
|
|
573
612
|
|
|
@@ -621,11 +660,12 @@ module Jamf
|
|
|
621
660
|
# @return [Hash] The params with defaults applied
|
|
622
661
|
#
|
|
623
662
|
def apply_module_defaults(params)
|
|
624
|
-
# if we have no port set by this point, assume on-prem
|
|
663
|
+
# if we have no port set by this point, assume on-prem.
|
|
625
664
|
params[:port] ||= ON_PREM_SSL_PORT
|
|
626
665
|
params[:timeout] ||= DFT_TIMEOUT
|
|
627
666
|
params[:open_timeout] ||= DFT_OPEN_TIMEOUT
|
|
628
667
|
params[:ssl_version] ||= DFT_SSL_VERSION
|
|
668
|
+
params[:token_refresh] ||= DFT_TOKEN_REFRESH
|
|
629
669
|
# if we have a TTY, pw defaults to :prompt
|
|
630
670
|
params[:pw] ||= :prompt if STDIN.tty?
|
|
631
671
|
end
|
|
@@ -641,36 +681,38 @@ module Jamf
|
|
|
641
681
|
# and is already parsed
|
|
642
682
|
return if @token
|
|
643
683
|
|
|
644
|
-
# must have a host
|
|
645
|
-
params[:host] ||= params[:server]
|
|
684
|
+
# must have a host
|
|
646
685
|
raise Jamf::MissingDataError, 'No Jamf :host specified, or in configuration.' unless params[:host]
|
|
647
686
|
|
|
648
687
|
# no need for user or pass if using a token string
|
|
649
688
|
return if params[:token].is_a? String
|
|
650
689
|
|
|
690
|
+
# must have user and pw
|
|
651
691
|
raise Jamf::MissingDataError, 'No Jamf :user specified, or in configuration.' unless params[:user]
|
|
652
692
|
raise Jamf::MissingDataError, "No :pw specified for user '#{params[:user]}'" unless params[:pw]
|
|
653
693
|
end
|
|
654
694
|
|
|
695
|
+
# Turn the connection parameters into instance vars
|
|
655
696
|
def parse_connect_params(params)
|
|
656
697
|
@host = params[:host]
|
|
657
698
|
@port = params[:port]
|
|
658
|
-
@port ||= @host.end_with?(JAMFCLOUD_DOMAIN) ? JAMFCLOUD_PORT : ON_PREM_SSL_PORT
|
|
659
699
|
@user = params[:user]
|
|
660
700
|
|
|
661
|
-
@
|
|
662
|
-
|
|
663
|
-
@token_refresh =
|
|
701
|
+
@keep_alive = params[:keep_alive].nil? ? false : params[:keep_alive]
|
|
702
|
+
@pw_fallback = params[:pw_fallback].nil? ? true : params[:pw_fallback]
|
|
703
|
+
@token_refresh = params[:token_refresh].to_i
|
|
664
704
|
|
|
665
|
-
@timeout = params[:timeout]
|
|
666
|
-
@open_timeout = params[:open_timeout]
|
|
705
|
+
@timeout = params[:timeout]
|
|
706
|
+
@open_timeout = params[:open_timeout]
|
|
667
707
|
@base_url = URI.parse "https://#{@host}:#{@port}/#{RSRC_BASE}"
|
|
708
|
+
|
|
668
709
|
# ssl opts for faraday
|
|
669
710
|
# TODO: implement all of faraday's options
|
|
670
711
|
@ssl_options = {
|
|
671
712
|
verify: params[:verify_cert],
|
|
672
713
|
version: params[:ssl_version]
|
|
673
714
|
}
|
|
715
|
+
|
|
674
716
|
@name = "#{@user}@#{@host}:#{@port}" if @name == NOT_CONNECTED
|
|
675
717
|
end
|
|
676
718
|
|
|
@@ -701,16 +743,18 @@ module Jamf
|
|
|
701
743
|
# @return [String] The password for the connection
|
|
702
744
|
#
|
|
703
745
|
def acquire_password(param_pw)
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
param_pw.
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
746
|
+
pw =
|
|
747
|
+
if param_pw == :prompt
|
|
748
|
+
Jamf.prompt_for_password "Enter the password for Jamf user #{@user}@#{@host}:"
|
|
749
|
+
elsif param_pw.is_a?(Symbol) && param_pw.to_s.start_with?('stdin')
|
|
750
|
+
param_pw.to_s =~ /^stdin(\d+)$/
|
|
751
|
+
line = Regexp.last_match(1)
|
|
752
|
+
line ||= 1
|
|
753
|
+
Jamf.stdin line
|
|
754
|
+
else
|
|
755
|
+
param_pw
|
|
756
|
+
end # if
|
|
757
|
+
pw
|
|
714
758
|
end # acquire pw
|
|
715
759
|
|
|
716
760
|
# create the faraday connection object
|
|
@@ -747,11 +791,11 @@ module Jamf
|
|
|
747
791
|
begin
|
|
748
792
|
next if @token.secs_remaining > @token_refresh
|
|
749
793
|
|
|
750
|
-
@token.refresh
|
|
794
|
+
@token.refresh @pw
|
|
751
795
|
# make sure faraday uses the new token
|
|
752
796
|
@rest_cnx.headers[:authorization] = @token.auth_token
|
|
753
797
|
rescue
|
|
754
|
-
# TODO: Some kind of error reporting
|
|
798
|
+
# TODO: Some kind of error reporting
|
|
755
799
|
next
|
|
756
800
|
end
|
|
757
801
|
end # loop
|
|
@@ -764,7 +808,9 @@ module Jamf
|
|
|
764
808
|
# @return [void]
|
|
765
809
|
#
|
|
766
810
|
def stop_keep_alive
|
|
767
|
-
@keep_alive_thread
|
|
811
|
+
return unless @keep_alive_thread
|
|
812
|
+
|
|
813
|
+
@keep_alive_thread.kill if @keep_alive_thread.alive?
|
|
768
814
|
@keep_alive_thread = nil
|
|
769
815
|
end
|
|
770
816
|
|
|
@@ -811,7 +857,7 @@ module Jamf
|
|
|
811
857
|
end
|
|
812
858
|
|
|
813
859
|
def self.disconnect
|
|
814
|
-
@active_connection
|
|
860
|
+
@active_connection.disconnect if @active_connection
|
|
815
861
|
end
|
|
816
862
|
|
|
817
863
|
end # module Jamf
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2020 Pixar
|
|
2
2
|
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "Apache License")
|
|
@@ -30,6 +30,8 @@ module Jamf
|
|
|
30
30
|
# A token used for a JSS connection
|
|
31
31
|
class Token
|
|
32
32
|
|
|
33
|
+
JAMF_VERSION_RSRC = 'v1/jamf-pro-version'.freeze
|
|
34
|
+
|
|
33
35
|
AUTH_RSRC = 'auth'.freeze
|
|
34
36
|
|
|
35
37
|
NEW_TOKEN_RSRC = "#{AUTH_RSRC}/tokens".freeze
|
|
@@ -56,9 +58,22 @@ module Jamf
|
|
|
56
58
|
# @return [URI] The base API url, e.g. https://myjamf.jamfcloud.com/uapi
|
|
57
59
|
attr_reader :base_url
|
|
58
60
|
|
|
59
|
-
# when was this token created?
|
|
61
|
+
# @return [Jamf::Timestamp] when was this token created?
|
|
60
62
|
attr_reader :login_time
|
|
61
63
|
|
|
64
|
+
# What happened the last time we tried to refresh?
|
|
65
|
+
# :expired_refreshed - token was expired, a new token was created with the pw
|
|
66
|
+
# :expired_pw_failed - token was expired, pw failed to make a new token
|
|
67
|
+
# :expired_no_pw - token was expired, but no pw was given to make a new one
|
|
68
|
+
# :refreshed - the token refresh worked with no need for the pw
|
|
69
|
+
# :refresh_failed - the token refresh failed, and no pw was given to make a new one
|
|
70
|
+
# :refreshed_with_pw - the token refresh failed, pw worked to make a new token
|
|
71
|
+
# :refresh_failed_no_pw - the token refresh failed, pw also failed to make a new token
|
|
72
|
+
# nil - no refresh has been attempted for this token.
|
|
73
|
+
#
|
|
74
|
+
# @return [Symbol, nil] :refreshed, :pw, :expired,:failed, or nil if never refreshed
|
|
75
|
+
attr_reader :last_refresh_result
|
|
76
|
+
|
|
62
77
|
def initialize(**params)
|
|
63
78
|
@valid = false
|
|
64
79
|
@user = params[:user]
|
|
@@ -90,7 +105,7 @@ module Jamf
|
|
|
90
105
|
raise Jamf::AuthenticationError, 'Incorrect name or password'
|
|
91
106
|
else
|
|
92
107
|
# TODO: better error reporting here
|
|
93
|
-
raise 'An error occurred while authenticating'
|
|
108
|
+
raise Jamf::AuthenticationError, 'An error occurred while authenticating'
|
|
94
109
|
end
|
|
95
110
|
end # init_from_pw
|
|
96
111
|
|
|
@@ -118,8 +133,13 @@ module Jamf
|
|
|
118
133
|
end
|
|
119
134
|
|
|
120
135
|
# @return [String]
|
|
121
|
-
def
|
|
122
|
-
|
|
136
|
+
def jamf_version
|
|
137
|
+
raw_jamf_version.split('-').first
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# @return [String]
|
|
141
|
+
def jamf_build
|
|
142
|
+
raw_jamf_version.split('-').last
|
|
123
143
|
end
|
|
124
144
|
|
|
125
145
|
# @return [Boolean]
|
|
@@ -165,18 +185,39 @@ module Jamf
|
|
|
165
185
|
@account = Jamf::APIAccount.new resp.body
|
|
166
186
|
end
|
|
167
187
|
|
|
168
|
-
# Use this token to get a fresh one
|
|
169
|
-
#
|
|
170
|
-
|
|
171
|
-
|
|
188
|
+
# Use this token to get a fresh one. If a pw is provided
|
|
189
|
+
# try to use it to get a new token if a proper refresh fails.
|
|
190
|
+
#
|
|
191
|
+
# @param pw [String] Optional password to use if token refresh fails.
|
|
192
|
+
# Must be the correct passwd or the token's user (obviously)
|
|
193
|
+
#
|
|
194
|
+
# @return [Jamf::Timestamp] the new expiration time
|
|
195
|
+
#
|
|
196
|
+
def refresh(pw = nil)
|
|
197
|
+
# gotta have a pw if expired
|
|
198
|
+
if expired?
|
|
199
|
+
# try the passwd
|
|
200
|
+
return refresh_with_passwd(pw, :expired_refreshed, :expired_pw_failed) if pw
|
|
201
|
+
|
|
202
|
+
# no passwd? no chance!
|
|
203
|
+
@last_refresh_result = :expired_no_pw
|
|
204
|
+
raise Jamf::InvalidTokenError, 'Token has expired'
|
|
205
|
+
end
|
|
172
206
|
|
|
207
|
+
# Now try a normal refresh of our non-expired token
|
|
173
208
|
keep_alive_token_resp = token_connection(KEEP_ALIVE_RSRC, token: @auth_token).post
|
|
209
|
+
if keep_alive_token_resp.success?
|
|
210
|
+
parse_token_from_response keep_alive_token_resp
|
|
211
|
+
@last_refresh_result = :refreshed
|
|
212
|
+
return expires
|
|
213
|
+
end
|
|
174
214
|
|
|
175
|
-
|
|
215
|
+
# if we're here, the normal refresh failed, so try the pw
|
|
216
|
+
return refresh_with_passwd(pw, :refreshed_with_pw, :refresh_failed_no_pw) if pw
|
|
176
217
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
218
|
+
# if we're here, no pw? no chance!
|
|
219
|
+
@last_refresh_result = :refresh_failed
|
|
220
|
+
raise 'An error occurred while refreshing the token' unless pw
|
|
180
221
|
end
|
|
181
222
|
alias keep_alive refresh
|
|
182
223
|
|
|
@@ -190,6 +231,32 @@ module Jamf
|
|
|
190
231
|
#################################
|
|
191
232
|
private
|
|
192
233
|
|
|
234
|
+
# refresh a token using a password, return a result
|
|
235
|
+
# @param pw[String] the password to use
|
|
236
|
+
# @return [JamfTimestamp] the new expiration
|
|
237
|
+
def refresh_with_passwd(pw, success, failure)
|
|
238
|
+
init_from_pw(pw)
|
|
239
|
+
@last_refresh_result = success
|
|
240
|
+
expires
|
|
241
|
+
rescue => e
|
|
242
|
+
@last_refresh_result = failure
|
|
243
|
+
raise e, "#{e}. Status: :#{failure}"
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# @return [String]
|
|
247
|
+
def raw_jamf_version
|
|
248
|
+
# TODO: Remove this once we require Jamf Pro 10.19 and up
|
|
249
|
+
# the rsrc for getting the version used to be nothing (the
|
|
250
|
+
# base url itself returnedit) but now its JAMF_VERSION_RSRC
|
|
251
|
+
resp = token_connection(Jamf::BLANK, token: @auth_token).get # .body # [:version]
|
|
252
|
+
return resp.body[:version] if resp.success?
|
|
253
|
+
|
|
254
|
+
resp = token_connection(JAMF_VERSION_RSRC, token: @auth_token).get
|
|
255
|
+
return resp.body[:version] if resp.success?
|
|
256
|
+
|
|
257
|
+
raise Jamf::InvalidConnectionError, 'Unable to read Jamf version from the API'
|
|
258
|
+
end
|
|
259
|
+
|
|
193
260
|
# a generic, one-time Faraday connection for token
|
|
194
261
|
# acquision & manipulation
|
|
195
262
|
#
|