Module: Scimitar::Support::Utilities
- Defined in:
- lib/scimitar/support/utilities.rb
Overview
A namespace that contains various stand-alone utility methods which act as helpers for other parts of the code base, without risking namespace pollution by e.g. being part of a module loaded into a client class.
Class Method Summary collapse
-
.dot_path(array, value) ⇒ Object
Takes an array of components that usually come from a dotted path such as
foo.bar.baz
, along with a value that is found at the end of that path, then converts it into a nested Hash with each level of the Hash corresponding to a step along the path. -
.path_str_to_array(schemas, path_str) ⇒ Object
Schema ID-aware splitter handling “:” or “.” separators.
Class Method Details
.dot_path(array, value) ⇒ Object
Takes an array of components that usually come from a dotted path such as foo.bar.baz
, along with a value that is found at the end of that path, then converts it into a nested Hash with each level of the Hash corresponding to a step along the path.
This was written to help with edge case SCIM uses where (most often, at least) inbound calls use a dotted notation where nested values are more commonly accepted; converting to nesting makes it easier for subsequent processing code, which needs only handle nested Hash data.
As an example, passing:
['foo', 'bar', 'baz'], 'value'
…yields:
{'foo' => {'bar' => {'baz' => 'value'}}}
Parameters:
array
-
Array containing path components, usually acquired from a string with dot separators and a call to String#split.
value
-
The value found at the path indicated by
array
.
If array
is empty, value
is returned directly, with no nesting Hash wrapping it.
42 43 44 45 46 47 48 |
# File 'lib/scimitar/support/utilities.rb', line 42 def self.dot_path(array, value) return value if array.empty? {}.tap do | hash | hash[array.shift()] = self.dot_path(array, value) end end |
.path_str_to_array(schemas, path_str) ⇒ Object
Schema ID-aware splitter handling “:” or “.” separators. Adapted from contribution by @bettysteger and @MorrisFreeman in:
https://github.com/RIPAGlobal/scimitar/issues/48
https://github.com/RIPAGlobal/scimitar/pull/49
- +schemas
-
Array of extension schemas, e.g. a SCIM resource class’
scim_resource_type.extended_schemas
value. The Array should be empty if there are no extensions. path_str
-
Path String, e.g.
"password"
,"name.givenName"
,"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
(special case),"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:organization"
(if given a Symbol, it’ll be converted to a String).
Returns an array of components, e.g. ["password"]
, ["name", "givenName"]
, ["urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]
(special case), ["urn:ietf:params:scim:schemas:extension:enterprise:2.0:User", "organization"]
.
The called-out special case is for a schema ID without any appended path components, which is returned as a single element ID to aid in traversal particularly of things like PATCH requests. There, a “value” attribute might have a key string that’s simply a schema ID, with an object beneath that’s got attribute-name pairs, possibly nested, in a path-free payload.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/scimitar/support/utilities.rb', line 77 def self.path_str_to_array(schemas, path_str) path_str = path_str.to_s components = [] # Note the ":" separating the schema ID (URN) from the attribute. # The nature of JSON rendering / other payloads might lead you to # expect a "." as with any complex types, but that's not the case; # see https://tools.ietf.org/html/rfc7644#section-3.10, or # https://tools.ietf.org/html/rfc7644#section-3.5.2 of which in # particular, https://tools.ietf.org/html/rfc7644#page-35. # if path_str.include?(':') lower_case_path_str = path_str.downcase() schemas.each do |schema| lower_case_schema_id = schema.id.downcase() attributes_after_schema_id = lower_case_path_str.split(lower_case_schema_id + ':').drop(1) if attributes_after_schema_id.empty? components += [schema.id] if lower_case_path_str == lower_case_schema_id else attributes_after_schema_id.each do |component| components += [schema.id] + component.split('.') end end end end components = path_str.split('.') if components.empty? return components end |