ruby-jss 4.2.0 → 4.2.2
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 +42 -1
- data/lib/jamf/api/jamf_pro/api_objects/j_package.rb +44 -16
- data/lib/jamf/api/jamf_pro/base_classes/oapi_object.rb +16 -3
- data/lib/jamf/api/jamf_pro/other_classes/pager.rb +7 -1
- data/lib/jamf/utility.rb +20 -14
- data/lib/jamf/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c7c5b51e4752d7be68fb4e6caab5fa98d00e2bba66bfa356a316004a5f7ea49
|
4
|
+
data.tar.gz: 455ef851b1e8bb75faf2e9abc171a0fbd84a8a1b30156c18b30933fc0ad51edf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8c9d09216f3105002b9c9200896223d94a191a5601cb21cde79df1aeb1745275d86481765cfa840ed25fcb93ba9d634f1efd4332e774d8a74d079a7a036604f
|
7
|
+
data.tar.gz: 640aef2c3794c0337ab6ce7c08598eb096280e3feab54d245f5e0af7cef62903898f0c8d405c0265c2febe065f2bac05182081f3736c5d5fe75f879ce44d40ba
|
data/CHANGES.md
CHANGED
@@ -14,6 +14,47 @@ __Please update all installations of ruby-jss to at least v1.6.0.__
|
|
14
14
|
|
15
15
|
Many many thanks to actae0n of Blacksun Hackers Club for reporting this issue and providing examples of how it could be exploited.
|
16
16
|
|
17
|
+
--------
|
18
|
+
## \[4.2.2] Unreleased
|
19
|
+
|
20
|
+
### Fixed
|
21
|
+
- Class `Jamf::JPackage` no longer raises `Errno::EINVAL Invalid argument @ io_fread` when generating manifest checksums for very large package files.
|
22
|
+
|
23
|
+
|
24
|
+
### Deprecated
|
25
|
+
|
26
|
+
- Class `Jamf::DBConnection`. Access to the MySQL backend database for on-prem Jamf Pro installations will be removed in a future release, probably some time in mid-late 2026. If you use this class, please update your code to make and use such connections independently of ruby-jss. This removal also includes the 'default' instance stored in `Jamf::DB_CNX` and `Jamf.db`.
|
27
|
+
|
28
|
+
The following methods will also be removed, as they require that class for direct database access.
|
29
|
+
- `Jamf::ComputerExtensionAttribute#history`
|
30
|
+
- `Jamf::MobileDeviceExtensionAttribute#history`
|
31
|
+
- `Jamf::Icon.all`
|
32
|
+
- `Jamf::SelfServable#validate_icon`
|
33
|
+
- `Jamf::APIObject#add_object_history_entry`
|
34
|
+
|
35
|
+
Note that some objects in the Jamf Pro API have access to their object_history. As classes are migrated (see release notes for 4.2.0 below) that access will be included when available.
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
--------
|
40
|
+
## \[4.2.1] 2025-08-11
|
41
|
+
|
42
|
+
### Fixed
|
43
|
+
|
44
|
+
- `Jamf::JPackage#osRequirements=` now properly expands versions starting with '>='
|
45
|
+
- `OAPIObject` no longer overwrites custom getters & setters with autogenerated ones.
|
46
|
+
- calling `.all instantiate: true` no longer raises an error for JPAPI collection classes in ruby 3.x
|
47
|
+
|
48
|
+
### Changed
|
49
|
+
|
50
|
+
- `Jamf.expand_min_os` now knows that Apple has skipped macOS v16-25, and that starting with
|
51
|
+
Tahoe, the os is v26, incremented yearly. It now expands to v40, which should hold us for over
|
52
|
+
a decade.
|
53
|
+
|
54
|
+
### Added
|
55
|
+
|
56
|
+
- `OAPIObject` subclasses now have an attr_reader `creating_from_create` indicating that they are being instantiated by the `.create` class method, as opposed to being fetched or given API data
|
57
|
+
|
17
58
|
--------
|
18
59
|
## \[4.2.0] 2025-06-11
|
19
60
|
|
@@ -52,7 +93,7 @@ If you have thoughts or comments on this, please reach out:
|
|
52
93
|
|
53
94
|
- Collection Resource classes from the Jamf Pro API can now define a constant OBJECT_NAME_ATTR, which indicates the attribute that holds the individual object's name, if that isn't "name".
|
54
95
|
|
55
|
-
For example, Computer and MobileDevice prestage objects, the name is in the "displayName" attribute. For JPackages via the Jamf Pro API, the package object's name (not its file name) is in the "packageName"
|
96
|
+
For example, Computer and MobileDevice prestage objects, the name is in the "displayName" attribute. For JPackages via the Jamf Pro API, the package object's name (not its file name) is in the "packageName" attribute.
|
56
97
|
|
57
98
|
When the OBJECT_NAME_ATTR is defined, the class can use "name" as a alias of the OBJECT_NAME_ATTR with getters & setters (`name=` is an alias of `displayName=`, etc) and can be used for .fetch and .valid_id: `Jamf::JPackage.fetch name: 'foo'` is the same as `Jamf::JPackage.fetch packageName: 'foo'`
|
58
99
|
|
@@ -340,6 +340,12 @@ module Jamf
|
|
340
340
|
self.suppressEula = DEFAULT_SUPPRESS_EULA if suppressEula.nil?
|
341
341
|
self.suppressRegistration = DEFAULT_SUPPRESS_REGISTRATION if suppressRegistration.nil?
|
342
342
|
|
343
|
+
if creating_from_create && osRequirements
|
344
|
+
# if we're creating a new object, and osRequirements is set,
|
345
|
+
# convert it to a comma-separated string
|
346
|
+
@osRequirements = osRequirements_as_comma_sep_string(osRequirements)
|
347
|
+
end
|
348
|
+
|
343
349
|
@checksum =
|
344
350
|
case hashType
|
345
351
|
when CHECKSUM_HASH_TYPE_MD5
|
@@ -374,16 +380,36 @@ module Jamf
|
|
374
380
|
# @return [void]
|
375
381
|
#############################
|
376
382
|
def osRequirements=(new_val)
|
377
|
-
|
378
|
-
|
379
|
-
new_val
|
383
|
+
orig_osRequirements = osRequirements
|
384
|
+
|
385
|
+
new_val = osRequirements_as_comma_sep_string(new_val)
|
386
|
+
@osRequirements = new_val
|
387
|
+
|
388
|
+
note_unsaved_change :osRequirements, orig_osRequirements
|
389
|
+
end
|
390
|
+
|
391
|
+
# Take a value for osRequirements, and return it as a comma-separated string,
|
392
|
+
# possibly expanded if any of them starts with '>='.
|
393
|
+
#
|
394
|
+
# @see Jamf.expand_min_os
|
395
|
+
#
|
396
|
+
# @param val [String,Array<String>] comma-separated string, or array of os versions
|
397
|
+
#
|
398
|
+
# @return [Array<String>] the osRequirements as an array of strings
|
399
|
+
#############################
|
400
|
+
def osRequirements_as_comma_sep_string(val)
|
401
|
+
# make sure we have a flat array of strings
|
402
|
+
val = val.split(',').map(&:strip) if val.is_a? String
|
403
|
+
val = [val].flatten.compact.uniq.map(&:to_s)
|
404
|
+
|
405
|
+
# expand any minimum OS versions
|
406
|
+
val.map! do |vers|
|
380
407
|
vers.start_with?('>=') ? Jamf.expand_min_os(vers) : vers
|
381
408
|
end
|
382
409
|
|
383
|
-
|
384
|
-
@osRequirements = new_val.join(', ')
|
385
|
-
note_unsaved_change :osRequirements, orig_osRequirements
|
410
|
+
val.flatten.join(', ')
|
386
411
|
end
|
412
|
+
private :osRequirements_as_comma_sep_string
|
387
413
|
|
388
414
|
# Recalculate the checksum of the package file from a given filepath, and update the
|
389
415
|
# object's checksum and hashValue attributes.
|
@@ -635,7 +661,15 @@ module Jamf
|
|
635
661
|
# @return [void]
|
636
662
|
##############################
|
637
663
|
def calculate_manifest_checksums(file, new_manifest, chunk_size: nil)
|
664
|
+
# we need the whole file checksum even if chunking, so
|
665
|
+
# get that first
|
666
|
+
# The Digest::SHA256.file method will read even huge files successfully
|
667
|
+
# without loading the whole file into memory, as would File.read.
|
668
|
+
#
|
669
|
+
whole_file_checksum = Digest::SHA256.file(file).hexdigest
|
670
|
+
|
638
671
|
# are we chunking the download?
|
672
|
+
# we need checksums for each chunk, and the size of each chunk
|
639
673
|
if chunk_size.is_a? Integer
|
640
674
|
new_manifest[:items][0][:assets][0]['sha256-size'] = chunk_size
|
641
675
|
file.open do |f|
|
@@ -644,23 +678,17 @@ module Jamf
|
|
644
678
|
end
|
645
679
|
end
|
646
680
|
|
647
|
-
# not chunking, use the file filesize
|
681
|
+
# not chunking, use the file filesize and whole-file checksum
|
648
682
|
else
|
649
683
|
new_manifest[:items][0][:assets][0]['sha256-size'] = file.size
|
650
|
-
new_manifest[:items][0][:assets][0]['sha256s'] = [
|
684
|
+
new_manifest[:items][0][:assets][0]['sha256s'] = [whole_file_checksum]
|
651
685
|
end
|
652
686
|
|
653
687
|
# Store the whole-file checksum in
|
654
|
-
# manifest[:items][0][:metadata]['sha256-whole']
|
655
|
-
# manifest[:items][0][:assets][0]['sha256s'][0], if available, or generate it if needed
|
688
|
+
# manifest[:items][0][:metadata]['sha256-whole'], a non-standard key used by ruby-jss.
|
656
689
|
# It is used by the deploy_via_mdm method.
|
657
690
|
# This value is required for MDM deployments, even if the file is chunked in the manifest.
|
658
|
-
new_manifest[:items][0][:metadata]['sha256-whole'] =
|
659
|
-
if new_manifest[:items][0][:assets][0]['sha256s'].size == 1
|
660
|
-
new_manifest[:items][0][:assets][0]['sha256s'][0]
|
661
|
-
else
|
662
|
-
Digest::SHA256.hexdigest(file.read)
|
663
|
-
end
|
691
|
+
new_manifest[:items][0][:metadata]['sha256-whole'] = whole_file_checksum
|
664
692
|
end
|
665
693
|
private :calculate_manifest_checksums
|
666
694
|
|
@@ -118,6 +118,9 @@ module Jamf
|
|
118
118
|
# create a getter for an attribute, and any aliases needed
|
119
119
|
##############################
|
120
120
|
def self.create_getters(attr_name, attr_def)
|
121
|
+
# if the getter has already been defined, don't overwrite it
|
122
|
+
return if instance_methods.include? attr_name.to_sym
|
123
|
+
|
121
124
|
# multi_value - only return a frozen dup, no direct editing of the Array
|
122
125
|
if attr_def[:multi]
|
123
126
|
define_method(attr_name) do
|
@@ -139,6 +142,11 @@ module Jamf
|
|
139
142
|
# create setter(s) for an attribute, and any aliases needed
|
140
143
|
##############################
|
141
144
|
def self.create_setters(attr_name, attr_def)
|
145
|
+
setter_method_name = "#{attr_name}="
|
146
|
+
|
147
|
+
# if the setter has already been defined, don't overwrite it
|
148
|
+
return if instance_methods.include? setter_method_name.to_sym
|
149
|
+
|
142
150
|
# multi_value
|
143
151
|
if attr_def[:multi]
|
144
152
|
create_array_setters(attr_name, attr_def)
|
@@ -146,7 +154,7 @@ module Jamf
|
|
146
154
|
end
|
147
155
|
|
148
156
|
# single value
|
149
|
-
define_method(
|
157
|
+
define_method(setter_method_name) do |new_value|
|
150
158
|
new_value = validate_attr attr_name, new_value
|
151
159
|
old_value = instance_variable_get("@#{attr_name}")
|
152
160
|
return if new_value == old_value
|
@@ -345,6 +353,11 @@ module Jamf
|
|
345
353
|
# @return [Hash]
|
346
354
|
attr_reader :init_data
|
347
355
|
|
356
|
+
# If this is true, we are being created via the .create method
|
357
|
+
# and not fetched from the API.
|
358
|
+
# @return [Boolean]
|
359
|
+
attr_reader :creating_from_create
|
360
|
+
|
348
361
|
# Constructor
|
349
362
|
#####################################
|
350
363
|
|
@@ -356,9 +369,9 @@ module Jamf
|
|
356
369
|
@init_data = data
|
357
370
|
|
358
371
|
# creating a new one via ruby-jss, not fetching one from the API
|
359
|
-
|
372
|
+
@creating_from_create = data.delete :creating_from_create if data.is_a?(Hash)
|
360
373
|
|
361
|
-
if
|
374
|
+
if @creating_from_create
|
362
375
|
self.class::OAPI_PROPERTIES.each_key do |attr_name|
|
363
376
|
# we'll enforce required values when we save
|
364
377
|
next unless data.key? attr_name
|
@@ -226,7 +226,13 @@ module Jamf
|
|
226
226
|
|
227
227
|
data = @cnx.jp_get "#{@query_path}&page=#{page_number}"
|
228
228
|
data = data[:results]
|
229
|
-
|
229
|
+
|
230
|
+
if @instantiate
|
231
|
+
data.map! do |r|
|
232
|
+
r[:cnx] = @cnx
|
233
|
+
@instantiate.new(**r)
|
234
|
+
end
|
235
|
+
end
|
230
236
|
|
231
237
|
if increment_next
|
232
238
|
@last_fetched_page = page_number
|
data/lib/jamf/utility.rb
CHANGED
@@ -65,27 +65,33 @@ module Jamf
|
|
65
65
|
#
|
66
66
|
# 12 is the default for the current OS and higher
|
67
67
|
# (and hoping apple doesn't release, e.g., 11.13)
|
68
|
+
#
|
69
|
+
# There is no 16-25 because in 2025 Apple changed the numbering
|
70
|
+
# scheme to match the year after release. So the OS released in
|
71
|
+
# 2025 is versino 26, not 16.
|
72
|
+
#
|
73
|
+
# This array should take us thru to 2039.
|
68
74
|
MAC_OS_MAXS = {
|
69
75
|
11 => 12,
|
70
76
|
12 => 12,
|
71
77
|
13 => 12,
|
72
78
|
14 => 12,
|
73
79
|
15 => 12,
|
74
|
-
16 => 12,
|
75
|
-
17 => 12,
|
76
|
-
18 => 12,
|
77
|
-
19 => 12,
|
78
|
-
20 => 12,
|
79
|
-
21 => 12,
|
80
|
-
22 => 12,
|
81
|
-
23 => 12,
|
82
|
-
24 => 12,
|
83
|
-
25 => 12,
|
84
80
|
26 => 12,
|
85
81
|
27 => 12,
|
86
82
|
28 => 12,
|
87
83
|
29 => 12,
|
88
|
-
30 => 12
|
84
|
+
30 => 12,
|
85
|
+
31 => 12,
|
86
|
+
32 => 12,
|
87
|
+
33 => 12,
|
88
|
+
34 => 12,
|
89
|
+
35 => 12,
|
90
|
+
36 => 12,
|
91
|
+
37 => 12,
|
92
|
+
38 => 12,
|
93
|
+
39 => 12,
|
94
|
+
40 => 12
|
89
95
|
}
|
90
96
|
|
91
97
|
# Converts an OS Version into an Array of equal or higher OS versions, up to
|
@@ -188,7 +194,7 @@ module Jamf
|
|
188
194
|
# e.g. 11.x, or 11.x.x
|
189
195
|
# expand to 11.x, 12.x, 13.x, ... 30.x
|
190
196
|
if minor == 'x'
|
191
|
-
((major.to_i)..MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" }
|
197
|
+
((major.to_i)..MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" unless (16..25).include?(v) } # skip 16-25
|
192
198
|
|
193
199
|
# e.g. 11.2.x
|
194
200
|
# expand to 11.2.x, 11.3.x, ... 11.12.x,
|
@@ -202,7 +208,7 @@ module Jamf
|
|
202
208
|
end # each m
|
203
209
|
|
204
210
|
# then add the majors out to 20
|
205
|
-
((major.to_i + 1)...MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" }
|
211
|
+
((major.to_i + 1)...MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" unless (16..25).include?(v) }
|
206
212
|
|
207
213
|
# e.g. 11.2.3
|
208
214
|
# expand to 11.2.3, 11.2.4, ... 11.2.10,
|
@@ -219,7 +225,7 @@ module Jamf
|
|
219
225
|
((minor.to_i + 1)..max_minor_for_major).each { |min| ok_oses << "#{major}.#{min}.x" }
|
220
226
|
|
221
227
|
# then add the majors out to 20
|
222
|
-
((major.to_i + 1)..MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" }
|
228
|
+
((major.to_i + 1)..MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" unless (16..25).include?(v) }
|
223
229
|
end
|
224
230
|
|
225
231
|
ok_oses
|
data/lib/jamf/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-jss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.2.
|
4
|
+
version: 4.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Lasell
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2025-06
|
12
|
+
date: 2025-09-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: CFPropertyList
|
@@ -502,7 +502,7 @@ files:
|
|
502
502
|
- test/tests/policy.rb
|
503
503
|
homepage: http://pixaranimationstudios.github.io/ruby-jss/
|
504
504
|
licenses:
|
505
|
-
-
|
505
|
+
- LicenseRef-LICENSE.txt
|
506
506
|
metadata:
|
507
507
|
source_code_uri: https://github.com/PixarAnimationStudios/ruby-jss
|
508
508
|
changelog_uri: https://github.com/PixarAnimationStudios/ruby-jss/blob/master/CHANGES.md
|