scimitar 1.10.0 → 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 +23 -98
- data/app/controllers/scimitar/application_controller.rb +13 -41
- data/app/controllers/scimitar/resource_types_controller.rb +2 -0
- data/app/controllers/scimitar/resources_controller.rb +2 -0
- data/app/controllers/scimitar/schemas_controller.rb +3 -366
- data/app/controllers/scimitar/service_provider_configurations_controller.rb +1 -0
- data/app/models/scimitar/complex_types/address.rb +6 -0
- data/app/models/scimitar/engine_configuration.rb +5 -15
- data/app/models/scimitar/error_response.rb +0 -12
- data/app/models/scimitar/lists/query_parser.rb +13 -113
- data/app/models/scimitar/resource_invalid_error.rb +1 -1
- data/app/models/scimitar/resources/base.rb +9 -53
- data/app/models/scimitar/resources/mixin.rb +59 -646
- 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/name.rb +2 -2
- data/app/models/scimitar/schema/user.rb +10 -10
- 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 -69
- data/lib/scimitar/engine.rb +12 -57
- data/lib/scimitar/support/hash_with_indifferent_case_insensitive_access.rb +10 -140
- 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 +9 -52
- 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 -90
- data/spec/apps/dummy/config/routes.rb +7 -28
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -11
- 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 -12
- 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 +48 -344
- 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 -146
- data/spec/models/scimitar/resources/base_spec.rb +71 -217
- data/spec/models/scimitar/resources/base_validation_spec.rb +5 -43
- data/spec/models/scimitar/resources/mixin_spec.rb +129 -1508
- 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 +2 -12
- data/spec/requests/active_record_backed_resources_controller_spec.rb +66 -1016
- data/spec/requests/application_controller_spec.rb +3 -16
- data/spec/requests/engine_spec.rb +0 -75
- data/spec/spec_helper.rb +1 -9
- data/spec/support/hash_with_indifferent_case_insensitive_access_spec.rb +0 -108
- metadata +26 -37
- data/LICENSE.txt +0 -21
- data/README.md +0 -717
- data/lib/scimitar/support/utilities.rb +0 -111
- 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
@@ -1,111 +0,0 @@
|
|
1
|
-
module Scimitar
|
2
|
-
|
3
|
-
# Namespace containing various chunks of Scimitar support code that don't
|
4
|
-
# logically fit into other areas.
|
5
|
-
#
|
6
|
-
module Support
|
7
|
-
|
8
|
-
# A namespace that contains various stand-alone utility methods which act
|
9
|
-
# as helpers for other parts of the code base, without risking namespace
|
10
|
-
# pollution by e.g. being part of a module loaded into a client class.
|
11
|
-
#
|
12
|
-
module Utilities
|
13
|
-
|
14
|
-
# Takes an array of components that usually come from a dotted path such
|
15
|
-
# as <tt>foo.bar.baz</tt>, along with a value that is found at the end of
|
16
|
-
# that path, then converts it into a nested Hash with each level of the
|
17
|
-
# Hash corresponding to a step along the path.
|
18
|
-
#
|
19
|
-
# This was written to help with edge case SCIM uses where (most often, at
|
20
|
-
# least) inbound calls use a dotted notation where nested values are more
|
21
|
-
# commonly accepted; converting to nesting makes it easier for subsequent
|
22
|
-
# processing code, which needs only handle nested Hash data.
|
23
|
-
#
|
24
|
-
# As an example, passing:
|
25
|
-
#
|
26
|
-
# ['foo', 'bar', 'baz'], 'value'
|
27
|
-
#
|
28
|
-
# ...yields:
|
29
|
-
#
|
30
|
-
# {'foo' => {'bar' => {'baz' => 'value'}}}
|
31
|
-
#
|
32
|
-
# Parameters:
|
33
|
-
#
|
34
|
-
# +array+:: Array containing path components, usually acquired from a
|
35
|
-
# string with dot separators and a call to String#split.
|
36
|
-
#
|
37
|
-
# +value+:: The value found at the path indicated by +array+.
|
38
|
-
#
|
39
|
-
# If +array+ is empty, +value+ is returned directly, with no nesting
|
40
|
-
# Hash wrapping it.
|
41
|
-
#
|
42
|
-
def self.dot_path(array, value)
|
43
|
-
return value if array.empty?
|
44
|
-
|
45
|
-
{}.tap do | hash |
|
46
|
-
hash[array.shift()] = self.dot_path(array, value)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Schema ID-aware splitter handling ":" or "." separators. Adapted from
|
51
|
-
# contribution by @bettysteger and @MorrisFreeman in:
|
52
|
-
#
|
53
|
-
# https://github.com/RIPAGlobal/scimitar/issues/48
|
54
|
-
# https://github.com/RIPAGlobal/scimitar/pull/49
|
55
|
-
#
|
56
|
-
# +schemas:: Array of extension schemas, e.g. a SCIM resource class'
|
57
|
-
# <tt>scim_resource_type.extended_schemas</tt> value. The
|
58
|
-
# Array should be empty if there are no extensions.
|
59
|
-
#
|
60
|
-
# +path_str+:: Path String, e.g. <tt>"password"</tt>, <tt>"name.givenName"</tt>,
|
61
|
-
# <tt>"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"</tt> (special case),
|
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).
|
64
|
-
#
|
65
|
-
# Returns an array of components, e.g. <tt>["password"]</tt>, <tt>["name",
|
66
|
-
# "givenName"]</tt>,
|
67
|
-
# <tt>["urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]</tt> (special case),
|
68
|
-
# <tt>["urn:ietf:params:scim:schemas:extension:enterprise:2.0:User", "organization"]</tt>.
|
69
|
-
#
|
70
|
-
# The called-out special case is for a schema ID without any appended
|
71
|
-
# path components, which is returned as a single element ID to aid in
|
72
|
-
# traversal particularly of things like PATCH requests. There, a "value"
|
73
|
-
# attribute might have a key string that's simply a schema ID, with an
|
74
|
-
# object beneath that's got attribute-name pairs, possibly nested, in a
|
75
|
-
# path-free payload.
|
76
|
-
#
|
77
|
-
def self.path_str_to_array(schemas, path_str)
|
78
|
-
path_str = path_str.to_s
|
79
|
-
components = []
|
80
|
-
|
81
|
-
# Note the ":" separating the schema ID (URN) from the attribute.
|
82
|
-
# The nature of JSON rendering / other payloads might lead you to
|
83
|
-
# expect a "." as with any complex types, but that's not the case;
|
84
|
-
# see https://tools.ietf.org/html/rfc7644#section-3.10, or
|
85
|
-
# https://tools.ietf.org/html/rfc7644#section-3.5.2 of which in
|
86
|
-
# particular, https://tools.ietf.org/html/rfc7644#page-35.
|
87
|
-
#
|
88
|
-
if path_str.include?(':')
|
89
|
-
lower_case_path_str = path_str.downcase()
|
90
|
-
|
91
|
-
schemas.each do |schema|
|
92
|
-
lower_case_schema_id = schema.id.downcase()
|
93
|
-
attributes_after_schema_id = lower_case_path_str.split(lower_case_schema_id + ':').drop(1)
|
94
|
-
|
95
|
-
if attributes_after_schema_id.empty?
|
96
|
-
components += [schema.id] if lower_case_path_str == lower_case_schema_id
|
97
|
-
else
|
98
|
-
attributes_after_schema_id.each do |component|
|
99
|
-
components += [schema.id] + component.split('.')
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
components = path_str.split('.') if components.empty?
|
106
|
-
return components
|
107
|
-
end
|
108
|
-
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# For tests only - uses custom 'create' implementation which passes a block to
|
2
|
-
# Scimitar::ActiveRecordBackedResourcesController#create.
|
3
|
-
#
|
4
|
-
class CustomCreateMockUsersController < Scimitar::ActiveRecordBackedResourcesController
|
5
|
-
|
6
|
-
OVERRIDDEN_NAME = SecureRandom.uuid
|
7
|
-
|
8
|
-
def create
|
9
|
-
super do | resource |
|
10
|
-
resource.first_name = OVERRIDDEN_NAME
|
11
|
-
resource.save!
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
def storage_class
|
18
|
-
MockUser
|
19
|
-
end
|
20
|
-
|
21
|
-
def storage_scope
|
22
|
-
MockUser.all
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# For tests only - uses custom 'replace' implementation which passes a block to
|
2
|
-
# Scimitar::ActiveRecordBackedResourcesController#create.
|
3
|
-
#
|
4
|
-
class CustomReplaceMockUsersController < Scimitar::ActiveRecordBackedResourcesController
|
5
|
-
|
6
|
-
OVERRIDDEN_NAME = SecureRandom.uuid
|
7
|
-
|
8
|
-
def replace
|
9
|
-
super do | resource |
|
10
|
-
resource.first_name = OVERRIDDEN_NAME
|
11
|
-
resource.save!
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
def storage_class
|
18
|
-
MockUser
|
19
|
-
end
|
20
|
-
|
21
|
-
def storage_scope
|
22
|
-
MockUser.all
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# For tests only - uses custom 'save!' implementation which passes a block to
|
2
|
-
# Scimitar::ActiveRecordBackedResourcesController#save!.
|
3
|
-
#
|
4
|
-
class CustomSaveMockUsersController < Scimitar::ActiveRecordBackedResourcesController
|
5
|
-
|
6
|
-
CUSTOM_SAVE_BLOCK_USERNAME_INDICATOR = 'Custom save-block invoked'
|
7
|
-
|
8
|
-
protected
|
9
|
-
|
10
|
-
def save!(_record)
|
11
|
-
super do | record |
|
12
|
-
record.update!(username: CUSTOM_SAVE_BLOCK_USERNAME_INDICATOR)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def storage_class
|
17
|
-
MockUser
|
18
|
-
end
|
19
|
-
|
20
|
-
def storage_scope
|
21
|
-
MockUser.all
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# For tests only - uses custom 'update' implementation which passes a block to
|
2
|
-
# Scimitar::ActiveRecordBackedResourcesController#create.
|
3
|
-
#
|
4
|
-
class CustomUpdateMockUsersController < Scimitar::ActiveRecordBackedResourcesController
|
5
|
-
|
6
|
-
OVERRIDDEN_NAME = SecureRandom.uuid
|
7
|
-
|
8
|
-
def update
|
9
|
-
super do | resource |
|
10
|
-
resource.first_name = OVERRIDDEN_NAME
|
11
|
-
resource.save!
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
def storage_class
|
18
|
-
MockUser
|
19
|
-
end
|
20
|
-
|
21
|
-
def storage_scope
|
22
|
-
MockUser.all
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|