ruby-jss 1.2.10 → 1.3.2

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

Potentially problematic release.


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

Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +92 -1
  3. data/lib/jamf/api/abstract_classes/json_object.rb +1 -1
  4. data/lib/jamf/api/abstract_classes/prestage.rb +1 -1
  5. data/lib/jamf/api/connection.rb +7 -3
  6. data/lib/jamf/configuration.rb +7 -9
  7. data/lib/jamf/ruby_extensions.rb +1 -0
  8. data/lib/jamf/ruby_extensions/array.rb +1 -1
  9. data/lib/jamf/ruby_extensions/array/utils.rb +3 -3
  10. data/lib/jamf/ruby_extensions/dig.rb +52 -0
  11. data/lib/jss.rb +2 -0
  12. data/lib/jss/api_connection.rb +2 -29
  13. data/lib/jss/api_object.rb +15 -2
  14. data/lib/jss/api_object/directory_binding.rb +273 -0
  15. data/lib/jss/api_object/directory_binding_type.rb +90 -0
  16. data/lib/jss/api_object/directory_binding_type/active_directory.rb +502 -0
  17. data/lib/jss/api_object/directory_binding_type/admitmac.rb +525 -0
  18. data/lib/jss/api_object/directory_binding_type/centrify.rb +212 -0
  19. data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
  20. data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
  21. data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
  22. data/lib/jss/api_object/distribution_point.rb +95 -35
  23. data/lib/jss/api_object/dock_item.rb +137 -0
  24. data/lib/jss/api_object/mobile_device_application.rb +12 -0
  25. data/lib/jss/api_object/network_segment.rb +152 -58
  26. data/lib/jss/api_object/package.rb +106 -41
  27. data/lib/jss/api_object/policy.rb +379 -4
  28. data/lib/jss/api_object/printer.rb +440 -0
  29. data/lib/jss/api_object/scopable/scope.rb +24 -24
  30. data/lib/jss/composer.rb +1 -1
  31. data/lib/jss/utility.rb +8 -22
  32. data/lib/jss/version.rb +1 -1
  33. metadata +13 -2
@@ -0,0 +1,114 @@
1
+ module JSS
2
+ ### Module Constants
3
+ #####################################
4
+
5
+ ### Module Variables
6
+ #####################################
7
+
8
+ ### Module Methods
9
+ #####################################
10
+
11
+ ### Classes
12
+ #####################################
13
+
14
+ ### Disk Encryption Configuration object inside JSS
15
+ ###
16
+ ### More Detailed Description if needed
17
+ class DiskEncryptionConfiguration < JSS::APIObject
18
+ ## Mix-Ins
19
+ #####################################
20
+ include JSS::Updatable
21
+
22
+ ## Class Constants
23
+ #####################################
24
+
25
+ # @note Currently "Individual and Institutional" configuration type is unsupported through the API
26
+ KEY_TYPE = {
27
+ individual: 'Individual',
28
+ institutional: 'Institutional',
29
+ individual_and_institutional: 'Individual and Institutional'
30
+ }.freeze
31
+
32
+ # @note as of 10.13 Management Account cannot be used due to the lack of a secure token.
33
+ ENABLED_USERS_TYPE = {
34
+ management: "Management Account",
35
+ current: "Current or Next User"
36
+ }.freeze
37
+
38
+ ### The base for REST resources of this class
39
+ RSRC_BASE = 'diskencryptionconfigurations'.freeze
40
+
41
+ ### the hash key used for the JSON list output of all objects in the JSS
42
+ RSRC_LIST_KEY = :disk_encryption_configurations
43
+
44
+ ### The hash key used for the JSON object output
45
+ ### It's also used in various error messages
46
+ RSRC_OBJECT_KEY = :disk_encryption_configuration
47
+
48
+ ## Attributes
49
+ #####################################
50
+ attr_reader :key_type
51
+ attr_reader :file_vault_enabled_users
52
+ attr_reader :institutional_recovery_key
53
+
54
+ ## Constructor
55
+ #####################################
56
+
57
+ ###
58
+ def initialize(args = {})
59
+ super
60
+
61
+ if self.in_jss?
62
+ @key_type = @init_data[:key_type]
63
+ @file_vault_enabled_users = @init_data[:file_vault_enabled_users]
64
+ @institutional_recovery_key = @init_data[:institutional_recovery_key]
65
+ else
66
+ raise JSS::InvalidDataError, "Currently the ability to create a Disk Encryption Configuration is not possible through ruby-jss."
67
+ end
68
+
69
+
70
+
71
+ end
72
+
73
+ ## Class Methods
74
+ #####################################
75
+
76
+ # Sets what type of account is to be enabled using the new value
77
+ #
78
+ # @author Tyler Morgan
79
+ #
80
+ # @param newvalue[Symbol] One of ENABLED_USERS_TYPE
81
+ #
82
+ # @return [Void]
83
+ #
84
+ def file_vault_enabled_users=(newvalue)
85
+ raise JSS::InvalidDataError, "file_vault_enabled_users must be one of :#{ENABLED_USERS_TYPE.keys.join(',:')}." unless ENABLED_USERS_TYPE.keys.include? newvalue
86
+
87
+ @file_vault_enabled_users = ENABLED_USERS_TYPE[newvalue]
88
+
89
+ @need_to_update = true
90
+
91
+ end
92
+
93
+ ## Private Instance Methods
94
+ #####################################
95
+
96
+ private
97
+
98
+ def rest_xml
99
+ raise JSS::UnsupportedError, "Key type of \"Individual and Institutional\" is currently unsupported via. API. So changes are unable to be saved." if @key_type == KEY_TYPE[:individual_and_institutional]
100
+ doc = REXML::Document.new
101
+ disk_encryption_configuration = doc.add_element 'disk_encryption_configuration'
102
+
103
+ disk_encryption_configuration.add_element('id').text = @id
104
+ disk_encryption_configuration.add_element('name').text = @name
105
+ disk_encryption_configuration.add_element('key_type').text = @key_type
106
+ disk_encryption_configuration.add_element('file_vault_enabled_users').text = @file_vault_enabled_users
107
+
108
+ doc.to_s
109
+
110
+
111
+
112
+ end
113
+ end
114
+ end
@@ -27,7 +27,7 @@ module JSS
27
27
  # Module Methods
28
28
  #####################################
29
29
 
30
- # A Distribution Point in the JSS
30
+ # A FileShare Distribution Point in the JSS
31
31
  #
32
32
  # As well as the normal Class and Instance methods for {APIObject} subclasses, the
33
33
  # DistributionPoint class provides more interaction with other parts of the API.
@@ -43,6 +43,11 @@ module JSS
43
43
  # and unmount it with {#unmount}. The {JSS::Package} and possibly {JSS::Script} classes use this to upload
44
44
  # items to the master.
45
45
  #
46
+ # NOTE: This class only deals with FileShare Distribution Points.
47
+ # There is no access to the Cloud Distribution Point in the classic API.
48
+ # See the .master_distribution_point and .my_distribution_point class methods
49
+ # for how they handle things when the Cloud DP is the master.
50
+ #
46
51
  # @see JSS::APIObject
47
52
  #
48
53
  class DistributionPoint < JSS::APIObject
@@ -80,32 +85,92 @@ module JSS
80
85
  # Class Methods
81
86
  #####################################
82
87
 
83
- # Get the DistributionPoint instance for the master
84
- # distribution point in the JSS. If there's only one
85
- # in the JSS, return it even if not marked as master.
88
+ # Get the DistributionPoint instance for the master distribution point.
89
+ #
90
+ # If the Cloud Dist Point is master, then the classic API has no way to
91
+ # know that or access it. In that case you can provide the 'default:' parameter.
92
+ # Give it the name or id of any dist. point to be used instead, or give it
93
+ # :random to randomly choose one.
94
+ #
95
+ # If there are no fileshare dist points defined (the cloud is the only one)
96
+ # then this whole class can't really be used.
86
97
  #
87
98
  # @param refresh[Boolean] should the distribution point be re-queried?
88
99
  #
100
+ # @param default[String, Integer, Symbol] Name or ID of a dist point to use
101
+ # if no master is found, or :random to randomly choose one.
102
+ #
89
103
  # @param api[JSS::APIConnection] which API connection should we query?
90
104
  #
91
105
  # @return [JSS::DistributionPoint]
92
106
  #
93
- def self.master_distribution_point(refresh = false, api: JSS.api)
94
- api.master_distribution_point refresh
107
+ def self.master_distribution_point(refresh = false, default: nil, api: JSS.api)
108
+ @master_distribution_point = nil if refresh
109
+ return @master_distribution_point if @master_distribution_point
110
+
111
+ all_ids(refresh, api: api).each do |dp_id|
112
+ dp = fetch id: dp_id, api: api
113
+ if dp.master?
114
+ @master_distribution_point = dp
115
+ break
116
+ end
117
+ end
118
+
119
+ # If we're here, the Cloud DP might be master, but there's no
120
+ # access to it in the API :/
121
+ raise JSS::NoSuchItemError, 'No Master FileShare Distribtion Point. Use the default: parameter if needed.' unless @master_distribution_point || default
122
+
123
+ if @master_distribution_point
124
+ @master_distribution_point
125
+ elsif default == :random
126
+ @master_distribution_point = fetch(id: all_ids.sample, api: api)
127
+ else
128
+ @master_distribution_point = fetch(default, api: api)
129
+ end
95
130
  end
96
131
 
97
132
  # Get the DistributionPoint instance for the machine running
98
133
  # this code, based on its IP address. If none is defined for this IP address,
99
- # use the result of master_distribution_point
134
+ # use the name or id provided as default. If no default: is provided,
135
+ # the master dp is used. If no master dp available (meaning its the
136
+ # cloud dp) then use a randomly chosen dp.
100
137
  #
101
138
  # @param refresh[Boolean] should the distribution point be re-queried?
102
139
  #
140
+ # @param default[String, Integer, Symbol] the name or id of a Dist Point
141
+ # to use if none is specified for this IP addr. Or :master, to use the
142
+ # master DP, or :random to use a randomly chosen one. If :master is
143
+ # specified and there is no master (master is cloud) then a random one is used.
144
+ #
103
145
  # @param api[JSS::APIConnection] which API connection should we query?
104
146
  #
105
147
  # @return [JSS::DistributionPoint]
106
148
  #
107
- def self.my_distribution_point(refresh = false, api: JSS.api)
108
- api.my_distribution_point refresh
149
+ def self.my_distribution_point(refresh = false, default: :master, api: JSS.api)
150
+ @my_distribution_point = nil if refresh
151
+ return @my_distribution_point if @my_distribution_point
152
+
153
+ my_net_seg_id = JSS::NetworkSegment.my_network_segment refresh, api: api
154
+
155
+ if my_net_seg_id
156
+ my_net_seg = JSS::NetworkSegment.fetch id: my_net_seg_id, api: api
157
+ my_dp_name = my_net_seg.distribution_point
158
+ @my_distribution_point = fetch name: my_dp_name, api: api if my_dp_name
159
+ end # if my_net_seg_id
160
+
161
+ return @my_distribution_point if @my_distribution_point
162
+
163
+ @my_distribution_point =
164
+ case default
165
+ when String
166
+ fetch name: default, api: api
167
+ when Integer
168
+ fetch id: default, api: api
169
+ when :master
170
+ master_distribution_point refresh, default: :random, api: api
171
+ when :random
172
+ fetch id: all_ids(refresh).sample, api: api
173
+ end
109
174
  end
110
175
 
111
176
  # Class Attributes
@@ -274,7 +339,7 @@ module JSS
274
339
  # Seemms the read-only pw isn't available in the API
275
340
 
276
341
  # if we mount for fileservice, where's the mountpoint?
277
- @mountpoint = Pathname.new "/#{DEFAULT_MOUNTPOINT_DIR}/#{DEFAULT_MOUNTPOINT_PREFIX}#{@id}"
342
+ @mountpoint = DEFAULT_MOUNTPOINT_DIR + "#{DEFAULT_MOUNTPOINT_PREFIX}#{@id}"
278
343
  end # init
279
344
 
280
345
  # Check the validity of a password.
@@ -315,37 +380,15 @@ module JSS
315
380
  # @return [FalseClass, Symbol] false if not reachable, otherwise :http or :mountable
316
381
  #
317
382
  def reachable_for_download?(pw = '', check_http = true)
318
- pw ||= ''
319
- http_checked = ''
320
- if check_http && http_downloads_enabled
321
- if @username_password_required
322
- # we don't check the pw here, because if the connection fails, we'll
323
- # drop down below to try the password for mounting.
324
- # we'll escape all the chars that aren't unreserved
325
- # reserved_chars = Regexp.new("[^#{URI::REGEXP::PATTERN::UNRESERVED}]")
326
- user_pass = "#{CGI.escape @http_username.to_s}:#{CGI.escape ro_pw.to_s}@"
327
- url = @http_url.sub "://#{@ip_address}", "://#{user_pass}#{@ip_address}"
328
- else
329
- url = @http_url
330
- end
331
-
332
- begin
333
- open(url).read
334
- return :http
335
- rescue
336
- http_checked = 'http and '
337
- end
338
- end # if check_http && http_downloads_enabled
339
-
383
+ return :http if check_http && http_reachable?(pw)
340
384
  return :mountable if mounted?
341
-
342
385
  return false unless check_pw :ro, pw
343
386
 
344
387
  begin
345
388
  mount pw, :ro
346
- return :mountable
389
+ :mountable
347
390
  rescue
348
- return false
391
+ false
349
392
  ensure
350
393
  unmount
351
394
  end
@@ -469,6 +512,23 @@ module JSS
469
512
  ######################################
470
513
  private
471
514
 
515
+ # can the dp be reached for http downloads?
516
+ def http_reachable?(pw)
517
+ return false unless http_downloads_enabled
518
+
519
+ url =
520
+ if @username_password_required
521
+ user_pass = "#{CGI.escape @http_username.to_s}:#{CGI.escape pw.to_s}@"
522
+ @http_url.sub "://#{@ip_address}", "://#{user_pass}#{@ip_address}"
523
+ else
524
+ @http_url
525
+ end
526
+ URI.parse(url).read
527
+ true
528
+ rescue
529
+ false
530
+ end
531
+
472
532
  # Unused - until I get around to making DP's updatable
473
533
  #
474
534
  # the XML representation of the current state of this object,
@@ -0,0 +1,137 @@
1
+ ### Copyright 2019 Rixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+
26
+ module JSS
27
+
28
+ # Module Variables
29
+ #####################################
30
+
31
+ # Module Methods
32
+ #####################################
33
+
34
+ # Classes
35
+ #####################################
36
+
37
+ # A Dock Item in the JSS.
38
+ # These are rather simple. They have an ID, name, path, type, and contents which is read-only
39
+ #
40
+ # @see JSS::APIObject
41
+ #
42
+ class DockItem < JSS::APIObject
43
+
44
+ # Mix-Ins
45
+ #####################################
46
+ include JSS::Creatable
47
+ include JSS::Updatable
48
+
49
+ # Class Methods
50
+ #####################################
51
+
52
+ # Class Constants
53
+ #####################################
54
+
55
+ # The Dock Item type
56
+ DOCK_ITEM_TYPE = [
57
+ "App",
58
+ "File",
59
+ "Folder"
60
+ ].freeze
61
+
62
+ # The base for REST resources of this class
63
+ RSRC_BASE = 'dockitems'.freeze
64
+
65
+ # the hash key used for the JSON list output of all objects in the JSS
66
+ RSRC_LIST_KEY = :dock_items
67
+
68
+ # The hash key used for the JSON object output.
69
+ # It's also used in various error messages
70
+ RSRC_OBJECT_KEY = :dock_item
71
+
72
+ # the object type for this object in
73
+ # the object history table.
74
+ # See {APIObject#add_object_history_entry}
75
+ #OBJECT_HISTORY_OBJECT_TYPE = 41
76
+
77
+ # Attributes
78
+ #####################################
79
+ attr_reader :id
80
+ attr_reader :name
81
+ attr_reader :type
82
+ attr_reader :path
83
+
84
+ # Constructor
85
+ # @see JSS::APIObject.initialize
86
+ #####################################
87
+ def initialize(args = {})
88
+ super args
89
+
90
+ @type = "App" unless !@init_data[:type].nil?
91
+ @type = @init_data[:type]
92
+ @path = @init_data[:path]
93
+ end
94
+
95
+ # Public Instance Methods
96
+ #####################################
97
+
98
+ # set the type
99
+ #
100
+ # @param newval[String] the new app type
101
+ #
102
+ # @return [void]
103
+ #
104
+ def type=(newval)
105
+ raise JSS::InvalidDataError, 'Type must be a string' unless message.is_a? String
106
+ raise JSS::InvalidDataError, "Type must be one of the following: #{DOCK_ITEM_TYPE.to_s}; not #{newval.to_s}" unless DOCK_ITEM_TYPE.include? newval.to_s
107
+ @type = newval
108
+ @need_to_update = true
109
+ end
110
+
111
+ # set the path
112
+ #
113
+ # @param newval[String] the new app path
114
+ def path=(newval)
115
+ raise JSS::InvalidDataError, 'Path must be a String' unless newval.is_a? String
116
+ @path = newval
117
+ @need_to_update = true
118
+ end
119
+
120
+ # private instance methods
121
+ ######################
122
+ private
123
+
124
+ # the xml formated data for adding or updating this in the JSS
125
+ #
126
+ def rest_xml
127
+ doc = REXML::Document.new APIConnection::XML_HEADER
128
+ ns = doc.add_element RSRC_OBJECT_KEY.to_s
129
+ ns.add_element('name').text = @name
130
+ ns.add_element('type').text = @type.to_s
131
+ ns.add_element('path').text = @path.to_s
132
+ doc.to_s
133
+ end # rest_xml
134
+ end
135
+
136
+
137
+ end
@@ -444,6 +444,18 @@ module JSS
444
444
  refresh_ipa
445
445
  end
446
446
 
447
+ # Remove the various cached data
448
+ # from the instance_variables used to create
449
+ # pretty-print (pp) output.
450
+ #
451
+ # @return [Array] the desired instance_variables
452
+ #
453
+ def pretty_print_instance_variables
454
+ vars = super
455
+ vars.delete :@ipa
456
+ vars
457
+ end
458
+
447
459
  # Private Instance Methods
448
460
  ###########################################
449
461
  private