scimitar 1.10.0 → 2.0.0
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.
- checksums.yaml +4 -4
- data/app/controllers/scimitar/active_record_backed_resources_controller.rb +23 -98
- data/app/controllers/scimitar/application_controller.rb +13 -41
- data/app/controllers/scimitar/resource_types_controller.rb +2 -0
- data/app/controllers/scimitar/resources_controller.rb +2 -0
- data/app/controllers/scimitar/schemas_controller.rb +3 -366
- data/app/controllers/scimitar/service_provider_configurations_controller.rb +1 -0
- data/app/models/scimitar/complex_types/address.rb +6 -0
- data/app/models/scimitar/engine_configuration.rb +5 -15
- data/app/models/scimitar/error_response.rb +0 -12
- data/app/models/scimitar/lists/query_parser.rb +13 -113
- data/app/models/scimitar/resource_invalid_error.rb +1 -1
- data/app/models/scimitar/resources/base.rb +9 -53
- data/app/models/scimitar/resources/mixin.rb +59 -646
- data/app/models/scimitar/schema/address.rb +0 -1
- data/app/models/scimitar/schema/attribute.rb +5 -14
- data/app/models/scimitar/schema/base.rb +1 -1
- data/app/models/scimitar/schema/name.rb +2 -2
- data/app/models/scimitar/schema/user.rb +10 -10
- data/app/models/scimitar/schema/vdtp.rb +1 -1
- data/app/models/scimitar/service_provider_configuration.rb +3 -14
- data/config/initializers/scimitar.rb +3 -69
- data/lib/scimitar/engine.rb +12 -57
- data/lib/scimitar/support/hash_with_indifferent_case_insensitive_access.rb +10 -140
- data/lib/scimitar/version.rb +2 -2
- data/lib/scimitar.rb +2 -7
- data/spec/apps/dummy/app/controllers/mock_groups_controller.rb +1 -1
- data/spec/apps/dummy/app/models/mock_group.rb +1 -1
- data/spec/apps/dummy/app/models/mock_user.rb +9 -52
- data/spec/apps/dummy/config/application.rb +1 -0
- data/spec/apps/dummy/config/environments/test.rb +28 -5
- data/spec/apps/dummy/config/initializers/scimitar.rb +10 -90
- data/spec/apps/dummy/config/routes.rb +7 -28
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -11
- data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +3 -8
- data/spec/apps/dummy/db/schema.rb +4 -12
- data/spec/controllers/scimitar/application_controller_spec.rb +3 -126
- data/spec/controllers/scimitar/resource_types_controller_spec.rb +2 -2
- data/spec/controllers/scimitar/schemas_controller_spec.rb +48 -344
- data/spec/models/scimitar/complex_types/address_spec.rb +4 -3
- data/spec/models/scimitar/complex_types/email_spec.rb +2 -0
- data/spec/models/scimitar/lists/query_parser_spec.rb +9 -146
- data/spec/models/scimitar/resources/base_spec.rb +71 -217
- data/spec/models/scimitar/resources/base_validation_spec.rb +5 -43
- data/spec/models/scimitar/resources/mixin_spec.rb +129 -1508
- data/spec/models/scimitar/schema/attribute_spec.rb +3 -22
- data/spec/models/scimitar/schema/base_spec.rb +1 -1
- data/spec/models/scimitar/schema/user_spec.rb +2 -12
- data/spec/requests/active_record_backed_resources_controller_spec.rb +66 -1016
- data/spec/requests/application_controller_spec.rb +3 -16
- data/spec/requests/engine_spec.rb +0 -75
- data/spec/spec_helper.rb +1 -9
- data/spec/support/hash_with_indifferent_case_insensitive_access_spec.rb +0 -108
- metadata +26 -37
- data/LICENSE.txt +0 -21
- data/README.md +0 -717
- data/lib/scimitar/support/utilities.rb +0 -111
- data/spec/apps/dummy/app/controllers/custom_create_mock_users_controller.rb +0 -25
- data/spec/apps/dummy/app/controllers/custom_replace_mock_users_controller.rb +0 -25
- data/spec/apps/dummy/app/controllers/custom_save_mock_users_controller.rb +0 -24
- data/spec/apps/dummy/app/controllers/custom_update_mock_users_controller.rb +0 -25
@@ -81,102 +81,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
81
81
|
include Scimitar::Resources::Mixin
|
82
82
|
end
|
83
83
|
|
84
|
-
# A simple schema containing two attributes that looks very like complex
|
85
|
-
# type "name", except shorter and with "familyName" never returned.
|
86
|
-
#
|
87
|
-
NestedReturnedNeverTestNameSchema = Class.new(Scimitar::Schema::Base) do
|
88
|
-
def self.id
|
89
|
-
'nested-returned-never-name-id'
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.scim_attributes
|
93
|
-
@scim_attributes ||= [
|
94
|
-
Scimitar::Schema::Attribute.new(name: 'familyName', type: 'string', required: true, returned: 'never'),
|
95
|
-
Scimitar::Schema::Attribute.new(name: 'givenName', type: 'string', required: true)
|
96
|
-
]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
# A complex type that uses the above schema, giving us the ability to define
|
101
|
-
# an attribute using this complex type, with therefore the *nested* attribute
|
102
|
-
# "familyName" being never returned.
|
103
|
-
#
|
104
|
-
NestedReturnedNeverTestNameType = Class.new(Scimitar::ComplexTypes::Base) do
|
105
|
-
set_schema NestedReturnedNeverTestNameSchema
|
106
|
-
end
|
107
|
-
|
108
|
-
# A test schema that uses the above type, the standard name type (but that
|
109
|
-
# *entire* top-level attribute is never returned) and a simple String item.
|
110
|
-
#
|
111
|
-
NestedReturnedNeverTestSchema = Class.new(Scimitar::Schema::Base) do
|
112
|
-
def self.id
|
113
|
-
'nested-returned-never-id'
|
114
|
-
end
|
115
|
-
|
116
|
-
def self.scim_attributes
|
117
|
-
[
|
118
|
-
Scimitar::Schema::Attribute.new(
|
119
|
-
name: 'name', complexType: NestedReturnedNeverTestNameType
|
120
|
-
),
|
121
|
-
Scimitar::Schema::Attribute.new(
|
122
|
-
name: 'privateName', complexType: Scimitar::ComplexTypes::Name, returned: 'never'
|
123
|
-
),
|
124
|
-
Scimitar::Schema::Attribute.new(
|
125
|
-
name: 'simpleName', type: 'string'
|
126
|
-
)
|
127
|
-
]
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# Define a resource that is based upon the above schema.
|
132
|
-
#
|
133
|
-
NestedReturnedNeverTestResourse = Class.new(Scimitar::Resources::Base) do
|
134
|
-
set_schema NestedReturnedNeverTestSchema
|
135
|
-
end
|
136
|
-
|
137
|
-
# Create a testable model that is our internal representation of the above
|
138
|
-
# resource.
|
139
|
-
#
|
140
|
-
class NestedReturnedNeverTest
|
141
|
-
include ActiveModel::Model
|
142
|
-
|
143
|
-
def self.scim_resource_type
|
144
|
-
return NestedReturnedNeverTestResourse
|
145
|
-
end
|
146
|
-
|
147
|
-
attr_accessor :given_name,
|
148
|
-
:last_name,
|
149
|
-
:private_given_name,
|
150
|
-
:private_last_name,
|
151
|
-
:simple_name
|
152
|
-
|
153
|
-
def self.scim_attributes_map
|
154
|
-
return {
|
155
|
-
name: {
|
156
|
-
givenName: :given_name,
|
157
|
-
familyName: :last_name
|
158
|
-
},
|
159
|
-
|
160
|
-
privateName: {
|
161
|
-
givenName: :private_given_name,
|
162
|
-
familyName: :private_last_name
|
163
|
-
},
|
164
|
-
|
165
|
-
simpleName: :simple_name
|
166
|
-
}
|
167
|
-
end
|
168
|
-
|
169
|
-
def self.scim_mutable_attributes
|
170
|
-
return nil
|
171
|
-
end
|
172
|
-
|
173
|
-
def self.scim_queryable_attributes
|
174
|
-
return nil
|
175
|
-
end
|
176
|
-
|
177
|
-
include Scimitar::Resources::Mixin
|
178
|
-
end
|
179
|
-
|
180
84
|
# ===========================================================================
|
181
85
|
# Errant class definitions
|
182
86
|
# ===========================================================================
|
@@ -255,127 +159,41 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
255
159
|
# =========================================================================
|
256
160
|
|
257
161
|
context '#to_scim' do
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User',
|
294
|
-
'urn:ietf:params:scim:schemas:extension:manager:1.0:User',
|
295
|
-
],
|
296
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {
|
297
|
-
'organization' => 'SOMEORG',
|
298
|
-
},
|
299
|
-
'urn:ietf:params:scim:schemas:extension:manager:1.0:User' => {},
|
300
|
-
})
|
301
|
-
end
|
302
|
-
end # "context 'with list of requested attributes' do"
|
303
|
-
|
304
|
-
context 'with a UUID, renamed primary key column' do
|
305
|
-
it 'compiles instance attribute values into a SCIM representation, but omits do-not-return fields' do
|
306
|
-
uuid = SecureRandom.uuid
|
307
|
-
|
308
|
-
instance = MockUser.new
|
309
|
-
instance.primary_key = uuid
|
310
|
-
instance.scim_uid = 'AA02984'
|
311
|
-
instance.username = 'foo'
|
312
|
-
instance.password = 'correcthorsebatterystaple'
|
313
|
-
instance.first_name = 'Foo'
|
314
|
-
instance.last_name = 'Bar'
|
315
|
-
instance.work_email_address = 'foo.bar@test.com'
|
316
|
-
instance.home_email_address = nil
|
317
|
-
instance.work_phone_number = '+642201234567'
|
318
|
-
instance.organization = 'SOMEORG'
|
319
|
-
|
320
|
-
g1 = MockGroup.create!(display_name: 'Group 1')
|
321
|
-
g2 = MockGroup.create!(display_name: 'Group 2')
|
322
|
-
g3 = MockGroup.create!(display_name: 'Group 3')
|
323
|
-
|
324
|
-
g1.mock_users << instance
|
325
|
-
g3.mock_users << instance
|
326
|
-
|
327
|
-
scim = instance.to_scim(location: "https://test.com/mock_users/#{uuid}")
|
328
|
-
json = scim.to_json()
|
329
|
-
hash = JSON.parse(json)
|
330
|
-
|
331
|
-
expect(hash).to eql({
|
332
|
-
'userName' => 'foo',
|
333
|
-
'name' => {'givenName'=>'Foo', 'familyName'=>'Bar'},
|
334
|
-
'active' => true,
|
335
|
-
'emails' => [{'type'=>'work', 'primary'=>true, 'value'=>'foo.bar@test.com'}, {"primary"=>false, "type"=>"home", "value"=>nil}],
|
336
|
-
'phoneNumbers'=> [{'type'=>'work', 'primary'=>false, 'value'=>'+642201234567'}],
|
337
|
-
'id' => uuid,
|
338
|
-
'externalId' => 'AA02984',
|
339
|
-
'groups' => [{'display'=>g1.display_name, 'value'=>g1.id.to_s}, {'display'=>g3.display_name, 'value'=>g3.id.to_s}],
|
340
|
-
'meta' => {'location'=>"https://test.com/mock_users/#{uuid}", 'resourceType'=>'User'},
|
341
|
-
'schemas' => [
|
342
|
-
'urn:ietf:params:scim:schemas:core:2.0:User',
|
343
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User',
|
344
|
-
'urn:ietf:params:scim:schemas:extension:manager:1.0:User',
|
345
|
-
],
|
346
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {
|
347
|
-
'organization' => 'SOMEORG',
|
348
|
-
'department' => nil,
|
349
|
-
'primaryEmail' => instance.work_email_address,
|
350
|
-
},
|
351
|
-
'urn:ietf:params:scim:schemas:extension:manager:1.0:User' => {
|
352
|
-
'manager' => nil
|
353
|
-
},
|
354
|
-
})
|
355
|
-
end
|
356
|
-
end # "context 'with a UUID, renamed primary key column' do"
|
357
|
-
|
358
|
-
context 'with an integer, conventionally named primary key column' do
|
359
|
-
it 'compiles instance attribute values into a SCIM representation' do
|
360
|
-
instance = MockGroup.new
|
361
|
-
instance.id = 42
|
362
|
-
instance.scim_uid = 'GG02984'
|
363
|
-
instance.display_name = 'Some group'
|
364
|
-
|
365
|
-
scim = instance.to_scim(location: 'https://test.com/mock_groups/42')
|
366
|
-
json = scim.to_json()
|
367
|
-
hash = JSON.parse(json)
|
368
|
-
|
369
|
-
expect(hash).to eql({
|
370
|
-
'displayName' => 'Some group',
|
371
|
-
'id' => '42', # Note, String
|
372
|
-
'externalId' => 'GG02984',
|
373
|
-
'members' => [],
|
374
|
-
'meta' => {'location'=>'https://test.com/mock_groups/42', 'resourceType'=>'Group'},
|
375
|
-
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:Group']
|
376
|
-
})
|
377
|
-
end
|
378
|
-
end # "context 'with an integer, conventionally named primary key column' do"
|
162
|
+
it 'compiles instance attribute values into a SCIM representation' do
|
163
|
+
instance = MockUser.new
|
164
|
+
instance.id = 42
|
165
|
+
instance.scim_uid = 'AA02984'
|
166
|
+
instance.username = 'foo'
|
167
|
+
instance.first_name = 'Foo'
|
168
|
+
instance.last_name = 'Bar'
|
169
|
+
instance.work_email_address = 'foo.bar@test.com'
|
170
|
+
instance.home_email_address = nil
|
171
|
+
instance.work_phone_number = '+642201234567'
|
172
|
+
|
173
|
+
g1 = MockGroup.create!(display_name: 'Group 1')
|
174
|
+
g2 = MockGroup.create!(display_name: 'Group 2')
|
175
|
+
g3 = MockGroup.create!(display_name: 'Group 3')
|
176
|
+
|
177
|
+
g1.mock_users << instance
|
178
|
+
g3.mock_users << instance
|
179
|
+
|
180
|
+
scim = instance.to_scim(location: 'https://test.com/mock_users/42')
|
181
|
+
json = scim.to_json()
|
182
|
+
hash = JSON.parse(json)
|
183
|
+
|
184
|
+
expect(hash).to eql({
|
185
|
+
'userName' => 'foo',
|
186
|
+
'name' => {'givenName'=>'Foo', 'familyName'=>'Bar'},
|
187
|
+
'active' => true,
|
188
|
+
'emails' => [{'type'=>'work', 'primary'=>true, 'value'=>'foo.bar@test.com'}, {"primary"=>false, "type"=>"home", "value"=>nil}],
|
189
|
+
'phoneNumbers'=> [{'type'=>'work', 'primary'=>false, 'value'=>'+642201234567'}],
|
190
|
+
'id' => '42', # Note, String
|
191
|
+
'externalId' => 'AA02984',
|
192
|
+
'groups' => [{'display'=>g1.display_name, 'value'=>g1.id.to_s}, {'display'=>g3.display_name, 'value'=>g3.id.to_s}],
|
193
|
+
'meta' => {'location'=>'https://test.com/mock_users/42', 'resourceType'=>'User'},
|
194
|
+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
|
195
|
+
})
|
196
|
+
end
|
379
197
|
|
380
198
|
context 'with optional timestamps' do
|
381
199
|
context 'creation only' do
|
@@ -474,13 +292,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
474
292
|
],
|
475
293
|
|
476
294
|
'meta' => {'location'=>'https://test.com/static_map_test', 'resourceType'=>'User'},
|
477
|
-
'schemas' => [
|
478
|
-
'urn:ietf:params:scim:schemas:core:2.0:User',
|
479
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User',
|
480
|
-
'urn:ietf:params:scim:schemas:extension:manager:1.0:User',
|
481
|
-
],
|
482
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {},
|
483
|
-
'urn:ietf:params:scim:schemas:extension:manager:1.0:User' => {},
|
295
|
+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
|
484
296
|
})
|
485
297
|
end
|
486
298
|
end # "context 'using static mappings' do"
|
@@ -507,42 +319,12 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
507
319
|
],
|
508
320
|
|
509
321
|
'meta' => {'location'=>'https://test.com/dynamic_map_test', 'resourceType'=>'User'},
|
510
|
-
'schemas' => [
|
511
|
-
'urn:ietf:params:scim:schemas:core:2.0:User',
|
512
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User',
|
513
|
-
'urn:ietf:params:scim:schemas:extension:manager:1.0:User',
|
514
|
-
],
|
515
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {},
|
516
|
-
'urn:ietf:params:scim:schemas:extension:manager:1.0:User' => {},
|
322
|
+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
|
517
323
|
})
|
518
324
|
end
|
519
325
|
end # "context 'using dynamic lists' do"
|
520
326
|
end # "context 'with arrays' do"
|
521
327
|
|
522
|
-
context 'with "returned: \'never\' fields' do
|
523
|
-
it 'hides appropriate top-level and nested attributes' do
|
524
|
-
instance = NestedReturnedNeverTest.new(
|
525
|
-
given_name: 'One',
|
526
|
-
last_name: 'Two',
|
527
|
-
private_given_name: 'Three',
|
528
|
-
private_last_name: 'Four',
|
529
|
-
simple_name: 'Five'
|
530
|
-
)
|
531
|
-
|
532
|
-
scim = instance.to_scim(location: 'https://test.com/never_retutrned_test')
|
533
|
-
json = scim.to_json()
|
534
|
-
hash = JSON.parse(json)
|
535
|
-
|
536
|
-
expect(hash).to eql({
|
537
|
-
'name' => { 'givenName' => 'One' },
|
538
|
-
'simpleName' => 'Five',
|
539
|
-
|
540
|
-
'meta' => {'location'=>'https://test.com/never_retutrned_test', 'resourceType'=>'NestedReturnedNeverTestResourse'},
|
541
|
-
'schemas' => ['nested-returned-never-id']
|
542
|
-
})
|
543
|
-
end
|
544
|
-
end # "context 'with "returned: \'never\' fields' do"
|
545
|
-
|
546
328
|
context 'with bad definitions' do
|
547
329
|
it 'complains about non-Hash entries in mapping Arrays' do
|
548
330
|
expect(StaticMapTest).to receive(:scim_attributes_map).and_return({
|
@@ -586,7 +368,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
586
368
|
it 'ignoring read-only lists' do
|
587
369
|
hash = {
|
588
370
|
'userName' => 'foo',
|
589
|
-
'password' => 'staplebatteryhorsecorrect',
|
590
371
|
'name' => {'givenName' => 'Foo', 'familyName' => 'Bar'},
|
591
372
|
'active' => true,
|
592
373
|
'emails' => [{'type' => 'work', 'primary' => true, 'value' => 'foo.bar@test.com'}],
|
@@ -595,12 +376,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
595
376
|
'id' => '42', # Note, String
|
596
377
|
'externalId' => 'AA02984',
|
597
378
|
'meta' => {'location' => 'https://test.com/mock_users/42', 'resourceType' => 'User'},
|
598
|
-
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User'
|
599
|
-
|
600
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {
|
601
|
-
'organization' => 'SOMEORG',
|
602
|
-
'DEPARTMENT' => 'SOMEDPT'
|
603
|
-
}
|
379
|
+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
|
604
380
|
}
|
605
381
|
|
606
382
|
hash = spec_helper_hupcase(hash) if force_upper_case
|
@@ -611,14 +387,11 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
611
387
|
|
612
388
|
expect(instance.scim_uid ).to eql('AA02984')
|
613
389
|
expect(instance.username ).to eql('foo')
|
614
|
-
expect(instance.password ).to eql('staplebatteryhorsecorrect')
|
615
390
|
expect(instance.first_name ).to eql('Foo')
|
616
391
|
expect(instance.last_name ).to eql('Bar')
|
617
392
|
expect(instance.work_email_address).to eql('foo.bar@test.com')
|
618
393
|
expect(instance.home_email_address).to be_nil
|
619
394
|
expect(instance.work_phone_number ).to eql('+642201234567')
|
620
|
-
expect(instance.organization ).to eql('SOMEORG')
|
621
|
-
expect(instance.department ).to eql('SOMEDPT')
|
622
395
|
end
|
623
396
|
|
624
397
|
it 'honouring read-write lists' do
|
@@ -632,8 +405,8 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
632
405
|
'displayName' => 'Foo Group',
|
633
406
|
'members' => [
|
634
407
|
{'type' => 'Group', 'value' => g1.id.to_s},
|
635
|
-
{'type' => 'User', 'value' => u1.
|
636
|
-
{'type' => 'User', 'value' => u3.
|
408
|
+
{'type' => 'User', 'value' => u1.id.to_s},
|
409
|
+
{'type' => 'User', 'value' => u3.id.to_s}
|
637
410
|
],
|
638
411
|
'externalId' => 'GG01536',
|
639
412
|
'meta' => {'location'=>'https://test.com/mock_groups/1', 'resourceType'=>'Group'},
|
@@ -680,10 +453,8 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
680
453
|
end # "context 'using upper case' do"
|
681
454
|
|
682
455
|
it 'clears things not present in input' do
|
683
|
-
uuid = SecureRandom.uuid
|
684
|
-
|
685
456
|
instance = MockUser.new
|
686
|
-
instance.
|
457
|
+
instance.id = 42
|
687
458
|
instance.scim_uid = 'AA02984'
|
688
459
|
instance.username = 'foo'
|
689
460
|
instance.first_name = 'Foo'
|
@@ -694,7 +465,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
694
465
|
|
695
466
|
instance.from_scim!(scim_hash: {})
|
696
467
|
|
697
|
-
expect(instance.
|
468
|
+
expect(instance.id ).to eql(42)
|
698
469
|
expect(instance.scim_uid ).to be_nil
|
699
470
|
expect(instance.username ).to be_nil
|
700
471
|
expect(instance.first_name ).to be_nil
|
@@ -883,8 +654,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
883
654
|
nature: 'add',
|
884
655
|
path: path,
|
885
656
|
value: 'foo',
|
886
|
-
altering_hash: scim_hash
|
887
|
-
with_attr_map: { userName: :user_name }
|
657
|
+
altering_hash: scim_hash
|
888
658
|
)
|
889
659
|
|
890
660
|
expect(scim_hash['userName']).to eql('foo')
|
@@ -899,30 +669,13 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
899
669
|
nature: 'add',
|
900
670
|
path: path,
|
901
671
|
value: 'Baz',
|
902
|
-
altering_hash: scim_hash
|
903
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
672
|
+
altering_hash: scim_hash
|
904
673
|
)
|
905
674
|
|
906
675
|
expect(scim_hash['name']['givenName' ]).to eql('Baz')
|
907
676
|
expect(scim_hash['name']['familyName']).to eql('Bar')
|
908
677
|
end
|
909
678
|
|
910
|
-
it 'with schema extensions: overwrites' do
|
911
|
-
path = [ 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User', 'organization' ]
|
912
|
-
scim_hash = { 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => { 'organization' => 'SOMEORG' } }.with_indifferent_case_insensitive_access()
|
913
|
-
|
914
|
-
@instance.send(
|
915
|
-
:from_patch_backend!,
|
916
|
-
nature: 'add',
|
917
|
-
path: path,
|
918
|
-
value: 'OTHERORG',
|
919
|
-
altering_hash: scim_hash,
|
920
|
-
with_attr_map: { organization: :org_name }
|
921
|
-
)
|
922
|
-
|
923
|
-
expect(scim_hash['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['organization' ]).to eql('OTHERORG')
|
924
|
-
end
|
925
|
-
|
926
679
|
# For 'add', filter at end-of-path is nonsensical and not
|
927
680
|
# supported by spec or Scimitar; we only test mid-path filters.
|
928
681
|
#
|
@@ -947,13 +700,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
947
700
|
nature: 'add',
|
948
701
|
path: path,
|
949
702
|
value: 'added_over_original@test.com',
|
950
|
-
altering_hash: scim_hash
|
951
|
-
with_attr_map: {
|
952
|
-
emails: [
|
953
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
954
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
955
|
-
]
|
956
|
-
}
|
703
|
+
altering_hash: scim_hash
|
957
704
|
)
|
958
705
|
|
959
706
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -979,13 +726,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
979
726
|
nature: 'add',
|
980
727
|
path: path,
|
981
728
|
value: 'added_over_original@test.com',
|
982
|
-
altering_hash: scim_hash
|
983
|
-
with_attr_map: {
|
984
|
-
emails: [
|
985
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
986
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
987
|
-
]
|
988
|
-
}
|
729
|
+
altering_hash: scim_hash
|
989
730
|
)
|
990
731
|
|
991
732
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -1012,13 +753,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1012
753
|
nature: 'add',
|
1013
754
|
path: path,
|
1014
755
|
value: 'added_over_original@test.com',
|
1015
|
-
altering_hash: scim_hash
|
1016
|
-
with_attr_map: {
|
1017
|
-
emails: [
|
1018
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1019
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1020
|
-
]
|
1021
|
-
}
|
756
|
+
altering_hash: scim_hash
|
1022
757
|
)
|
1023
758
|
|
1024
759
|
expect(scim_hash['emails'][0]['value']).to eql('added_over_original@test.com')
|
@@ -1042,13 +777,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1042
777
|
nature: 'add',
|
1043
778
|
path: path,
|
1044
779
|
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
|
1045
|
-
altering_hash: scim_hash
|
1046
|
-
with_attr_map: {
|
1047
|
-
emails: [
|
1048
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1049
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1050
|
-
]
|
1051
|
-
}
|
780
|
+
altering_hash: scim_hash
|
1052
781
|
)
|
1053
782
|
|
1054
783
|
expect(scim_hash['emails'].size).to eql(2)
|
@@ -1096,12 +825,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1096
825
|
nature: 'add',
|
1097
826
|
path: ['root'],
|
1098
827
|
value: {'members' => [{'value' => '3'}]},
|
1099
|
-
altering_hash: scim_hash
|
1100
|
-
with_attr_map: {
|
1101
|
-
members: [
|
1102
|
-
{ list: :members, using: { value: :id } }
|
1103
|
-
]
|
1104
|
-
}
|
828
|
+
altering_hash: scim_hash
|
1105
829
|
)
|
1106
830
|
|
1107
831
|
expect(scim_hash['root']['members']).to match_array([{'value' => '1'}, {'value' => '2'}, {'value' => '3'}])
|
@@ -1119,8 +843,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1119
843
|
nature: 'add',
|
1120
844
|
path: path,
|
1121
845
|
value: 'foo',
|
1122
|
-
altering_hash: scim_hash
|
1123
|
-
with_attr_map: { userName: :user_name }
|
846
|
+
altering_hash: scim_hash
|
1124
847
|
)
|
1125
848
|
|
1126
849
|
expect(scim_hash['userName']).to eql('foo')
|
@@ -1135,29 +858,12 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1135
858
|
nature: 'add',
|
1136
859
|
path: path,
|
1137
860
|
value: 'Baz',
|
1138
|
-
altering_hash: scim_hash
|
1139
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
861
|
+
altering_hash: scim_hash
|
1140
862
|
)
|
1141
863
|
|
1142
864
|
expect(scim_hash['name']['givenName']).to eql('Baz')
|
1143
865
|
end
|
1144
866
|
|
1145
|
-
it 'with schema extensions: adds' do
|
1146
|
-
path = [ 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User', 'organization' ]
|
1147
|
-
scim_hash = {}.with_indifferent_case_insensitive_access()
|
1148
|
-
|
1149
|
-
@instance.send(
|
1150
|
-
:from_patch_backend!,
|
1151
|
-
nature: 'add',
|
1152
|
-
path: path,
|
1153
|
-
value: 'SOMEORG',
|
1154
|
-
altering_hash: scim_hash,
|
1155
|
-
with_attr_map: { organization: :org_name }
|
1156
|
-
)
|
1157
|
-
|
1158
|
-
expect(scim_hash['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['organization' ]).to eql('SOMEORG')
|
1159
|
-
end
|
1160
|
-
|
1161
867
|
context 'with filter mid-path: adds' do
|
1162
868
|
it 'by string match' do
|
1163
869
|
path = [ 'emails[type eq "work"]', 'value' ]
|
@@ -1178,13 +884,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1178
884
|
nature: 'add',
|
1179
885
|
path: path,
|
1180
886
|
value: 'added@test.com',
|
1181
|
-
altering_hash: scim_hash
|
1182
|
-
with_attr_map: {
|
1183
|
-
emails: [
|
1184
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1185
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1186
|
-
]
|
1187
|
-
}
|
887
|
+
altering_hash: scim_hash
|
1188
888
|
)
|
1189
889
|
|
1190
890
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -1209,13 +909,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1209
909
|
nature: 'add',
|
1210
910
|
path: path,
|
1211
911
|
value: 'added@test.com',
|
1212
|
-
altering_hash: scim_hash
|
1213
|
-
with_attr_map: {
|
1214
|
-
emails: [
|
1215
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1216
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1217
|
-
]
|
1218
|
-
}
|
912
|
+
altering_hash: scim_hash
|
1219
913
|
)
|
1220
914
|
|
1221
915
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -1231,13 +925,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1231
925
|
nature: 'add',
|
1232
926
|
path: path,
|
1233
927
|
value: 'added@test.com',
|
1234
|
-
altering_hash: scim_hash
|
1235
|
-
with_attr_map: {
|
1236
|
-
emails: [
|
1237
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1238
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1239
|
-
]
|
1240
|
-
}
|
928
|
+
altering_hash: scim_hash
|
1241
929
|
)
|
1242
930
|
|
1243
931
|
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
|
@@ -1261,13 +949,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1261
949
|
nature: 'add',
|
1262
950
|
path: path,
|
1263
951
|
value: 'added@test.com',
|
1264
|
-
altering_hash: scim_hash
|
1265
|
-
with_attr_map: {
|
1266
|
-
emails: [
|
1267
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1268
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1269
|
-
]
|
1270
|
-
}
|
952
|
+
altering_hash: scim_hash
|
1271
953
|
)
|
1272
954
|
|
1273
955
|
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
|
@@ -1284,13 +966,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1284
966
|
nature: 'add',
|
1285
967
|
path: path,
|
1286
968
|
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
|
1287
|
-
altering_hash: scim_hash
|
1288
|
-
with_attr_map: {
|
1289
|
-
emails: [
|
1290
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1291
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1292
|
-
]
|
1293
|
-
}
|
969
|
+
altering_hash: scim_hash
|
1294
970
|
)
|
1295
971
|
|
1296
972
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -1306,7 +982,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1306
982
|
#
|
1307
983
|
context 'remove' do
|
1308
984
|
context 'when prior value already exists' do
|
1309
|
-
it 'simple value:
|
985
|
+
it 'simple value: removes' do
|
1310
986
|
path = [ 'userName' ]
|
1311
987
|
scim_hash = { 'userName' => 'bar' }.with_indifferent_case_insensitive_access()
|
1312
988
|
|
@@ -1315,14 +991,13 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1315
991
|
nature: 'remove',
|
1316
992
|
path: path,
|
1317
993
|
value: nil,
|
1318
|
-
altering_hash: scim_hash
|
1319
|
-
with_attr_map: { userName: :user_name }
|
994
|
+
altering_hash: scim_hash
|
1320
995
|
)
|
1321
996
|
|
1322
|
-
expect(scim_hash).to
|
997
|
+
expect(scim_hash).to be_empty
|
1323
998
|
end
|
1324
999
|
|
1325
|
-
it 'nested simple value:
|
1000
|
+
it 'nested simple value: removes' do
|
1326
1001
|
path = [ 'name', 'givenName' ]
|
1327
1002
|
scim_hash = { 'name' => { 'givenName' => 'Foo', 'familyName' => 'Bar' } }.with_indifferent_case_insensitive_access()
|
1328
1003
|
|
@@ -1331,15 +1006,15 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1331
1006
|
nature: 'remove',
|
1332
1007
|
path: path,
|
1333
1008
|
value: nil,
|
1334
|
-
altering_hash: scim_hash
|
1335
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
1009
|
+
altering_hash: scim_hash
|
1336
1010
|
)
|
1337
1011
|
|
1338
|
-
expect(scim_hash).
|
1012
|
+
expect(scim_hash['name']).to_not have_key('givenName')
|
1013
|
+
expect(scim_hash['name']['familyName']).to eql('Bar')
|
1339
1014
|
end
|
1340
1015
|
|
1341
1016
|
context 'with filter mid-path' do
|
1342
|
-
it 'by string match:
|
1017
|
+
it 'by string match: removes' do
|
1343
1018
|
path = [ 'emails[type eq "work"]', 'value' ]
|
1344
1019
|
scim_hash = {
|
1345
1020
|
'emails' => [
|
@@ -1359,30 +1034,14 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1359
1034
|
nature: 'remove',
|
1360
1035
|
path: path,
|
1361
1036
|
value: nil,
|
1362
|
-
altering_hash: scim_hash
|
1363
|
-
with_attr_map: {
|
1364
|
-
emails: [
|
1365
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1366
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1367
|
-
]
|
1368
|
-
}
|
1037
|
+
altering_hash: scim_hash
|
1369
1038
|
)
|
1370
1039
|
|
1371
|
-
expect(scim_hash).to eql(
|
1372
|
-
|
1373
|
-
{
|
1374
|
-
'type' => 'home',
|
1375
|
-
'value' => 'home@test.com'
|
1376
|
-
},
|
1377
|
-
{
|
1378
|
-
'type' => 'work',
|
1379
|
-
'value' => nil
|
1380
|
-
}
|
1381
|
-
]
|
1382
|
-
})
|
1040
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1041
|
+
expect(scim_hash['emails'][1]).to_not have_key('value')
|
1383
1042
|
end
|
1384
1043
|
|
1385
|
-
it 'by boolean match:
|
1044
|
+
it 'by boolean match: removes' do
|
1386
1045
|
path = [ 'emails[primary eq true]', 'value' ]
|
1387
1046
|
scim_hash = {
|
1388
1047
|
'emails' => [
|
@@ -1401,29 +1060,14 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1401
1060
|
nature: 'remove',
|
1402
1061
|
path: path,
|
1403
1062
|
value: nil,
|
1404
|
-
altering_hash: scim_hash
|
1405
|
-
with_attr_map: {
|
1406
|
-
emails: [
|
1407
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1408
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1409
|
-
]
|
1410
|
-
}
|
1063
|
+
altering_hash: scim_hash
|
1411
1064
|
)
|
1412
1065
|
|
1413
|
-
expect(scim_hash).to eql(
|
1414
|
-
|
1415
|
-
{
|
1416
|
-
'value' => 'home@test.com'
|
1417
|
-
},
|
1418
|
-
{
|
1419
|
-
'value' => nil,
|
1420
|
-
'primary' => true
|
1421
|
-
}
|
1422
|
-
]
|
1423
|
-
})
|
1066
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1067
|
+
expect(scim_hash['emails'][1]).to_not have_key('value')
|
1424
1068
|
end
|
1425
1069
|
|
1426
|
-
it 'multiple matches:
|
1070
|
+
it 'multiple matches: removes all' do
|
1427
1071
|
path = [ 'emails[type eq "work"]', 'value' ]
|
1428
1072
|
scim_hash = {
|
1429
1073
|
'emails' => [
|
@@ -1434,11 +1078,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1434
1078
|
{
|
1435
1079
|
'type' => 'work',
|
1436
1080
|
'value' => 'work_2@test.com'
|
1437
|
-
}
|
1438
|
-
{
|
1439
|
-
'type' => 'home',
|
1440
|
-
'value' => 'home@test.com'
|
1441
|
-
},
|
1081
|
+
}
|
1442
1082
|
]
|
1443
1083
|
}.with_indifferent_case_insensitive_access()
|
1444
1084
|
|
@@ -1447,36 +1087,16 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1447
1087
|
nature: 'remove',
|
1448
1088
|
path: path,
|
1449
1089
|
value: nil,
|
1450
|
-
altering_hash: scim_hash
|
1451
|
-
with_attr_map: {
|
1452
|
-
emails: [
|
1453
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1454
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1455
|
-
]
|
1456
|
-
}
|
1090
|
+
altering_hash: scim_hash
|
1457
1091
|
)
|
1458
1092
|
|
1459
|
-
expect(scim_hash).
|
1460
|
-
|
1461
|
-
{
|
1462
|
-
'type' => 'work',
|
1463
|
-
'value' => nil
|
1464
|
-
},
|
1465
|
-
{
|
1466
|
-
'type' => 'work',
|
1467
|
-
'value' => nil
|
1468
|
-
},
|
1469
|
-
{
|
1470
|
-
'type' => 'home',
|
1471
|
-
'value' => 'home@test.com'
|
1472
|
-
},
|
1473
|
-
]
|
1474
|
-
})
|
1093
|
+
expect(scim_hash['emails'][0]).to_not have_key('value')
|
1094
|
+
expect(scim_hash['emails'][1]).to_not have_key('value')
|
1475
1095
|
end
|
1476
1096
|
end # "context 'with filter mid-path' do"
|
1477
1097
|
|
1478
1098
|
context 'with filter at end of path' do
|
1479
|
-
it 'by string match:
|
1099
|
+
it 'by string match: removes entire matching array entry' do
|
1480
1100
|
path = [ 'emails[type eq "work"]' ]
|
1481
1101
|
scim_hash = {
|
1482
1102
|
'emails' => [
|
@@ -1496,39 +1116,23 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1496
1116
|
nature: 'remove',
|
1497
1117
|
path: path,
|
1498
1118
|
value: nil,
|
1499
|
-
altering_hash: scim_hash
|
1500
|
-
with_attr_map: {
|
1501
|
-
emails: [
|
1502
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1503
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1504
|
-
]
|
1505
|
-
}
|
1119
|
+
altering_hash: scim_hash
|
1506
1120
|
)
|
1507
1121
|
|
1508
|
-
expect(scim_hash).to eql(
|
1509
|
-
|
1510
|
-
{
|
1511
|
-
'type' => 'home',
|
1512
|
-
'value' => 'home@test.com'
|
1513
|
-
},
|
1514
|
-
{
|
1515
|
-
'type' => 'work',
|
1516
|
-
'value' => nil
|
1517
|
-
}
|
1518
|
-
]
|
1519
|
-
})
|
1122
|
+
expect(scim_hash['emails'].size).to eql(1)
|
1123
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1520
1124
|
end
|
1521
1125
|
|
1522
|
-
it 'by boolean match:
|
1126
|
+
it 'by boolean match: removes entire matching array entry' do
|
1523
1127
|
path = [ 'emails[primary eq true]' ]
|
1524
1128
|
scim_hash = {
|
1525
1129
|
'emails' => [
|
1526
1130
|
{
|
1527
|
-
'value' => 'home@test.com'
|
1528
|
-
'primary' => true
|
1131
|
+
'value' => 'home@test.com'
|
1529
1132
|
},
|
1530
1133
|
{
|
1531
|
-
'value' => 'work@test.com'
|
1134
|
+
'value' => 'work@test.com',
|
1135
|
+
'primary' => true
|
1532
1136
|
}
|
1533
1137
|
]
|
1534
1138
|
}.with_indifferent_case_insensitive_access()
|
@@ -1538,29 +1142,14 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1538
1142
|
nature: 'remove',
|
1539
1143
|
path: path,
|
1540
1144
|
value: nil,
|
1541
|
-
altering_hash: scim_hash
|
1542
|
-
with_attr_map: {
|
1543
|
-
emails: [
|
1544
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1545
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1546
|
-
]
|
1547
|
-
}
|
1145
|
+
altering_hash: scim_hash
|
1548
1146
|
)
|
1549
1147
|
|
1550
|
-
expect(scim_hash).to eql(
|
1551
|
-
|
1552
|
-
{
|
1553
|
-
'value' => nil,
|
1554
|
-
'primary' => true
|
1555
|
-
},
|
1556
|
-
{
|
1557
|
-
'value' => 'work@test.com'
|
1558
|
-
}
|
1559
|
-
]
|
1560
|
-
})
|
1148
|
+
expect(scim_hash['emails'].size).to eql(1)
|
1149
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1561
1150
|
end
|
1562
1151
|
|
1563
|
-
it 'multiple matches:
|
1152
|
+
it 'multiple matches: removes all matching array entries' do
|
1564
1153
|
path = [ 'emails[type eq "work"]' ]
|
1565
1154
|
scim_hash = {
|
1566
1155
|
'emails' => [
|
@@ -1584,45 +1173,21 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1584
1173
|
nature: 'remove',
|
1585
1174
|
path: path,
|
1586
1175
|
value: nil,
|
1587
|
-
altering_hash: scim_hash
|
1588
|
-
with_attr_map: {
|
1589
|
-
emails: [
|
1590
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1591
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1592
|
-
]
|
1593
|
-
}
|
1176
|
+
altering_hash: scim_hash
|
1594
1177
|
)
|
1595
1178
|
|
1596
|
-
expect(scim_hash).to eql(
|
1597
|
-
|
1598
|
-
{
|
1599
|
-
'type' => 'work',
|
1600
|
-
'value' => nil
|
1601
|
-
},
|
1602
|
-
{
|
1603
|
-
'type' => 'work',
|
1604
|
-
'value' => nil
|
1605
|
-
},
|
1606
|
-
{
|
1607
|
-
'type' => 'home',
|
1608
|
-
'value' => 'home@test.com'
|
1609
|
-
},
|
1610
|
-
]
|
1611
|
-
})
|
1179
|
+
expect(scim_hash['emails'].size).to eql(1)
|
1180
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1612
1181
|
end
|
1613
1182
|
end # "context 'with filter at end of path' do"
|
1614
1183
|
|
1615
|
-
it 'whole array:
|
1184
|
+
it 'whole array: removes' do
|
1616
1185
|
path = [ 'emails' ]
|
1617
1186
|
scim_hash = {
|
1618
1187
|
'emails' => [
|
1619
1188
|
{
|
1620
1189
|
'type' => 'home',
|
1621
1190
|
'value' => 'home@test.com'
|
1622
|
-
},
|
1623
|
-
{
|
1624
|
-
'type' => 'work',
|
1625
|
-
'value' => 'work@test.com'
|
1626
1191
|
}
|
1627
1192
|
]
|
1628
1193
|
}.with_indifferent_case_insensitive_access()
|
@@ -1632,741 +1197,11 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1632
1197
|
nature: 'remove',
|
1633
1198
|
path: path,
|
1634
1199
|
value: nil,
|
1635
|
-
altering_hash: scim_hash
|
1636
|
-
with_attr_map: {
|
1637
|
-
emails: [
|
1638
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1639
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1640
|
-
]
|
1641
|
-
}
|
1200
|
+
altering_hash: scim_hash
|
1642
1201
|
)
|
1643
1202
|
|
1644
|
-
expect(scim_hash).
|
1645
|
-
'emails' => [
|
1646
|
-
{
|
1647
|
-
'type' => 'home',
|
1648
|
-
'value' => nil
|
1649
|
-
},
|
1650
|
-
{
|
1651
|
-
'type' => 'work',
|
1652
|
-
'value' => nil
|
1653
|
-
}
|
1654
|
-
]
|
1655
|
-
})
|
1203
|
+
expect(scim_hash).to_not have_key('emails')
|
1656
1204
|
end
|
1657
|
-
|
1658
|
-
# What we expect:
|
1659
|
-
#
|
1660
|
-
# https://tools.ietf.org/html/rfc7644#section-3.5.2.2
|
1661
|
-
# https://docs.snowflake.com/en/user-guide/scim-intro.html#patch-scim-v2-groups-id
|
1662
|
-
#
|
1663
|
-
# ...vs accounting for the unusual payloads we sometimes get,
|
1664
|
-
# tested here.
|
1665
|
-
#
|
1666
|
-
context 'special cases' do
|
1667
|
-
|
1668
|
-
# https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
|
1669
|
-
#
|
1670
|
-
context 'Microsoft-style payload' do
|
1671
|
-
context 'removing a user from a group' do
|
1672
|
-
it 'removes identified user' do
|
1673
|
-
path = [ 'members' ]
|
1674
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ]
|
1675
|
-
scim_hash = {
|
1676
|
-
'displayname' => 'Mock group',
|
1677
|
-
'members' => [
|
1678
|
-
{
|
1679
|
-
'value' => '50ca93d04ab0c2de4772',
|
1680
|
-
'display' => 'Ingrid Smith',
|
1681
|
-
'type' => 'User'
|
1682
|
-
},
|
1683
|
-
{
|
1684
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1685
|
-
'display' => 'Fred Smith',
|
1686
|
-
'type' => 'User'
|
1687
|
-
},
|
1688
|
-
{
|
1689
|
-
'value' => 'a774d480e8112101375b',
|
1690
|
-
'display' => 'Taylor Smith',
|
1691
|
-
'type' => 'User'
|
1692
|
-
}
|
1693
|
-
]
|
1694
|
-
}.with_indifferent_case_insensitive_access()
|
1695
|
-
|
1696
|
-
@instance.send(
|
1697
|
-
:from_patch_backend!,
|
1698
|
-
nature: 'remove',
|
1699
|
-
path: path,
|
1700
|
-
value: value,
|
1701
|
-
altering_hash: scim_hash,
|
1702
|
-
with_attr_map: {
|
1703
|
-
members: [
|
1704
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1705
|
-
]
|
1706
|
-
}
|
1707
|
-
)
|
1708
|
-
|
1709
|
-
expect(scim_hash).to eql({
|
1710
|
-
'displayname' => 'Mock group',
|
1711
|
-
'members' => [
|
1712
|
-
{
|
1713
|
-
'value' => '50ca93d04ab0c2de4772',
|
1714
|
-
'display' => 'Ingrid Smith',
|
1715
|
-
'type' => 'User'
|
1716
|
-
},
|
1717
|
-
{
|
1718
|
-
'value' => 'a774d480e8112101375b',
|
1719
|
-
'display' => 'Taylor Smith',
|
1720
|
-
'type' => 'User'
|
1721
|
-
}
|
1722
|
-
]
|
1723
|
-
})
|
1724
|
-
end
|
1725
|
-
|
1726
|
-
it 'removes multiple identified users' do
|
1727
|
-
path = [ 'members' ]
|
1728
|
-
value = [
|
1729
|
-
{ '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' },
|
1730
|
-
{ '$ref' => nil, 'value' => '50ca93d04ab0c2de4772' }
|
1731
|
-
]
|
1732
|
-
scim_hash = {
|
1733
|
-
'displayname' => 'Mock group',
|
1734
|
-
'members' => [
|
1735
|
-
{
|
1736
|
-
'value' => '50ca93d04ab0c2de4772',
|
1737
|
-
'display' => 'Ingrid Smith',
|
1738
|
-
'type' => 'User'
|
1739
|
-
},
|
1740
|
-
{
|
1741
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1742
|
-
'display' => 'Fred Smith',
|
1743
|
-
'type' => 'User'
|
1744
|
-
},
|
1745
|
-
{
|
1746
|
-
'value' => 'a774d480e8112101375b',
|
1747
|
-
'display' => 'Taylor Smith',
|
1748
|
-
'type' => 'User'
|
1749
|
-
}
|
1750
|
-
]
|
1751
|
-
}.with_indifferent_case_insensitive_access()
|
1752
|
-
|
1753
|
-
@instance.send(
|
1754
|
-
:from_patch_backend!,
|
1755
|
-
nature: 'remove',
|
1756
|
-
path: path,
|
1757
|
-
value: value,
|
1758
|
-
altering_hash: scim_hash,
|
1759
|
-
with_attr_map: {
|
1760
|
-
members: [
|
1761
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1762
|
-
]
|
1763
|
-
}
|
1764
|
-
)
|
1765
|
-
|
1766
|
-
expect(scim_hash).to eql({
|
1767
|
-
'displayname' => 'Mock group',
|
1768
|
-
'members' => [
|
1769
|
-
{
|
1770
|
-
'value' => 'a774d480e8112101375b',
|
1771
|
-
'display' => 'Taylor Smith',
|
1772
|
-
'type' => 'User'
|
1773
|
-
}
|
1774
|
-
]
|
1775
|
-
})
|
1776
|
-
end
|
1777
|
-
|
1778
|
-
it 'removes all users individually without error' do
|
1779
|
-
path = [ 'members' ]
|
1780
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ]
|
1781
|
-
scim_hash = {
|
1782
|
-
'displayname' => 'Mock group',
|
1783
|
-
'members' => [
|
1784
|
-
{
|
1785
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1786
|
-
'display' => 'Fred Smith',
|
1787
|
-
'type' => 'User'
|
1788
|
-
}
|
1789
|
-
]
|
1790
|
-
}.with_indifferent_case_insensitive_access()
|
1791
|
-
|
1792
|
-
@instance.send(
|
1793
|
-
:from_patch_backend!,
|
1794
|
-
nature: 'remove',
|
1795
|
-
path: path,
|
1796
|
-
value: value,
|
1797
|
-
altering_hash: scim_hash,
|
1798
|
-
with_attr_map: {
|
1799
|
-
members: [
|
1800
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1801
|
-
]
|
1802
|
-
}
|
1803
|
-
)
|
1804
|
-
|
1805
|
-
expect(scim_hash).to eql({
|
1806
|
-
'displayname' => 'Mock group',
|
1807
|
-
'members' => []
|
1808
|
-
})
|
1809
|
-
end
|
1810
|
-
|
1811
|
-
it 'can match on multiple attributes' do
|
1812
|
-
path = [ 'members' ]
|
1813
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'User' } ]
|
1814
|
-
scim_hash = {
|
1815
|
-
'displayname' => 'Mock group',
|
1816
|
-
'members' => [
|
1817
|
-
{
|
1818
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1819
|
-
'display' => 'Fred Smith',
|
1820
|
-
'type' => 'User'
|
1821
|
-
}
|
1822
|
-
]
|
1823
|
-
}.with_indifferent_case_insensitive_access()
|
1824
|
-
|
1825
|
-
@instance.send(
|
1826
|
-
:from_patch_backend!,
|
1827
|
-
nature: 'remove',
|
1828
|
-
path: path,
|
1829
|
-
value: value,
|
1830
|
-
altering_hash: scim_hash,
|
1831
|
-
with_attr_map: {
|
1832
|
-
members: [
|
1833
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1834
|
-
]
|
1835
|
-
}
|
1836
|
-
)
|
1837
|
-
|
1838
|
-
expect(scim_hash).to eql({
|
1839
|
-
'displayname' => 'Mock group',
|
1840
|
-
'members' => []
|
1841
|
-
})
|
1842
|
-
end
|
1843
|
-
|
1844
|
-
it 'ignores unrecognised users' do
|
1845
|
-
path = [ 'members' ]
|
1846
|
-
value = [ { '$ref' => nil, 'value' => '11b054a9c85216ed9356' } ]
|
1847
|
-
scim_hash = {
|
1848
|
-
'displayname' => 'Mock group',
|
1849
|
-
'members' => [
|
1850
|
-
{
|
1851
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1852
|
-
'display' => 'Fred Smith',
|
1853
|
-
'type' => 'User'
|
1854
|
-
}
|
1855
|
-
]
|
1856
|
-
}.with_indifferent_case_insensitive_access()
|
1857
|
-
|
1858
|
-
@instance.send(
|
1859
|
-
:from_patch_backend!,
|
1860
|
-
nature: 'remove',
|
1861
|
-
path: path,
|
1862
|
-
value: value,
|
1863
|
-
altering_hash: scim_hash,
|
1864
|
-
with_attr_map: {
|
1865
|
-
members: [
|
1866
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1867
|
-
]
|
1868
|
-
}
|
1869
|
-
)
|
1870
|
-
|
1871
|
-
# The 'value' mismatched, so the user was not removed.
|
1872
|
-
#
|
1873
|
-
expect(scim_hash).to eql({
|
1874
|
-
'displayname' => 'Mock group',
|
1875
|
-
'members' => [
|
1876
|
-
{
|
1877
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1878
|
-
'display' => 'Fred Smith',
|
1879
|
-
'type' => 'User'
|
1880
|
-
}
|
1881
|
-
]
|
1882
|
-
})
|
1883
|
-
end
|
1884
|
-
|
1885
|
-
it 'ignores a mismatch on (for example) "type"' do
|
1886
|
-
path = [ 'members' ]
|
1887
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'Group' } ]
|
1888
|
-
scim_hash = {
|
1889
|
-
'displayname' => 'Mock group',
|
1890
|
-
'members' => [
|
1891
|
-
{
|
1892
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1893
|
-
'display' => 'Fred Smith',
|
1894
|
-
'type' => 'User'
|
1895
|
-
}
|
1896
|
-
]
|
1897
|
-
}.with_indifferent_case_insensitive_access()
|
1898
|
-
|
1899
|
-
@instance.send(
|
1900
|
-
:from_patch_backend!,
|
1901
|
-
nature: 'remove',
|
1902
|
-
path: path,
|
1903
|
-
value: value,
|
1904
|
-
altering_hash: scim_hash,
|
1905
|
-
with_attr_map: {
|
1906
|
-
members: [
|
1907
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1908
|
-
]
|
1909
|
-
}
|
1910
|
-
)
|
1911
|
-
|
1912
|
-
# Type 'Group' mismatches 'User', so the user was not
|
1913
|
-
# removed.
|
1914
|
-
#
|
1915
|
-
expect(scim_hash).to eql({
|
1916
|
-
'displayname' => 'Mock group',
|
1917
|
-
'members' => [
|
1918
|
-
{
|
1919
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1920
|
-
'display' => 'Fred Smith',
|
1921
|
-
'type' => 'User'
|
1922
|
-
}
|
1923
|
-
]
|
1924
|
-
})
|
1925
|
-
end
|
1926
|
-
|
1927
|
-
it 'matches keys case-insensitive (but preserves case in response)' do
|
1928
|
-
path = [ 'members' ]
|
1929
|
-
value = [ { '$ref' => nil, 'VALUe' => 'f648f8d5ea4e4cd38e9c' } ]
|
1930
|
-
scim_hash = {
|
1931
|
-
'displayname' => 'Mock group',
|
1932
|
-
'memBERS' => [
|
1933
|
-
{
|
1934
|
-
'vaLUe' => 'f648f8d5ea4e4cd38e9c',
|
1935
|
-
'display' => 'Fred Smith',
|
1936
|
-
'type' => 'User'
|
1937
|
-
}
|
1938
|
-
]
|
1939
|
-
}.with_indifferent_case_insensitive_access()
|
1940
|
-
|
1941
|
-
@instance.send(
|
1942
|
-
:from_patch_backend!,
|
1943
|
-
nature: 'remove',
|
1944
|
-
path: path,
|
1945
|
-
value: value,
|
1946
|
-
altering_hash: scim_hash,
|
1947
|
-
with_attr_map: {
|
1948
|
-
members: [
|
1949
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1950
|
-
]
|
1951
|
-
}
|
1952
|
-
)
|
1953
|
-
|
1954
|
-
expect(scim_hash).to eql({
|
1955
|
-
'displayname' => 'Mock group',
|
1956
|
-
'memBERS' => []
|
1957
|
-
})
|
1958
|
-
end
|
1959
|
-
|
1960
|
-
it 'matches values case-sensitive' do
|
1961
|
-
path = [ 'members' ]
|
1962
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'USER' } ]
|
1963
|
-
scim_hash = {
|
1964
|
-
'displayName' => 'Mock group',
|
1965
|
-
'members' => [
|
1966
|
-
{
|
1967
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1968
|
-
'display' => 'Fred Smith',
|
1969
|
-
'type' => 'User'
|
1970
|
-
}
|
1971
|
-
]
|
1972
|
-
}.with_indifferent_case_insensitive_access()
|
1973
|
-
|
1974
|
-
@instance.send(
|
1975
|
-
:from_patch_backend!,
|
1976
|
-
nature: 'remove',
|
1977
|
-
path: path,
|
1978
|
-
value: value,
|
1979
|
-
altering_hash: scim_hash,
|
1980
|
-
with_attr_map: {
|
1981
|
-
members: [
|
1982
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1983
|
-
]
|
1984
|
-
}
|
1985
|
-
)
|
1986
|
-
|
1987
|
-
# USER mismatches User, so the user was not removed.
|
1988
|
-
#
|
1989
|
-
expect(scim_hash).to eql({
|
1990
|
-
'displayName' => 'Mock group',
|
1991
|
-
'members' => [
|
1992
|
-
{
|
1993
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1994
|
-
'display' => 'Fred Smith',
|
1995
|
-
'type' => 'User'
|
1996
|
-
}
|
1997
|
-
]
|
1998
|
-
})
|
1999
|
-
end
|
2000
|
-
end # "context 'removing a user from a group' do"
|
2001
|
-
|
2002
|
-
context 'generic use' do
|
2003
|
-
it 'clears static map matched items to "nil" in order to remove' do
|
2004
|
-
path = [ 'emails' ]
|
2005
|
-
value = [ { 'type' => 'work' } ]
|
2006
|
-
scim_hash = {
|
2007
|
-
'emails' => [
|
2008
|
-
{
|
2009
|
-
'type' => 'home',
|
2010
|
-
'value' => 'home@test.com'
|
2011
|
-
},
|
2012
|
-
{
|
2013
|
-
'type' => 'work',
|
2014
|
-
'value' => 'work@test.com'
|
2015
|
-
}
|
2016
|
-
]
|
2017
|
-
}.with_indifferent_case_insensitive_access()
|
2018
|
-
|
2019
|
-
@instance.send(
|
2020
|
-
:from_patch_backend!,
|
2021
|
-
nature: 'remove',
|
2022
|
-
path: path,
|
2023
|
-
value: value,
|
2024
|
-
altering_hash: scim_hash,
|
2025
|
-
with_attr_map: {
|
2026
|
-
emails: [
|
2027
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2028
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2029
|
-
]
|
2030
|
-
}
|
2031
|
-
)
|
2032
|
-
|
2033
|
-
expect(scim_hash).to eql({
|
2034
|
-
'emails' => [
|
2035
|
-
{
|
2036
|
-
'type' => 'home',
|
2037
|
-
'value' => 'home@test.com'
|
2038
|
-
},
|
2039
|
-
{
|
2040
|
-
'type' => 'work',
|
2041
|
-
'value' => nil
|
2042
|
-
}
|
2043
|
-
]
|
2044
|
-
})
|
2045
|
-
end
|
2046
|
-
|
2047
|
-
it 'ignores unmatched items' do
|
2048
|
-
path = [ 'emails' ]
|
2049
|
-
value = [ { 'type' => 'missing' } ]
|
2050
|
-
scim_hash = {
|
2051
|
-
'emails' => [
|
2052
|
-
{
|
2053
|
-
'type' => 'home',
|
2054
|
-
'value' => 'home@test.com'
|
2055
|
-
},
|
2056
|
-
{
|
2057
|
-
'type' => 'work',
|
2058
|
-
'value' => 'work@test.com'
|
2059
|
-
}
|
2060
|
-
]
|
2061
|
-
}.with_indifferent_case_insensitive_access()
|
2062
|
-
|
2063
|
-
@instance.send(
|
2064
|
-
:from_patch_backend!,
|
2065
|
-
nature: 'remove',
|
2066
|
-
path: path,
|
2067
|
-
value: value,
|
2068
|
-
altering_hash: scim_hash,
|
2069
|
-
with_attr_map: {
|
2070
|
-
emails: [
|
2071
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2072
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2073
|
-
]
|
2074
|
-
}
|
2075
|
-
)
|
2076
|
-
|
2077
|
-
expect(scim_hash).to eql({
|
2078
|
-
'emails' => [
|
2079
|
-
{
|
2080
|
-
'type' => 'home',
|
2081
|
-
'value' => 'home@test.com'
|
2082
|
-
},
|
2083
|
-
{
|
2084
|
-
'type' => 'work',
|
2085
|
-
'value' => 'work@test.com'
|
2086
|
-
}
|
2087
|
-
]
|
2088
|
-
})
|
2089
|
-
end
|
2090
|
-
|
2091
|
-
it 'compares string forms' do
|
2092
|
-
path = [ 'test' ]
|
2093
|
-
value = [
|
2094
|
-
{ 'active' => true, 'value' => '12' },
|
2095
|
-
{ 'active' => 'false', 'value' => 42 }
|
2096
|
-
]
|
2097
|
-
scim_hash = {
|
2098
|
-
'test' => [
|
2099
|
-
{
|
2100
|
-
'active' => 'true',
|
2101
|
-
'value' => 12
|
2102
|
-
},
|
2103
|
-
{
|
2104
|
-
'active' => false,
|
2105
|
-
'value' => '42'
|
2106
|
-
},
|
2107
|
-
{
|
2108
|
-
'active' => 'hello',
|
2109
|
-
'value' => 'world'
|
2110
|
-
}
|
2111
|
-
]
|
2112
|
-
}.with_indifferent_case_insensitive_access()
|
2113
|
-
|
2114
|
-
@instance.send(
|
2115
|
-
:from_patch_backend!,
|
2116
|
-
nature: 'remove',
|
2117
|
-
path: path,
|
2118
|
-
value: value,
|
2119
|
-
altering_hash: scim_hash,
|
2120
|
-
with_attr_map: {
|
2121
|
-
test: [
|
2122
|
-
{
|
2123
|
-
list: :test,
|
2124
|
-
using: {
|
2125
|
-
active: :active,
|
2126
|
-
value: :value
|
2127
|
-
}
|
2128
|
-
}
|
2129
|
-
]
|
2130
|
-
}
|
2131
|
-
)
|
2132
|
-
|
2133
|
-
expect(scim_hash).to eql({
|
2134
|
-
'test' => [
|
2135
|
-
{
|
2136
|
-
'active' => 'hello',
|
2137
|
-
'value' => 'world'
|
2138
|
-
}
|
2139
|
-
]
|
2140
|
-
})
|
2141
|
-
end
|
2142
|
-
|
2143
|
-
it 'handles a singular to-remove value rather than an array' do
|
2144
|
-
path = [ 'emails' ]
|
2145
|
-
value = { 'type' => 'work' }
|
2146
|
-
scim_hash = {
|
2147
|
-
'emails' => [
|
2148
|
-
{
|
2149
|
-
'type' => 'home',
|
2150
|
-
'value' => 'home@test.com'
|
2151
|
-
},
|
2152
|
-
{
|
2153
|
-
'type' => 'work',
|
2154
|
-
'value' => 'work@test.com'
|
2155
|
-
}
|
2156
|
-
]
|
2157
|
-
}.with_indifferent_case_insensitive_access()
|
2158
|
-
|
2159
|
-
@instance.send(
|
2160
|
-
:from_patch_backend!,
|
2161
|
-
nature: 'remove',
|
2162
|
-
path: path,
|
2163
|
-
value: value,
|
2164
|
-
altering_hash: scim_hash,
|
2165
|
-
with_attr_map: {
|
2166
|
-
emails: [
|
2167
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2168
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2169
|
-
]
|
2170
|
-
}
|
2171
|
-
)
|
2172
|
-
|
2173
|
-
expect(scim_hash).to eql({
|
2174
|
-
'emails' => [
|
2175
|
-
{
|
2176
|
-
'type' => 'home',
|
2177
|
-
'value' => 'home@test.com'
|
2178
|
-
},
|
2179
|
-
{
|
2180
|
-
'type' => 'work',
|
2181
|
-
'value' => nil
|
2182
|
-
}
|
2183
|
-
]
|
2184
|
-
})
|
2185
|
-
end
|
2186
|
-
|
2187
|
-
it 'handles simple values rather than object (Hash) values' do
|
2188
|
-
path = [ 'test' ]
|
2189
|
-
value = 42
|
2190
|
-
scim_hash = {
|
2191
|
-
'test' => [
|
2192
|
-
'21',
|
2193
|
-
'42',
|
2194
|
-
'15'
|
2195
|
-
]
|
2196
|
-
}.with_indifferent_case_insensitive_access()
|
2197
|
-
|
2198
|
-
@instance.send(
|
2199
|
-
:from_patch_backend!,
|
2200
|
-
nature: 'remove',
|
2201
|
-
path: path,
|
2202
|
-
value: value,
|
2203
|
-
altering_hash: scim_hash,
|
2204
|
-
with_attr_map: {
|
2205
|
-
test: []
|
2206
|
-
}
|
2207
|
-
)
|
2208
|
-
|
2209
|
-
expect(scim_hash).to eql({
|
2210
|
-
'test' => [
|
2211
|
-
'21',
|
2212
|
-
'15'
|
2213
|
-
]
|
2214
|
-
})
|
2215
|
-
end
|
2216
|
-
end
|
2217
|
-
end # "context 'Microsoft-style payload' do"
|
2218
|
-
|
2219
|
-
# https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
|
2220
|
-
#
|
2221
|
-
context 'Salesforce-style payload' do
|
2222
|
-
it 'removes identified user' do
|
2223
|
-
path = [ 'members' ]
|
2224
|
-
value = { 'members' => [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ] }
|
2225
|
-
scim_hash = {
|
2226
|
-
'displayname' => 'Mock group',
|
2227
|
-
'members' => [
|
2228
|
-
{
|
2229
|
-
'value' => '50ca93d04ab0c2de4772',
|
2230
|
-
'display' => 'Ingrid Smith',
|
2231
|
-
'type' => 'User'
|
2232
|
-
},
|
2233
|
-
{
|
2234
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
2235
|
-
'display' => 'Fred Smith',
|
2236
|
-
'type' => 'User'
|
2237
|
-
}
|
2238
|
-
]
|
2239
|
-
}.with_indifferent_case_insensitive_access()
|
2240
|
-
|
2241
|
-
@instance.send(
|
2242
|
-
:from_patch_backend!,
|
2243
|
-
nature: 'remove',
|
2244
|
-
path: path,
|
2245
|
-
value: value,
|
2246
|
-
altering_hash: scim_hash,
|
2247
|
-
with_attr_map: {
|
2248
|
-
displayName: :name,
|
2249
|
-
members: [
|
2250
|
-
list: :members,
|
2251
|
-
using: {
|
2252
|
-
value: :id,
|
2253
|
-
display: :full_name,
|
2254
|
-
type: 'User'
|
2255
|
-
}
|
2256
|
-
]
|
2257
|
-
}
|
2258
|
-
)
|
2259
|
-
|
2260
|
-
expect(scim_hash).to eql({
|
2261
|
-
'displayname' => 'Mock group',
|
2262
|
-
'members' => [
|
2263
|
-
{
|
2264
|
-
'value' => '50ca93d04ab0c2de4772',
|
2265
|
-
'display' => 'Ingrid Smith',
|
2266
|
-
'type' => 'User'
|
2267
|
-
}
|
2268
|
-
]
|
2269
|
-
})
|
2270
|
-
end
|
2271
|
-
|
2272
|
-
it 'matches the "members" key case-insensitive' do
|
2273
|
-
path = [ 'members' ]
|
2274
|
-
value = { 'MEMBERS' => [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ] }
|
2275
|
-
scim_hash = {
|
2276
|
-
'displayname' => 'Mock group',
|
2277
|
-
'members' => [
|
2278
|
-
{
|
2279
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
2280
|
-
'display' => 'Fred Smith',
|
2281
|
-
'type' => 'User'
|
2282
|
-
},
|
2283
|
-
{
|
2284
|
-
'value' => 'a774d480e8112101375b',
|
2285
|
-
'display' => 'Taylor Smith',
|
2286
|
-
'type' => 'User'
|
2287
|
-
}
|
2288
|
-
]
|
2289
|
-
}.with_indifferent_case_insensitive_access()
|
2290
|
-
|
2291
|
-
@instance.send(
|
2292
|
-
:from_patch_backend!,
|
2293
|
-
nature: 'remove',
|
2294
|
-
path: path,
|
2295
|
-
value: value,
|
2296
|
-
altering_hash: scim_hash,
|
2297
|
-
with_attr_map: {
|
2298
|
-
displayName: :name,
|
2299
|
-
members: [
|
2300
|
-
list: :members,
|
2301
|
-
using: {
|
2302
|
-
value: :id,
|
2303
|
-
display: :full_name,
|
2304
|
-
type: 'User'
|
2305
|
-
}
|
2306
|
-
]
|
2307
|
-
}
|
2308
|
-
)
|
2309
|
-
|
2310
|
-
expect(scim_hash).to eql({
|
2311
|
-
'displayname' => 'Mock group',
|
2312
|
-
'members' => [
|
2313
|
-
{
|
2314
|
-
'value' => 'a774d480e8112101375b',
|
2315
|
-
'display' => 'Taylor Smith',
|
2316
|
-
'type' => 'User'
|
2317
|
-
}
|
2318
|
-
]
|
2319
|
-
})
|
2320
|
-
end
|
2321
|
-
|
2322
|
-
it 'ignores unrecognised users' do
|
2323
|
-
path = [ 'members' ]
|
2324
|
-
value = { 'members' => [ { '$ref' => nil, 'value' => '11b054a9c85216ed9356' } ] }
|
2325
|
-
scim_hash = {
|
2326
|
-
'displayname' => 'Mock group',
|
2327
|
-
'members' => [
|
2328
|
-
{
|
2329
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
2330
|
-
'display' => 'Fred Smith',
|
2331
|
-
'type' => 'User'
|
2332
|
-
}
|
2333
|
-
]
|
2334
|
-
}.with_indifferent_case_insensitive_access()
|
2335
|
-
|
2336
|
-
@instance.send(
|
2337
|
-
:from_patch_backend!,
|
2338
|
-
nature: 'remove',
|
2339
|
-
path: path,
|
2340
|
-
value: value,
|
2341
|
-
altering_hash: scim_hash,
|
2342
|
-
with_attr_map: {
|
2343
|
-
displayName: :name,
|
2344
|
-
members: [
|
2345
|
-
list: :members,
|
2346
|
-
using: {
|
2347
|
-
value: :id,
|
2348
|
-
display: :full_name,
|
2349
|
-
type: 'User'
|
2350
|
-
}
|
2351
|
-
]
|
2352
|
-
}
|
2353
|
-
)
|
2354
|
-
|
2355
|
-
# The 'value' mismatched, so the user was not removed.
|
2356
|
-
#
|
2357
|
-
expect(scim_hash).to eql({
|
2358
|
-
'displayname' => 'Mock group',
|
2359
|
-
'members' => [
|
2360
|
-
{
|
2361
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
2362
|
-
'display' => 'Fred Smith',
|
2363
|
-
'type' => 'User'
|
2364
|
-
}
|
2365
|
-
]
|
2366
|
-
})
|
2367
|
-
end
|
2368
|
-
end # "context 'Salesforce-style payload' do"
|
2369
|
-
end # "context 'special cases' do"
|
2370
1205
|
end # context 'when prior value already exists' do
|
2371
1206
|
|
2372
1207
|
context 'when value is not present' do
|
@@ -2379,8 +1214,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2379
1214
|
nature: 'remove',
|
2380
1215
|
path: path,
|
2381
1216
|
value: nil,
|
2382
|
-
altering_hash: scim_hash
|
2383
|
-
with_attr_map: { userName: :user_name }
|
1217
|
+
altering_hash: scim_hash
|
2384
1218
|
)
|
2385
1219
|
|
2386
1220
|
expect(scim_hash).to be_empty
|
@@ -2395,8 +1229,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2395
1229
|
nature: 'remove',
|
2396
1230
|
path: path,
|
2397
1231
|
value: nil,
|
2398
|
-
altering_hash: scim_hash
|
2399
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
1232
|
+
altering_hash: scim_hash
|
2400
1233
|
)
|
2401
1234
|
|
2402
1235
|
expect(scim_hash['name']).to_not have_key('givenName')
|
@@ -2420,13 +1253,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2420
1253
|
nature: 'remove',
|
2421
1254
|
path: path,
|
2422
1255
|
value: nil,
|
2423
|
-
altering_hash: scim_hash
|
2424
|
-
with_attr_map: {
|
2425
|
-
emails: [
|
2426
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2427
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2428
|
-
]
|
2429
|
-
}
|
1256
|
+
altering_hash: scim_hash
|
2430
1257
|
)
|
2431
1258
|
|
2432
1259
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2448,13 +1275,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2448
1275
|
nature: 'remove',
|
2449
1276
|
path: path,
|
2450
1277
|
value: nil,
|
2451
|
-
altering_hash: scim_hash
|
2452
|
-
with_attr_map: {
|
2453
|
-
emails: [
|
2454
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2455
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2456
|
-
]
|
2457
|
-
}
|
1278
|
+
altering_hash: scim_hash
|
2458
1279
|
)
|
2459
1280
|
|
2460
1281
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2477,13 +1298,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2477
1298
|
nature: 'remove',
|
2478
1299
|
path: path,
|
2479
1300
|
value: nil,
|
2480
|
-
altering_hash: scim_hash
|
2481
|
-
with_attr_map: {
|
2482
|
-
emails: [
|
2483
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2484
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2485
|
-
]
|
2486
|
-
}
|
1301
|
+
altering_hash: scim_hash
|
2487
1302
|
)
|
2488
1303
|
|
2489
1304
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2501,13 +1316,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2501
1316
|
nature: 'remove',
|
2502
1317
|
path: path,
|
2503
1318
|
value: nil,
|
2504
|
-
altering_hash: scim_hash
|
2505
|
-
with_attr_map: {
|
2506
|
-
emails: [
|
2507
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2508
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2509
|
-
]
|
2510
|
-
}
|
1319
|
+
altering_hash: scim_hash
|
2511
1320
|
)
|
2512
1321
|
|
2513
1322
|
expect(scim_hash).to be_empty
|
@@ -2529,13 +1338,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2529
1338
|
nature: 'remove',
|
2530
1339
|
path: path,
|
2531
1340
|
value: nil,
|
2532
|
-
altering_hash: scim_hash
|
2533
|
-
with_attr_map: {
|
2534
|
-
emails: [
|
2535
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2536
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2537
|
-
]
|
2538
|
-
}
|
1341
|
+
altering_hash: scim_hash
|
2539
1342
|
)
|
2540
1343
|
|
2541
1344
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2552,13 +1355,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2552
1355
|
nature: 'remove',
|
2553
1356
|
path: path,
|
2554
1357
|
value: nil,
|
2555
|
-
altering_hash: scim_hash
|
2556
|
-
with_attr_map: {
|
2557
|
-
emails: [
|
2558
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2559
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2560
|
-
]
|
2561
|
-
}
|
1358
|
+
altering_hash: scim_hash
|
2562
1359
|
)
|
2563
1360
|
|
2564
1361
|
expect(scim_hash).to_not have_key('emails')
|
@@ -2584,8 +1381,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2584
1381
|
nature: 'replace',
|
2585
1382
|
path: path,
|
2586
1383
|
value: 'foo',
|
2587
|
-
altering_hash: scim_hash
|
2588
|
-
with_attr_map: { userName: :user_name }
|
1384
|
+
altering_hash: scim_hash
|
2589
1385
|
)
|
2590
1386
|
|
2591
1387
|
expect(scim_hash['userName']).to eql('foo')
|
@@ -2600,8 +1396,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2600
1396
|
nature: 'replace',
|
2601
1397
|
path: path,
|
2602
1398
|
value: 'Baz',
|
2603
|
-
altering_hash: scim_hash
|
2604
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
1399
|
+
altering_hash: scim_hash
|
2605
1400
|
)
|
2606
1401
|
|
2607
1402
|
expect(scim_hash['name']['givenName' ]).to eql('Baz')
|
@@ -2629,13 +1424,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2629
1424
|
nature: 'replace',
|
2630
1425
|
path: path,
|
2631
1426
|
value: 'added_over_original@test.com',
|
2632
|
-
altering_hash: scim_hash
|
2633
|
-
with_attr_map: {
|
2634
|
-
emails: [
|
2635
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2636
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2637
|
-
]
|
2638
|
-
}
|
1427
|
+
altering_hash: scim_hash
|
2639
1428
|
)
|
2640
1429
|
|
2641
1430
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -2661,13 +1450,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2661
1450
|
nature: 'replace',
|
2662
1451
|
path: path,
|
2663
1452
|
value: 'added_over_original@test.com',
|
2664
|
-
altering_hash: scim_hash
|
2665
|
-
with_attr_map: {
|
2666
|
-
emails: [
|
2667
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2668
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2669
|
-
]
|
2670
|
-
}
|
1453
|
+
altering_hash: scim_hash
|
2671
1454
|
)
|
2672
1455
|
|
2673
1456
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -2694,13 +1477,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2694
1477
|
nature: 'replace',
|
2695
1478
|
path: path,
|
2696
1479
|
value: 'added_over_original@test.com',
|
2697
|
-
altering_hash: scim_hash
|
2698
|
-
with_attr_map: {
|
2699
|
-
emails: [
|
2700
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2701
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2702
|
-
]
|
2703
|
-
}
|
1480
|
+
altering_hash: scim_hash
|
2704
1481
|
)
|
2705
1482
|
|
2706
1483
|
expect(scim_hash['emails'][0]['value']).to eql('added_over_original@test.com')
|
@@ -2729,13 +1506,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2729
1506
|
nature: 'replace',
|
2730
1507
|
path: path,
|
2731
1508
|
value: {'type' => 'home', 'primary' => true, 'value' => 'home@test.com'},
|
2732
|
-
altering_hash: scim_hash
|
2733
|
-
with_attr_map: {
|
2734
|
-
emails: [
|
2735
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2736
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2737
|
-
]
|
2738
|
-
}
|
1509
|
+
altering_hash: scim_hash
|
2739
1510
|
)
|
2740
1511
|
|
2741
1512
|
expect(scim_hash['emails'].size).to eql(2)
|
@@ -2769,13 +1540,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2769
1540
|
nature: 'replace',
|
2770
1541
|
path: path,
|
2771
1542
|
value: {'type' => 'workinate', 'value' => 'replaced@test.com'},
|
2772
|
-
altering_hash: scim_hash
|
2773
|
-
with_attr_map: {
|
2774
|
-
emails: [
|
2775
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2776
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2777
|
-
]
|
2778
|
-
}
|
1543
|
+
altering_hash: scim_hash
|
2779
1544
|
)
|
2780
1545
|
|
2781
1546
|
expect(scim_hash['emails'].size).to eql(3)
|
@@ -2804,13 +1569,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2804
1569
|
nature: 'replace',
|
2805
1570
|
path: path,
|
2806
1571
|
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
|
2807
|
-
altering_hash: scim_hash
|
2808
|
-
with_attr_map: {
|
2809
|
-
emails: [
|
2810
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2811
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2812
|
-
]
|
2813
|
-
}
|
1572
|
+
altering_hash: scim_hash
|
2814
1573
|
)
|
2815
1574
|
|
2816
1575
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2829,8 +1588,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2829
1588
|
nature: 'replace',
|
2830
1589
|
path: path,
|
2831
1590
|
value: 'foo',
|
2832
|
-
altering_hash: scim_hash
|
2833
|
-
with_attr_map: { userName: :user_name }
|
1591
|
+
altering_hash: scim_hash
|
2834
1592
|
)
|
2835
1593
|
|
2836
1594
|
expect(scim_hash['userName']).to eql('foo')
|
@@ -2845,8 +1603,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2845
1603
|
nature: 'replace',
|
2846
1604
|
path: path,
|
2847
1605
|
value: 'Baz',
|
2848
|
-
altering_hash: scim_hash
|
2849
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
1606
|
+
altering_hash: scim_hash
|
2850
1607
|
)
|
2851
1608
|
|
2852
1609
|
expect(scim_hash['name']['givenName']).to eql('Baz')
|
@@ -2872,13 +1629,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2872
1629
|
nature: 'replace',
|
2873
1630
|
path: path,
|
2874
1631
|
value: 'added@test.com',
|
2875
|
-
altering_hash: scim_hash
|
2876
|
-
with_attr_map: {
|
2877
|
-
emails: [
|
2878
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2879
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2880
|
-
]
|
2881
|
-
}
|
1632
|
+
altering_hash: scim_hash
|
2882
1633
|
)
|
2883
1634
|
|
2884
1635
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -2903,13 +1654,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2903
1654
|
nature: 'replace',
|
2904
1655
|
path: path,
|
2905
1656
|
value: 'added@test.com',
|
2906
|
-
altering_hash: scim_hash
|
2907
|
-
with_attr_map: {
|
2908
|
-
emails: [
|
2909
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2910
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2911
|
-
]
|
2912
|
-
}
|
1657
|
+
altering_hash: scim_hash
|
2913
1658
|
)
|
2914
1659
|
|
2915
1660
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -2934,13 +1679,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2934
1679
|
nature: 'replace',
|
2935
1680
|
path: path,
|
2936
1681
|
value: 'added@test.com',
|
2937
|
-
altering_hash: scim_hash
|
2938
|
-
with_attr_map: {
|
2939
|
-
emails: [
|
2940
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2941
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2942
|
-
]
|
2943
|
-
}
|
1682
|
+
altering_hash: scim_hash
|
2944
1683
|
)
|
2945
1684
|
|
2946
1685
|
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
|
@@ -2958,13 +1697,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2958
1697
|
nature: 'replace',
|
2959
1698
|
path: path,
|
2960
1699
|
value: {'type' => 'work', 'value' => 'work@test.com'},
|
2961
|
-
altering_hash: scim_hash
|
2962
|
-
with_attr_map: {
|
2963
|
-
emails: [
|
2964
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2965
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2966
|
-
]
|
2967
|
-
}
|
1700
|
+
altering_hash: scim_hash
|
2968
1701
|
)
|
2969
1702
|
|
2970
1703
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2988,13 +1721,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2988
1721
|
nature: 'replace',
|
2989
1722
|
path: path,
|
2990
1723
|
value: {'type' => 'work', 'value' => 'work@test.com'},
|
2991
|
-
altering_hash: scim_hash
|
2992
|
-
with_attr_map: {
|
2993
|
-
emails: [
|
2994
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2995
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2996
|
-
]
|
2997
|
-
}
|
1724
|
+
altering_hash: scim_hash
|
2998
1725
|
)
|
2999
1726
|
|
3000
1727
|
expect(scim_hash['emails'].size).to eql(2)
|
@@ -3013,41 +1740,13 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3013
1740
|
nature: 'replace',
|
3014
1741
|
path: path,
|
3015
1742
|
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
|
3016
|
-
altering_hash: scim_hash
|
3017
|
-
with_attr_map: {
|
3018
|
-
emails: [
|
3019
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
3020
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
3021
|
-
]
|
3022
|
-
}
|
1743
|
+
altering_hash: scim_hash
|
3023
1744
|
)
|
3024
1745
|
|
3025
1746
|
expect(scim_hash['emails'].size).to eql(1)
|
3026
1747
|
expect(scim_hash['emails'][0]['type' ]).to eql('work')
|
3027
1748
|
expect(scim_hash['emails'][0]['value']).to eql('work@test.com')
|
3028
1749
|
end
|
3029
|
-
|
3030
|
-
context 'when prior value already exists, and no path' do
|
3031
|
-
it 'simple value: overwrites' do
|
3032
|
-
path = [ 'root' ]
|
3033
|
-
scim_hash = { 'root' => { 'userName' => 'bar', 'active' => true } }.with_indifferent_case_insensitive_access()
|
3034
|
-
|
3035
|
-
@instance.send(
|
3036
|
-
:from_patch_backend!,
|
3037
|
-
nature: 'replace',
|
3038
|
-
path: path,
|
3039
|
-
value: { 'active' => false }.with_indifferent_case_insensitive_access(),
|
3040
|
-
altering_hash: scim_hash,
|
3041
|
-
with_attr_map: {
|
3042
|
-
userName: :user_name,
|
3043
|
-
active: :active
|
3044
|
-
}
|
3045
|
-
)
|
3046
|
-
|
3047
|
-
expect(scim_hash['root']['userName']).to eql('bar')
|
3048
|
-
expect(scim_hash['root']['active']).to eql(false)
|
3049
|
-
end
|
3050
|
-
end
|
3051
1750
|
end # context 'when value is not present' do
|
3052
1751
|
end # "context 'replace' do"
|
3053
1752
|
|
@@ -3162,8 +1861,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3162
1861
|
nature: 'add',
|
3163
1862
|
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
|
3164
1863
|
value: [{ 'deeper' => 'addition' }],
|
3165
|
-
altering_hash: scim_hash
|
3166
|
-
with_attr_map: @contrived_class.scim_attributes_map()
|
1864
|
+
altering_hash: scim_hash
|
3167
1865
|
)
|
3168
1866
|
|
3169
1867
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
|
@@ -3186,8 +1884,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3186
1884
|
nature: 'replace',
|
3187
1885
|
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
|
3188
1886
|
value: [{ 'deeper' => 'addition' }],
|
3189
|
-
altering_hash: scim_hash
|
3190
|
-
with_attr_map: @contrived_class.scim_attributes_map()
|
1887
|
+
altering_hash: scim_hash
|
3191
1888
|
)
|
3192
1889
|
|
3193
1890
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged?
|
@@ -3204,25 +1901,24 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3204
1901
|
expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info', 0, 'deep')).to eql('nature2deep3') # Unchanged
|
3205
1902
|
end
|
3206
1903
|
|
3207
|
-
it 'removes
|
1904
|
+
it 'removes across multiple deep matching points' do
|
3208
1905
|
scim_hash = @original_hash.deep_dup().with_indifferent_case_insensitive_access()
|
3209
1906
|
contrived_instance = @contrived_class.new
|
3210
1907
|
contrived_instance.send(
|
3211
1908
|
:from_patch_backend!,
|
3212
1909
|
nature: 'remove',
|
3213
1910
|
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
|
3214
|
-
value:
|
3215
|
-
altering_hash: scim_hash
|
3216
|
-
with_attr_map: @contrived_class.scim_attributes_map()
|
1911
|
+
value: [{ 'deeper' => 'addition' }],
|
1912
|
+
altering_hash: scim_hash
|
3217
1913
|
)
|
3218
1914
|
|
3219
1915
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
|
3220
|
-
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to
|
1916
|
+
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to be_nil
|
3221
1917
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'nature')).to be_present
|
3222
|
-
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to
|
1918
|
+
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to be_nil
|
3223
1919
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'nature')).to be_present
|
3224
1920
|
|
3225
|
-
expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'info')).to
|
1921
|
+
expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'info')).to be_nil
|
3226
1922
|
expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'nature')).to be_present
|
3227
1923
|
|
3228
1924
|
expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
|
@@ -3256,13 +1952,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3256
1952
|
nature: 'replace',
|
3257
1953
|
path: path,
|
3258
1954
|
value: 'ignored',
|
3259
|
-
altering_hash: scim_hash
|
3260
|
-
with_attr_map: {
|
3261
|
-
emails: [
|
3262
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
3263
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
3264
|
-
]
|
3265
|
-
}
|
1955
|
+
altering_hash: scim_hash
|
3266
1956
|
)
|
3267
1957
|
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
|
3268
1958
|
end
|
@@ -3279,8 +1969,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3279
1969
|
nature: 'replace',
|
3280
1970
|
path: path,
|
3281
1971
|
value: 'ignored',
|
3282
|
-
altering_hash: scim_hash
|
3283
|
-
with_attr_map: { userName: :user_name }
|
1972
|
+
altering_hash: scim_hash
|
3284
1973
|
)
|
3285
1974
|
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
|
3286
1975
|
end
|
@@ -3300,13 +1989,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3300
1989
|
nature: 'replace',
|
3301
1990
|
path: path,
|
3302
1991
|
value: 'ignored',
|
3303
|
-
altering_hash: scim_hash
|
3304
|
-
with_attr_map: {
|
3305
|
-
emails: [
|
3306
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
3307
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
3308
|
-
]
|
3309
|
-
}
|
1992
|
+
altering_hash: scim_hash
|
3310
1993
|
)
|
3311
1994
|
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
|
3312
1995
|
end
|
@@ -3320,14 +2003,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3320
2003
|
#
|
3321
2004
|
context 'public interface' do
|
3322
2005
|
shared_examples 'a patcher' do | force_upper_case: |
|
3323
|
-
it 'gives the user a comprehensible error when operations are missing' do
|
3324
|
-
patch = { 'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'] }
|
3325
|
-
|
3326
|
-
expect do
|
3327
|
-
@instance.from_scim_patch!(patch_hash: patch)
|
3328
|
-
end.to raise_error Scimitar::InvalidSyntaxError, "Missing PATCH \"operations\""
|
3329
|
-
end
|
3330
|
-
|
3331
2006
|
it 'which updates simple values' do
|
3332
2007
|
@instance.update!(username: 'foo')
|
3333
2008
|
|
@@ -3349,28 +2024,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3349
2024
|
expect(@instance.username).to eql('1234')
|
3350
2025
|
end
|
3351
2026
|
|
3352
|
-
it 'which updates nested values using root syntax' do
|
3353
|
-
@instance.update!(first_name: 'Foo', last_name: 'Bar')
|
3354
|
-
|
3355
|
-
path = 'name.givenName'
|
3356
|
-
path = path.upcase if force_upper_case
|
3357
|
-
|
3358
|
-
patch = {
|
3359
|
-
'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
|
3360
|
-
'Operations' => [
|
3361
|
-
{
|
3362
|
-
'op' => 'replace',
|
3363
|
-
'value' => {
|
3364
|
-
path => 'Baz'
|
3365
|
-
}
|
3366
|
-
}
|
3367
|
-
]
|
3368
|
-
}
|
3369
|
-
|
3370
|
-
@instance.from_scim_patch!(patch_hash: patch)
|
3371
|
-
expect(@instance.first_name).to eql('Baz')
|
3372
|
-
end
|
3373
|
-
|
3374
2027
|
it 'which updates nested values' do
|
3375
2028
|
@instance.update!(first_name: 'Foo', last_name: 'Bar')
|
3376
2029
|
|
@@ -3392,38 +2045,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3392
2045
|
expect(@instance.first_name).to eql('Baz')
|
3393
2046
|
end
|
3394
2047
|
|
3395
|
-
# Note odd ":" separating schema ID from first attribute, although
|
3396
|
-
# the nature of JSON rendering / other payloads might lead you to
|
3397
|
-
# expect a "." as with any other path component.
|
3398
|
-
#
|
3399
|
-
# Note the ":" separating the schema ID (URN) from the attribute.
|
3400
|
-
# The nature of JSON rendering / other payloads might lead you to
|
3401
|
-
# expect a "." as with any complex types, but that's not the case;
|
3402
|
-
# see https://tools.ietf.org/html/rfc7644#section-3.10, or
|
3403
|
-
# https://tools.ietf.org/html/rfc7644#section-3.5.2 of which in
|
3404
|
-
# particular, https://tools.ietf.org/html/rfc7644#page-35.
|
3405
|
-
#
|
3406
|
-
it 'which updates attributes defined by extension schema' do
|
3407
|
-
@instance.update!(department: 'SOMEDPT')
|
3408
|
-
|
3409
|
-
path = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department'
|
3410
|
-
path = path.upcase if force_upper_case
|
3411
|
-
|
3412
|
-
patch = {
|
3413
|
-
'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
|
3414
|
-
'Operations' => [
|
3415
|
-
{
|
3416
|
-
'op' => 'replace',
|
3417
|
-
'path' => path,
|
3418
|
-
'value' => 'OTHERDPT'
|
3419
|
-
}
|
3420
|
-
]
|
3421
|
-
}
|
3422
|
-
|
3423
|
-
@instance.from_scim_patch!(patch_hash: patch)
|
3424
|
-
expect(@instance.department).to eql('OTHERDPT')
|
3425
|
-
end
|
3426
|
-
|
3427
2048
|
it 'which updates with filter match' do
|
3428
2049
|
@instance.update!(work_email_address: 'work@test.com', home_email_address: 'home@test.com')
|
3429
2050
|
|