scimitar 1.8.1 → 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 +20 -94
- data/app/controllers/scimitar/application_controller.rb +13 -41
- data/app/controllers/scimitar/schemas_controller.rb +0 -5
- data/app/models/scimitar/complex_types/address.rb +6 -0
- data/app/models/scimitar/engine_configuration.rb +5 -13
- data/app/models/scimitar/error_response.rb +0 -12
- data/app/models/scimitar/lists/query_parser.rb +10 -25
- data/app/models/scimitar/resource_invalid_error.rb +1 -1
- data/app/models/scimitar/resources/base.rb +4 -14
- data/app/models/scimitar/resources/mixin.rb +13 -140
- 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/vdtp.rb +1 -1
- data/app/models/scimitar/service_provider_configuration.rb +3 -14
- data/config/initializers/scimitar.rb +3 -28
- 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 +8 -36
- 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 -61
- data/spec/apps/dummy/config/routes.rb +7 -28
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -10
- 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 -11
- 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 +2 -10
- 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 -76
- data/spec/models/scimitar/resources/base_spec.rb +70 -208
- data/spec/models/scimitar/resources/base_validation_spec.rb +2 -27
- data/spec/models/scimitar/resources/mixin_spec.rb +43 -790
- 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 +0 -10
- data/spec/requests/active_record_backed_resources_controller_spec.rb +66 -709
- data/spec/requests/application_controller_spec.rb +3 -16
- data/spec/spec_helper.rb +0 -8
- metadata +14 -25
- data/LICENSE.txt +0 -21
- data/README.md +0 -710
- data/lib/scimitar/support/utilities.rb +0 -51
- 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
@@ -14,10 +14,7 @@ RSpec.describe Scimitar::Resources::Base do
|
|
14
14
|
),
|
15
15
|
Scimitar::Schema::Attribute.new(
|
16
16
|
name: 'names', multiValued: true, complexType: Scimitar::ComplexTypes::Name, required: false
|
17
|
-
)
|
18
|
-
Scimitar::Schema::Attribute.new(
|
19
|
-
name: 'privateName', complexType: Scimitar::ComplexTypes::Name, required: false, returned: false
|
20
|
-
),
|
17
|
+
)
|
21
18
|
]
|
22
19
|
end
|
23
20
|
end
|
@@ -33,10 +30,6 @@ RSpec.describe Scimitar::Resources::Base do
|
|
33
30
|
name: {
|
34
31
|
givenName: 'John',
|
35
32
|
familyName: 'Smith'
|
36
|
-
},
|
37
|
-
privateName: {
|
38
|
-
givenName: 'Alt John',
|
39
|
-
familyName: 'Alt Smith'
|
40
33
|
}
|
41
34
|
}
|
42
35
|
|
@@ -46,9 +39,6 @@ RSpec.describe Scimitar::Resources::Base do
|
|
46
39
|
expect(resource.name.is_a?(Scimitar::ComplexTypes::Name)).to be(true)
|
47
40
|
expect(resource.name.givenName).to eql('John')
|
48
41
|
expect(resource.name.familyName).to eql('Smith')
|
49
|
-
expect(resource.privateName.is_a?(Scimitar::ComplexTypes::Name)).to be(true)
|
50
|
-
expect(resource.privateName.givenName).to eql('Alt John')
|
51
|
-
expect(resource.privateName.familyName).to eql('Alt Smith')
|
52
42
|
end
|
53
43
|
|
54
44
|
it 'which builds an array of nested resources' do
|
@@ -111,38 +101,14 @@ RSpec.describe Scimitar::Resources::Base do
|
|
111
101
|
context '#as_json' do
|
112
102
|
it 'renders the json with the resourceType' do
|
113
103
|
resource = CustomResourse.new(name: {
|
114
|
-
givenName:
|
104
|
+
givenName: 'John',
|
115
105
|
familyName: 'Smith'
|
116
106
|
})
|
117
107
|
|
118
108
|
result = resource.as_json
|
119
|
-
|
120
|
-
expect(result['schemas'] ).to eql(['custom-id'])
|
109
|
+
expect(result['schemas']).to eql(['custom-id'])
|
121
110
|
expect(result['meta']['resourceType']).to eql('CustomResourse')
|
122
|
-
expect(result['errors']
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'excludes attributes that are flagged as do-not-return' do
|
126
|
-
resource = CustomResourse.new(
|
127
|
-
name: {
|
128
|
-
givenName: 'John',
|
129
|
-
familyName: 'Smith'
|
130
|
-
},
|
131
|
-
privateName: {
|
132
|
-
givenName: 'Alt John',
|
133
|
-
familyName: 'Alt Smith'
|
134
|
-
}
|
135
|
-
)
|
136
|
-
|
137
|
-
result = resource.as_json
|
138
|
-
|
139
|
-
expect(result['schemas'] ).to eql(['custom-id'])
|
140
|
-
expect(result['meta']['resourceType']).to eql('CustomResourse')
|
141
|
-
expect(result['errors'] ).to be_nil
|
142
|
-
expect(result['name'] ).to be_present
|
143
|
-
expect(result['name']['givenName'] ).to eql('John')
|
144
|
-
expect(result['name']['familyName'] ).to eql('Smith')
|
145
|
-
expect(result['privateName'] ).to be_present
|
111
|
+
expect(result['errors']).to be_nil
|
146
112
|
end
|
147
113
|
end # "context '#as_json' do"
|
148
114
|
|
@@ -284,194 +250,90 @@ RSpec.describe Scimitar::Resources::Base do
|
|
284
250
|
end # "context 'dynamic setters based on schema' do"
|
285
251
|
|
286
252
|
context 'schema extension' do
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
'custom-id'
|
291
|
-
end
|
292
|
-
|
293
|
-
def self.scim_attributes
|
294
|
-
[ Scimitar::Schema::Attribute.new(name: 'name', type: 'string') ]
|
295
|
-
end
|
253
|
+
ThirdCustomSchema = Class.new(Scimitar::Schema::Base) do
|
254
|
+
def self.id
|
255
|
+
'custom-id'
|
296
256
|
end
|
297
257
|
|
298
|
-
|
299
|
-
|
300
|
-
'extension-id'
|
301
|
-
end
|
302
|
-
|
303
|
-
def self.scim_attributes
|
304
|
-
[
|
305
|
-
Scimitar::Schema::Attribute.new(name: 'relationship', type: 'string', required: true),
|
306
|
-
Scimitar::Schema::Attribute.new(name: "userGroups", multiValued: true, complexType: Scimitar::ComplexTypes::ReferenceGroup, mutability: "writeOnly")
|
307
|
-
]
|
308
|
-
end
|
258
|
+
def self.scim_attributes
|
259
|
+
[ Scimitar::Schema::Attribute.new(name: 'name', type: 'string') ]
|
309
260
|
end
|
261
|
+
end
|
310
262
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
def self.endpoint
|
317
|
-
'/gaga'
|
318
|
-
end
|
319
|
-
|
320
|
-
def self.resource_type_id
|
321
|
-
'CustomResource'
|
322
|
-
end
|
323
|
-
end
|
324
|
-
}
|
325
|
-
|
326
|
-
context '#initialize' do
|
327
|
-
it 'allows setting extension attributes' do
|
328
|
-
resource = resource_class.new('extension-id' => {relationship: 'GAGA'})
|
329
|
-
expect(resource.relationship).to eql('GAGA')
|
330
|
-
end
|
331
|
-
|
332
|
-
it 'allows setting complex extension attributes' do
|
333
|
-
user_groups = [{ value: '123' }, { value: '456'}]
|
334
|
-
resource = resource_class.new('extension-id' => {userGroups: user_groups})
|
335
|
-
expect(resource.userGroups.map(&:value)).to eql(['123', '456'])
|
336
|
-
end
|
337
|
-
end # "context '#initialize' do"
|
338
|
-
|
339
|
-
context '#as_json' do
|
340
|
-
it 'namespaces the extension attributes' do
|
341
|
-
resource = resource_class.new(relationship: 'GAGA')
|
342
|
-
hash = resource.as_json
|
343
|
-
expect(hash["schemas"]).to eql(['custom-id', 'extension-id'])
|
344
|
-
expect(hash["extension-id"]).to eql("relationship" => 'GAGA')
|
345
|
-
end
|
346
|
-
end # "context '#as_json' do"
|
347
|
-
|
348
|
-
context '.resource_type' do
|
349
|
-
it 'appends the extension schemas' do
|
350
|
-
resource_type = resource_class.resource_type('http://gaga')
|
351
|
-
expect(resource_type.meta.location).to eql('http://gaga')
|
352
|
-
expect(resource_type.schemaExtensions.count).to eql(1)
|
353
|
-
end
|
354
|
-
|
355
|
-
context 'validation' do
|
356
|
-
it 'validates into custom schema' do
|
357
|
-
resource = resource_class.new('extension-id' => {})
|
358
|
-
expect(resource.valid?).to eql(false)
|
359
|
-
|
360
|
-
resource = resource_class.new('extension-id' => {relationship: 'GAGA'})
|
361
|
-
expect(resource.relationship).to eql('GAGA')
|
362
|
-
expect(resource.valid?).to eql(true)
|
363
|
-
end
|
364
|
-
end # context 'validation'
|
365
|
-
end # "context '.resource_type' do"
|
263
|
+
ExtensionSchema = Class.new(Scimitar::Schema::Base) do
|
264
|
+
def self.id
|
265
|
+
'extension-id'
|
266
|
+
end
|
366
267
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
expect(found.name).to eql('name')
|
372
|
-
expect(found.type).to eql('string')
|
373
|
-
end
|
268
|
+
def self.scim_attributes
|
269
|
+
[ Scimitar::Schema::Attribute.new(name: 'relationship', type: 'string', required: true) ]
|
270
|
+
end
|
271
|
+
end
|
374
272
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
expect(found.type).to eql('string')
|
380
|
-
end
|
381
|
-
end # "context '.find_attribute' do"
|
382
|
-
end # "context 'of custom schema' do"
|
273
|
+
let(:resource_class) {
|
274
|
+
Class.new(Scimitar::Resources::Base) do
|
275
|
+
set_schema ThirdCustomSchema
|
276
|
+
extend_schema ExtensionSchema
|
383
277
|
|
384
|
-
|
385
|
-
|
386
|
-
def self.id
|
387
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'
|
278
|
+
def self.endpoint
|
279
|
+
'/gaga'
|
388
280
|
end
|
389
281
|
|
390
|
-
def self.
|
391
|
-
|
392
|
-
Scimitar::Schema::Attribute.new(name: 'organization', type: 'string'),
|
393
|
-
Scimitar::Schema::Attribute.new(name: 'department', type: 'string')
|
394
|
-
]
|
282
|
+
def self.resource_type_id
|
283
|
+
'CustomResource'
|
395
284
|
end
|
396
285
|
end
|
286
|
+
}
|
397
287
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
'/Users'
|
405
|
-
end
|
406
|
-
|
407
|
-
def self.resource_type_id
|
408
|
-
'User'
|
409
|
-
end
|
410
|
-
end
|
411
|
-
}
|
412
|
-
|
413
|
-
context '#initialize' do
|
414
|
-
it 'allows setting extension attributes' do
|
415
|
-
resource = resource_class.new('urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {organization: 'SOMEORG', department: 'SOMEDPT'})
|
288
|
+
context '#initialize' do
|
289
|
+
it 'allows setting extension attributes' do
|
290
|
+
resource = resource_class.new('extension-id' => {relationship: 'GAGA'})
|
291
|
+
expect(resource.relationship).to eql('GAGA')
|
292
|
+
end
|
293
|
+
end # "context '#initialize' do"
|
416
294
|
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
295
|
+
context '#as_json' do
|
296
|
+
it 'namespaces the extension attributes' do
|
297
|
+
resource = resource_class.new(relationship: 'GAGA')
|
298
|
+
hash = resource.as_json
|
299
|
+
expect(hash["schemas"]).to eql(['custom-id', 'extension-id'])
|
300
|
+
expect(hash["extension-id"]).to eql("relationship" => 'GAGA')
|
301
|
+
end
|
302
|
+
end # "context '#as_json' do"
|
421
303
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
304
|
+
context '.resource_type' do
|
305
|
+
it 'appends the extension schemas' do
|
306
|
+
resource_type = resource_class.resource_type('http://gaga')
|
307
|
+
expect(resource_type.meta.location).to eql('http://gaga')
|
308
|
+
expect(resource_type.schemaExtensions.count).to eql(1)
|
309
|
+
end
|
426
310
|
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
311
|
+
context 'validation' do
|
312
|
+
it 'validates into custom schema' do
|
313
|
+
resource = resource_class.new('extension-id' => {})
|
314
|
+
expect(resource.valid?).to eql(false)
|
431
315
|
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
expect(resource_type.meta.location).to eql('http://example.com')
|
436
|
-
expect(resource_type.schemaExtensions.count).to eql(1)
|
316
|
+
resource = resource_class.new('extension-id' => {relationship: 'GAGA'})
|
317
|
+
expect(resource.relationship).to eql('GAGA')
|
318
|
+
expect(resource.valid?).to eql(true)
|
437
319
|
end
|
320
|
+
end # context 'validation'
|
321
|
+
end # "context '.resource_type' do"
|
438
322
|
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
userName: 'SOMEUSR',
|
447
|
-
organization: 'SOMEORG',
|
448
|
-
department: 'SOMEDPT'
|
449
|
-
}
|
450
|
-
)
|
451
|
-
|
452
|
-
expect(resource.organization).to eql('SOMEORG')
|
453
|
-
expect(resource.department ).to eql('SOMEDPT')
|
454
|
-
expect(resource.valid? ).to eql(true)
|
455
|
-
end
|
456
|
-
end # context 'validation'
|
457
|
-
end # "context '.resource_type' do"
|
458
|
-
|
459
|
-
context '.find_attribute' do
|
460
|
-
it 'finds in first schema' do
|
461
|
-
found = resource_class().find_attribute('userName') # Defined in Scimitar::Schema::User
|
462
|
-
|
463
|
-
expect(found).to be_present
|
464
|
-
expect(found.name).to eql('userName')
|
465
|
-
expect(found.type).to eql('string')
|
466
|
-
end
|
323
|
+
context '.find_attribute' do
|
324
|
+
it 'finds in first schema' do
|
325
|
+
found = resource_class().find_attribute('name') # Defined in ThirdCustomSchema
|
326
|
+
expect(found).to be_present
|
327
|
+
expect(found.name).to eql('name')
|
328
|
+
expect(found.type).to eql('string')
|
329
|
+
end
|
467
330
|
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
end # "context 'of core schema' do"
|
331
|
+
it 'finds across schemas' do
|
332
|
+
found = resource_class().find_attribute('relationship') # Defined in ExtensionSchema
|
333
|
+
expect(found).to be_present
|
334
|
+
expect(found.name).to eql('relationship')
|
335
|
+
expect(found.type).to eql('string')
|
336
|
+
end
|
337
|
+
end # "context '.find_attribute' do"
|
476
338
|
end # "context 'schema extension' do"
|
477
339
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Scimitar::Resources::Base do
|
4
|
+
|
4
5
|
context '#valid?' do
|
5
6
|
MyCustomSchema = Class.new(Scimitar::Schema::Base) do
|
6
7
|
def self.id
|
@@ -20,9 +21,6 @@ RSpec.describe Scimitar::Resources::Base do
|
|
20
21
|
),
|
21
22
|
Scimitar::Schema::Attribute.new(
|
22
23
|
name: 'complexNames', complexType: Scimitar::ComplexTypes::Name, multiValued:true, required: false
|
23
|
-
),
|
24
|
-
Scimitar::Schema::Attribute.new(
|
25
|
-
name: 'vdtpTestByEmail', complexType: Scimitar::ComplexTypes::Email, required: false
|
26
24
|
)
|
27
25
|
]
|
28
26
|
end
|
@@ -59,28 +57,5 @@ RSpec.describe Scimitar::Resources::Base do
|
|
59
57
|
expect(resource.valid?).to be(false)
|
60
58
|
expect(resource.errors.full_messages).to match_array(["Complexnames has to follow the complexType format.", "Complexnames familyname has the wrong type. It has to be a(n) string."])
|
61
59
|
end
|
62
|
-
|
63
|
-
context 'configuration of required values in VDTP schema' do
|
64
|
-
around :each do | example |
|
65
|
-
original_configuration = Scimitar.engine_configuration.optional_value_fields_required
|
66
|
-
Scimitar::Schema::Email.instance_variable_set('@scim_attributes', nil)
|
67
|
-
example.run()
|
68
|
-
ensure
|
69
|
-
Scimitar.engine_configuration.optional_value_fields_required = original_configuration
|
70
|
-
Scimitar::Schema::Email.instance_variable_set('@scim_attributes', nil)
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'requires a value by default' do
|
74
|
-
resource = MyCustomResource.new(vdtpTestByEmail: { value: nil }, enforce: false)
|
75
|
-
expect(resource.valid?).to be(false)
|
76
|
-
expect(resource.errors.full_messages).to match_array(['Vdtptestbyemail value is required'])
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'can be configured for optional values' do
|
80
|
-
Scimitar.engine_configuration.optional_value_fields_required = false
|
81
|
-
resource = MyCustomResource.new(vdtpTestByEmail: { value: nil }, enforce: false)
|
82
|
-
expect(resource.valid?).to be(true)
|
83
|
-
end
|
84
|
-
end # "context 'configuration of required values in VDTP schema' do"
|
85
|
-
end # "context '#valid?' do"
|
60
|
+
end
|
86
61
|
end
|