ruby-jss 1.0.3b3 → 1.0.3b4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e023160e63bd4d2ae22316affa806e28ad38559d17c9cc8e2f6624f8a72e2c09
4
- data.tar.gz: 24689091017132fb6a95e5fc6ea6ad36d771d660665df540bd82cd3856f05b3a
3
+ metadata.gz: 2b0bf5083913e6e9d2cf6588f229109ef8013fe64d5ea522c4a0031cc1ed2c88
4
+ data.tar.gz: 6cd578111688ad29bba7595e522a2bfd97b298e2c85fb7a3e14a4d92c8c50980
5
5
  SHA512:
6
- metadata.gz: 4200856d8cfdfa38e1dd3b6a4a86ea1aef995c9fd72e70bc5bf7205c86e817bc1edc9cc3cb06115b0b34ab5d117e73fac27dbc376152054dd9edb21649696a36
7
- data.tar.gz: f9dc27ad6c8398b6743c2ea654331ab8efabf1a5ee22747ac555fc598d0276de955a94edbdc8d29802df68abad706e72902b33b47ba3c14e31f4fbd997bbd976
6
+ metadata.gz: f1d0a5b50436e1c66dff5079ee1a1c1bb72298c527db8682adff99db986cca3c4993e02c01bdf5117e9be5e6c6020788a47d5c4eee4e1b744c7e54a9ea649021
7
+ data.tar.gz: 3913594f7506a232b29f004790645762a52f47fcae1968c35e3cd17c633cfe165d6d26ec35d8506c93cb5658cbf9c6b70f863de6f6da29d371381789f1f059ed
data/CHANGES.md CHANGED
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## \[Unreleased]
8
8
  ### Added
9
+ - JSS::Group (and its subclasses) now have a `change_membership` class and instance method for static groups.
10
+ - The class method allows adding and removing members without fetching an instance of the group.
11
+ - The instance method adds and/or removes members immediately, without needing to call #update or #save
12
+
9
13
  - LDAPServer.server_for_user and .server_for_group class methods, return the id of the first LDAP server containing the given user or group
10
14
 
11
15
  - Client.homdir(user) and Client.do_not_disturb?(user)
@@ -22,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
22
26
  (Thanks @christopher.kemp!)
23
27
 
24
28
  ### Fixed
29
+ - JSS::MobileDevice.update now returns the device's jss id, as advertised.
30
+
25
31
  - default port number choice for on-prem vs. JamfCloud connections
26
32
 
27
33
  - Client.primary_console_user returns nil when at the loginwindow
@@ -37,8 +37,13 @@ module JSS
37
37
  # When changing the criteria of a smart group, use the #criteria attribute,
38
38
  # which is a {JSS::Criteria} instance.
39
39
  #
40
- # Subclasses must define the constant MEMBER_CLASS which indicates Ruby class
41
- # to which the group members belong (e.g. JSS::MobileDevice)
40
+ # Subclasses must define these constants:
41
+ # - MEMBER_CLASS: the ruby-jss class to which the group
42
+ # members belong (e.g. JSS::MobileDevice)
43
+ # - ADD_MEMBERS_ELEMENT: the XML element tag for adding members to the group
44
+ # wuth a PUT call to the API, e.g. 'computer_additions'
45
+ # - REMOVE_MEMBERS_ELEMENT: the XML element tag for removing members from the
46
+ # group wuth a PUT call to the API, e.g. 'computer_deletions'
42
47
  #
43
48
  # @see JSS::APIObject
44
49
  #
@@ -62,6 +67,9 @@ module JSS
62
67
  # Where is the Site data in the API JSON?
63
68
  SITE_SUBSET = :top
64
69
 
70
+ # the 'id' xml element tag
71
+ ID_XML_TAG = 'id'.freeze
72
+
65
73
  # Class Methods
66
74
  #####################################
67
75
 
@@ -79,6 +87,103 @@ module JSS
79
87
  all(refresh, api: api).select { |g| (g[:is_smart]) }
80
88
  end
81
89
 
90
+ # Immediatly add and/or remove members in a static group without
91
+ # instantiating it first. Uses the <x_additions> and <x_deletions>
92
+ # XML elements available when sending a PUT request to the API.
93
+ #
94
+ # @param group [String, Integer] The name or id of the group being changed
95
+ #
96
+ # @param add_members [String, Integer, Array<String, Integer>] valid
97
+ # identifier(s) for members to add
98
+ #
99
+ # @param remove_members [String, Integer, Array<String, Integer>] valid
100
+ # identifier(s) for members to remove
101
+ #
102
+ # @param api [JSS::APIConnection] The API connetion to use, uses the default
103
+ # connection if not specified
104
+ #
105
+ # @return [void]
106
+ #
107
+ def self.change_membership(group, add_members: [], remove_members: [], api: JSS.api)
108
+ raise JSS::NoSuchItemError, "No #{self} matching '#{ident}'" unless (group_id = valid_id group, api: api)
109
+ raise JSS::UnsupportedError, "Not a static group, can't change membership directly" if map_all_ids_to(:is_smart, api: api)[group_id]
110
+
111
+ add_members = [add_members].flatten
112
+ remove_members = [remove_members].flatten
113
+ return if add_members.empty? && remove_members.empty?
114
+
115
+ # we must know the current group membership, because the API
116
+ # will raise a conflict error if we try to remove a member
117
+ # that isn't in the group (which is kinda lame - it should just
118
+ # ignore this, like it does when we add a member that's already
119
+ # in the group.)
120
+ current_member_ids = fetch(id: group_id).member_ids
121
+
122
+ # nil if no changes to be made
123
+ xml_doc = change_membership_xml add_members, remove_members, current_member_ids
124
+ return unless xml_doc
125
+
126
+ api.put_rsrc "#{self::RSRC_BASE}/id/#{group_id}", xml_doc.to_s
127
+ end
128
+
129
+ # return [REXML::Document, nil]
130
+ #
131
+ def self.change_membership_xml(add_members, remove_members, current_member_ids)
132
+ # these are nil if there are no changes to make
133
+ addx = member_additions_xml(add_members, current_member_ids)
134
+ remx = member_removals_xml(remove_members, current_member_ids)
135
+ return nil unless addx || remx
136
+
137
+ doc = REXML::Document.new JSS::APIConnection::XML_HEADER
138
+ groupelem = doc.add_element self::RSRC_OBJECT_KEY.to_s
139
+ groupelem << addx if addx
140
+ groupelem << remx if remx
141
+ doc
142
+ end
143
+ private_class_method :change_membership_xml
144
+
145
+ # @return [REXML::Element, nil]
146
+ #
147
+ def self.member_additions_xml(add_members, current_member_ids)
148
+ return nil if add_members.empty?
149
+
150
+ additions = REXML::Element.new self::ADD_MEMBERS_ELEMENT
151
+ member_added = false
152
+ add_members.each do |am|
153
+ am_id = self::MEMBER_CLASS.valid_id am
154
+ raise JSS::NoSuchItemError, "No #{self::MEMBER_CLASS} matching '#{am}'" unless am_id
155
+ next if current_member_ids.include? am_id
156
+
157
+ xam = additions.add_element self::MEMBER_CLASS::RSRC_OBJECT_KEY.to_s
158
+ xam.add_element(ID_XML_TAG).text = am_id.to_s
159
+ member_added = true
160
+ end # each
161
+
162
+ member_added ? additions : nil
163
+ end
164
+ private_class_method :member_additions_xml
165
+
166
+ # @return [REXML::Element, nil]
167
+ #
168
+ def self.member_removals_xml(remove_members, current_member_ids)
169
+ return nil if remove_members.empty?
170
+
171
+ removals = REXML::Element.new self::REMOVE_MEMBERS_ELEMENT
172
+ member_removed = false
173
+ remove_members.each do |rm|
174
+ rm_id = self::MEMBER_CLASS.valid_id rm
175
+ next unless rm_id && current_member_ids.include?(rm_id)
176
+
177
+ xrm = removals.add_element self::MEMBER_CLASS::RSRC_OBJECT_KEY.to_s
178
+ xrm.add_element(ID_XML_TAG).text = rm_id.to_s
179
+ member_removed = true
180
+ end # each
181
+
182
+ member_removed ? removals : nil
183
+ end
184
+ private_class_method :member_removals_xml
185
+
186
+
82
187
  # Attributes
83
188
  #####################################
84
189
 
@@ -100,8 +205,6 @@ module JSS
100
205
  # @return [Boolean] does this group send notifications when it changes?
101
206
  attr_reader :notify_on_change
102
207
 
103
- # @return [String] the :name of the site for this group
104
- attr_reader :site
105
208
 
106
209
  # Constructor
107
210
  #####################################
@@ -126,8 +229,6 @@ module JSS
126
229
  else
127
230
  []
128
231
  end
129
-
130
- @site = JSS::APIObject.get_name(@init_data[:site])
131
232
  end # init
132
233
 
133
234
  # Public Instance Methods
@@ -149,7 +250,7 @@ module JSS
149
250
  def update
150
251
  super
151
252
  refresh_members
152
- true
253
+ @id
153
254
  end
154
255
 
155
256
  # @see APIObject#delete
@@ -253,24 +354,33 @@ module JSS
253
354
  @need_to_update = true
254
355
  end
255
356
 
256
- # Refresh the membership from the API
357
+ # Immediatly add and/or remove members in this static group
257
358
  #
258
- # @return [Array<Hash>] the refresh membership
359
+ # IMPORTANT: This method changes the group in the JSS immediately,
360
+ # there is no need to call #update/#save
259
361
  #
260
- def refresh_members
261
- @members = @api.get_rsrc(@rest_rsrc)[self.class::RSRC_OBJECT_KEY][self.class::MEMBER_CLASS::RSRC_LIST_KEY]
262
- end
263
-
264
- # Change the site for this group
362
+ # @param add_members [String, Integer, Array<String, Integer>] valid
363
+ # identifier(s) for members to add
364
+ #
365
+ # @param remove_members [String, Integer, Array<String, Integer>] valid
366
+ # identifier(s) for members to remove
265
367
  #
266
- # @param new_val[String] the name of the new site
368
+ # @param api [JSS::APIConnection] The API connetion to use, uses the default
369
+ # connection if not specified
267
370
  #
268
371
  # @return [void]
269
372
  #
270
- def site=(new_val)
271
- raise JSS::NoSuchItemError, "No site named #{new_val} in the JSS" unless JSS::Site.all_names(api: @api).include? new_val
272
- @site = new_val
273
- @need_to_update = true
373
+ def change_membership(add_members: [], remove_members: [])
374
+ self.class.change_membership(@id, add_members: add_members, remove_members: remove_members, api: @api)
375
+ refresh_members
376
+ end
377
+
378
+ # Refresh the membership from the API
379
+ #
380
+ # @return [Array<Hash>] the refresh membership
381
+ #
382
+ def refresh_members
383
+ @members = @api.get_rsrc(@rest_rsrc)[self.class::RSRC_OBJECT_KEY][self.class::MEMBER_CLASS::RSRC_LIST_KEY]
274
384
  end
275
385
 
276
386
  # aliases
@@ -82,6 +82,12 @@ module JSS
82
82
  ### this allows the parent Group class to do things right
83
83
  MEMBER_CLASS = JSS::Computer
84
84
 
85
+ # the XML element for immediate member additions via PUT
86
+ ADD_MEMBERS_ELEMENT = 'computer_additions'.freeze
87
+
88
+ # the XML element for immediate member removals via PUT
89
+ REMOVE_MEMBERS_ELEMENT = 'computer_deletions'.freeze
90
+
85
91
  # the object type for this object in
86
92
  # the object history table.
87
93
  # See {APIObject#add_object_history_entry}
@@ -78,6 +78,12 @@ module JSS
78
78
  ### this allows the parent Group class to do things right
79
79
  MEMBER_CLASS = JSS::MobileDevice
80
80
 
81
+ # the XML element for immediate member additions via PUT
82
+ ADD_MEMBERS_ELEMENT = 'mobile_device_additions'.freeze
83
+
84
+ # the XML element for immediate member removals via PUT
85
+ REMOVE_MEMBERS_ELEMENT = 'mobile_device_deletions'.freeze
86
+
81
87
  # the object type for this object in
82
88
  # the object history table.
83
89
  # See {APIObject#add_object_history_entry}
@@ -78,6 +78,12 @@ module JSS
78
78
  ### this allows the parent Group class to do things right
79
79
  MEMBER_CLASS = JSS::User
80
80
 
81
+ # the XML element for immediate member additions via PUT
82
+ ADD_MEMBERS_ELEMENT = 'user_additions'.freeze
83
+
84
+ # the XML element for immediate member removals via PUT
85
+ REMOVE_MEMBERS_ELEMENT = 'user_deletions'.freeze
86
+
81
87
  # the object type for this object in
82
88
  # the object history table.
83
89
  # See {APIObject#add_object_history_entry}
@@ -523,9 +523,10 @@ module JSS
523
523
  #
524
524
  def update
525
525
  super
526
- return unless @needs_mdm_name_change
526
+ return @id unless @needs_mdm_name_change
527
527
  set_device_name @name if managed? && supervised?
528
528
  @needs_mdm_name_change = false
529
+ @id
529
530
  end
530
531
 
531
532
  # private methods
@@ -27,6 +27,6 @@
27
27
  module JSS
28
28
 
29
29
  ### The version of the JSS ruby gem
30
- VERSION = '1.0.3b3'.freeze
30
+ VERSION = '1.0.3b4'.freeze
31
31
 
32
32
  end # module
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-jss
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3b3
4
+ version: 1.0.3b4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Lasell
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-03-15 00:00:00.000000000 Z
12
+ date: 2019-03-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: plist