scimitar 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scimitar/active_record_backed_resources_controller.rb +6 -27
  3. data/app/controllers/scimitar/application_controller.rb +9 -29
  4. data/app/models/scimitar/engine_configuration.rb +3 -7
  5. data/app/models/scimitar/error_response.rb +0 -12
  6. data/app/models/scimitar/errors.rb +1 -1
  7. data/app/models/scimitar/lists/query_parser.rb +4 -14
  8. data/app/models/scimitar/resources/base.rb +1 -1
  9. data/app/models/scimitar/resources/mixin.rb +2 -78
  10. data/app/models/scimitar/schema/address.rb +0 -1
  11. data/app/models/scimitar/schema/attribute.rb +1 -1
  12. data/app/models/scimitar/schema/base.rb +3 -1
  13. data/app/models/scimitar/schema/vdtp.rb +1 -1
  14. data/config/initializers/scimitar.rb +70 -86
  15. data/lib/scimitar/version.rb +2 -2
  16. data/spec/apps/dummy/app/controllers/mock_groups_controller.rb +1 -1
  17. data/spec/apps/dummy/app/models/mock_group.rb +1 -1
  18. data/spec/apps/dummy/app/models/mock_user.rb +7 -10
  19. data/spec/apps/dummy/config/application.rb +1 -0
  20. data/spec/apps/dummy/config/environments/test.rb +28 -5
  21. data/spec/apps/dummy/config/initializers/scimitar.rb +10 -8
  22. data/spec/apps/dummy/config/routes.rb +0 -4
  23. data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +2 -2
  24. data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +3 -8
  25. data/spec/apps/dummy/db/schema.rb +4 -8
  26. data/spec/controllers/scimitar/application_controller_spec.rb +1 -70
  27. data/spec/models/scimitar/complex_types/email_spec.rb +2 -0
  28. data/spec/models/scimitar/lists/query_parser_spec.rb +9 -9
  29. data/spec/models/scimitar/resources/base_validation_spec.rb +2 -27
  30. data/spec/models/scimitar/resources/mixin_spec.rb +40 -675
  31. data/spec/models/scimitar/resources/user_spec.rb +4 -4
  32. data/spec/models/scimitar/schema/attribute_spec.rb +3 -0
  33. data/spec/models/scimitar/schema/base_spec.rb +1 -1
  34. data/spec/models/scimitar/schema/user_spec.rb +0 -10
  35. data/spec/requests/active_record_backed_resources_controller_spec.rb +40 -309
  36. data/spec/requests/application_controller_spec.rb +3 -7
  37. metadata +7 -7
@@ -159,67 +159,41 @@ RSpec.describe Scimitar::Resources::Mixin do
159
159
  # =========================================================================
160
160
 
161
161
  context '#to_scim' do
162
- context 'with a UUID, renamed primary key column' do
163
- it 'compiles instance attribute values into a SCIM representation' do
164
- uuid = SecureRandom.uuid
165
-
166
- instance = MockUser.new
167
- instance.primary_key = uuid
168
- instance.scim_uid = 'AA02984'
169
- instance.username = 'foo'
170
- instance.first_name = 'Foo'
171
- instance.last_name = 'Bar'
172
- instance.work_email_address = 'foo.bar@test.com'
173
- instance.home_email_address = nil
174
- instance.work_phone_number = '+642201234567'
175
-
176
- g1 = MockGroup.create!(display_name: 'Group 1')
177
- g2 = MockGroup.create!(display_name: 'Group 2')
178
- g3 = MockGroup.create!(display_name: 'Group 3')
179
-
180
- g1.mock_users << instance
181
- g3.mock_users << instance
182
-
183
- scim = instance.to_scim(location: "https://test.com/mock_users/#{uuid}")
184
- json = scim.to_json()
185
- hash = JSON.parse(json)
186
-
187
- expect(hash).to eql({
188
- 'userName' => 'foo',
189
- 'name' => {'givenName'=>'Foo', 'familyName'=>'Bar'},
190
- 'active' => true,
191
- 'emails' => [{'type'=>'work', 'primary'=>true, 'value'=>'foo.bar@test.com'}, {"primary"=>false, "type"=>"home", "value"=>nil}],
192
- 'phoneNumbers'=> [{'type'=>'work', 'primary'=>false, 'value'=>'+642201234567'}],
193
- 'id' => uuid,
194
- 'externalId' => 'AA02984',
195
- 'groups' => [{'display'=>g1.display_name, 'value'=>g1.id.to_s}, {'display'=>g3.display_name, 'value'=>g3.id.to_s}],
196
- 'meta' => {'location'=>"https://test.com/mock_users/#{uuid}", 'resourceType'=>'User'},
197
- 'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
198
- })
199
- end
200
- end # "context 'with a UUID, renamed primary key column' do"
201
-
202
- context 'with an integer, conventionally named primary key column' do
203
- it 'compiles instance attribute values into a SCIM representation' do
204
- instance = MockGroup.new
205
- instance.id = 42
206
- instance.scim_uid = 'GG02984'
207
- instance.display_name = 'Some group'
208
-
209
- scim = instance.to_scim(location: 'https://test.com/mock_groups/42')
210
- json = scim.to_json()
211
- hash = JSON.parse(json)
212
-
213
- expect(hash).to eql({
214
- 'displayName' => 'Some group',
215
- 'id' => '42', # Note, String
216
- 'externalId' => 'GG02984',
217
- 'members' => [],
218
- 'meta' => {'location'=>'https://test.com/mock_groups/42', 'resourceType'=>'Group'},
219
- 'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:Group']
220
- })
221
- end
222
- 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
223
197
 
224
198
  context 'with optional timestamps' do
225
199
  context 'creation only' do
@@ -431,8 +405,8 @@ RSpec.describe Scimitar::Resources::Mixin do
431
405
  'displayName' => 'Foo Group',
432
406
  'members' => [
433
407
  {'type' => 'Group', 'value' => g1.id.to_s},
434
- {'type' => 'User', 'value' => u1.primary_key.to_s},
435
- {'type' => 'User', 'value' => u3.primary_key.to_s}
408
+ {'type' => 'User', 'value' => u1.id.to_s},
409
+ {'type' => 'User', 'value' => u3.id.to_s}
436
410
  ],
437
411
  'externalId' => 'GG01536',
438
412
  'meta' => {'location'=>'https://test.com/mock_groups/1', 'resourceType'=>'Group'},
@@ -479,10 +453,8 @@ RSpec.describe Scimitar::Resources::Mixin do
479
453
  end # "context 'using upper case' do"
480
454
 
481
455
  it 'clears things not present in input' do
482
- uuid = SecureRandom.uuid
483
-
484
456
  instance = MockUser.new
485
- instance.primary_key = uuid
457
+ instance.id = 42
486
458
  instance.scim_uid = 'AA02984'
487
459
  instance.username = 'foo'
488
460
  instance.first_name = 'Foo'
@@ -493,7 +465,7 @@ RSpec.describe Scimitar::Resources::Mixin do
493
465
 
494
466
  instance.from_scim!(scim_hash: {})
495
467
 
496
- expect(instance.primary_key ).to eql(uuid)
468
+ expect(instance.id ).to eql(42)
497
469
  expect(instance.scim_uid ).to be_nil
498
470
  expect(instance.username ).to be_nil
499
471
  expect(instance.first_name ).to be_nil
@@ -1230,595 +1202,6 @@ RSpec.describe Scimitar::Resources::Mixin do
1230
1202
 
1231
1203
  expect(scim_hash).to_not have_key('emails')
1232
1204
  end
1233
-
1234
- # What we expect:
1235
- #
1236
- # https://www.rfc-editor.org/rfc/rfc7644#section-3.5.2.2
1237
- # https://docs.snowflake.com/en/user-guide/scim-intro.html#patch-scim-v2-groups-id
1238
- #
1239
- # ...vs accounting for the unusual payloads we sometimes get,
1240
- # tested here.
1241
- #
1242
- context 'special cases' do
1243
-
1244
- # https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
1245
- #
1246
- context 'Microsoft-style payload' do
1247
- context 'removing a user from a group' do
1248
- it 'removes identified user' do
1249
- path = [ 'members' ]
1250
- value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ]
1251
- scim_hash = {
1252
- 'displayname' => 'Mock group',
1253
- 'members' => [
1254
- {
1255
- 'value' => '50ca93d04ab0c2de4772',
1256
- 'display' => 'Ingrid Smith',
1257
- 'type' => 'User'
1258
- },
1259
- {
1260
- 'value' => 'f648f8d5ea4e4cd38e9c',
1261
- 'display' => 'Fred Smith',
1262
- 'type' => 'User'
1263
- },
1264
- {
1265
- 'value' => 'a774d480e8112101375b',
1266
- 'display' => 'Taylor Smith',
1267
- 'type' => 'User'
1268
- }
1269
- ]
1270
- }.with_indifferent_case_insensitive_access()
1271
-
1272
- @instance.send(
1273
- :from_patch_backend!,
1274
- nature: 'remove',
1275
- path: path,
1276
- value: value,
1277
- altering_hash: scim_hash
1278
- )
1279
-
1280
- expect(scim_hash).to eql({
1281
- 'displayname' => 'Mock group',
1282
- 'members' => [
1283
- {
1284
- 'value' => '50ca93d04ab0c2de4772',
1285
- 'display' => 'Ingrid Smith',
1286
- 'type' => 'User'
1287
- },
1288
- {
1289
- 'value' => 'a774d480e8112101375b',
1290
- 'display' => 'Taylor Smith',
1291
- 'type' => 'User'
1292
- }
1293
- ]
1294
- })
1295
- end
1296
-
1297
- it 'removes multiple identified users' do
1298
- path = [ 'members' ]
1299
- value = [
1300
- { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' },
1301
- { '$ref' => nil, 'value' => '50ca93d04ab0c2de4772' }
1302
- ]
1303
- scim_hash = {
1304
- 'displayname' => 'Mock group',
1305
- 'members' => [
1306
- {
1307
- 'value' => '50ca93d04ab0c2de4772',
1308
- 'display' => 'Ingrid Smith',
1309
- 'type' => 'User'
1310
- },
1311
- {
1312
- 'value' => 'f648f8d5ea4e4cd38e9c',
1313
- 'display' => 'Fred Smith',
1314
- 'type' => 'User'
1315
- },
1316
- {
1317
- 'value' => 'a774d480e8112101375b',
1318
- 'display' => 'Taylor Smith',
1319
- 'type' => 'User'
1320
- }
1321
- ]
1322
- }.with_indifferent_case_insensitive_access()
1323
-
1324
- @instance.send(
1325
- :from_patch_backend!,
1326
- nature: 'remove',
1327
- path: path,
1328
- value: value,
1329
- altering_hash: scim_hash
1330
- )
1331
-
1332
- expect(scim_hash).to eql({
1333
- 'displayname' => 'Mock group',
1334
- 'members' => [
1335
- {
1336
- 'value' => 'a774d480e8112101375b',
1337
- 'display' => 'Taylor Smith',
1338
- 'type' => 'User'
1339
- }
1340
- ]
1341
- })
1342
- end
1343
-
1344
- it 'removes all users individually without error' do
1345
- path = [ 'members' ]
1346
- value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ]
1347
- scim_hash = {
1348
- 'displayname' => 'Mock group',
1349
- 'members' => [
1350
- {
1351
- 'value' => 'f648f8d5ea4e4cd38e9c',
1352
- 'display' => 'Fred Smith',
1353
- 'type' => 'User'
1354
- }
1355
- ]
1356
- }.with_indifferent_case_insensitive_access()
1357
-
1358
- @instance.send(
1359
- :from_patch_backend!,
1360
- nature: 'remove',
1361
- path: path,
1362
- value: value,
1363
- altering_hash: scim_hash
1364
- )
1365
-
1366
- expect(scim_hash).to eql({
1367
- 'displayname' => 'Mock group',
1368
- 'members' => []
1369
- })
1370
- end
1371
-
1372
- it 'can match on multiple attributes' do
1373
- path = [ 'members' ]
1374
- value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'User' } ]
1375
- scim_hash = {
1376
- 'displayname' => 'Mock group',
1377
- 'members' => [
1378
- {
1379
- 'value' => 'f648f8d5ea4e4cd38e9c',
1380
- 'display' => 'Fred Smith',
1381
- 'type' => 'User'
1382
- }
1383
- ]
1384
- }.with_indifferent_case_insensitive_access()
1385
-
1386
- @instance.send(
1387
- :from_patch_backend!,
1388
- nature: 'remove',
1389
- path: path,
1390
- value: value,
1391
- altering_hash: scim_hash
1392
- )
1393
-
1394
- expect(scim_hash).to eql({
1395
- 'displayname' => 'Mock group',
1396
- 'members' => []
1397
- })
1398
- end
1399
-
1400
- it 'ignores unrecognised users' do
1401
- path = [ 'members' ]
1402
- value = [ { '$ref' => nil, 'value' => '11b054a9c85216ed9356' } ]
1403
- scim_hash = {
1404
- 'displayname' => 'Mock group',
1405
- 'members' => [
1406
- {
1407
- 'value' => 'f648f8d5ea4e4cd38e9c',
1408
- 'display' => 'Fred Smith',
1409
- 'type' => 'User'
1410
- }
1411
- ]
1412
- }.with_indifferent_case_insensitive_access()
1413
-
1414
- @instance.send(
1415
- :from_patch_backend!,
1416
- nature: 'remove',
1417
- path: path,
1418
- value: value,
1419
- altering_hash: scim_hash
1420
- )
1421
-
1422
- # The 'value' mismatched, so the user was not removed.
1423
- #
1424
- expect(scim_hash).to eql({
1425
- 'displayname' => 'Mock group',
1426
- 'members' => [
1427
- {
1428
- 'value' => 'f648f8d5ea4e4cd38e9c',
1429
- 'display' => 'Fred Smith',
1430
- 'type' => 'User'
1431
- }
1432
- ]
1433
- })
1434
- end
1435
-
1436
- it 'ignores a mismatch on (for example) "type"' do
1437
- path = [ 'members' ]
1438
- value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'Group' } ]
1439
- scim_hash = {
1440
- 'displayname' => 'Mock group',
1441
- 'members' => [
1442
- {
1443
- 'value' => 'f648f8d5ea4e4cd38e9c',
1444
- 'display' => 'Fred Smith',
1445
- 'type' => 'User'
1446
- }
1447
- ]
1448
- }.with_indifferent_case_insensitive_access()
1449
-
1450
- @instance.send(
1451
- :from_patch_backend!,
1452
- nature: 'remove',
1453
- path: path,
1454
- value: value,
1455
- altering_hash: scim_hash
1456
- )
1457
-
1458
- # Type 'Group' mismatches 'User', so the user was not
1459
- # removed.
1460
- #
1461
- expect(scim_hash).to eql({
1462
- 'displayname' => 'Mock group',
1463
- 'members' => [
1464
- {
1465
- 'value' => 'f648f8d5ea4e4cd38e9c',
1466
- 'display' => 'Fred Smith',
1467
- 'type' => 'User'
1468
- }
1469
- ]
1470
- })
1471
- end
1472
-
1473
- it 'matches keys case-insensitive' do
1474
- path = [ 'members' ]
1475
- value = [ { '$ref' => nil, 'VALUe' => 'f648f8d5ea4e4cd38e9c' } ]
1476
- scim_hash = {
1477
- 'displayname' => 'Mock group',
1478
- 'memBERS' => [
1479
- {
1480
- 'vaLUe' => 'f648f8d5ea4e4cd38e9c',
1481
- 'display' => 'Fred Smith',
1482
- 'type' => 'User'
1483
- }
1484
- ]
1485
- }.with_indifferent_case_insensitive_access()
1486
-
1487
- @instance.send(
1488
- :from_patch_backend!,
1489
- nature: 'remove',
1490
- path: path,
1491
- value: value,
1492
- altering_hash: scim_hash
1493
- )
1494
-
1495
- expect(scim_hash).to eql({
1496
- 'displayname' => 'Mock group',
1497
- 'members' => []
1498
- })
1499
- end
1500
-
1501
- it 'matches values case-sensitive' do
1502
- path = [ 'members' ]
1503
- value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'USER' } ]
1504
- scim_hash = {
1505
- 'displayname' => 'Mock group',
1506
- 'members' => [
1507
- {
1508
- 'value' => 'f648f8d5ea4e4cd38e9c',
1509
- 'display' => 'Fred Smith',
1510
- 'type' => 'User'
1511
- }
1512
- ]
1513
- }.with_indifferent_case_insensitive_access()
1514
-
1515
- @instance.send(
1516
- :from_patch_backend!,
1517
- nature: 'remove',
1518
- path: path,
1519
- value: value,
1520
- altering_hash: scim_hash
1521
- )
1522
-
1523
- # USER mismatchs User, so the user was not removed.
1524
- #
1525
- expect(scim_hash).to eql({
1526
- 'displayname' => 'Mock group',
1527
- 'members' => [
1528
- {
1529
- 'value' => 'f648f8d5ea4e4cd38e9c',
1530
- 'display' => 'Fred Smith',
1531
- 'type' => 'User'
1532
- }
1533
- ]
1534
- })
1535
- end
1536
- end # "context 'removing a user from a group' do"
1537
-
1538
- context 'generic use' do
1539
- it 'removes matched items' do
1540
- path = [ 'emails' ]
1541
- value = [ { 'type' => 'work' } ]
1542
- scim_hash = {
1543
- 'emails' => [
1544
- {
1545
- 'type' => 'home',
1546
- 'value' => 'home@test.com'
1547
- },
1548
- {
1549
- 'type' => 'work',
1550
- 'value' => 'work@test.com'
1551
- }
1552
- ]
1553
- }.with_indifferent_case_insensitive_access()
1554
-
1555
- @instance.send(
1556
- :from_patch_backend!,
1557
- nature: 'remove',
1558
- path: path,
1559
- value: value,
1560
- altering_hash: scim_hash
1561
- )
1562
-
1563
- expect(scim_hash).to eql({
1564
- 'emails' => [
1565
- {
1566
- 'type' => 'home',
1567
- 'value' => 'home@test.com'
1568
- }
1569
- ]
1570
- })
1571
- end
1572
-
1573
- it 'ignores unmatched items' do
1574
- path = [ 'emails' ]
1575
- value = [ { 'type' => 'missing' } ]
1576
- scim_hash = {
1577
- 'emails' => [
1578
- {
1579
- 'type' => 'home',
1580
- 'value' => 'home@test.com'
1581
- },
1582
- {
1583
- 'type' => 'work',
1584
- 'value' => 'work@test.com'
1585
- }
1586
- ]
1587
- }.with_indifferent_case_insensitive_access()
1588
-
1589
- @instance.send(
1590
- :from_patch_backend!,
1591
- nature: 'remove',
1592
- path: path,
1593
- value: value,
1594
- altering_hash: scim_hash
1595
- )
1596
-
1597
- expect(scim_hash).to eql({
1598
- 'emails' => [
1599
- {
1600
- 'type' => 'home',
1601
- 'value' => 'home@test.com'
1602
- },
1603
- {
1604
- 'type' => 'work',
1605
- 'value' => 'work@test.com'
1606
- }
1607
- ]
1608
- })
1609
- end
1610
-
1611
- it 'compares string forms' do
1612
- path = [ 'test' ]
1613
- value = [
1614
- { 'active' => true, 'value' => '12' },
1615
- { 'active' => 'false', 'value' => 42 }
1616
- ]
1617
- scim_hash = {
1618
- 'test' => [
1619
- {
1620
- 'active' => 'true',
1621
- 'value' => 12
1622
- },
1623
- {
1624
- 'active' => false,
1625
- 'value' => '42'
1626
- }
1627
- ]
1628
- }.with_indifferent_case_insensitive_access()
1629
-
1630
- @instance.send(
1631
- :from_patch_backend!,
1632
- nature: 'remove',
1633
- path: path,
1634
- value: value,
1635
- altering_hash: scim_hash
1636
- )
1637
-
1638
- expect(scim_hash).to eql({'test' => []})
1639
- end
1640
-
1641
- it 'handles a singular to-remove value rather than an array' do
1642
- path = [ 'emails' ]
1643
- value = { 'type' => 'work' }
1644
- scim_hash = {
1645
- 'emails' => [
1646
- {
1647
- 'type' => 'home',
1648
- 'value' => 'home@test.com'
1649
- },
1650
- {
1651
- 'type' => 'work',
1652
- 'value' => 'work@test.com'
1653
- }
1654
- ]
1655
- }.with_indifferent_case_insensitive_access()
1656
-
1657
- @instance.send(
1658
- :from_patch_backend!,
1659
- nature: 'remove',
1660
- path: path,
1661
- value: value,
1662
- altering_hash: scim_hash
1663
- )
1664
-
1665
- expect(scim_hash).to eql({
1666
- 'emails' => [
1667
- {
1668
- 'type' => 'home',
1669
- 'value' => 'home@test.com'
1670
- }
1671
- ]
1672
- })
1673
- end
1674
-
1675
- it 'handles simple values rather than object (Hash) values' do
1676
- path = [ 'test' ]
1677
- value = 42
1678
- scim_hash = {
1679
- 'test' => [
1680
- '21',
1681
- '42',
1682
- '15'
1683
- ]
1684
- }.with_indifferent_case_insensitive_access()
1685
-
1686
- @instance.send(
1687
- :from_patch_backend!,
1688
- nature: 'remove',
1689
- path: path,
1690
- value: value,
1691
- altering_hash: scim_hash
1692
- )
1693
-
1694
- expect(scim_hash).to eql({
1695
- 'test' => [
1696
- '21',
1697
- '15'
1698
- ]
1699
- })
1700
- end
1701
- end
1702
- end # "context 'Microsoft-style payload' do"
1703
-
1704
- # https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
1705
- #
1706
- context 'Salesforce-style payload' do
1707
- it 'removes identified user' do
1708
- path = [ 'members' ]
1709
- value = { 'members' => [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ] }
1710
- scim_hash = {
1711
- 'displayname' => 'Mock group',
1712
- 'members' => [
1713
- {
1714
- 'value' => '50ca93d04ab0c2de4772',
1715
- 'display' => 'Ingrid Smith',
1716
- 'type' => 'User'
1717
- },
1718
- {
1719
- 'value' => 'f648f8d5ea4e4cd38e9c',
1720
- 'display' => 'Fred Smith',
1721
- 'type' => 'User'
1722
- }
1723
- ]
1724
- }.with_indifferent_case_insensitive_access()
1725
-
1726
- @instance.send(
1727
- :from_patch_backend!,
1728
- nature: 'remove',
1729
- path: path,
1730
- value: value,
1731
- altering_hash: scim_hash
1732
- )
1733
-
1734
- expect(scim_hash).to eql({
1735
- 'displayname' => 'Mock group',
1736
- 'members' => [
1737
- {
1738
- 'value' => '50ca93d04ab0c2de4772',
1739
- 'display' => 'Ingrid Smith',
1740
- 'type' => 'User'
1741
- }
1742
- ]
1743
- })
1744
- end
1745
-
1746
- it 'matches the "members" key case-insensitive' do
1747
- path = [ 'members' ]
1748
- value = { 'MEMBERS' => [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ] }
1749
- scim_hash = {
1750
- 'displayname' => 'Mock group',
1751
- 'members' => [
1752
- {
1753
- 'value' => 'f648f8d5ea4e4cd38e9c',
1754
- 'display' => 'Fred Smith',
1755
- 'type' => 'User'
1756
- },
1757
- {
1758
- 'value' => 'a774d480e8112101375b',
1759
- 'display' => 'Taylor Smith',
1760
- 'type' => 'User'
1761
- }
1762
- ]
1763
- }.with_indifferent_case_insensitive_access()
1764
-
1765
- @instance.send(
1766
- :from_patch_backend!,
1767
- nature: 'remove',
1768
- path: path,
1769
- value: value,
1770
- altering_hash: scim_hash
1771
- )
1772
-
1773
- expect(scim_hash).to eql({
1774
- 'displayname' => 'Mock group',
1775
- 'members' => [
1776
- {
1777
- 'value' => 'a774d480e8112101375b',
1778
- 'display' => 'Taylor Smith',
1779
- 'type' => 'User'
1780
- }
1781
- ]
1782
- })
1783
- end
1784
-
1785
- it 'ignores unrecognised users' do
1786
- path = [ 'members' ]
1787
- value = { 'members' => [ { '$ref' => nil, 'value' => '11b054a9c85216ed9356' } ] }
1788
- scim_hash = {
1789
- 'displayname' => 'Mock group',
1790
- 'members' => [
1791
- {
1792
- 'value' => 'f648f8d5ea4e4cd38e9c',
1793
- 'display' => 'Fred Smith',
1794
- 'type' => 'User'
1795
- }
1796
- ]
1797
- }.with_indifferent_case_insensitive_access()
1798
-
1799
- @instance.send(
1800
- :from_patch_backend!,
1801
- nature: 'remove',
1802
- path: path,
1803
- value: value,
1804
- altering_hash: scim_hash
1805
- )
1806
-
1807
- # The 'value' mismatched, so the user was not removed.
1808
- #
1809
- expect(scim_hash).to eql({
1810
- 'displayname' => 'Mock group',
1811
- 'members' => [
1812
- {
1813
- 'value' => 'f648f8d5ea4e4cd38e9c',
1814
- 'display' => 'Fred Smith',
1815
- 'type' => 'User'
1816
- }
1817
- ]
1818
- })
1819
- end
1820
- end # "context 'Salesforce-style payload' do"
1821
- end # "context 'special cases' do"
1822
1205
  end # context 'when prior value already exists' do
1823
1206
 
1824
1207
  context 'when value is not present' do
@@ -2364,24 +1747,6 @@ RSpec.describe Scimitar::Resources::Mixin do
2364
1747
  expect(scim_hash['emails'][0]['type' ]).to eql('work')
2365
1748
  expect(scim_hash['emails'][0]['value']).to eql('work@test.com')
2366
1749
  end
2367
-
2368
- context 'when prior value already exists, and no path' do
2369
- it 'simple value: overwrites' do
2370
- path = [ 'root' ]
2371
- scim_hash = { 'root' => { 'userName' => 'bar', 'active' => true } }.with_indifferent_case_insensitive_access()
2372
-
2373
- @instance.send(
2374
- :from_patch_backend!,
2375
- nature: 'replace',
2376
- path: path,
2377
- value: { 'active' => false }.with_indifferent_case_insensitive_access(),
2378
- altering_hash: scim_hash
2379
- )
2380
-
2381
- expect(scim_hash['root']['userName']).to eql('bar')
2382
- expect(scim_hash['root']['active']).to eql(false)
2383
- end
2384
- end
2385
1750
  end # context 'when value is not present' do
2386
1751
  end # "context 'replace' do"
2387
1752
 
@@ -2543,7 +1908,7 @@ RSpec.describe Scimitar::Resources::Mixin do
2543
1908
  :from_patch_backend!,
2544
1909
  nature: 'remove',
2545
1910
  path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
2546
- value: nil,
1911
+ value: [{ 'deeper' => 'addition' }],
2547
1912
  altering_hash: scim_hash
2548
1913
  )
2549
1914