scimitar 1.3.3 → 1.5.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 +27 -7
- data/app/models/scimitar/resources/mixin.rb +73 -1
- data/lib/scimitar/version.rb +2 -2
- 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 +3 -3
- data/spec/apps/dummy/config/routes.rb +4 -0
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +2 -2
- data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +8 -3
- data/spec/apps/dummy/db/schema.rb +9 -7
- data/spec/models/scimitar/lists/query_parser_spec.rb +8 -8
- data/spec/models/scimitar/resources/mixin_spec.rb +657 -40
- data/spec/models/scimitar/resources/user_spec.rb +2 -2
- data/spec/requests/active_record_backed_resources_controller_spec.rb +232 -48
- metadata +35 -37
- data/spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb +0 -5
@@ -42,13 +42,13 @@ RSpec.describe Scimitar::Resources::User do
|
|
42
42
|
let(:user) { described_class.new }
|
43
43
|
|
44
44
|
it 'adds the error when the value is a string' do
|
45
|
-
user.add_errors_from_hash(key: 'some error')
|
45
|
+
user.add_errors_from_hash({key: 'some error'})
|
46
46
|
expect(user.errors.messages.to_h).to eql({key: ['some error']})
|
47
47
|
expect(user.errors.full_messages).to eql(['Key some error'])
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'adds the error when the value is an array' do
|
51
|
-
user.add_errors_from_hash(key: ['error1', 'error2'])
|
51
|
+
user.add_errors_from_hash({key: ['error1', 'error2']})
|
52
52
|
expect(user.errors.messages.to_h).to eql({key: ['error1', 'error2']})
|
53
53
|
expect(user.errors.full_messages).to eql(['Key error1', 'Key error2'])
|
54
54
|
end
|
@@ -7,9 +7,21 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
7
7
|
|
8
8
|
lmt = Time.parse("2023-01-09 14:25:00 +1300")
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
# If a sort order is unspecified, the controller defaults to ID ascending.
|
11
|
+
# With UUID based IDs, testing life is made easier by ensuring that the
|
12
|
+
# creation order matches an ascending UUID sort order (which is what would
|
13
|
+
# happen if we were using integer primary keys).
|
14
|
+
#
|
15
|
+
lmt = Time.parse("2023-01-09 14:25:00 +1300")
|
16
|
+
ids = 3.times.map { SecureRandom.uuid }.sort()
|
17
|
+
|
18
|
+
@u1 = MockUser.create(primary_key: ids.shift(), username: '1', first_name: 'Foo', last_name: 'Ark', home_email_address: 'home_1@test.com', scim_uid: '001', created_at: lmt, updated_at: lmt + 1)
|
19
|
+
@u2 = MockUser.create(primary_key: ids.shift(), username: '2', first_name: 'Foo', last_name: 'Bar', home_email_address: 'home_2@test.com', scim_uid: '002', created_at: lmt, updated_at: lmt + 2)
|
20
|
+
@u3 = MockUser.create(primary_key: ids.shift(), username: '3', first_name: 'Foo', home_email_address: 'home_3@test.com', scim_uid: '003', created_at: lmt, updated_at: lmt + 3)
|
21
|
+
|
22
|
+
@g1 = MockGroup.create!(display_name: 'Group 1')
|
23
|
+
@g2 = MockGroup.create!(display_name: 'Group 2')
|
24
|
+
@g3 = MockGroup.create!(display_name: 'Group 3')
|
13
25
|
end
|
14
26
|
|
15
27
|
# ===========================================================================
|
@@ -32,21 +44,41 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
32
44
|
end # "context 'with no items' do"
|
33
45
|
|
34
46
|
context 'with items' do
|
35
|
-
|
36
|
-
|
47
|
+
context 'with a UUID, renamed primary key column' do
|
48
|
+
it 'returns all items' do
|
49
|
+
get '/Users', params: { format: :scim }
|
37
50
|
|
38
|
-
|
39
|
-
|
51
|
+
expect(response.status).to eql(200)
|
52
|
+
result = JSON.parse(response.body)
|
40
53
|
|
41
|
-
|
42
|
-
|
54
|
+
expect(result['totalResults']).to eql(3)
|
55
|
+
expect(result['Resources'].size).to eql(3)
|
43
56
|
|
44
|
-
|
45
|
-
|
57
|
+
ids = result['Resources'].map { |resource| resource['id'] }
|
58
|
+
expect(ids).to match_array([@u1.primary_key.to_s, @u2.primary_key.to_s, @u3.primary_key.to_s])
|
46
59
|
|
47
|
-
|
48
|
-
|
49
|
-
|
60
|
+
usernames = result['Resources'].map { |resource| resource['userName'] }
|
61
|
+
expect(usernames).to match_array(['1', '2', '3'])
|
62
|
+
end
|
63
|
+
end # "context 'with a UUID, renamed primary key column' do"
|
64
|
+
|
65
|
+
context 'with an integer, conventionally named primary key column' do
|
66
|
+
it 'returns all items' do
|
67
|
+
get '/Groups', params: { format: :scim }
|
68
|
+
|
69
|
+
expect(response.status).to eql(200)
|
70
|
+
result = JSON.parse(response.body)
|
71
|
+
|
72
|
+
expect(result['totalResults']).to eql(3)
|
73
|
+
expect(result['Resources'].size).to eql(3)
|
74
|
+
|
75
|
+
ids = result['Resources'].map { |resource| resource['id'] }
|
76
|
+
expect(ids).to match_array([@g1.id.to_s, @g2.id.to_s, @g3.id.to_s])
|
77
|
+
|
78
|
+
usernames = result['Resources'].map { |resource| resource['displayName'] }
|
79
|
+
expect(usernames).to match_array(['Group 1', 'Group 2', 'Group 3'])
|
80
|
+
end
|
81
|
+
end # "context 'with an integer, conventionally named primary key column' do"
|
50
82
|
|
51
83
|
it 'applies a filter, with case-insensitive value comparison' do
|
52
84
|
get '/Users', params: {
|
@@ -61,7 +93,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
61
93
|
expect(result['Resources'].size).to eql(1)
|
62
94
|
|
63
95
|
ids = result['Resources'].map { |resource| resource['id'] }
|
64
|
-
expect(ids).to match_array([@u2.
|
96
|
+
expect(ids).to match_array([@u2.primary_key.to_s])
|
65
97
|
|
66
98
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
67
99
|
expect(usernames).to match_array(['2'])
|
@@ -80,7 +112,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
80
112
|
expect(result['Resources'].size).to eql(1)
|
81
113
|
|
82
114
|
ids = result['Resources'].map { |resource| resource['id'] }
|
83
|
-
expect(ids).to match_array([@u2.
|
115
|
+
expect(ids).to match_array([@u2.primary_key.to_s])
|
84
116
|
|
85
117
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
86
118
|
expect(usernames).to match_array(['2'])
|
@@ -93,7 +125,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
93
125
|
it 'applies a filter on primary keys, using direct comparison (rather than e.g. case-insensitive operators)' do
|
94
126
|
get '/Users', params: {
|
95
127
|
format: :scim,
|
96
|
-
filter: "id eq \"#{@u3.
|
128
|
+
filter: "id eq \"#{@u3.primary_key}\""
|
97
129
|
}
|
98
130
|
|
99
131
|
expect(response.status).to eql(200)
|
@@ -103,7 +135,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
103
135
|
expect(result['Resources'].size).to eql(1)
|
104
136
|
|
105
137
|
ids = result['Resources'].map { |resource| resource['id'] }
|
106
|
-
expect(ids).to match_array([@u3.
|
138
|
+
expect(ids).to match_array([@u3.primary_key.to_s])
|
107
139
|
|
108
140
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
109
141
|
expect(usernames).to match_array(['3'])
|
@@ -122,7 +154,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
122
154
|
expect(result['Resources'].size).to eql(1)
|
123
155
|
|
124
156
|
ids = result['Resources'].map { |resource| resource['id'] }
|
125
|
-
expect(ids).to match_array([@u2.
|
157
|
+
expect(ids).to match_array([@u2.primary_key.to_s])
|
126
158
|
|
127
159
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
128
160
|
expect(usernames).to match_array(['2'])
|
@@ -141,7 +173,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
141
173
|
expect(result['Resources'].size).to eql(1)
|
142
174
|
|
143
175
|
ids = result['Resources'].map { |resource| resource['id'] }
|
144
|
-
expect(ids).to match_array([@u3.
|
176
|
+
expect(ids).to match_array([@u3.primary_key.to_s])
|
145
177
|
|
146
178
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
147
179
|
expect(usernames).to match_array(['3'])
|
@@ -161,7 +193,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
161
193
|
expect(result['Resources'].size).to eql(2)
|
162
194
|
|
163
195
|
ids = result['Resources'].map { |resource| resource['id'] }
|
164
|
-
expect(ids).to match_array([@u1.
|
196
|
+
expect(ids).to match_array([@u1.primary_key.to_s, @u2.primary_key.to_s])
|
165
197
|
|
166
198
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
167
199
|
expect(usernames).to match_array(['1', '2'])
|
@@ -180,7 +212,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
180
212
|
expect(result['Resources'].size).to eql(2)
|
181
213
|
|
182
214
|
ids = result['Resources'].map { |resource| resource['id'] }
|
183
|
-
expect(ids).to match_array([@u2.
|
215
|
+
expect(ids).to match_array([@u2.primary_key.to_s, @u3.primary_key.to_s])
|
184
216
|
|
185
217
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
186
218
|
expect(usernames).to match_array(['2', '3'])
|
@@ -204,18 +236,34 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
204
236
|
# ===========================================================================
|
205
237
|
|
206
238
|
context '#show' do
|
207
|
-
|
208
|
-
|
209
|
-
|
239
|
+
context 'with a UUID, renamed primary key column' do
|
240
|
+
it 'shows an item' do
|
241
|
+
expect_any_instance_of(MockUsersController).to receive(:show).once.and_call_original
|
242
|
+
get "/Users/#{@u2.primary_key}", params: { format: :scim }
|
210
243
|
|
211
|
-
|
212
|
-
|
244
|
+
expect(response.status).to eql(200)
|
245
|
+
result = JSON.parse(response.body)
|
213
246
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
247
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
248
|
+
expect(result['userName']).to eql('2')
|
249
|
+
expect(result['name']['familyName']).to eql('Bar')
|
250
|
+
expect(result['meta']['resourceType']).to eql('User')
|
251
|
+
end
|
252
|
+
end # "context 'with a UUID, renamed primary key column' do"
|
253
|
+
|
254
|
+
context 'with an integer, conventionally named primary key column' do
|
255
|
+
it 'shows an item' do
|
256
|
+
expect_any_instance_of(MockGroupsController).to receive(:show).once.and_call_original
|
257
|
+
get "/Groups/#{@g2.id}", params: { format: :scim }
|
258
|
+
|
259
|
+
expect(response.status).to eql(200)
|
260
|
+
result = JSON.parse(response.body)
|
261
|
+
|
262
|
+
expect(result['id']).to eql(@g2.id.to_s) # Note - ID was converted String; not Integer
|
263
|
+
expect(result['displayName']).to eql('Group 2')
|
264
|
+
expect(result['meta']['resourceType']).to eql('Group')
|
265
|
+
end
|
266
|
+
end # "context 'with an integer, conventionally named primary key column' do"
|
219
267
|
|
220
268
|
it 'renders 404' do
|
221
269
|
get '/Users/xyz', params: { format: :scim }
|
@@ -248,7 +296,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
248
296
|
expect(response.status).to eql(201)
|
249
297
|
result = JSON.parse(response.body)
|
250
298
|
|
251
|
-
expect(result['id']).to eql(new_mock.
|
299
|
+
expect(result['id']).to eql(new_mock.primary_key.to_s)
|
252
300
|
expect(result['meta']['resourceType']).to eql('User')
|
253
301
|
expect(new_mock.username).to eql('4')
|
254
302
|
end
|
@@ -289,7 +337,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
289
337
|
expect(response.status).to eql(201)
|
290
338
|
result = JSON.parse(response.body)
|
291
339
|
|
292
|
-
expect(result['id']).to eql(new_mock.
|
340
|
+
expect(result['id']).to eql(new_mock.primary_key.to_s)
|
293
341
|
expect(result['meta']['resourceType']).to eql('User')
|
294
342
|
expect(new_mock.username).to eql('4')
|
295
343
|
expect(new_mock.first_name).to eql('Given')
|
@@ -363,13 +411,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
363
411
|
|
364
412
|
expect_any_instance_of(MockUsersController).to receive(:replace).once.and_call_original
|
365
413
|
expect {
|
366
|
-
put "/Users/#{@u2.
|
414
|
+
put "/Users/#{@u2.primary_key}", params: attributes.merge(format: :scim)
|
367
415
|
}.to_not change { MockUser.count }
|
368
416
|
|
369
417
|
expect(response.status).to eql(200)
|
370
418
|
result = JSON.parse(response.body)
|
371
419
|
|
372
|
-
expect(result['id']).to eql(@u2.
|
420
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
373
421
|
expect(result['meta']['resourceType']).to eql('User')
|
374
422
|
|
375
423
|
@u2.reload
|
@@ -391,7 +439,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
391
439
|
|
392
440
|
it 'notes schema validation failures' do
|
393
441
|
expect {
|
394
|
-
put "/Users/#{@u2.
|
442
|
+
put "/Users/#{@u2.primary_key}", params: {
|
395
443
|
format: :scim
|
396
444
|
# userName parameter is required by schema, but missing
|
397
445
|
}
|
@@ -470,13 +518,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
470
518
|
|
471
519
|
expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
|
472
520
|
expect {
|
473
|
-
patch "/Users/#{@u2.
|
521
|
+
patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
|
474
522
|
}.to_not change { MockUser.count }
|
475
523
|
|
476
524
|
expect(response.status).to eql(200)
|
477
525
|
result = JSON.parse(response.body)
|
478
526
|
|
479
|
-
expect(result['id']).to eql(@u2.
|
527
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
480
528
|
expect(result['meta']['resourceType']).to eql('User')
|
481
529
|
|
482
530
|
@u2.reload
|
@@ -507,13 +555,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
507
555
|
|
508
556
|
expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
|
509
557
|
expect {
|
510
|
-
patch "/Users/#{@u2.
|
558
|
+
patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
|
511
559
|
}.to_not change { MockUser.count }
|
512
560
|
|
513
561
|
expect(response.status).to eql(200)
|
514
562
|
result = JSON.parse(response.body)
|
515
563
|
|
516
|
-
expect(result['id']).to eql(@u2.
|
564
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
517
565
|
expect(result['meta']['resourceType']).to eql('User')
|
518
566
|
|
519
567
|
@u2.reload
|
@@ -539,13 +587,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
539
587
|
|
540
588
|
expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
|
541
589
|
expect {
|
542
|
-
patch "/Users/#{@u2.
|
590
|
+
patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
|
543
591
|
}.to_not change { MockUser.count }
|
544
592
|
|
545
593
|
expect(response.status).to eql(200)
|
546
594
|
result = JSON.parse(response.body)
|
547
595
|
|
548
|
-
expect(result['id']).to eql(@u2.
|
596
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
549
597
|
expect(result['meta']['resourceType']).to eql('User')
|
550
598
|
|
551
599
|
@u2.reload
|
@@ -571,13 +619,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
571
619
|
|
572
620
|
expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
|
573
621
|
expect {
|
574
|
-
patch "/Users/#{@u2.
|
622
|
+
patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
|
575
623
|
}.to_not change { MockUser.count }
|
576
624
|
|
577
625
|
expect(response.status).to eql(200)
|
578
626
|
result = JSON.parse(response.body)
|
579
627
|
|
580
|
-
expect(result['id']).to eql(@u2.
|
628
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
581
629
|
expect(result['meta']['resourceType']).to eql('User')
|
582
630
|
|
583
631
|
@u2.reload
|
@@ -601,7 +649,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
601
649
|
|
602
650
|
it 'notes Rails validation failures' do
|
603
651
|
expect {
|
604
|
-
patch "/Users/#{@u2.
|
652
|
+
patch "/Users/#{@u2.primary_key}", params: {
|
605
653
|
format: :scim,
|
606
654
|
Operations: [
|
607
655
|
{
|
@@ -645,6 +693,142 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
645
693
|
result = JSON.parse(response.body)
|
646
694
|
expect(result['status']).to eql('404')
|
647
695
|
end
|
696
|
+
|
697
|
+
context 'when removing users from groups' do
|
698
|
+
before :each do
|
699
|
+
@g1.mock_users << @u1
|
700
|
+
@g1.mock_users << @u2
|
701
|
+
@g1.mock_users << @u3
|
702
|
+
|
703
|
+
# (Self-check) Verify group representation
|
704
|
+
#
|
705
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
706
|
+
|
707
|
+
expect(response.status).to eql(200)
|
708
|
+
result = JSON.parse(response.body)
|
709
|
+
|
710
|
+
expect(result['members'].map { |m| m['value'] }.sort()).to eql(MockUser.pluck(:primary_key).sort())
|
711
|
+
end
|
712
|
+
|
713
|
+
it 'can remove all users' do
|
714
|
+
expect {
|
715
|
+
expect {
|
716
|
+
patch "/Groups/#{@g1.id}", params: {
|
717
|
+
format: :scim,
|
718
|
+
Operations: [
|
719
|
+
{
|
720
|
+
op: 'remove',
|
721
|
+
path: 'members'
|
722
|
+
}
|
723
|
+
]
|
724
|
+
}
|
725
|
+
}.to_not change { MockUser.count }
|
726
|
+
}.to_not change { MockGroup.count }
|
727
|
+
|
728
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
729
|
+
|
730
|
+
expect(response.status).to eql(200)
|
731
|
+
result = JSON.parse(response.body)
|
732
|
+
|
733
|
+
expect(result['members']).to be_empty
|
734
|
+
expect(@g1.reload().mock_users).to be_empty
|
735
|
+
end
|
736
|
+
|
737
|
+
# Define via 'let':
|
738
|
+
#
|
739
|
+
# * Hash 'payload', to send via 'patch'
|
740
|
+
# * MockUser 'removed_user', which is the user that should be removed
|
741
|
+
#
|
742
|
+
shared_examples 'a user remover' do
|
743
|
+
it 'which removes the identified user' do
|
744
|
+
expect {
|
745
|
+
expect {
|
746
|
+
patch "/Groups/#{@g1.id}", params: payload()
|
747
|
+
}.to_not change { MockUser.count }
|
748
|
+
}.to_not change { MockGroup.count }
|
749
|
+
|
750
|
+
expected_remaining_user_ids = MockUser
|
751
|
+
.where.not(primary_key: removed_user().id)
|
752
|
+
.pluck(:primary_key)
|
753
|
+
.sort()
|
754
|
+
|
755
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
756
|
+
|
757
|
+
expect(response.status).to eql(200)
|
758
|
+
result = JSON.parse(response.body)
|
759
|
+
|
760
|
+
expect(result['members'].map { |m| m['value'] }.sort()).to eql(expected_remaining_user_ids)
|
761
|
+
expect(@g1.reload().mock_users.map(&:primary_key).sort()).to eql(expected_remaining_user_ids)
|
762
|
+
end
|
763
|
+
end
|
764
|
+
|
765
|
+
# https://www.rfc-editor.org/rfc/rfc7644#section-3.5.2.2
|
766
|
+
#
|
767
|
+
context 'and using an RFC-compliant payload' do
|
768
|
+
let(:removed_user) { @u2 }
|
769
|
+
let(:payload) do
|
770
|
+
{
|
771
|
+
format: :scim,
|
772
|
+
Operations: [
|
773
|
+
{
|
774
|
+
op: 'remove',
|
775
|
+
path: "members[value eq \"#{removed_user().primary_key}\"]",
|
776
|
+
}
|
777
|
+
]
|
778
|
+
}
|
779
|
+
end
|
780
|
+
|
781
|
+
it_behaves_like 'a user remover'
|
782
|
+
end # context 'and using an RFC-compliant payload' do
|
783
|
+
|
784
|
+
# https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
|
785
|
+
#
|
786
|
+
context 'and using a Microsoft variant payload' do
|
787
|
+
let(:removed_user) { @u2 }
|
788
|
+
let(:payload) do
|
789
|
+
{
|
790
|
+
format: :scim,
|
791
|
+
Operations: [
|
792
|
+
{
|
793
|
+
op: 'remove',
|
794
|
+
path: 'members',
|
795
|
+
value: [{
|
796
|
+
'$ref' => nil,
|
797
|
+
'value' => removed_user().primary_key
|
798
|
+
}]
|
799
|
+
}
|
800
|
+
]
|
801
|
+
}
|
802
|
+
end
|
803
|
+
|
804
|
+
it_behaves_like 'a user remover'
|
805
|
+
end # context 'and using a Microsoft variant payload' do
|
806
|
+
|
807
|
+
# https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
|
808
|
+
#
|
809
|
+
context 'and using a Salesforce variant payload' do
|
810
|
+
let(:removed_user) { @u2 }
|
811
|
+
let(:payload) do
|
812
|
+
{
|
813
|
+
format: :scim,
|
814
|
+
Operations: [
|
815
|
+
{
|
816
|
+
op: 'remove',
|
817
|
+
path: 'members',
|
818
|
+
value: {
|
819
|
+
'members' => [{
|
820
|
+
'$ref' => nil,
|
821
|
+
'value' => removed_user().primary_key
|
822
|
+
}]
|
823
|
+
}
|
824
|
+
}
|
825
|
+
]
|
826
|
+
}
|
827
|
+
end
|
828
|
+
|
829
|
+
it_behaves_like 'a user remover'
|
830
|
+
end # context 'and using a Salesforce variant payload' do
|
831
|
+
end # "context 'when removing users from groups' do"
|
648
832
|
end # "context '#update' do"
|
649
833
|
|
650
834
|
# ===========================================================================
|
@@ -654,7 +838,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
654
838
|
expect_any_instance_of(MockUsersController).to receive(:destroy).once.and_call_original
|
655
839
|
expect_any_instance_of(MockUser).to receive(:destroy!).once.and_call_original
|
656
840
|
expect {
|
657
|
-
delete "/Users/#{@u2.
|
841
|
+
delete "/Users/#{@u2.primary_key}", params: { format: :scim }
|
658
842
|
}.to change { MockUser.count }.by(-1)
|
659
843
|
|
660
844
|
expect(response.status).to eql(204)
|
@@ -666,7 +850,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
666
850
|
expect_any_instance_of(MockUser).to_not receive(:destroy!)
|
667
851
|
|
668
852
|
expect {
|
669
|
-
delete "/CustomDestroyUsers/#{@u2.
|
853
|
+
delete "/CustomDestroyUsers/#{@u2.primary_key}", params: { format: :scim }
|
670
854
|
}.to_not change { MockUser.count }
|
671
855
|
|
672
856
|
expect(response.status).to eql(204)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scimitar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- RIPA Global
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-01-
|
12
|
+
date: 2023-01-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -211,7 +211,6 @@ files:
|
|
211
211
|
- spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb
|
212
212
|
- spec/apps/dummy/db/migrate/20210308020313_create_mock_groups.rb
|
213
213
|
- spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb
|
214
|
-
- spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb
|
215
214
|
- spec/apps/dummy/db/schema.rb
|
216
215
|
- spec/controllers/scimitar/application_controller_spec.rb
|
217
216
|
- spec/controllers/scimitar/resource_types_controller_spec.rb
|
@@ -261,52 +260,51 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
261
260
|
- !ruby/object:Gem::Version
|
262
261
|
version: '0'
|
263
262
|
requirements: []
|
264
|
-
rubygems_version: 3.
|
263
|
+
rubygems_version: 3.4.4
|
265
264
|
signing_key:
|
266
265
|
specification_version: 4
|
267
266
|
summary: SCIM v2 for Rails
|
268
267
|
test_files:
|
269
|
-
- spec/
|
270
|
-
- spec/
|
268
|
+
- spec/apps/dummy/app/controllers/custom_destroy_mock_users_controller.rb
|
269
|
+
- spec/apps/dummy/app/controllers/custom_request_verifiers_controller.rb
|
270
|
+
- spec/apps/dummy/app/controllers/mock_groups_controller.rb
|
271
|
+
- spec/apps/dummy/app/controllers/mock_users_controller.rb
|
272
|
+
- spec/apps/dummy/app/models/mock_group.rb
|
273
|
+
- spec/apps/dummy/app/models/mock_user.rb
|
274
|
+
- spec/apps/dummy/config/application.rb
|
275
|
+
- spec/apps/dummy/config/boot.rb
|
276
|
+
- spec/apps/dummy/config/environment.rb
|
277
|
+
- spec/apps/dummy/config/environments/test.rb
|
278
|
+
- spec/apps/dummy/config/initializers/cookies_serializer.rb
|
279
|
+
- spec/apps/dummy/config/initializers/scimitar.rb
|
280
|
+
- spec/apps/dummy/config/initializers/session_store.rb
|
281
|
+
- spec/apps/dummy/config/routes.rb
|
282
|
+
- spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb
|
283
|
+
- spec/apps/dummy/db/migrate/20210308020313_create_mock_groups.rb
|
284
|
+
- spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb
|
285
|
+
- spec/apps/dummy/db/schema.rb
|
286
|
+
- spec/controllers/scimitar/application_controller_spec.rb
|
287
|
+
- spec/controllers/scimitar/resource_types_controller_spec.rb
|
288
|
+
- spec/controllers/scimitar/resources_controller_spec.rb
|
289
|
+
- spec/controllers/scimitar/schemas_controller_spec.rb
|
290
|
+
- spec/controllers/scimitar/service_provider_configurations_controller_spec.rb
|
291
|
+
- spec/models/scimitar/complex_types/address_spec.rb
|
292
|
+
- spec/models/scimitar/complex_types/email_spec.rb
|
271
293
|
- spec/models/scimitar/lists/count_spec.rb
|
294
|
+
- spec/models/scimitar/lists/query_parser_spec.rb
|
295
|
+
- spec/models/scimitar/resource_type_spec.rb
|
296
|
+
- spec/models/scimitar/resources/base_spec.rb
|
272
297
|
- spec/models/scimitar/resources/base_validation_spec.rb
|
273
298
|
- spec/models/scimitar/resources/mixin_spec.rb
|
274
299
|
- spec/models/scimitar/resources/user_spec.rb
|
275
|
-
- spec/models/scimitar/resources/base_spec.rb
|
276
300
|
- spec/models/scimitar/schema/attribute_spec.rb
|
301
|
+
- spec/models/scimitar/schema/base_spec.rb
|
277
302
|
- spec/models/scimitar/schema/group_spec.rb
|
278
303
|
- spec/models/scimitar/schema/user_spec.rb
|
279
|
-
- spec/models/scimitar/schema/base_spec.rb
|
280
|
-
- spec/models/scimitar/resource_type_spec.rb
|
281
|
-
- spec/models/scimitar/complex_types/email_spec.rb
|
282
|
-
- spec/models/scimitar/complex_types/address_spec.rb
|
283
|
-
- spec/requests/controller_configuration_spec.rb
|
284
|
-
- spec/requests/engine_spec.rb
|
285
304
|
- spec/requests/active_record_backed_resources_controller_spec.rb
|
286
305
|
- spec/requests/application_controller_spec.rb
|
306
|
+
- spec/requests/controller_configuration_spec.rb
|
307
|
+
- spec/requests/engine_spec.rb
|
308
|
+
- spec/spec_helper.rb
|
287
309
|
- spec/spec_helper_spec.rb
|
288
310
|
- spec/support/hash_with_indifferent_case_insensitive_access_spec.rb
|
289
|
-
- spec/controllers/scimitar/schemas_controller_spec.rb
|
290
|
-
- spec/controllers/scimitar/resource_types_controller_spec.rb
|
291
|
-
- spec/controllers/scimitar/resources_controller_spec.rb
|
292
|
-
- spec/controllers/scimitar/service_provider_configurations_controller_spec.rb
|
293
|
-
- spec/controllers/scimitar/application_controller_spec.rb
|
294
|
-
- spec/apps/dummy/app/models/mock_group.rb
|
295
|
-
- spec/apps/dummy/app/models/mock_user.rb
|
296
|
-
- spec/apps/dummy/app/controllers/custom_request_verifiers_controller.rb
|
297
|
-
- spec/apps/dummy/app/controllers/custom_destroy_mock_users_controller.rb
|
298
|
-
- spec/apps/dummy/app/controllers/mock_groups_controller.rb
|
299
|
-
- spec/apps/dummy/app/controllers/mock_users_controller.rb
|
300
|
-
- spec/apps/dummy/config/routes.rb
|
301
|
-
- spec/apps/dummy/config/environments/test.rb
|
302
|
-
- spec/apps/dummy/config/environment.rb
|
303
|
-
- spec/apps/dummy/config/application.rb
|
304
|
-
- spec/apps/dummy/config/boot.rb
|
305
|
-
- spec/apps/dummy/config/initializers/session_store.rb
|
306
|
-
- spec/apps/dummy/config/initializers/cookies_serializer.rb
|
307
|
-
- spec/apps/dummy/config/initializers/scimitar.rb
|
308
|
-
- spec/apps/dummy/db/schema.rb
|
309
|
-
- spec/apps/dummy/db/migrate/20210308020313_create_mock_groups.rb
|
310
|
-
- spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb
|
311
|
-
- spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb
|
312
|
-
- spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb
|