ruby-jss 1.2.4a4 → 1.3.3
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.
- 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
|
#
|