lib/jss/api_object/self_servable.rb in ruby-jss-0.14.0 vs lib/jss/api_object/self_servable.rb in ruby-jss-1.0.0b2
- old
+ new
@@ -1,5 +1,6 @@
+
### Copyright 2018 Pixar
###
### Licensed under the Apache License, Version 2.0 (the "Apache License")
### with the following modification; you may not use this file except in
@@ -48,12 +49,18 @@
#
# Config Profiles in self service have this key:
# - :security
#
# Additionally, items that apper in macOS Slf Svc have these keys:
+ # - :self_service_display_name
# - :install_button_text
+ # - :reinstall_button_text
# - :force_users_to_view_description
+ # - :notification
+ # - :notification_location # PENDING API FIX
+ # - :notification_subject
+ # - :notification_message
#
# See the attribute definitions for details of these values and structures.
#
# Including this module in an {APIObject} subclass will give it matching
# attributes with 'self_service_' appended if needed,
@@ -87,11 +94,23 @@
AUTO_INSTALL_OR_PROMPT = 'Install Automatically/Prompt Users to Install'.freeze
PATCHPOL_SELF_SERVICE = 'selfservice'.freeze # 'Make Available in Self Service' in the UI
PATCHPOL_AUTO = 'prompt'.freeze # 'Install Automatically' in the UI
DEFAULT_INSTALL_BUTTON_TEXT = 'Install'.freeze
+ DEFAULT_REINSTALL_BUTTON_TEXT = 'Reinstall'.freeze
+ DEFAULT_FORCE_TO_VIEW_DESC = false
+ NOTIFICATION_TYPES = {
+ ssvc_only: 'Self Service',
+ ssvc_and_nctr: 'Self Service and Notification Center'
+ }.freeze
+ DFT_NOTIFICATION_TYPE = :ssvc_only
+
+ USER_URL_BASE = 'jamfselfservice://content?entity='.freeze
+ USER_URL_EXEC_ACTION = 'execute'.freeze
+ USER_URL_VIEW_ACTION = 'view'.freeze
+
# This hash contains the details about the inconsistencies of how
# Self Service data is dealt with in the API data of the different
# self-servable classes.
#
# - in_self_service_data_path: Array, In the API data hash (the @init_data)
@@ -103,10 +122,14 @@
# the thing IS in self service
#
# - not_in_self_service: Object, In the path defined above, what value means
# the thing IS NOT in self service
#
+ # - self_service_subset: Symbol. Which key of the init data hash contains
+ # the self service data. If not defined, its :self_service, but
+ # PatchPolcies use :user_interaction
+ #
# - targets: Array<Symbol>, the array contains either :macos, :ios, or both.
#
# - payload: Symbol, The thing that is deployed by self service, one of:
# :policy, :app, :profile, :patchpolicy (ebooks are considered apps)
#
@@ -114,70 +137,92 @@
# can the thing be 'displayed in' those categories?
#
# - can_feature_in_categories: Boolean, when adding 'self service categories'
# can the thing be 'featured in' those categories?
#
+ # - notifications_supported: either nil (not supported), :ssvc_only, or
+ # :ssvc_and_nctr NOTE: when notifications are supported for :ssvc_only,
+ # its due to a bug in the handling of the XML (two separate values are
+ # using the same XML element tag <notification>) Items that support both
+ # have a <notifications> subset inside the <self_service> subset
+ #
+ # - notification_reminders: if true, supports notification reminders.
+ # Only true for items that have a <notifications> subset
+ #
+ # - url_entity: the 'entity' value used in user-urls for this SSVc item.
+ #
# It's unfortunate that this is needed in order to keep all the
# self service ruby code in this one module.
#
SELF_SERVICE_CLASSES = {
JSS::Policy => {
- in_self_service_data_path: [:self_service, :use_for_self_service],
+ in_self_service_data_path: %i[self_service use_for_self_service],
in_self_service: true,
not_in_self_service: false,
targets: [:macos],
payload: :policy,
can_display_in_categories: true,
- can_feature_in_categories: true
+ can_feature_in_categories: true,
+ notifications_supported: :ssvc_only,
+ url_entity: 'policy'
},
JSS::PatchPolicy => {
- in_self_service_data_path: [:general, :distribution_method],
+ in_self_service_data_path: %i[general distribution_method],
in_self_service: PATCHPOL_SELF_SERVICE,
not_in_self_service: PATCHPOL_AUTO,
+ self_service_subset: :user_interaction,
targets: [:macos],
payload: :patchpolicy,
can_display_in_categories: false,
- can_feature_in_categories: false
+ can_feature_in_categories: false,
+ notifications_supported: :ssvc_and_nctr,
+ notification_reminders: true
},
JSS::MacApplication => { # TODO: add the correct values when Jamf fixes this bug
in_self_service_data_path: nil, # [:general, :distribution_method],
in_self_service: nil, # MAKE_AVAILABLE,
not_in_self_service: nil, # AUTO_INSTALL_OR_PROMPT,
targets: [:macos],
payload: :app,
can_display_in_categories: true,
- can_feature_in_categories: true
+ can_feature_in_categories: true,
+ url_entity: 'app'
+ # OTHER BUG: no notification options seem to be changable via the API
},
JSS::OSXConfigurationProfile => {
- in_self_service_data_path: [:general, :distribution_method],
+ in_self_service_data_path: %i[general distribution_method],
in_self_service: MAKE_AVAILABLE,
not_in_self_service: AUTO_INSTALL,
targets: [:macos],
payload: :profile,
can_display_in_categories: true,
- can_feature_in_categories: true
+ can_feature_in_categories: true,
+ notifications_supported: :ssvc_only,
+ url_entity: 'configprofile'
},
JSS::EBook => {
- in_self_service_data_path: [:general, :deployment_type],
+ in_self_service_data_path: %i[general deployment_type],
in_self_service: MAKE_AVAILABLE,
not_in_self_service: AUTO_INSTALL_OR_PROMPT,
- targets: [:macos, :ios],
+ targets: %i[macos ios],
payload: :app, # ebooks are handled the same way as apps, it seems,
can_display_in_categories: true,
- can_feature_in_categories: true
+ can_feature_in_categories: true,
+ notifications_supported: :ssvc_only,
+ url_entity: 'ebook'
},
JSS::MobileDeviceApplication => {
- in_self_service_data_path: [:general, :deployment_type],
+ in_self_service_data_path: %i[general deployment_type],
in_self_service: MAKE_AVAILABLE,
not_in_self_service: AUTO_INSTALL_OR_PROMPT,
targets: [:ios],
payload: :app,
can_display_in_categories: true,
can_feature_in_categories: false
},
JSS::MobileDeviceConfigurationProfile => {
- in_self_service_data_path: [:general, :deployment_method],
+ in_self_service_data_path: %i[general deployment_method],
in_self_service: MAKE_AVAILABLE,
not_in_self_service: AUTO_INSTALL,
targets: [:ios],
payload: :profile,
can_display_in_categories: false,
@@ -197,10 +242,13 @@
# @return [JSS::Icon, nil] The icon used in self-service
attr_reader :icon
alias self_service_icon icon
+ # @return [String] The name to display in macOS Self Service.
+ attr_reader :self_service_display_name
+
# @return [String] The verbage that appears in SelfSvc for this item
attr_reader :self_service_description
# @return [Boolean] Should this item feature on the main page of SSvc?
# Only applicable to macOS targets
@@ -237,21 +285,63 @@
# @return [String] The password needed for removal, in plain text.
attr_reader :self_service_removal_password
# @return [String] The text label on the install button in SSvc (OSX SSvc only)
+ # defaults to 'Install'
attr_reader :self_service_install_button_text
+ # @return [String] The text label on the reinstall button in SSvc (OSX SSvc only)
+ # defaults to 'Reinstall'
+ attr_reader :self_service_reinstall_button_text
+
# @return [Boolean] Should an extra window appear before the user can install the item? (OSX SSvc only)
attr_reader :self_service_force_users_to_view_description
+ # @return [Boolean] Should jamf send notifications to self service?
+ attr_reader :self_service_notifications_enabled
+ alias self_service_notifications_enabled? self_service_notifications_enabled
+
+ # @return [Symbol] How should notifications be sent
+ # either :ssvc_only or :ssvc_and_nctr
+ attr_reader :self_service_notification_type
+
+ # @return [String] The subject text of the notification. Defaults to the
+ # object name.
+ attr_reader :self_service_notification_subject
+
+ # @return [String] The message text of the notification
+ attr_reader :self_service_notification_message
+
+ # @return [Boolean] Should self service give reminders by displaying the
+ # notification repeatedly?
+ attr_reader :self_service_reminders_enabled
+ alias self_service_reminders_enabled? self_service_reminders_enabled
+
+ # @return [Integer] How often (in days) should reminders be given
+ attr_reader :self_service_reminder_frequency
+
# Mixed-in Public Instance Methods
#####################################
- # Setters
+ # @return [String] The url to view this thing in Self Service
#
+ def self_service_view_url
+ return nil unless @self_service_data_config[:url_entity]
+ "#{USER_URL_BASE}#{@self_service_data_config[:url_entity]}&id=#{id}&action=#{USER_URL_VIEW_ACTION}"
+ end
+ # @return [String] The url to view this thing in Self Service
+ #
+ def self_service_execute_url
+ return nil unless @self_service_data_config[:url_entity]
+ "#{USER_URL_BASE}#{@self_service_data_config[:url_entity]}&id=#{id}&action=#{USER_URL_EXEC_ACTION}"
+ end
+
+ # Setters
+ #####################################
+
# @param new_val[String] the new discription
#
# @return [void]
#
def self_service_description=(new_val)
@@ -259,21 +349,46 @@
return if @self_service_description == new_val
@self_service_description = new_val
@need_to_update = true
end
+ # @param new_val[String] The display name of the item in SSvc
+ #
+ # @return [void]
+ #
+ def self_service_dislay_name=(new_val)
+ new_val.strip!
+ return nil if @self_service_dislay_name == new_val
+ raise JSS::InvalidDataError, 'Only macOS Self Service items have display names' unless self_service_targets.include? :macos
+ @self_service_dislay_name = new_val
+ @need_to_update = true
+ end
+
# @param new_val[String] the new install button text
#
# @return [void]
#
def self_service_install_button_text=(new_val)
+ new_val.strip!
return nil if @self_service_install_button_text == new_val
- raise JSS::InvalidDataError, 'Only OS X Self Service Items can have custom button text' unless self_service_targets.include? :macos
- @self_service_install_button_text = new_val.strip
+ raise JSS::InvalidDataError, 'Only macOS Self Service Items can have custom button text' unless self_service_targets.include? :macos
+ @self_service_install_button_text = new_val
@need_to_update = true
end
+ # @param new_val[String] the new reinstall button text
+ #
+ # @return [void]
+ #
+ def self_service_reinstall_button_text=(new_val)
+ new_val.strip!
+ return nil if @self_service_reinstall_button_text == new_val
+ raise JSS::InvalidDataError, 'Only macOS Self Service Items can have custom button text' unless self_service_targets.include? :macos
+ @self_service_reinstall_button_text = new_val
+ @need_to_update = true
+ end
+
# @param new_val[Boolean] should this appear on the main SelfSvc page?
#
# @return [void]
#
def self_service_feature_on_main_page=(new_val)
@@ -289,11 +404,11 @@
#
# @return [void]
#
def self_service_force_users_to_view_description=(new_val)
return nil if @self_service_force_users_to_view_description == new_val
- raise JSS::InvalidDataError, 'Only OS X Self Service Items can force users to view description' unless self_service_targets.include? :macos
+ raise JSS::InvalidDataError, 'Only macOS Self Service Items can force users to view description' unless self_service_targets.include? :macos
raise JSS::InvalidDataError, 'New value must be true or false' unless new_val.jss_boolean?
@self_service_force_users_to_view_description = new_val
@need_to_update = true
end
@@ -334,10 +449,11 @@
end
@need_to_update = true
end
alias set_self_service_category add_self_service_category
+ alias change_self_service_category add_self_service_category
# Remove a category from those for this item in SSvc
#
# @param cat [String, Integer] the name or id of the category to remove
#
@@ -360,19 +476,107 @@
#
def self_service_user_removable=(new_val, pw = @self_service_removal_password)
new_val, pw = *new_val if new_val.is_a? Array
pw = nil unless new_val == :with_auth
- return nil if new_val == self_service_user_removable && pw == self_service_removal_password
+ return if new_val == self_service_user_removable && pw == self_service_removal_password
validate_user_removable new_val
@self_service_user_removable = new_val
@self_service_removal_password = pw
@need_to_update = true
end
+ # en/disable notifications
+ #
+ # @param new_val [Boolean] should we display notifications?
+ #
+ # @return [void]
+ #
+ def self_service_notifications_enabled=(new_val)
+ return if new_val == self_service_notifications_enabled
+ validate_notifications_supported
+ JSS::Validate.boolean new_val
+ @self_service_notifications_enabled = new_val
+ @need_to_update = true
+ end
+
+ # How should self service notifications be displayed
+ #
+ # @param type[Symbol] A key from SelfServable::NOTIFICATION_TYPES
+ #
+ # @return [void]
+ #
+ def self_service_notification_type=(type)
+ validate_notifications_supported
+
+ # HACK: Until jamf fixes bugs, you can only set notifications
+ # :off or :ssvc_only. If you want :ssvc_and_nctr, you must
+ # check the checkbox in the web-UI.
+ if @self_service_data_config[:notifications_supported] == :ssvc_only && type != :ssvc_only
+ raise "JAMF BUG: Until Jamf fixes API bugs in #{self.class}, you can only set Self Service notifications to :ssvc_only. Use the WebUI to activate Notification Center notifications"
+ end
+
+ raise JSS::InvalidDataError, "type must be one of: :#{NOTIFICATION_TYPES.keys.join ', :'}" unless NOTIFICATION_TYPES.key? type
+
+ @self_service_notification_type = type
+ @need_to_update = true
+ end
+
+ # @param subj[String] The subject text for the notification
+ #
+ # @return [void]
+ #
+ def self_service_notification_subject=(subj)
+ subj.strip!
+ return if subj == @self_service_notification_subject
+ validate_notifications_supported
+ @self_service_notification_subject = subj
+ @need_to_update = true
+ end
+
+ # @param msg[String] The message text for the notification
+ #
+ # @return [void]
+ #
+ def self_service_notification_message=(msg)
+ msg.strip!
+ return if msg == @self_service_notification_message
+ validate_notifications_supported
+ @self_service_notification_message = msg
+ @need_to_update = true
+ end
+
+ # en/disable reminder notifications
+ #
+ # @param new_val [Boolean] should we display reminder notifications?
+ #
+ # @return [void]
+ #
+ def self_service_reminders_enabled=(new_val)
+ return if new_val == self_service_reminders_enabled
+ validate_notification_reminders_supported
+ JSS::Validate.boolean new_val
+ @self_service_reminders_enabled = new_val
+ @need_to_update = true
+ end
+
+ # set reminder notification frequency
+ #
+ # @param new_val[Integer] How many days between reminder notifications?
+ #
+ # @return [void]
+ #
+ def self_service_reminder_frequency=(days)
+ return if days == self_service_reminder_frequency
+ validate_notification_reminders_supported
+ JSS::Validate.integer days
+ @self_service_reminder_frequency = days
+ @need_to_update = true
+ end
+
# Set a new Self Service icon for this object.
#
# Since JSS::Icon objects are read-only,
# the icon can only be changed by supplying the id number
# of an icon already existing in the JSS, or a path to
@@ -390,11 +594,11 @@
return if @icon && new_icon == @icon.id
validate_icon new_icon
@new_icon_id = new_icon
@need_to_update = true
else
- unless uploadable? && defined?(self.class::UPLOAD_TYPES) && self.class::UPLOAD_TYPES.keys.include?(:icon)
+ unless uploadable? && defined?(self.class::UPLOAD_TYPES) && self.class::UPLOAD_TYPES.key?(:icon)
raise JSS::UnsupportedError, "Class #{self.class} does not support icon uploads."
end
new_icon = Pathname.new new_icon
upload(:icon, new_icon)
refresh_icon
@@ -450,49 +654,82 @@
#
def self_service_payload
@self_service_data_config[:payload]
end
+ # HACK: ity hack hack...
+ # remove when jamf fixes these bugs
+ def update
+ resp = super
+ force_notifications_on if @need_ss_notification_activation_hack
+ resp
+ end
+
+ # HACK: ity hack hack...
+ # remove when jamf fixes these bugs
+ def create
+ resp = super
+ force_notifications_on if @need_ss_notification_activation_hack
+ resp
+ end
+
# Mixed-in Private Instance Methods
#####################################
private
+ # HACK: ity hack hack...
+ # remove when jamf fixes these bugs
+ def force_notifications_on
+ xml = <<-ENDXML
+<#{self.class::RSRC_OBJECT_KEY}>
+ <self_service>
+ <notification>true</notification>
+ </self_service>
+</#{self.class::RSRC_OBJECT_KEY}>
+ ENDXML
+ @api.put_rsrc rest_rsrc, xml
+ @need_ss_notification_activation_hack = nil
+ end
+
# Call this during initialization of
# objects that have a self_service subset
# and the self_service attributes will be populated
# (as primary attributes) from @init_data
#
# @return [void]
#
def parse_self_service
- ss_data = @init_data[:self_service]
- ss_data ||= {}
@self_service_data_config = SELF_SERVICE_CLASSES[self.class]
- @in_self_service = in_self_service_at_init?
+ subset_key = @self_service_data_config[:self_service_subset] ? @self_service_data_config[:self_service_subset] : :self_service
- if ss_data[:security]
- removable_value = ss_data[:security][:removal_disallowed]
- @self_service_user_removable = PROFILE_REMOVAL_BY_USER.invert[removable_value]
- @self_service_removal_password = ss_data[:security][:password]
- end
+ ss_data = @init_data[subset_key]
+ ss_data ||= {}
+ @in_self_service = in_self_service_at_init?
+
@self_service_description = ss_data[:self_service_description]
@icon = JSS::Icon.new(ss_data[:self_service_icon]) if ss_data[:self_service_icon]
@self_service_feature_on_main_page = ss_data[:feature_on_main_page]
- @self_service_feature_on_main_page ||= false
@self_service_categories = ss_data[:self_service_categories]
@self_service_categories ||= []
- @self_service_install_button_text = ss_data[:install_button_text]
- @self_service_install_button_text ||= DEFAULT_INSTALL_BUTTON_TEXT
+ parse_self_service_profile ss_data
+ return unless self_service_targets.include? :macos
+
+ # Computers only...
+ @self_service_display_name = ss_data[:self_service_display_name]
+ @self_service_display_name ||= name
+ @self_service_install_button_text = ss_data[:install_button_text]
+ @self_service_reinstall_button_text = ss_data[:reinstall_button_text]
@self_service_force_users_to_view_description = ss_data[:force_users_to_view_description]
- @self_service_force_users_to_view_description ||= false
+
+ parse_self_service_notifications ss_data
end # parse
# Figure out if this object is in Self Service, from the API
# initialization data.
# Alas, how to do it is far from consistent
@@ -504,92 +741,202 @@
subsection, key = @self_service_data_config[:in_self_service_data_path]
return false unless @init_data[subsection]
@init_data[subsection][key] == @self_service_data_config[:in_self_service]
end
- def validate_user_removable(new_val)
- raise JSS::UnsupportedError, 'User removal settings not applicable to this class' unless self_service_payload == :profile
+ # parse incoming ssvc settings for profiles
+ def parse_self_service_profile(ss_data)
+ return unless self_service_payload == :profile
+ if self_service_targets.include? :ios
+ @self_service_user_removable = PROFILE_REMOVAL_BY_USER[ss_data[:security][:removal_disallowed]]
+ @self_service_removal_password = ss_data[:security][:password]
+ return
+ end
+ @self_service_user_removable = @init_data[:general][:user_removable]
+ end
- raise JSS::UnsupportedError, 'Removal :with_auth not applicable to this class' if new_val == :with_auth && !self_service_targets.include?(:ios)
+ # parse incoming ssvc notification settings
+ def parse_self_service_notifications(ss_data)
+ return unless @self_service_data_config[:notifications_supported]
- raise JSS::InvalidDataError, "Value must be one of: :#{PROFILE_REMOVAL_BY_USER.keys.join(', :')}" unless PROFILE_REMOVAL_BY_USER.keys.include? new_val
- end
+ # oldstyle/broken, we need the XML to know if notifications are turned on
+ if @self_service_data_config[:notifications_supported] == :ssvc_only && @in_jss
+ ssrsrc = "#{rest_rsrc}/subset/selfservice"
+ raw_xml = api.get_rsrc(ssrsrc, :xml)
+ @self_service_notifications_enabled = raw_xml.include? '<notification>true</notification>'
+ @self_service_notification_type = NOTIFICATION_TYPES.invert[ss_data[:notification]]
+ @self_service_notification_subject = ss_data[:notification_subject]
+ @self_service_notification_message = ss_data[:notification_message]
+ return
+ end
- def validate_icon(id)
- return nil unless JSS::DB_CNX.connected?
- raise JSS::NoSuchItemError, "No icon with id #{id}" unless JSS::Icon.all_ids.include? id
+ # newstyle, 'notifications' subset
+ notif_data = ss_data[:notifications]
+ notif_data ||= {}
+
+ @self_service_notifications_enabled = notif_data[:notification_enabled]
+ @self_service_notification_type = NOTIFICATION_TYPES.invert[notif_data[:notification_type]]
+ @self_service_notification_type ||= DFT_NOTIFICATION_TYPE
+ @self_service_notification_subject = notif_data[:notification_subject]
+ @self_service_notification_message = notif_data[:notification_message]
+
+ reminders = notif_data[:reminders]
+ reminders ||= {}
+ @self_service_reminders_enabled = reminders[:notification_reminders_enabled]
+ @self_service_reminder_frequency = reminders[:notification_reminder_frequency]
end
# Re-read the icon data for this object from the API
# Generally done after uploading a new icon via {#icon=}
#
# @return [void]
#
def refresh_icon
return nil unless @in_jss
fresh_data = @api.get_rsrc(@rest_rsrc)[self.class::RSRC_OBJECT_KEY]
- icon_data = fresh_data[:self_service][:self_service_icon]
+ subset_key = @self_service_data_config[:self_service_subset] ? @self_service_data_config[:self_service_subset] : :self_service
+
+ ss_data = fresh_data[subset_key]
+
+ icon_data = ss_data[:self_service_icon]
@icon = JSS::Icon.new icon_data
end # refresh icon
- # Add a REXML <self_service> element to the root of the provided REXML::Document
+ # Add approriate XML for self service data to the XML document for this
+ # item.
#
- # @param xdoc[REXML::Document] The XML Document to which we're adding a Self
- # Service subsection
+ # @param xdoc[REXML::Document] The XML Document to which we're adding Self
+ # Service data
#
# @return [void]
#
def add_self_service_xml(xdoc)
doc_root = xdoc.root
- ssvc = doc_root.add_element 'self_service'
- ssvc.add_element('self_service_description').text = @self_service_description
+ # whether or not we're in self service is usually not in the
+ # ssvc subset...
+ add_in_self_service_xml doc_root
+
+ subset_key = @self_service_data_config[:self_service_subset] ? @self_service_data_config[:self_service_subset] : :self_service
+
+ ssvc = doc_root.add_element subset_key.to_s
+
+ ssvc.add_element('self_service_description').text = @self_service_description if @self_service_description
ssvc.add_element('feature_on_main_page').text = @self_service_feature_on_main_page
if @new_icon_id
icon = ssvc.add_element('self_service_icon')
icon.add_element('id').text = @new_icon_id
end
- cats = ssvc.add_element('self_service_categories')
- if @self_service_categories
- @self_service_categories.each do |cat|
- catelem = cats.add_element('category')
- catelem.add_element('name').text = cat[:name]
- catelem.add_element('display_in').text = cat[:display_in] if @self_service_data_config[:can_display_in_categories]
- catelem.add_element('feature_in').text = cat[:feature_in] if @self_service_data_config[:can_feature_in_categories]
- end
- end
+ add_self_service_category_xml ssvc
- if self_service_targets.include? :macos
- ssvc.add_element('install_button_text').text = @self_service_install_button_text
- ssvc.add_element('force_users_to_view_description').text = @self_service_force_users_to_view_description
- end
+ add_self_service_profile_xml ssvc, doc_root
- if self_service_payload == :profile
- if self_service_targets.include? :ios
- sec = ssvc.add_element('security')
- sec.add_element('removal_disallowed').text = PROFILE_REMOVAL_BY_USER[@self_service_user_removable]
- sec.add_element('password').text = @self_service_removal_password.to_s
- else
- gen = doc_root.elements['general']
- gen.add_element('user_removable').text = (@self_service_user_removable == :always).to_s
- end
- end
+ add_self_service_macos_xml ssvc
+ add_self_service_notification_xml ssvc
+ end # add_self_service_xml
+
+ # add the correct XML indicating whether or not we're even in SSvc
+ def add_in_self_service_xml(doc_root)
return unless @self_service_data_config[:in_self_service_data_path]
in_ss_section, in_ss_elem = @self_service_data_config[:in_self_service_data_path]
in_ss_value = @in_self_service ? @self_service_data_config[:in_self_service] : @self_service_data_config[:not_in_self_service]
in_ss_section_xml = doc_root.elements[in_ss_section.to_s]
in_ss_section_xml ||= doc_root.add_element(in_ss_section.to_s)
in_ss_section_xml.add_element(in_ss_elem.to_s).text = in_ss_value.to_s
- end # add_self_service_xml
+ end
- # aliases
- alias change_self_service_category add_self_service_category
+ # add the xml specific to profiles
+ def add_self_service_profile_xml(ssvc, doc_root)
+ return unless self_service_payload == :profile
+ if self_service_targets.include? :ios
+ sec = ssvc.add_element('security')
+ sec.add_element('removal_disallowed').text = PROFILE_REMOVAL_BY_USER[@self_service_user_removable]
+ sec.add_element('password').text = @self_service_removal_password.to_s
+ return
+ end
+ gen = doc_root.elements['general']
+ gen.add_element('user_removable').text = (@self_service_user_removable == :always).to_s
+ end
+
+ # add the xml for self-service categories
+ def add_self_service_category_xml(ssvc)
+ cats = ssvc.add_element('self_service_categories')
+ return if self_service_categories.empty?
+ self_service_categories.each do |cat|
+ catelem = cats.add_element('category')
+ catelem.add_element('name').text = cat[:name]
+ catelem.add_element('display_in').text = cat[:display_in] if @self_service_data_config[:can_display_in_categories]
+ catelem.add_element('feature_in').text = cat[:feature_in] if @self_service_data_config[:can_feature_in_categories]
+ end
+ end
+
+ # set macOS settings in ssvc xml
+ def add_self_service_macos_xml(ssvc)
+ return unless self_service_targets.include? :macos
+ ssvc.add_element('self_service_display_name').text = self_service_display_name if self_service_display_name
+ ssvc.add_element('install_button_text').text = self_service_install_button_text if self_service_install_button_text
+ ssvc.add_element('reinstall_button_text').text = self_service_reinstall_button_text if self_service_reinstall_button_text
+ ssvc.add_element('force_users_to_view_description').text = self_service_force_users_to_view_description.to_s
+ end
+
+
+ # set ssvc notification settings in xml
+ def add_self_service_notification_xml(ssvc)
+ return unless @self_service_data_config[:notifications_supported]
+
+ # oldstyle/broken, only sscv notifs
+ if @self_service_data_config[:notifications_supported] == :ssvc_only
+ ssvc.add_element('notification').text = self_service_notifications_enabled.to_s
+ ssvc.add_element('notification_subject').text = self_service_notification_subject if self_service_notification_subject
+ ssvc.add_element('notification_message').text = self_service_notification_message if self_service_notification_message
+ return
+ end
+
+ # newstyle, 'notifications' subset
+ notif = ssvc.add_element('notifications')
+ notif.add_element('notifications_enabled').text = self_service_notifications_enabled.to_s
+ notif.add_element('notification_type').text = NOTIFICATION_TYPES[self_service_notification_type] if self_service_notification_type
+ notif.add_element('notification_subject').text = self_service_notification_subject if self_service_notification_subject
+ notif.add_element('notification_message').text = self_service_notification_message if self_service_notification_message
+
+ return unless @self_service_data_config[:notification_reminders]
+
+ reminds = notif.add_element('reminders')
+ reminds.add_element('notification_reminders_enabled').text = self_service_reminders_enabled.to_s
+ reminds.add_element('notification_reminder_frequency').text = self_service_reminder_frequency.to_s if self_service_reminder_frequency
+
+ end
+
+ # Raise an error if user_removable settings are wrong
+ def validate_user_removable(new_val)
+ raise JSS::UnsupportedError, 'User removal settings not applicable to this class' unless self_service_payload == :profile
+
+ raise JSS::UnsupportedError, 'Removal :with_auth not applicable to this class' if new_val == :with_auth && !self_service_targets.include?(:ios)
+
+ raise JSS::InvalidDataError, "Value must be one of: :#{PROFILE_REMOVAL_BY_USER.keys.join(', :')}" unless PROFILE_REMOVAL_BY_USER.key?(new_val)
+ end
+
+ # Raise an error if an icon id is not valid
+ def validate_icon(id)
+ return nil unless JSS::DB_CNX.connected?
+ raise JSS::NoSuchItemError, "No icon with id #{id}" unless JSS::Icon.all_ids.include? id
+ end
+
+ # Raise an error if notifications aren't supported
+ def validate_notifications_supported
+ raise JSS::UnsupportedError, "#{self.class} doesn't support Self Service notifications" unless @self_service_data_config[:notifications_supported]
+ end
+
+ # Raise an error if notification reminders aren't supported
+ def validate_notification_reminders_supported
+ raise JSS::UnsupportedError, "#{self.class} doesn't support Self Service notifications" unless @self_service_data_config[:notification_reminders]
+ end
end # module SelfServable
end # module JSS