Module: Jamf::SelfServable

Includes:
Uploadable
Included in:
ConfigurationProfile, MacApplication, MobileDeviceApplication, PatchPolicy, Policy
Defined in:
lib/jamf/api/classic/api_objects/self_servable.rb

Overview

A mix-in module for handling Self Service data for objects in the JSS.

The JSS objects that have Self Service data return it in a :self_service subset, which have somewhat similar data, i.e. a hash with at least these keys:

  • :self_service_description

  • :self_service_icon

  • :feature_on_main_page

  • :self_service_categories

Config Profiles in self service have this key:

  • :security

Additionally, items that apper in macOS Slf Svc have these keys:

  • :self_service_display_name (but not Jamf::MacApplication)

  • :install_button_text

  • :reinstall_button_text (but not Jamf::MacApplication)

  • :force_users_to_view_description

  • :notification

  • :notification_location # PENDING API FIX, and also, not Jamf::MacApplication

  • :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, e.g. #self_service_feature_on_main_page

Classes including this module MUST:

  • call #add_self_service_xml(xmldoc) in their #rest_xml method

IMPORTANT: Since SelfServable also includes #Uploadable, for uploading icons, see that module for its requirements.

Constant Summary collapse

SELF_SERVABLE =

Constants

true
PROFILE_REMOVAL_BY_USER =
{
  always: 'Always',
  never: 'Never',
  with_auth: 'With Authorization'
}.freeze
MAKE_AVAILABLE =
'Make Available in Self Service'.freeze
AUTO_INSTALL =
'Install Automatically'.freeze
AUTO_INSTALL_OR_PROMPT =
'Install Automatically/Prompt Users to Install'.freeze
PATCHPOL_SELF_SERVICE =

‘Make Available in Self Service’ in the UI

'selfservice'.freeze
PATCHPOL_AUTO =

‘Install Automatically’ in the UI

'prompt'.freeze
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
SELF_SERVICE_CLASSES =

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.

NOTE: The keys are the string versions of the Classes themselves, so that we don’t cause circular dependencies when loading these classes with zeitwerk

- in_self_service_data_path: Array, In the API data hash (the @init_data)
    where to find the value indicicating that a thing is in self service.
    e.g. [:self_service, :use_for_self_service] means
    @init_data[:self_service][:use_for_self_service]

- in_self_service: Object, In the path defined above, what value means
    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)

- can_display_in_categories: Boolean, when adding 'self service categories'
  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.

{
  'Jamf::Policy' => {
    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,
    notifications_supported: :ssvc_only,
    url_entity: 'policy'
  },
  'Jamf::PatchPolicy' => {
    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,
    notifications_supported: :ssvc_and_nctr,
    notification_reminders: true
  },
  'Jamf::MacApplication' => {
    in_self_service_data_path: i[general deployment_type],
    in_self_service: MAKE_AVAILABLE,
    not_in_self_service: AUTO_INSTALL_OR_PROMPT,
    targets: [:macos],
    payload: :app,
    can_display_in_categories: true,
    can_feature_in_categories: true,
    notifications_supported: :ssvc_and_nctr,
    url_entity: 'app'
    # OTHER BUG: no notification options seem to be changable via the API
  },
  'Jamf::OSXConfigurationProfile' => {
    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,
    notifications_supported: :ssvc_only,
    url_entity: 'configprofile'
  },
  'Jamf::Ebook' => {
    in_self_service_data_path: i[general deployment_type],
    in_self_service: MAKE_AVAILABLE,
    not_in_self_service: AUTO_INSTALL_OR_PROMPT,
    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,
    notifications_supported: :ssvc_only,
    url_entity: 'ebook'
  },
  'Jamf::MobileDeviceApplication' => {
    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
  },
  'Jamf::MobileDeviceConfigurationProfile' => {
    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,
    can_feature_in_categories: false
  }
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#iconJamf::Icon? Also known as: self_service_icon



247
248
249
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 247

def icon
  @icon
end

#in_self_serviceBoolean (readonly) Also known as: in_self_service?



243
244
245
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 243

def in_self_service
  @in_self_service
end

#self_service_categoriesArray<Hash> (readonly)

Each Hash has these keys about the category

  • :id => [Integer] the JSS id of the category

  • :name => [String] the name of the category

Most objects also include one or both of these keys:

  • :display_in => [Boolean] should the item be displayed in this category in SSvc? (not MobDevConfProfiles)

  • :feature_in => [Boolean] should the item be featured in this category in SSVC? (macOS targets only)



270
271
272
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 270

def self_service_categories
  @self_service_categories
end

#self_service_descriptionString



254
255
256
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 254

def self_service_description
  @self_service_description
end

#self_service_display_nameString Also known as: self_service_dislay_name



251
252
253
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 251

def self_service_display_name
  @self_service_display_name
end

#self_service_feature_on_main_pageBoolean

Only applicable to macOS targets



258
259
260
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 258

def self_service_feature_on_main_page
  @self_service_feature_on_main_page
end

#self_service_force_users_to_view_descriptionBoolean



301
302
303
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 301

def self_service_force_users_to_view_description
  @self_service_force_users_to_view_description
end

#self_service_install_button_textString

defaults to ‘Install’



294
295
296
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 294

def self_service_install_button_text
  @self_service_install_button_text
end

#self_service_notification_messageString



316
317
318
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 316

def self_service_notification_message
  @self_service_notification_message
end

#self_service_notification_subjectString

object name.



313
314
315
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 313

def self_service_notification_subject
  @self_service_notification_subject
end

#self_service_notification_typeSymbol



309
310
311
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 309

def self_service_notification_type
  @self_service_notification_type
end

#self_service_notifications_enabledBoolean Also known as: self_service_notifications_enabled?



304
305
306
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 304

def self_service_notifications_enabled
  @self_service_notifications_enabled
end

#self_service_reinstall_button_textString

defaults to ‘Reinstall’



298
299
300
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 298

def self_service_reinstall_button_text
  @self_service_reinstall_button_text
end

#self_service_reminder_frequencyInteger



324
325
326
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 324

def self_service_reminder_frequency
  @self_service_reminder_frequency
end

#self_service_reminders_enabledBoolean Also known as: self_service_reminders_enabled?



320
321
322
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 320

def self_service_reminders_enabled
  @self_service_reminders_enabled
end

#self_service_removal_passwordString (readonly)



290
291
292
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 290

def self_service_removal_password
  @self_service_removal_password
end

#self_service_user_removableSymbol



287
288
289
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 287

def self_service_user_removable
  @self_service_user_removable
end

Instance Method Details

#add_self_service_category(new_cat, display_in: true, feature_in: false) ⇒ void Also known as: set_self_service_category, change_self_service_category

This method returns an undefined value.

Add or change one of the categories for this item in self service



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 437

def add_self_service_category(new_cat, display_in: true, feature_in: false)
  new_cat = Jamf::Category.map_all_ids_to(:name, cnx: @cnx)[new_cat] if new_cat.is_a? Integer
  feature_in = false if display_in == false
  raise Jamf::NoSuchItemError, "No category '#{new_cat}' in the JSS" unless Jamf::Category.all_names(:refresh, cnx: @cnx).include? new_cat

  raise Jamf::InvalidDataError, 'display_in must be true or false' unless display_in.jss_boolean?

  raise Jamf::InvalidDataError, 'feature_in must be true or false' unless feature_in.jss_boolean?

  new_data = { name: new_cat }
  new_data[:display_in] = display_in if @self_service_data_config[:can_display_in_categories]
  new_data[:feature_in] = feature_in if @self_service_data_config[:can_feature_in_categories]

  # see if this category is already among our categories.
  idx = @self_service_categories.index { |c| c[:name] == new_cat }

  if idx
    @self_service_categories[idx] = new_data
  else
    @self_service_categories << new_data
  end

  @need_to_update = true
end

#add_to_self_servicevoid

This method returns an undefined value.

Add this object to self service if not already there.



623
624
625
626
627
628
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 623

def add_to_self_service
  return nil unless @self_service_data_config[:in_self_service_data_path]
  return nil if in_self_service?
  @in_self_service = true
  @need_to_update = true
end

#createObject

HACK: ity hack hack… remove when jamf fixes these bugs



677
678
679
680
681
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 677

def create
  resp = super
  force_notifications_on if @need_ss_notification_activation_hack
  resp
end

#remove_from_self_servicevoid

This method returns an undefined value.

Remove this object from self service if it’s there.



634
635
636
637
638
639
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 634

def remove_from_self_service
  return nil unless @self_service_data_config[:in_self_service_data_path]
  return nil unless in_self_service?
  @in_self_service = false
  @need_to_update = true
end

#remove_self_service_category(cat) ⇒ void

This method returns an undefined value.

Remove a category from those for this item in SSvc



470
471
472
473
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 470

def remove_self_service_category(cat)
  @self_service_categories.reject! { |c| c[:name] == cat || c[:id] == cat }
  @need_to_update = true
end

#self_service_execute_urlString



339
340
341
342
343
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 339

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

#self_service_payloadSymbol

What does this object deploy to the device via self service?



663
664
665
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 663

def self_service_payload
  @self_service_data_config[:payload]
end

#self_service_targetsArray<Symbol>

What devices types can get this thing in Self Service



654
655
656
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 654

def self_service_targets
  @self_service_data_config[:targets]
end

#self_service_view_urlString



331
332
333
334
335
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 331

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

#updateObject

HACK: ity hack hack… remove when jamf fixes these bugs



669
670
671
672
673
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 669

def update
  resp = super
  force_notifications_on if @need_ss_notification_activation_hack
  resp
end

#upload(type, local_file, force_ipa_upload: false) ⇒ Boolean Originally defined in module Uploadable

instance method wrapper for class method

Upload a file to the JSS to be stored with this instance of the class mixing in the Uploadable module

#user_removable?Boolean?

Can this thing be removed by the user?



645
646
647
648
# File 'lib/jamf/api/classic/api_objects/self_servable.rb', line 645

def user_removable?
  return nil unless self_service_payload == :profile
  @self_service_user_removable != :never
end