scimitar 2.8.0 → 2.9.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/README.md +22 -17
- data/app/controllers/scimitar/schemas_controller.rb +361 -1
- data/app/models/scimitar/engine_configuration.rb +3 -1
- data/app/models/scimitar/resources/base.rb +36 -5
- data/app/models/scimitar/resources/mixin.rb +9 -4
- data/config/initializers/scimitar.rb +41 -0
- data/lib/scimitar/engine.rb +50 -12
- data/lib/scimitar/support/utilities.rb +8 -3
- data/lib/scimitar/version.rb +2 -2
- data/spec/apps/dummy/app/models/mock_user.rb +11 -3
- data/spec/apps/dummy/config/initializers/scimitar.rb +29 -1
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -0
- data/spec/apps/dummy/db/schema.rb +1 -0
- data/spec/controllers/scimitar/schemas_controller_spec.rb +342 -54
- data/spec/models/scimitar/lists/query_parser_spec.rb +5 -0
- data/spec/models/scimitar/resources/base_spec.rb +11 -11
- data/spec/models/scimitar/resources/base_validation_spec.rb +1 -1
- data/spec/models/scimitar/resources/mixin_spec.rb +30 -11
- data/spec/requests/active_record_backed_resources_controller_spec.rb +86 -2
- data/spec/requests/engine_spec.rb +75 -0
- data/spec/spec_helper.rb +1 -1
- metadata +20 -20
data/lib/scimitar/engine.rb
CHANGED
@@ -15,8 +15,24 @@ module Scimitar
|
|
15
15
|
JSON.parse(body)
|
16
16
|
end
|
17
17
|
|
18
|
+
# Return an Array of all supported default and custom resource classes.
|
19
|
+
# See also :add_custom_resource and :set_default_resources.
|
20
|
+
#
|
18
21
|
def self.resources
|
19
|
-
default_resources + custom_resources
|
22
|
+
self.default_resources() + self.custom_resources()
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns a flat array of instances of all resource schema included in the
|
26
|
+
# resource classes returned by ::resources.
|
27
|
+
#
|
28
|
+
def self.schemas
|
29
|
+
self.resources().map(&:schemas).flatten.uniq.map(&:new)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the list of custom resources, if any.
|
33
|
+
#
|
34
|
+
def self.custom_resources
|
35
|
+
@custom_resources ||= []
|
20
36
|
end
|
21
37
|
|
22
38
|
# Can be used to add a new resource type which is not provided by the gem.
|
@@ -37,7 +53,7 @@ module Scimitar
|
|
37
53
|
# Scimitar::Engine.add_custom_resource Scim::Resources::ShinyResource
|
38
54
|
#
|
39
55
|
def self.add_custom_resource(resource)
|
40
|
-
custom_resources << resource
|
56
|
+
self.custom_resources() << resource
|
41
57
|
end
|
42
58
|
|
43
59
|
# Resets the resource list to default. This is really only intended for use
|
@@ -47,23 +63,45 @@ module Scimitar
|
|
47
63
|
@custom_resources = []
|
48
64
|
end
|
49
65
|
|
50
|
-
# Returns the
|
51
|
-
#
|
52
|
-
def self.custom_resources
|
53
|
-
@custom_resources ||= []
|
54
|
-
end
|
55
|
-
|
56
|
-
# Returns the default resources added in this gem:
|
66
|
+
# Returns the default resources added in this gem - by default, these are:
|
57
67
|
#
|
58
68
|
# * Scimitar::Resources::User
|
59
69
|
# * Scimitar::Resources::Group
|
60
70
|
#
|
71
|
+
# ...but if an implementation does not e.g. support Group, it can
|
72
|
+
# be overridden via ::set_default_resources to help with service
|
73
|
+
# auto-discovery.
|
74
|
+
#
|
61
75
|
def self.default_resources
|
62
|
-
[ Resources::User, Resources::Group ]
|
76
|
+
@standard_default_resources = [ Resources::User, Resources::Group ]
|
77
|
+
@default_resources ||= @standard_default_resources.dup()
|
63
78
|
end
|
64
79
|
|
65
|
-
|
66
|
-
|
80
|
+
# Override the resources returned by ::default_resources.
|
81
|
+
#
|
82
|
+
# +resource_array+:: An Array containing one or both of
|
83
|
+
# Scimitar::Resources::User and/or
|
84
|
+
# Scimitar::Resources::Group, and nothing else.
|
85
|
+
#
|
86
|
+
def self.set_default_resources(resource_array)
|
87
|
+
self.default_resources()
|
88
|
+
unrecognised_resources = resource_array - @standard_default_resources
|
89
|
+
|
90
|
+
if unrecognised_resources.any?
|
91
|
+
raise "Scimitar::Engine::set_default_resources: Only #{@standard_default_resources.map(&:name).join(', ')} are supported"
|
92
|
+
elsif resource_array.empty?
|
93
|
+
raise 'Scimitar::Engine::set_default_resources: At least one resource must be given'
|
94
|
+
end
|
95
|
+
|
96
|
+
@default_resources = resource_array
|
97
|
+
end
|
98
|
+
|
99
|
+
# Resets the default resource list. This is really only intended for use
|
100
|
+
# during testing, to avoid one test polluting another.
|
101
|
+
#
|
102
|
+
def self.reset_default_resources
|
103
|
+
self.default_resources()
|
104
|
+
@default_resources = @standard_default_resources
|
67
105
|
end
|
68
106
|
|
69
107
|
end
|
@@ -57,9 +57,10 @@ module Scimitar
|
|
57
57
|
# <tt>scim_resource_type.extended_schemas</tt> value. The
|
58
58
|
# Array should be empty if there are no extensions.
|
59
59
|
#
|
60
|
-
# +path_str+:: Path
|
60
|
+
# +path_str+:: Path String, e.g. <tt>"password"</tt>, <tt>"name.givenName"</tt>,
|
61
61
|
# <tt>"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"</tt> (special case),
|
62
62
|
# <tt>"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:organization"</tt>
|
63
|
+
# (if given a Symbol, it'll be converted to a String).
|
63
64
|
#
|
64
65
|
# Returns an array of components, e.g. <tt>["password"]</tt>, <tt>["name",
|
65
66
|
# "givenName"]</tt>,
|
@@ -74,6 +75,7 @@ module Scimitar
|
|
74
75
|
# path-free payload.
|
75
76
|
#
|
76
77
|
def self.path_str_to_array(schemas, path_str)
|
78
|
+
path_str = path_str.to_s
|
77
79
|
components = []
|
78
80
|
|
79
81
|
# Note the ":" separating the schema ID (URN) from the attribute.
|
@@ -84,11 +86,14 @@ module Scimitar
|
|
84
86
|
# particular, https://tools.ietf.org/html/rfc7644#page-35.
|
85
87
|
#
|
86
88
|
if path_str.include?(':')
|
89
|
+
lower_case_path_str = path_str.downcase()
|
90
|
+
|
87
91
|
schemas.each do |schema|
|
88
|
-
|
92
|
+
lower_case_schema_id = schema.id.downcase()
|
93
|
+
attributes_after_schema_id = lower_case_path_str.split(lower_case_schema_id + ':').drop(1)
|
89
94
|
|
90
95
|
if attributes_after_schema_id.empty?
|
91
|
-
components += [schema.id]
|
96
|
+
components += [schema.id] if lower_case_path_str == lower_case_schema_id
|
92
97
|
else
|
93
98
|
attributes_after_schema_id.each do |component|
|
94
99
|
components += [schema.id] + component.split('.')
|
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 = '2.
|
6
|
+
VERSION = '2.9.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 = '2024-06-
|
11
|
+
DATE = '2024-06-27'
|
12
12
|
|
13
13
|
end
|
@@ -18,6 +18,7 @@ class MockUser < ActiveRecord::Base
|
|
18
18
|
work_phone_number
|
19
19
|
organization
|
20
20
|
department
|
21
|
+
manager
|
21
22
|
mock_groups
|
22
23
|
}
|
23
24
|
|
@@ -48,6 +49,7 @@ class MockUser < ActiveRecord::Base
|
|
48
49
|
externalId: :scim_uid,
|
49
50
|
userName: :username,
|
50
51
|
password: :password,
|
52
|
+
active: :is_active,
|
51
53
|
name: {
|
52
54
|
givenName: :first_name,
|
53
55
|
familyName: :last_name
|
@@ -80,8 +82,11 @@ class MockUser < ActiveRecord::Base
|
|
80
82
|
}
|
81
83
|
},
|
82
84
|
],
|
83
|
-
groups: [
|
85
|
+
groups: [
|
84
86
|
{
|
87
|
+
# Read-only, so no :find_with key. There's no 'class' specified here
|
88
|
+
# either, to help test the "/Schemas" endpoint's reflection code.
|
89
|
+
#
|
85
90
|
list: :mock_groups,
|
86
91
|
using: {
|
87
92
|
value: :id,
|
@@ -89,7 +94,6 @@ class MockUser < ActiveRecord::Base
|
|
89
94
|
}
|
90
95
|
}
|
91
96
|
],
|
92
|
-
active: :is_active,
|
93
97
|
|
94
98
|
# Custom extension schema - see configuration in
|
95
99
|
# "spec/apps/dummy/config/initializers/scimitar.rb".
|
@@ -97,6 +101,9 @@ class MockUser < ActiveRecord::Base
|
|
97
101
|
organization: :organization,
|
98
102
|
department: :department,
|
99
103
|
primaryEmail: :scim_primary_email,
|
104
|
+
|
105
|
+
manager: :manager,
|
106
|
+
|
100
107
|
userGroups: [
|
101
108
|
{
|
102
109
|
list: :mock_groups,
|
@@ -130,7 +137,8 @@ class MockUser < ActiveRecord::Base
|
|
130
137
|
}
|
131
138
|
end
|
132
139
|
|
133
|
-
# reader
|
140
|
+
# Custom attribute reader
|
141
|
+
#
|
134
142
|
def scim_primary_email
|
135
143
|
work_email_address
|
136
144
|
end
|
@@ -33,10 +33,13 @@ Rails.application.config.to_prepare do
|
|
33
33
|
|
34
34
|
module ScimSchemaExtensions
|
35
35
|
module User
|
36
|
+
|
37
|
+
# This "looks like" part of the standard Enterprise extension.
|
38
|
+
#
|
36
39
|
class Enterprise < Scimitar::Schema::Base
|
37
40
|
def initialize(options = {})
|
38
41
|
super(
|
39
|
-
name: '
|
42
|
+
name: 'EnterpriseExtendedUser',
|
40
43
|
description: 'Enterprise extension for a User',
|
41
44
|
id: self.class.id,
|
42
45
|
scim_attributes: self.class.scim_attributes
|
@@ -55,8 +58,33 @@ Rails.application.config.to_prepare do
|
|
55
58
|
]
|
56
59
|
end
|
57
60
|
end
|
61
|
+
|
62
|
+
# In https://github.com/RIPAGlobal/scimitar/issues/122 we learn that with
|
63
|
+
# more than one extension, things can go wrong - so now we test with two.
|
64
|
+
#
|
65
|
+
class Manager < Scimitar::Schema::Base
|
66
|
+
def initialize(options = {})
|
67
|
+
super(
|
68
|
+
name: 'ManagementExtendedUser',
|
69
|
+
description: 'Management extension for a User',
|
70
|
+
id: self.class.id,
|
71
|
+
scim_attributes: self.class.scim_attributes
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.id
|
76
|
+
'urn:ietf:params:scim:schemas:extension:manager:1.0:User'
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.scim_attributes
|
80
|
+
[
|
81
|
+
Scimitar::Schema::Attribute.new(name: 'manager', type: 'string')
|
82
|
+
]
|
83
|
+
end
|
84
|
+
end
|
58
85
|
end
|
59
86
|
end
|
60
87
|
|
61
88
|
Scimitar::Resources::User.extend_schema ScimSchemaExtensions::User::Enterprise
|
89
|
+
Scimitar::Resources::User.extend_schema ScimSchemaExtensions::User::Manager
|
62
90
|
end
|