ruby-jss 0.7.0 → 0.8.1
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.
Potentially problematic release.
This version of ruby-jss might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGES.md +29 -22
- data/README.md +66 -86
- data/bin/jamfHelperBackgrounder +148 -0
- data/bin/netseg-update +0 -1
- data/lib/jss.rb +20 -9
- data/lib/jss/api_connection.rb +369 -295
- data/lib/jss/api_object.rb +651 -418
- data/lib/jss/api_object/account.rb +69 -77
- data/lib/jss/api_object/advanced_search.rb +201 -236
- data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +42 -42
- data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +33 -43
- data/lib/jss/api_object/advanced_search/advanced_user_search.rb +33 -43
- data/lib/jss/api_object/building.rb +39 -52
- data/lib/jss/api_object/categorizable.rb +221 -0
- data/lib/jss/api_object/category.rb +81 -89
- data/lib/jss/api_object/computer.rb +486 -525
- data/lib/jss/api_object/computer_invitation.rb +73 -86
- data/lib/jss/api_object/criteriable.rb +6 -7
- data/lib/jss/api_object/ebook.rb +21 -0
- data/lib/jss/api_object/extendable.rb +6 -8
- data/lib/jss/api_object/group.rb +0 -3
- data/lib/jss/api_object/locatable.rb +19 -20
- data/lib/jss/api_object/mac_application.rb +21 -0
- data/lib/jss/api_object/mobile_device.rb +30 -21
- data/lib/jss/api_object/mobile_device_application.rb +447 -0
- data/lib/jss/api_object/mobile_device_configuration_profile.rb +21 -0
- data/lib/jss/api_object/osx_configuration_profile.rb +0 -3
- data/lib/jss/api_object/package.rb +21 -34
- data/lib/jss/api_object/peripheral.rb +16 -18
- data/lib/jss/api_object/policy.rb +5 -83
- data/lib/jss/api_object/purchasable.rb +11 -13
- data/lib/jss/api_object/scopable.rb +11 -12
- data/lib/jss/api_object/script.rb +3 -17
- data/lib/jss/api_object/self_servable.rb +419 -205
- data/lib/jss/api_object/self_servable/icon.rb +179 -0
- data/lib/jss/api_object/updatable.rb +35 -34
- data/lib/jss/api_object/uploadable.rb +72 -70
- data/lib/jss/api_object/user.rb +6 -7
- data/lib/jss/api_object/vppable.rb +117 -0
- data/lib/jss/client.rb +264 -225
- data/lib/jss/db_connection.rb +7 -5
- data/lib/jss/exceptions.rb +50 -42
- data/lib/jss/ruby_extensions.rb +8 -7
- data/lib/jss/ruby_extensions/object.rb +19 -0
- data/lib/jss/utility.rb +82 -40
- data/lib/jss/version.rb +1 -1
- metadata +37 -68
- data/bin/jss-webhook-server +0 -3
- data/lib/jss/webhooks.rb +0 -53
- data/lib/jss/webhooks/README.md +0 -269
- data/lib/jss/webhooks/configuration.rb +0 -213
- data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation-executable +0 -91
- data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation.rb +0 -45
- data/lib/jss/webhooks/data/sample_jsons/ComputerAdded.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/ComputerCheckIn.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/ComputerInventoryCompleted.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/ComputerPolicyFinished.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/ComputerPushCapabilityChanged.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/JSSShutdown.json +0 -14
- data/lib/jss/webhooks/data/sample_jsons/JSSStartup.json +0 -14
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCheckIn.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCommandCompleted.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceEnrolled.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/MobileDevicePushSent.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceUnEnrolled.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/PatchSoftwareTitleUpdated.json +0 -14
- data/lib/jss/webhooks/data/sample_jsons/PushSent.json +0 -11
- data/lib/jss/webhooks/data/sample_jsons/RestAPIOperation.json +0 -15
- data/lib/jss/webhooks/data/sample_jsons/SCEPChallenge.json +0 -10
- data/lib/jss/webhooks/data/sample_jsons/SmartGroupComputerMembershipChange.json +0 -13
- data/lib/jss/webhooks/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +0 -13
- data/lib/jss/webhooks/event.rb +0 -139
- data/lib/jss/webhooks/event/computer_added.rb +0 -38
- data/lib/jss/webhooks/event/computer_check_in.rb +0 -38
- data/lib/jss/webhooks/event/computer_inventory_completed.rb +0 -38
- data/lib/jss/webhooks/event/computer_policy_finished.rb +0 -38
- data/lib/jss/webhooks/event/computer_push_capability_changed.rb +0 -38
- data/lib/jss/webhooks/event/handlers.rb +0 -192
- data/lib/jss/webhooks/event/jss_shutdown.rb +0 -38
- data/lib/jss/webhooks/event/jss_startup.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_check_in.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_command_completed.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_enrolled.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_push_sent.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_unenrolled.rb +0 -38
- data/lib/jss/webhooks/event/patch_software_title_updated.rb +0 -38
- data/lib/jss/webhooks/event/push_sent.rb +0 -38
- data/lib/jss/webhooks/event/rest_api_operation.rb +0 -38
- data/lib/jss/webhooks/event/scep_challenge.rb +0 -38
- data/lib/jss/webhooks/event/smart_group_computer_membership_change.rb +0 -38
- data/lib/jss/webhooks/event/smart_group_mobile_device_membership_change.rb +0 -38
- data/lib/jss/webhooks/event/webhook.rb +0 -40
- data/lib/jss/webhooks/event_objects.rb +0 -112
- data/lib/jss/webhooks/event_objects/computer.rb +0 -49
- data/lib/jss/webhooks/event_objects/jss.rb +0 -36
- data/lib/jss/webhooks/event_objects/mobile_device.rb +0 -48
- data/lib/jss/webhooks/event_objects/patch_software_title_update.rb +0 -38
- data/lib/jss/webhooks/event_objects/push.rb +0 -33
- data/lib/jss/webhooks/event_objects/rest_api_operation.rb +0 -37
- data/lib/jss/webhooks/event_objects/scep_challenge.rb +0 -32
- data/lib/jss/webhooks/event_objects/smart_group.rb +0 -35
- data/lib/jss/webhooks/server_app.rb +0 -37
- data/lib/jss/webhooks/server_app/routes.rb +0 -27
- data/lib/jss/webhooks/server_app/routes/handle_webhook_event.rb +0 -39
- data/lib/jss/webhooks/server_app/routes/home.rb +0 -37
- data/lib/jss/webhooks/server_app/self_signed_cert.rb +0 -65
- data/lib/jss/webhooks/server_app/server.rb +0 -60
- data/lib/jss/webhooks/version.rb +0 -32
@@ -1,26 +1,26 @@
|
|
1
1
|
### Copyright 2017 Pixar
|
2
2
|
|
3
|
-
###
|
3
|
+
###
|
4
4
|
### Licensed under the Apache License, Version 2.0 (the "Apache License")
|
5
5
|
### with the following modification; you may not use this file except in
|
6
6
|
### compliance with the Apache License and the following modification to it:
|
7
7
|
### Section 6. Trademarks. is deleted and replaced with:
|
8
|
-
###
|
8
|
+
###
|
9
9
|
### 6. Trademarks. This License does not grant permission to use the trade
|
10
10
|
### names, trademarks, service marks, or product names of the Licensor
|
11
11
|
### and its affiliates, except as required to comply with Section 4(c) of
|
12
12
|
### the License and to reproduce the content of the NOTICE file.
|
13
|
-
###
|
13
|
+
###
|
14
14
|
### You may obtain a copy of the Apache License at
|
15
|
-
###
|
15
|
+
###
|
16
16
|
### http://www.apache.org/licenses/LICENSE-2.0
|
17
|
-
###
|
17
|
+
###
|
18
18
|
### Unless required by applicable law or agreed to in writing, software
|
19
19
|
### distributed under the Apache License with the above modification is
|
20
20
|
### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
21
21
|
### KIND, either express or implied. See the Apache License for the specific
|
22
22
|
### language governing permissions and limitations under the Apache License.
|
23
|
-
###
|
23
|
+
###
|
24
24
|
###
|
25
25
|
|
26
26
|
###
|
@@ -50,7 +50,6 @@ module JSS
|
|
50
50
|
###
|
51
51
|
### Classes that mix in this module must:
|
52
52
|
### - Set a Constant SCOPE_TARGET_KEY that is either :computers or :mobile_devices
|
53
|
-
### - Call {#parse_scope} during initialization to make a {JSS::Scopable::Scope} instance for their @scope attribute.
|
54
53
|
### - Include the result of self.scope.scope_xml in their own rest_xml output if they are {Updatable} or {Creatable}
|
55
54
|
###
|
56
55
|
module Scopable
|
@@ -112,25 +111,25 @@ module JSS
|
|
112
111
|
@need_to_update = true if @in_jss
|
113
112
|
end
|
114
113
|
|
115
|
-
|
114
|
+
|
116
115
|
###
|
117
116
|
### A wrapper around the update method, to try catching RestClient::Conflict
|
118
117
|
### 409 errors when we couldn't verify all ldap users/groups due to lack of ldap connections
|
119
|
-
###
|
118
|
+
###
|
120
119
|
def update
|
121
120
|
begin
|
122
121
|
super
|
123
|
-
|
122
|
+
|
124
123
|
rescue RestClient::Conflict => conflict
|
125
124
|
if self.scope.unable_to_verify_ldap_entries == true
|
126
125
|
raise JSS::InvalidDataError, "Potentially non-existant LDAP user or group in new scope values."
|
127
126
|
else
|
128
127
|
raise conflict
|
129
128
|
end
|
130
|
-
|
129
|
+
|
131
130
|
end # begin
|
132
131
|
end # update
|
133
|
-
|
132
|
+
|
134
133
|
end # module Scopable
|
135
134
|
end # module JSS
|
136
135
|
|
@@ -61,6 +61,7 @@ module JSS
|
|
61
61
|
|
62
62
|
include JSS::Creatable
|
63
63
|
include JSS::Updatable
|
64
|
+
include JSS::Categorizable
|
64
65
|
|
65
66
|
### Class Methods
|
66
67
|
#####################################
|
@@ -127,7 +128,6 @@ module JSS
|
|
127
128
|
def initialize(args = {})
|
128
129
|
super
|
129
130
|
|
130
|
-
@category = JSS::APIObject.get_name(@init_data[:category])
|
131
131
|
@filename = @init_data[:filename] || @name
|
132
132
|
@info = @init_data[:info]
|
133
133
|
@notes = @init_data[:notes]
|
@@ -263,21 +263,6 @@ module JSS
|
|
263
263
|
@need_to_update = true
|
264
264
|
end # notes=
|
265
265
|
|
266
|
-
### Change the category
|
267
|
-
###
|
268
|
-
### @param new_val[String] the name of the new category, which must be in {JSS::Category.all_names}
|
269
|
-
###
|
270
|
-
### @return [void]
|
271
|
-
###
|
272
|
-
def category=(new_val)
|
273
|
-
return nil if new_val == @category
|
274
|
-
new_val = nil if new_val == ''
|
275
|
-
new_val ||= JSS::Category::DEFAULT_CATEGORY
|
276
|
-
raise JSS::InvalidDataError, "Category #{new_val} is not known to the JSS" unless JSS::Category.all_names.include? new_val
|
277
|
-
@need_to_update = true
|
278
|
-
@category = new_val
|
279
|
-
end # category=
|
280
|
-
|
281
266
|
### Replace all the script parameters at once.
|
282
267
|
###
|
283
268
|
### This will replace the entire set with the hash provided.
|
@@ -570,7 +555,7 @@ module JSS
|
|
570
555
|
def rest_xml
|
571
556
|
doc = REXML::Document.new
|
572
557
|
scpt = doc.add_element 'script'
|
573
|
-
|
558
|
+
|
574
559
|
scpt.add_element('filename').text = @filename
|
575
560
|
scpt.add_element('id').text = @id
|
576
561
|
scpt.add_element('info').text = @info
|
@@ -578,6 +563,7 @@ module JSS
|
|
578
563
|
scpt.add_element('notes').text = @notes
|
579
564
|
scpt.add_element('os_requirements').text = JSS.to_s_and_a(@os_requirements)[:stringform]
|
580
565
|
scpt.add_element('priority').text = @priority
|
566
|
+
add_category_to_xml(doc)
|
581
567
|
|
582
568
|
if @parameters.empty?
|
583
569
|
scpt.add_element('parameters').text = nil
|
@@ -23,184 +23,197 @@
|
|
23
23
|
###
|
24
24
|
###
|
25
25
|
|
26
|
+
require 'jss/api_object/self_servable/icon'
|
27
|
+
|
26
28
|
###
|
27
29
|
module JSS
|
28
30
|
|
29
|
-
|
30
|
-
### Module Variables
|
31
|
+
# Module Variables
|
31
32
|
#####################################
|
32
33
|
|
33
|
-
|
34
|
-
### Module Methods
|
34
|
+
# Module Methods
|
35
35
|
#####################################
|
36
36
|
|
37
|
-
|
38
|
-
### Sub-Modules
|
37
|
+
# Sub-Modules
|
39
38
|
#####################################
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
### available in self service. Different API objects indicate this in different ways (and
|
72
|
-
### macOS app store apps don't provide it at all via the API,
|
73
|
-
### so self service can't be implemented fully)
|
74
|
-
### - Define the methods #add_to_self_service and #remove_from_self_service, which is handled
|
75
|
-
### differently for policies, apps/ebooks, and profiles
|
76
|
-
### - Define the method #user_removable? which returns Boolean indicating that the item
|
77
|
-
### can be removed by the user in SSvc. macOS profiles store this in the :user_removable
|
78
|
-
### key of the :general subset as a boolean, whereas iOS profiles store it in
|
79
|
-
### the :security hash of the :self_service data as one of 3 strings
|
80
|
-
### - Define the method #user_removable= which sets the appropriate values depending
|
81
|
-
### on the class. (see above)
|
82
|
-
### - Define a #set_icon_to method which takes the id of a previously uploaded
|
83
|
-
### icon, or a local path (String or Pathname) to an image file to use.
|
84
|
-
### - Include the result of {#self_service_xml} in their #rest_xml output
|
85
|
-
###
|
86
|
-
###
|
87
|
-
### Generating XML for PUT or POST:
|
88
|
-
###
|
89
|
-
### If the class including this module is creatable or updatable, calling {#self_service_xml}
|
90
|
-
### returns a REXML element representing the Self Service subset, to be included with the
|
91
|
-
### #rest_xml output of the subclass.
|
92
|
-
###
|
93
|
-
### Because some self-service-related data is located outside of the Self Service
|
94
|
-
### data subset (e.g. the deployment method for profiles is in the general subset),
|
95
|
-
### classes including this module *must* also account for that and add an appropriate
|
96
|
-
### XML element as needed.
|
97
|
-
###
|
40
|
+
# A mix-in module for handling Self Service data for objects in the JSS.
|
41
|
+
#
|
42
|
+
# The JSS objects that have Self Service data return it in a :self_service subset,
|
43
|
+
# which have somewhat similar data, i.e. a hash with at least these keys:
|
44
|
+
# - :self_service_description
|
45
|
+
# - :self_service_icon
|
46
|
+
# - :feature_on_main_page
|
47
|
+
# - :self_service_categories
|
48
|
+
#
|
49
|
+
# Config Profiles in self service have this key:
|
50
|
+
# - :security
|
51
|
+
#
|
52
|
+
# Additionally, items that apper in macOS Slf Svc have these keys:
|
53
|
+
# - :install_button_text
|
54
|
+
# - :force_users_to_view_description
|
55
|
+
#
|
56
|
+
# See the attribute definitions for details of these values and structures.
|
57
|
+
#
|
58
|
+
# Including this module in an {APIObject} subclass will give it matching
|
59
|
+
# attributes with 'self_service_' appended if needed,
|
60
|
+
# e.g. {#self_service_feature_on_main_page}
|
61
|
+
#
|
62
|
+
#
|
63
|
+
# Classes including this module *MUST*:
|
64
|
+
# - call {#add_self_service_xml()} in their #rest_xml method
|
65
|
+
#
|
66
|
+
# IMPORTANT: Since SelfServable also includes #{JSS::Updatable}, for uploading icons,
|
67
|
+
# see that module for its requirements.
|
68
|
+
#
|
69
|
+
#
|
98
70
|
module SelfServable
|
99
71
|
|
100
|
-
|
72
|
+
include Uploadable
|
73
|
+
|
74
|
+
# Constants
|
101
75
|
#####################################
|
102
76
|
|
103
77
|
SELF_SERVABLE = true
|
104
78
|
|
105
|
-
|
106
|
-
|
107
|
-
|
79
|
+
PROFILE_REMOVAL_BY_USER = {
|
80
|
+
always: 'Always',
|
81
|
+
never: 'Never',
|
82
|
+
with_auth: 'With Authorization'
|
83
|
+
}.freeze
|
84
|
+
|
85
|
+
MAKE_AVAILABLE = 'Make Available in Self Service'.freeze
|
86
|
+
AUTO_INSTALL = 'Install Automatically'.freeze
|
87
|
+
AUTO_INSTALL_OR_PROMPT = 'Install Automatically/Prompt Users to Install'.freeze
|
88
|
+
|
89
|
+
DEFAULT_INSTALL_BUTTON_TEXT = 'Install'.freeze
|
90
|
+
|
91
|
+
SELF_SERVICE_CLASSES = {
|
92
|
+
JSS::Policy => {
|
93
|
+
in_self_service_data_path: [:self_service, :use_for_self_service],
|
94
|
+
in_self_service: true,
|
95
|
+
not_in_self_service: false,
|
96
|
+
targets: [:macos],
|
97
|
+
payload: :policy,
|
98
|
+
can_display_in_categories: true,
|
99
|
+
can_feature_in_categories: true
|
100
|
+
},
|
101
|
+
JSS::MacApplication => { # TODO: add the correct values when Jamf fixes this bug
|
102
|
+
in_self_service_data_path: nil, # [:general, :distribution_method],
|
103
|
+
in_self_service: nil, # MAKE_AVAILABLE,
|
104
|
+
not_in_self_service: nil, # AUTO_INSTALL_OR_PROMPT,
|
105
|
+
targets: [:macos],
|
106
|
+
payload: :app,
|
107
|
+
can_display_in_categories: true,
|
108
|
+
can_feature_in_categories: true
|
109
|
+
},
|
110
|
+
JSS::OSXConfigurationProfile => {
|
111
|
+
in_self_service_data_path: [:general, :distribution_method],
|
112
|
+
in_self_service: MAKE_AVAILABLE,
|
113
|
+
not_in_self_service: AUTO_INSTALL,
|
114
|
+
targets: [:macos],
|
115
|
+
payload: :profile,
|
116
|
+
can_display_in_categories: true,
|
117
|
+
can_feature_in_categories: true
|
118
|
+
},
|
119
|
+
JSS::EBook => {
|
120
|
+
in_self_service_data_path: [:general, :deployment_type],
|
121
|
+
in_self_service: MAKE_AVAILABLE,
|
122
|
+
not_in_self_service: AUTO_INSTALL_OR_PROMPT,
|
123
|
+
targets: [:macos, :ios],
|
124
|
+
payload: :app, # ebooks are handled the same way as apps, it seems,
|
125
|
+
can_display_in_categories: true,
|
126
|
+
can_feature_in_categories: true
|
127
|
+
},
|
128
|
+
JSS::MobileDeviceApplication => {
|
129
|
+
in_self_service_data_path: [:general, :deployment_type],
|
130
|
+
in_self_service: MAKE_AVAILABLE,
|
131
|
+
not_in_self_service: AUTO_INSTALL_OR_PROMPT,
|
132
|
+
targets: [:ios],
|
133
|
+
payload: :app,
|
134
|
+
can_display_in_categories: true,
|
135
|
+
can_feature_in_categories: false
|
136
|
+
},
|
137
|
+
JSS::MobileDeviceConfigurationProfile => {
|
138
|
+
in_self_service_data_path: [:general, :deployment_method],
|
139
|
+
in_self_service: MAKE_AVAILABLE,
|
140
|
+
not_in_self_service: AUTO_INSTALL,
|
141
|
+
targets: [:ios],
|
142
|
+
payload: :profile,
|
143
|
+
can_display_in_categories: false,
|
144
|
+
can_feature_in_categories: false
|
145
|
+
}
|
146
|
+
}.freeze
|
147
|
+
|
148
|
+
# Variables
|
108
149
|
#####################################
|
109
150
|
|
110
|
-
|
151
|
+
# Mixed-in Attributes
|
111
152
|
#####################################
|
112
153
|
|
113
|
-
|
154
|
+
# @return [Boolean] Is this thing available in Self Service?
|
155
|
+
attr_reader :in_self_service
|
156
|
+
alias in_self_service? in_self_service
|
157
|
+
|
158
|
+
# @return [JSS::Icon, nil] The icon used in self-service
|
159
|
+
attr_reader :icon
|
160
|
+
alias self_service_icon icon
|
161
|
+
|
162
|
+
# @return [String] The verbage that appears in SelfSvc for this item
|
114
163
|
attr_reader :self_service_description
|
115
164
|
|
116
|
-
|
165
|
+
# @return [Boolean] Should this item feature on the main page of SSvc?
|
166
|
+
# Only applicable to macOS targets
|
117
167
|
attr_reader :self_service_feature_on_main_page
|
118
168
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
### NOTE: as of Casper 9.61 there's a bug in the JSON output from the API, and only the last
|
130
|
-
### category is returned, if more than one are set.
|
131
|
-
###
|
169
|
+
# @return [Array<Hash>] The categories in which this item should appear in SSvc
|
170
|
+
#
|
171
|
+
# Each Hash has these keys about the category
|
172
|
+
# - :id => [Integer] the JSS id of the category
|
173
|
+
# - :name => [String] the name of the category
|
174
|
+
#
|
175
|
+
# Most objects also include one or both of these keys:
|
176
|
+
# - :display_in => [Boolean] should the item be displayed in this category in SSvc? (not MobDevConfProfiles)
|
177
|
+
# - :feature_in => [Boolean] should the item be featured in this category in SSVC? (macOS targets only)
|
178
|
+
#
|
132
179
|
attr_reader :self_service_categories
|
133
180
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
### needed to remove the profile.
|
150
|
-
###
|
151
|
-
### NOTE that the key should be called :removal_allowed, since 'Never' means it can't be removed.
|
152
|
-
###
|
181
|
+
# Profiles in Self Service have an option to allow the user to remove them
|
182
|
+
# and for iOS profiles, if authentication is required to do so, and if so,
|
183
|
+
# the password needed for removal.
|
184
|
+
#
|
185
|
+
# This data is held in the :security Hash of the selfsvc data.
|
186
|
+
# The keys are:
|
187
|
+
# - :removal_disallowed, which should be "removal allowed"
|
188
|
+
# - :password => [String] if :removal_disallowed is "With Authorization",
|
189
|
+
# this contains the passwd (in plaintext) needed to remove the profile.
|
190
|
+
#
|
191
|
+
# NOTE that the key should be called :removal_allowed, since 'Never' means it can't be removed.
|
192
|
+
#
|
193
|
+
# These values are stored in the next two attributes.
|
194
|
+
|
195
|
+
# @return [Symbol] one of the keys in PROFILE_REMOVAL_BY_USER
|
153
196
|
attr_reader :self_service_user_removable
|
154
197
|
|
155
|
-
|
198
|
+
# @return [String] The password needed for removal, in plain text.
|
199
|
+
attr_reader :self_service_removal_password
|
200
|
+
|
201
|
+
# @return [String] The text label on the install button in SSvc (OSX SSvc only)
|
156
202
|
attr_reader :self_service_install_button_text
|
157
203
|
|
158
|
-
|
204
|
+
# @return [Boolean] Should an extra window appear before the user can install the item? (OSX SSvc only)
|
159
205
|
attr_reader :self_service_force_users_to_view_description
|
160
206
|
|
207
|
+
# Mixed-in Public Instance Methods
|
161
208
|
#####################################
|
162
|
-
### Mixed-in Instance Methods
|
163
|
-
#####################################
|
164
|
-
|
165
|
-
### Call this during initialization of
|
166
|
-
### objects that have a self_service subset
|
167
|
-
### and the self_service attributes will be populated
|
168
|
-
### (as primary attributes) from @init_data
|
169
|
-
###
|
170
|
-
### @return [void]
|
171
|
-
###
|
172
|
-
def parse_self_service
|
173
|
-
@init_data[:self_service] ||= {}
|
174
|
-
@ss_data = @init_data[:self_service]
|
175
|
-
|
176
|
-
@self_service_description = @ss_data[:self_service_description]
|
177
|
-
@self_service_icon = @ss_data[:self_service_icon]
|
178
|
-
@self_service_icon ||= {}
|
179
|
-
|
180
|
-
@self_service_feature_on_main_page = @ss_data[:feature_on_main_page]
|
181
|
-
@self_service_feature_on_main_page ||= false
|
182
|
-
|
183
|
-
@self_service_categories = @ss_data[:self_service_categories]
|
184
|
-
@self_service_categories ||= []
|
185
|
-
|
186
|
-
# make this an empty hash if needed
|
187
|
-
@self_service_security = @ss_data[:security]
|
188
|
-
@self_service_security ||= {}
|
189
209
|
|
190
|
-
|
191
|
-
|
210
|
+
# Setters
|
211
|
+
#
|
192
212
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
### Setters
|
198
|
-
###
|
199
|
-
|
200
|
-
### @param new_val[String] the new discription
|
201
|
-
###
|
202
|
-
### @return [void]
|
203
|
-
###
|
213
|
+
# @param new_val[String] the new discription
|
214
|
+
#
|
215
|
+
# @return [void]
|
216
|
+
#
|
204
217
|
def self_service_description=(new_val)
|
205
218
|
new_val.strip!
|
206
219
|
return if @self_service_description == new_val
|
@@ -208,57 +221,68 @@ module JSS
|
|
208
221
|
@need_to_update = true
|
209
222
|
end
|
210
223
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
224
|
+
# @param new_val[String] the new install button text
|
225
|
+
#
|
226
|
+
# @return [void]
|
227
|
+
#
|
215
228
|
def self_service_install_button_text=(new_val)
|
216
229
|
return nil if @self_service_install_button_text == new_val
|
217
|
-
raise JSS::InvalidDataError, 'Only OS X Self Service Items can have custom button text' unless
|
230
|
+
raise JSS::InvalidDataError, 'Only OS X Self Service Items can have custom button text' unless self_service_targets.include? :macos
|
218
231
|
@self_service_install_button_text = new_val.strip
|
219
232
|
@need_to_update = true
|
220
233
|
end
|
221
234
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
235
|
+
# @param new_val[Boolean] should this appear on the main SelfSvc page?
|
236
|
+
#
|
237
|
+
# @return [void]
|
238
|
+
#
|
226
239
|
def self_service_feature_on_main_page=(new_val)
|
227
240
|
return nil if @self_service_feature_on_main_page == new_val
|
228
|
-
|
241
|
+
return nil unless @self_service_data_config[:can_feature_in_categories]
|
242
|
+
raise JSS::InvalidDataError, 'New value must be true or false' unless new_val.jss_boolean?
|
229
243
|
@self_service_feature_on_main_page = new_val
|
230
244
|
@need_to_update = true
|
231
245
|
end
|
232
246
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
247
|
+
# @param new_val[Boolean] Should the description be shown to users in a new
|
248
|
+
# window before executing the payload?
|
249
|
+
#
|
250
|
+
# @return [void]
|
251
|
+
#
|
237
252
|
def self_service_force_users_to_view_description=(new_val)
|
238
253
|
return nil if @self_service_force_users_to_view_description == new_val
|
239
|
-
raise JSS::InvalidDataError, 'Only OS X Self Service Items can force users to view description' unless
|
240
|
-
raise JSS::InvalidDataError, 'New value must be true or false' unless
|
254
|
+
raise JSS::InvalidDataError, 'Only OS X Self Service Items can force users to view description' unless self_service_targets.include? :macos
|
255
|
+
raise JSS::InvalidDataError, 'New value must be true or false' unless new_val.jss_boolean?
|
241
256
|
@self_service_force_users_to_view_description = new_val
|
242
257
|
@need_to_update = true
|
243
258
|
end
|
244
259
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
260
|
+
# Add or change one of the categories for this item in self service
|
261
|
+
#
|
262
|
+
# @param new_cat[String, Integer] the name or id of a category where this
|
263
|
+
# object should appear in SelfSvc
|
264
|
+
#
|
265
|
+
# @param display_in[Boolean] should this item appear in the SelfSvc page for
|
266
|
+
# the category? Only meaningful in applicable classes
|
267
|
+
#
|
268
|
+
# @param feature_in[Boolean] should this item be featured in the SelfSvc page
|
269
|
+
# for the category? Only meaningful in applicable classes.
|
270
|
+
# NOTE: this will always be false if display_in is false.
|
271
|
+
#
|
272
|
+
# @return [void]
|
273
|
+
#
|
255
274
|
def add_self_service_category(new_cat, display_in: true, feature_in: false)
|
256
|
-
new_cat.
|
275
|
+
new_cat = JSS::Category.map_all_ids_to(:name)[new_cat] if new_cat.is_a? Integer
|
276
|
+
feature_in = false if display_in == false
|
257
277
|
raise JSS::NoSuchItemError, "No category '#{new_cat}' in the JSS" unless JSS::Category.all_names(:refresh).include? new_cat
|
258
|
-
raise JSS::InvalidDataError, 'display_in must be true or false' unless JSS::TRUE_FALSE.include? display_in
|
259
|
-
raise JSS::InvalidDataError, 'feature_in must be true or false' unless JSS::TRUE_FALSE.include? feature_in
|
260
278
|
|
261
|
-
|
279
|
+
raise JSS::InvalidDataError, 'display_in must be true or false' unless display_in.jss_boolean?
|
280
|
+
|
281
|
+
raise JSS::InvalidDataError, 'feature_in must be true or false' unless feature_in.jss_boolean?
|
282
|
+
|
283
|
+
new_data = { name: new_cat }
|
284
|
+
new_data[:display_in] = display_in if @self_service_data_config[:can_display_in_categories]
|
285
|
+
new_data[:feature_in] = feature_in if @self_service_data_config[:can_feature_in_categories]
|
262
286
|
|
263
287
|
# see if this category is already among our categories.
|
264
288
|
idx = @self_service_categories.index { |c| c[:name] == new_cat }
|
@@ -271,57 +295,247 @@ module JSS
|
|
271
295
|
|
272
296
|
@need_to_update = true
|
273
297
|
end
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
298
|
+
alias set_self_service_category add_self_service_category
|
299
|
+
|
300
|
+
# Remove a category from those for this item in SSvc
|
301
|
+
#
|
302
|
+
# @param cat [String, Integer] the name or id of the category to remove
|
303
|
+
#
|
304
|
+
# @return [void]
|
305
|
+
#
|
281
306
|
def remove_self_service_category(cat)
|
282
|
-
@self_service_categories.reject! { |c| c[:name] == cat }
|
307
|
+
@self_service_categories.reject! { |c| c[:name] == cat || c[:id] == cat }
|
308
|
+
@need_to_update = true
|
309
|
+
end
|
310
|
+
|
311
|
+
# Set the value for user-removability of profiles, optionally
|
312
|
+
# providing a password for removal, on iOS targets.
|
313
|
+
#
|
314
|
+
# @param new_val[Symbol] One of the keys of PROFILE_REMOVAL_BY_USER,
|
315
|
+
# :always, :never, or :with_auth
|
316
|
+
#
|
317
|
+
# @param pw[String] A new password to use if removable :with_auth
|
318
|
+
#
|
319
|
+
# @return [void]
|
320
|
+
#
|
321
|
+
def self_service_user_removable=(new_val, pw = @self_service_removal_password)
|
322
|
+
return nil if new_val == @self_service_user_removable && pw == @self_service_removal_password
|
323
|
+
validate_user_removable new_val
|
324
|
+
|
325
|
+
@self_service_user_removable = new_val
|
326
|
+
@self_service_removal_password = pw
|
327
|
+
@need_to_update = true
|
328
|
+
end
|
329
|
+
|
330
|
+
# Set a new Self Service icon for this object.
|
331
|
+
#
|
332
|
+
# Since JSS::Icon objects are read-only,
|
333
|
+
# the icon can only be changed by supplying the id number
|
334
|
+
# of an icon already existing in the JSS, or a path to
|
335
|
+
# a local file, which will be uploaded to the JSS and added
|
336
|
+
# to this instance. Uploads
|
337
|
+
# take effect immediately, but if an integer is supplied, the change
|
338
|
+
# must be sent to the JSS via {#update} or {#create}
|
339
|
+
#
|
340
|
+
# @param new_icon[Integer, String, Pathname] The id or path to the new icon.
|
341
|
+
#
|
342
|
+
# @return [false, Integer, Pathname] false means no change was made.
|
343
|
+
#
|
344
|
+
def icon=(new_icon)
|
345
|
+
if new_icon.is_a? Integer
|
346
|
+
return if new_icon == @icon.id
|
347
|
+
validate_icon new_icon
|
348
|
+
@new_icon_id = new_icon
|
349
|
+
@need_to_update = true
|
350
|
+
else
|
351
|
+
unless uploadable? && self.class::UPLOAD_TYPES.keys.include?(:icon)
|
352
|
+
raise JSS::UnsupportedError, "Class #{self.class} does not support icon uploads."
|
353
|
+
end
|
354
|
+
new_icon = Pathname.new new_icon
|
355
|
+
upload(:icon, new_icon)
|
356
|
+
refresh_icon
|
357
|
+
end # new_icon.is_a? Integer
|
358
|
+
new_icon
|
359
|
+
end # icon =
|
360
|
+
alias self_service_icon= icon=
|
361
|
+
alias assign_icon icon=
|
362
|
+
|
363
|
+
# Add this object to self service if not already there.
|
364
|
+
#
|
365
|
+
# @return [void]
|
366
|
+
#
|
367
|
+
def add_to_self_service
|
368
|
+
return nil unless @self_service_data_config[:in_self_service_data_path]
|
369
|
+
return nil if in_self_service?
|
370
|
+
@in_self_service = true
|
283
371
|
@need_to_update = true
|
284
372
|
end
|
285
373
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
374
|
+
# Remove this object from self service if it's there.
|
375
|
+
#
|
376
|
+
# @return [void]
|
377
|
+
#
|
378
|
+
def remove_from_self_service
|
379
|
+
return nil unless @self_service_data_config[:in_self_service_data_path]
|
380
|
+
return nil unless in_self_service?
|
381
|
+
@in_self_service = false
|
382
|
+
@need_to_update = true
|
383
|
+
end
|
384
|
+
|
385
|
+
# Can this thing be removed by the user?
|
386
|
+
#
|
387
|
+
# @return [Boolean, nil] nil means 'not applicable'
|
388
|
+
#
|
389
|
+
def user_removable?
|
390
|
+
return nil unless self_service_payload == :profile
|
391
|
+
@self_service_user_removable != :never
|
392
|
+
end
|
393
|
+
|
394
|
+
# What devices types can get this thing in Self Service
|
395
|
+
#
|
396
|
+
# @return [Array<Symbol>] An array of :macos, :ios, or both.
|
397
|
+
#
|
398
|
+
def self_service_targets
|
399
|
+
@self_service_data_config[:targets]
|
400
|
+
end
|
401
|
+
|
402
|
+
# What does this object deploy to the device
|
403
|
+
# via self service?
|
404
|
+
#
|
405
|
+
# @return [Symbol] :profile, :app, or :policy
|
406
|
+
#
|
407
|
+
def self_service_payload
|
408
|
+
@self_service_data_config[:payload]
|
409
|
+
end
|
410
|
+
|
411
|
+
# Mixed-in Private Instance Methods
|
412
|
+
#####################################
|
413
|
+
private
|
414
|
+
|
415
|
+
# Call this during initialization of
|
416
|
+
# objects that have a self_service subset
|
417
|
+
# and the self_service attributes will be populated
|
418
|
+
# (as primary attributes) from @init_data
|
419
|
+
#
|
420
|
+
# @return [void]
|
421
|
+
#
|
422
|
+
def parse_self_service
|
423
|
+
ss_data = @init_data[:self_service]
|
424
|
+
ss_data ||= {}
|
425
|
+
@self_service_data_config = SELF_SERVICE_CLASSES[self.class]
|
426
|
+
|
427
|
+
@in_self_service = in_self_service_at_init?
|
428
|
+
|
429
|
+
if ss_data[:security]
|
430
|
+
removable_value = ss_data[:security][:removal_disallowed]
|
431
|
+
@self_service_user_removable = PROFILE_REMOVAL_BY_USER.invert[removable_value]
|
432
|
+
@self_service_removal_password = ss_data[:security][:password]
|
433
|
+
end
|
434
|
+
|
435
|
+
@self_service_description = ss_data[:self_service_description]
|
436
|
+
|
437
|
+
@icon = JSS::Icon.new(ss_data[:self_service_icon]) if ss_data[:self_service_icon]
|
438
|
+
|
439
|
+
@self_service_feature_on_main_page = ss_data[:feature_on_main_page]
|
440
|
+
@self_service_feature_on_main_page ||= false
|
441
|
+
|
442
|
+
@self_service_categories = ss_data[:self_service_categories]
|
443
|
+
@self_service_categories ||= []
|
444
|
+
|
445
|
+
@self_service_install_button_text = ss_data[:install_button_text]
|
446
|
+
@self_service_install_button_text ||= DEFAULT_INSTALL_BUTTON_TEXT
|
447
|
+
|
448
|
+
@self_service_force_users_to_view_description = ss_data[:force_users_to_view_description]
|
449
|
+
@self_service_force_users_to_view_description ||= false
|
450
|
+
end # parse
|
451
|
+
|
452
|
+
# Figure out if this object is in Self Service, from the API
|
453
|
+
# initialization data.
|
454
|
+
# Alas, how to do it is far from consistent
|
455
|
+
#
|
456
|
+
# @return [Boolean]
|
457
|
+
#
|
458
|
+
def in_self_service_at_init?
|
459
|
+
return nil unless @self_service_data_config[:in_self_service_data_path]
|
460
|
+
subsection, key = @self_service_data_config[:in_self_service_data_path]
|
461
|
+
@init_data[subsection][key] == @self_service_data_config[:in_self_service]
|
462
|
+
end
|
463
|
+
|
464
|
+
def validate_user_removable=(new_val)
|
465
|
+
raise JSS::UnsupportedError, 'User removal settings not applicable to this class' unless self_service_payload == :profile
|
466
|
+
|
467
|
+
raise JSS::UnsupportedError, 'Removal :with_auth not applicable to this class' if new_val == :with_auth && !self_service_targets.include?(:ios)
|
468
|
+
|
469
|
+
raise JSS::InvalidDataError, "Value must be one of: :#{PROFILE_REMOVAL_BY_USER.keys.join(', :')}" unless PROFILE_REMOVAL_BY_USER.keys.include? new_val
|
470
|
+
end
|
471
|
+
|
472
|
+
def validate_icon(id)
|
473
|
+
if JSS::DB_CNX.connected?
|
474
|
+
raise JSS::NoSuchItemError, "No icon with id #{new_icon}" unless JSS::Icon.all_ids.include? id
|
475
|
+
end
|
476
|
+
end
|
477
|
+
# Re-read the icon data for this object from the API
|
478
|
+
# Generally done after uploading a new icon via {#icon=}
|
479
|
+
#
|
480
|
+
# @return [void]
|
481
|
+
#
|
482
|
+
def refresh_icon
|
483
|
+
return nil unless @in_jss
|
484
|
+
fresh_data = JSS::API.get_rsrc(@rest_rsrc)[self.class::RSRC_OBJECT_KEY]
|
485
|
+
icon_data = fresh_data[:self_service][:self_service_icon]
|
486
|
+
@icon = JSS::Icon.new icon_data
|
487
|
+
end # refresh icon
|
488
|
+
|
489
|
+
# Add a REXML <self_service> element to the root of the provided REXML::Document
|
490
|
+
#
|
491
|
+
# @param xdoc[REXML::Document] The XML Document to which we're adding a Self
|
492
|
+
# Service subsection
|
493
|
+
#
|
494
|
+
# @return [void]
|
495
|
+
#
|
496
|
+
def add_self_service_xml(xdoc)
|
497
|
+
doc_root = xdoc.root
|
498
|
+
ssvc = doc_root.add_element 'self_service'
|
296
499
|
|
297
500
|
ssvc.add_element('self_service_description').text = @self_service_description
|
298
501
|
ssvc.add_element('feature_on_main_page').text = @self_service_feature_on_main_page
|
299
502
|
|
503
|
+
if @new_icon_id
|
504
|
+
icon = ssvc.add_element('self_service_icon')
|
505
|
+
icon.add_element('id').text = @new_icon_id
|
506
|
+
end
|
507
|
+
|
300
508
|
cats = ssvc.add_element('self_service_categories')
|
301
509
|
@self_service_categories.each do |cat|
|
302
510
|
catelem = cats.add_element('category')
|
303
511
|
catelem.add_element('name').text = cat[:name]
|
304
|
-
catelem.add_element('display_in').text = cat[:display_in] if
|
305
|
-
catelem.add_element('feature_in').text = cat[:feature_in] if
|
512
|
+
catelem.add_element('display_in').text = cat[:display_in] if @self_service_data_config[:can_display_in_categories]
|
513
|
+
catelem.add_element('feature_in').text = cat[:feature_in] if @self_service_data_config[:can_feature_in_categories]
|
306
514
|
end
|
307
515
|
|
308
|
-
|
309
|
-
|
516
|
+
if self_service_targets.include? :macos
|
517
|
+
ssvc.add_element('install_button_text').text = @self_service_install_button_text
|
518
|
+
ssvc.add_element('force_users_to_view_description').text = @self_service_force_users_to_view_description
|
519
|
+
end
|
310
520
|
|
311
|
-
|
521
|
+
if self_service_payload == :profile
|
312
522
|
sec = ssvc.add_element('security')
|
313
|
-
sec.add_element('removal_disallowed').text =
|
314
|
-
sec.add_element('password').text = @
|
523
|
+
sec.add_element('removal_disallowed').text = PROFILE_REMOVAL_BY_USER[@self_service_user_removable]
|
524
|
+
sec.add_element('password').text = @self_service_removal_password if @self_service_removal_password
|
315
525
|
end
|
316
526
|
|
317
|
-
|
318
|
-
ssvc.add_element('force_users_to_view_description').text = @self_service_force_users_to_view_description \
|
319
|
-
unless @self_service_force_users_to_view_description.nil?
|
527
|
+
return unless @self_service_data_config[:in_self_service_data_path]
|
320
528
|
|
321
|
-
|
322
|
-
|
529
|
+
in_ss_section, in_ss_elem = @self_service_data_config[:in_self_service_data_path]
|
530
|
+
|
531
|
+
in_ss_value = @in_self_service ? @self_service_data_config[:in_self_service] : @self_service_data_config[:not_in_self_service]
|
532
|
+
|
533
|
+
in_ss_section_xml = doc_root.elements[in_ss_section.to_s]
|
534
|
+
in_ss_section_xml ||= doc_root.add_element(in_ss_section.to_s)
|
535
|
+
in_ss_section_xml.add_element(in_ss_elem.to_s).text = in_ss_value.to_s
|
536
|
+
end # add_self_service_xml
|
323
537
|
|
324
|
-
|
538
|
+
# aliases
|
325
539
|
alias change_self_service_category add_self_service_category
|
326
540
|
|
327
541
|
end # module SelfServable
|