scimitar 1.3.3 → 1.4.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/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 +3 -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 +67 -39
- data/spec/models/scimitar/resources/user_spec.rb +2 -2
- data/spec/requests/active_record_backed_resources_controller_spec.rb +96 -48
- metadata +35 -37
- data/spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd0efbdecece6297062b46cf46bdeaccd8330cd58fc94fb2bcb0de7c7bb90806
|
4
|
+
data.tar.gz: 7f3528ee080f0f295d03c77fba1586484b5cadd6ef5e4de1fc00d7807ec7a0c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8044cc09d7b964401b09e6fe8ccfa272b6c67ab97687c79a151010a447109f9e671bb864094905b2495100591e2472f673ce2b977fc07f2a13213a8d4fbc75b1
|
7
|
+
data.tar.gz: 51a5522fcf948d3b9f19c6bc5b28732f0fb4537034106d47dca83d7d043d5749d9adf1c31acf10fc7eb79a63739787a0ec42f0a261eb293072634aabca0ec92d
|
@@ -21,6 +21,8 @@ module Scimitar
|
|
21
21
|
|
22
22
|
rescue_from ActiveRecord::RecordNotFound, with: :handle_resource_not_found # See Scimitar::ApplicationController
|
23
23
|
|
24
|
+
before_action :obtain_id_column_name_from_attribute_map
|
25
|
+
|
24
26
|
# GET (list)
|
25
27
|
#
|
26
28
|
def index
|
@@ -37,13 +39,13 @@ module Scimitar
|
|
37
39
|
pagination_info = scim_pagination_info(query.count())
|
38
40
|
|
39
41
|
page_of_results = query
|
40
|
-
.order(
|
42
|
+
.order(@id_column => :asc)
|
41
43
|
.offset(pagination_info.offset)
|
42
44
|
.limit(pagination_info.limit)
|
43
45
|
.to_a()
|
44
46
|
|
45
47
|
super(pagination_info, page_of_results) do | record |
|
46
|
-
|
48
|
+
record_to_scim(record)
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
@@ -52,7 +54,7 @@ module Scimitar
|
|
52
54
|
def show
|
53
55
|
super do |record_id|
|
54
56
|
record = self.find_record(record_id)
|
55
|
-
record
|
57
|
+
record_to_scim(record)
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
@@ -64,7 +66,7 @@ module Scimitar
|
|
64
66
|
record = self.storage_class().new
|
65
67
|
record.from_scim!(scim_hash: scim_resource.as_json())
|
66
68
|
self.save!(record)
|
67
|
-
|
69
|
+
record_to_scim(record)
|
68
70
|
end
|
69
71
|
end
|
70
72
|
end
|
@@ -77,7 +79,7 @@ module Scimitar
|
|
77
79
|
record = self.find_record(record_id)
|
78
80
|
record.from_scim!(scim_hash: scim_resource.as_json())
|
79
81
|
self.save!(record)
|
80
|
-
|
82
|
+
record_to_scim(record)
|
81
83
|
end
|
82
84
|
end
|
83
85
|
end
|
@@ -90,7 +92,7 @@ module Scimitar
|
|
90
92
|
record = self.find_record(record_id)
|
91
93
|
record.from_scim_patch!(patch_hash: patch_hash)
|
92
94
|
self.save!(record)
|
93
|
-
|
95
|
+
record_to_scim(record)
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|
@@ -138,7 +140,14 @@ module Scimitar
|
|
138
140
|
# +record_id+:: Record ID (SCIM schema 'id' value - "our" ID).
|
139
141
|
#
|
140
142
|
def find_record(record_id)
|
141
|
-
self.storage_scope().
|
143
|
+
self.storage_scope().find_by!(@id_column => record_id)
|
144
|
+
end
|
145
|
+
|
146
|
+
# DRY up controller actions - pass a record; returns the SCIM
|
147
|
+
# representation, with a "show" location specified via #url_for.
|
148
|
+
#
|
149
|
+
def record_to_scim(record)
|
150
|
+
record.to_scim(location: url_for(action: :show, id: record.send(@id_column)))
|
142
151
|
end
|
143
152
|
|
144
153
|
# Save a record, dealing with validation exceptions by raising SCIM
|
@@ -177,5 +186,16 @@ module Scimitar
|
|
177
186
|
end
|
178
187
|
end
|
179
188
|
|
189
|
+
# Called via +before_action+ - stores in @id_column the name of whatever
|
190
|
+
# model column is used to store the record ID, via
|
191
|
+
# Scimitar::Resources::Mixin::scim_attributes_map.
|
192
|
+
#
|
193
|
+
# Default is <tt>:id</tt>.
|
194
|
+
#
|
195
|
+
def obtain_id_column_name_from_attribute_map
|
196
|
+
attrs = storage_class().scim_attributes_map() || {}
|
197
|
+
@id_column = attrs[:id] || :id
|
198
|
+
end
|
199
|
+
|
180
200
|
end
|
181
201
|
end
|
data/lib/scimitar/version.rb
CHANGED
@@ -3,11 +3,11 @@ module Scimitar
|
|
3
3
|
# Gem version. If this changes, be sure to re-run "bundle install" or
|
4
4
|
# "bundle update".
|
5
5
|
#
|
6
|
-
VERSION = '1.
|
6
|
+
VERSION = '1.4.0'
|
7
7
|
|
8
8
|
# Date for VERSION. If this changes, be sure to re-run "bundle install"
|
9
9
|
# or "bundle update".
|
10
10
|
#
|
11
|
-
DATE = '2023-01-
|
11
|
+
DATE = '2023-01-26'
|
12
12
|
|
13
13
|
end
|
@@ -5,7 +5,7 @@ class MockUser < ActiveRecord::Base
|
|
5
5
|
# ===========================================================================
|
6
6
|
|
7
7
|
READWRITE_ATTRS = %w{
|
8
|
-
|
8
|
+
primary_key
|
9
9
|
scim_uid
|
10
10
|
username
|
11
11
|
first_name
|
@@ -38,7 +38,7 @@ class MockUser < ActiveRecord::Base
|
|
38
38
|
|
39
39
|
def self.scim_attributes_map
|
40
40
|
return {
|
41
|
-
id: :
|
41
|
+
id: :primary_key,
|
42
42
|
externalId: :scim_uid,
|
43
43
|
userName: :username,
|
44
44
|
name: {
|
@@ -92,7 +92,7 @@ class MockUser < ActiveRecord::Base
|
|
92
92
|
|
93
93
|
def self.scim_queryable_attributes
|
94
94
|
return {
|
95
|
-
'id' => { column: :
|
95
|
+
'id' => { column: :primary_key },
|
96
96
|
'externalId' => { column: :scim_uid },
|
97
97
|
'meta.lastModified' => { column: :updated_at },
|
98
98
|
'name.givenName' => { column: :first_name },
|
@@ -13,6 +13,9 @@ Rails.application.routes.draw do
|
|
13
13
|
patch 'Users/:id', to: 'mock_users#update'
|
14
14
|
delete 'Users/:id', to: 'mock_users#destroy'
|
15
15
|
|
16
|
+
get 'Groups', to: 'mock_groups#index'
|
17
|
+
get 'Groups/:id', to: 'mock_groups#show'
|
18
|
+
|
16
19
|
# For testing blocks passed to ActiveRecordBackedResourcesController#destroy
|
17
20
|
#
|
18
21
|
delete 'CustomDestroyUsers/:id', to: 'custom_destroy_mock_users#destroy'
|
@@ -1,6 +1,7 @@
|
|
1
1
|
class CreateMockUsers < ActiveRecord::Migration[6.1]
|
2
2
|
def change
|
3
|
-
create_table :mock_users do |t|
|
3
|
+
create_table :mock_users, id: :uuid, primary_key: :primary_key do |t|
|
4
|
+
t.timestamps
|
4
5
|
|
5
6
|
t.text :scim_uid
|
6
7
|
t.text :username
|
@@ -9,7 +10,6 @@ class CreateMockUsers < ActiveRecord::Migration[6.1]
|
|
9
10
|
t.text :work_email_address
|
10
11
|
t.text :home_email_address
|
11
12
|
t.text :work_phone_number
|
12
|
-
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -1,8 +1,13 @@
|
|
1
1
|
class CreateJoinTableMockGroupsMockUsers < ActiveRecord::Migration[6.1]
|
2
2
|
def change
|
3
|
-
|
4
|
-
t.
|
5
|
-
t.index
|
3
|
+
create_table :mock_groups_users, id: false do | t |
|
4
|
+
t.references :mock_group, foreign_key: true, type: :int8, index: true, null: false
|
5
|
+
t.references :mock_user, type: :uuid, index: true, null: false, primary_key: :primary_key
|
6
|
+
|
7
|
+
# The 'foreign_key:' option (used above) only works for 'id' column names
|
8
|
+
# but the test data has a column named 'primary_key' for 'mock_users'.
|
9
|
+
#
|
10
|
+
t.foreign_key :mock_users, primary_key: :primary_key
|
6
11
|
end
|
7
12
|
end
|
8
13
|
end
|
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 2021_03_08_044214) do
|
14
14
|
|
15
15
|
# These are extensions that must be enabled in order to support this database
|
16
16
|
enable_extension "plpgsql"
|
@@ -24,12 +24,14 @@ ActiveRecord::Schema.define(version: 2023_01_09_012729) do
|
|
24
24
|
|
25
25
|
create_table "mock_groups_users", id: false, force: :cascade do |t|
|
26
26
|
t.bigint "mock_group_id", null: false
|
27
|
-
t.
|
28
|
-
t.index ["mock_group_id"
|
29
|
-
t.index ["mock_user_id"
|
27
|
+
t.uuid "mock_user_id", null: false
|
28
|
+
t.index ["mock_group_id"], name: "index_mock_groups_users_on_mock_group_id"
|
29
|
+
t.index ["mock_user_id"], name: "index_mock_groups_users_on_mock_user_id"
|
30
30
|
end
|
31
31
|
|
32
|
-
create_table "mock_users", force: :cascade do |t|
|
32
|
+
create_table "mock_users", primary_key: "primary_key", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
33
|
+
t.datetime "created_at", precision: 6, null: false
|
34
|
+
t.datetime "updated_at", precision: 6, null: false
|
33
35
|
t.text "scim_uid"
|
34
36
|
t.text "username"
|
35
37
|
t.text "first_name"
|
@@ -37,8 +39,8 @@ ActiveRecord::Schema.define(version: 2023_01_09_012729) do
|
|
37
39
|
t.text "work_email_address"
|
38
40
|
t.text "home_email_address"
|
39
41
|
t.text "work_phone_number"
|
40
|
-
t.datetime "created_at", precision: 6, null: false
|
41
|
-
t.datetime "updated_at", precision: 6, null: false
|
42
42
|
end
|
43
43
|
|
44
|
+
add_foreign_key "mock_groups_users", "mock_groups"
|
45
|
+
add_foreign_key "mock_groups_users", "mock_users", primary_key: "primary_key"
|
44
46
|
end
|
@@ -405,19 +405,19 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
405
405
|
query = @instance.to_activerecord_query(MockUser.all)
|
406
406
|
|
407
407
|
expect(query.count).to eql(1)
|
408
|
-
expect(query.pluck(:
|
408
|
+
expect(query.pluck(:primary_key)).to eql([user_1.id])
|
409
409
|
|
410
410
|
@instance.parse('name.givenName sw J') # First name starts with 'J'
|
411
411
|
query = @instance.to_activerecord_query(MockUser.all)
|
412
412
|
|
413
413
|
expect(query.count).to eql(2)
|
414
|
-
expect(query.pluck(:
|
414
|
+
expect(query.pluck(:primary_key)).to match_array([user_1.primary_key, user_2.primary_key])
|
415
415
|
|
416
416
|
@instance.parse('name.familyName ew he') # Last name ends with 'he'
|
417
417
|
query = @instance.to_activerecord_query(MockUser.all)
|
418
418
|
|
419
419
|
expect(query.count).to eql(1)
|
420
|
-
expect(query.pluck(:
|
420
|
+
expect(query.pluck(:primary_key)).to eql([user_2.primary_key])
|
421
421
|
|
422
422
|
# Test presence
|
423
423
|
|
@@ -425,7 +425,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
425
425
|
query = @instance.to_activerecord_query(MockUser.all)
|
426
426
|
|
427
427
|
expect(query.count).to eql(2)
|
428
|
-
expect(query.pluck(:
|
428
|
+
expect(query.pluck(:primary_key)).to match_array([user_1.primary_key, user_2.primary_key])
|
429
429
|
|
430
430
|
# Test a simple not-equals, but use a custom starting scope. Note that
|
431
431
|
# the query would find "user_3" *except* there is no first name defined
|
@@ -435,7 +435,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
435
435
|
query = @instance.to_activerecord_query(MockUser.where.not('first_name' => 'John'))
|
436
436
|
|
437
437
|
expect(query.count).to eql(1)
|
438
|
-
expect(query.pluck(:
|
438
|
+
expect(query.pluck(:primary_key)).to match_array([user_1.primary_key])
|
439
439
|
end
|
440
440
|
|
441
441
|
context 'when mapped to multiple columns' do
|
@@ -499,7 +499,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
499
499
|
query = @instance.to_activerecord_query(MockUser.all)
|
500
500
|
|
501
501
|
expect(query.count).to eql(1)
|
502
|
-
expect(query.pluck(:
|
502
|
+
expect(query.pluck(:primary_key)).to match_array([user_2.primary_key])
|
503
503
|
end
|
504
504
|
end # "context 'simple AND' do"
|
505
505
|
|
@@ -520,7 +520,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
520
520
|
query = @instance.to_activerecord_query(MockUser.all)
|
521
521
|
|
522
522
|
expect(query.count).to eql(2)
|
523
|
-
expect(query.pluck(:
|
523
|
+
expect(query.pluck(:primary_key)).to match_array([user_1.primary_key, user_2.primary_key])
|
524
524
|
end
|
525
525
|
end # "context 'simple OR' do"
|
526
526
|
|
@@ -546,7 +546,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
546
546
|
query = @instance.to_activerecord_query(MockUser.all)
|
547
547
|
|
548
548
|
expect(query.count).to eql(3)
|
549
|
-
expect(query.pluck(:
|
549
|
+
expect(query.pluck(:primary_key)).to match_array([user_1.primary_key, user_2.primary_key, user_3.primary_key])
|
550
550
|
end
|
551
551
|
end # "context 'combined AND and OR' do"
|
552
552
|
|
@@ -159,41 +159,67 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
159
159
|
# =========================================================================
|
160
160
|
|
161
161
|
context '#to_scim' do
|
162
|
-
|
163
|
-
instance
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
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"
|
197
223
|
|
198
224
|
context 'with optional timestamps' do
|
199
225
|
context 'creation only' do
|
@@ -405,8 +431,8 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
405
431
|
'displayName' => 'Foo Group',
|
406
432
|
'members' => [
|
407
433
|
{'type' => 'Group', 'value' => g1.id.to_s},
|
408
|
-
{'type' => 'User', 'value' => u1.
|
409
|
-
{'type' => 'User', 'value' => u3.
|
434
|
+
{'type' => 'User', 'value' => u1.primary_key.to_s},
|
435
|
+
{'type' => 'User', 'value' => u3.primary_key.to_s}
|
410
436
|
],
|
411
437
|
'externalId' => 'GG01536',
|
412
438
|
'meta' => {'location'=>'https://test.com/mock_groups/1', 'resourceType'=>'Group'},
|
@@ -453,8 +479,10 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
453
479
|
end # "context 'using upper case' do"
|
454
480
|
|
455
481
|
it 'clears things not present in input' do
|
482
|
+
uuid = SecureRandom.uuid
|
483
|
+
|
456
484
|
instance = MockUser.new
|
457
|
-
instance.
|
485
|
+
instance.primary_key = uuid
|
458
486
|
instance.scim_uid = 'AA02984'
|
459
487
|
instance.username = 'foo'
|
460
488
|
instance.first_name = 'Foo'
|
@@ -465,7 +493,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
465
493
|
|
466
494
|
instance.from_scim!(scim_hash: {})
|
467
495
|
|
468
|
-
expect(instance.
|
496
|
+
expect(instance.primary_key ).to eql(uuid)
|
469
497
|
expect(instance.scim_uid ).to be_nil
|
470
498
|
expect(instance.username ).to be_nil
|
471
499
|
expect(instance.first_name ).to be_nil
|
@@ -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
|
{
|
@@ -654,7 +702,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
654
702
|
expect_any_instance_of(MockUsersController).to receive(:destroy).once.and_call_original
|
655
703
|
expect_any_instance_of(MockUser).to receive(:destroy!).once.and_call_original
|
656
704
|
expect {
|
657
|
-
delete "/Users/#{@u2.
|
705
|
+
delete "/Users/#{@u2.primary_key}", params: { format: :scim }
|
658
706
|
}.to change { MockUser.count }.by(-1)
|
659
707
|
|
660
708
|
expect(response.status).to eql(204)
|
@@ -666,7 +714,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
666
714
|
expect_any_instance_of(MockUser).to_not receive(:destroy!)
|
667
715
|
|
668
716
|
expect {
|
669
|
-
delete "/CustomDestroyUsers/#{@u2.
|
717
|
+
delete "/CustomDestroyUsers/#{@u2.primary_key}", params: { format: :scim }
|
670
718
|
}.to_not change { MockUser.count }
|
671
719
|
|
672
720
|
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.4.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-26 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
|