Class: Scimitar::Resources::Base
- Inherits:
-
Object
- Object
- Scimitar::Resources::Base
- Includes:
- ActiveModel::Model, Errors, Schema::DerivedAttributes
- Defined in:
- app/models/scimitar/resources/base.rb
Overview
The base class for all SCIM resources.
Instance Attribute Summary collapse
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#externalId ⇒ Object
Returns the value of attribute externalId.
-
#id ⇒ Object
Returns the value of attribute id.
-
#meta ⇒ Object
Returns the value of attribute meta.
Class Method Summary collapse
- .all_attributes ⇒ Object
- .complex_scim_attributes ⇒ Object
-
.extend_schema(schema) ⇒ Object
Can be used to extend an existing resource type’s schema.
- .extended_schemas ⇒ Object
-
.find_attribute(*path) ⇒ Object
Calls to Scimitar::Schema::Base::find_attribute for each of the schemas in ::schemas, in order returned (so main schema would be first, then any extended schemas searched next).
- .resource_type(location) ⇒ Object
- .resource_type_id ⇒ Object
- .schemas ⇒ Object
Instance Method Summary collapse
-
#as_json(options = {}) ⇒ Object
Renders *in full* as JSON; typically used for write-based operations…
- #complex_type_from_hash(scim_attribute, attr_value) ⇒ Object
- #constantize_complex_types(hash) ⇒ Object
- #flatten_extension_attributes(options) ⇒ Object
-
#initialize(options = {}) ⇒ Base
constructor
A new instance of Base.
- #validate_resource ⇒ Object
Methods included from Errors
Constructor Details
#initialize(options = {}) ⇒ Base
Returns a new instance of Base.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'app/models/scimitar/resources/base.rb', line 13 def initialize( = {}) flattened_attributes = flatten_extension_attributes() ci_all_attributes = Scimitar::Support::HashWithIndifferentCaseInsensitiveAccess.new camel_attributes = {} # Create a map where values are the schema-correct-case attribute names # and the values are set the same, but since the ci_all_attributes data # type is HashWithIndifferentCaseInsensitiveAccess, lookups in this are # case insensitive. Thus, arbitrary case input data can be mapped to # the case correctness required for ActiveModel's attribute accessors. # self.class.all_attributes.each { |attr| ci_all_attributes[attr] = attr } flattened_attributes.each do | key, value | if ci_all_attributes.key?(key) camel_attributes[ci_all_attributes[key]] = value end end super(camel_attributes) constantize_complex_types(camel_attributes) @errors = ActiveModel::Errors.new(self) end |
Instance Attribute Details
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
10 11 12 |
# File 'app/models/scimitar/resources/base.rb', line 10 def errors @errors end |
#externalId ⇒ Object
Returns the value of attribute externalId.
9 10 11 |
# File 'app/models/scimitar/resources/base.rb', line 9 def externalId @externalId end |
#id ⇒ Object
Returns the value of attribute id.
9 10 11 |
# File 'app/models/scimitar/resources/base.rb', line 9 def id @id end |
#meta ⇒ Object
Returns the value of attribute meta.
9 10 11 |
# File 'app/models/scimitar/resources/base.rb', line 9 def @meta end |
Class Method Details
.all_attributes ⇒ Object
90 91 92 93 |
# File 'app/models/scimitar/resources/base.rb', line 90 def self.all_attributes scim_attributes = schemas.map(&:scim_attributes).flatten.map(&:name) scim_attributes + [:id, :externalId, :meta] end |
.complex_scim_attributes ⇒ Object
114 115 116 |
# File 'app/models/scimitar/resources/base.rb', line 114 def self.complex_scim_attributes schemas.flat_map(&:scim_attributes).select(&:complexType).group_by(&:name) end |
.extend_schema(schema) ⇒ Object
Can be used to extend an existing resource type’s schema. For example:
module Scim
module Schema
class MyExtension < Scimitar::Schema::Base
def initialize( = {})
super(name: 'ExtendedGroup',
id: self.class.id,
description: 'Represents extra info about a group',
scim_attributes: self.class.scim_attributes)
end
def self.id
'urn:ietf:params:scim:schemas:extension:extendedgroup:2.0:Group'
end
def self.scim_attributes
[Scimitar::Schema::Attribute.new(name: 'someAddedAttribute',
type: 'string',
required: true,
canonicalValues: ['FOO', 'BAR'])]
end
end
end
end
Scimitar::Resources::Group.extend_schema Scim::Schema::MyExtension
77 78 79 80 |
# File 'app/models/scimitar/resources/base.rb', line 77 def self.extend_schema(schema) derive_attributes_from_schema(schema) extended_schemas << schema end |
.extended_schemas ⇒ Object
82 83 84 |
# File 'app/models/scimitar/resources/base.rb', line 82 def self.extended_schemas @extended_schemas ||= [] end |
.find_attribute(*path) ⇒ Object
Calls to Scimitar::Schema::Base::find_attribute for each of the schemas in ::schemas, in order returned (so main schema would be first, then any extended schemas searched next). Returns the first match found, or nil
.
See Scimitar::Schema::Base::find_attribute for details on parameters, more about the return value and other general information.
103 104 105 106 107 108 109 110 111 112 |
# File 'app/models/scimitar/resources/base.rb', line 103 def self.find_attribute(*path) found_attribute = nil self.schemas.each do | schema | found_attribute = schema.find_attribute(*path) break unless found_attribute.nil? end return found_attribute end |
.resource_type(location) ⇒ Object
169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'app/models/scimitar/resources/base.rb', line 169 def self.resource_type(location) resource_type = ResourceType.new( endpoint: endpoint, schema: schema.id, id: resource_type_id, name: resource_type_id, schemaExtensions: extended_schemas.map(&:id) ) resource_type..location = location resource_type end |
.resource_type_id ⇒ Object
165 166 167 |
# File 'app/models/scimitar/resources/base.rb', line 165 def self.resource_type_id name.demodulize end |
.schemas ⇒ Object
86 87 88 |
# File 'app/models/scimitar/resources/base.rb', line 86 def self.schemas ([schema] + extended_schemas).flatten end |
Instance Method Details
#as_json(options = {}) ⇒ Object
Renders *in full* as JSON; typically used for write-based operations…
record = self.storage_class().new
record.from_scim!(scim_hash: scim_resource.as_json())
self.save!(record)
…so all fields, even those marked “returned: false”, are included. Use Scimitar::Resources::Mixin::to_scim to obtain a SCIM object with non-returnable fields omitted, rendering that as JSON via #to_json.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'app/models/scimitar/resources/base.rb', line 150 def as_json( = {}) self. = Meta.new unless self. && self..is_a?(Meta) self..resourceType = self.class.resource_type_id original_hash = super().except('errors') original_hash.merge!('schemas' => self.class.schemas.map(&:id)) self.class.extended_schemas.each do |extension_schema| extension_attributes = extension_schema.scim_attributes.map(&:name) original_hash.merge!(extension_schema.id => original_hash.extract!(*extension_attributes)) end original_hash end |
#complex_type_from_hash(scim_attribute, attr_value) ⇒ Object
118 119 120 121 122 123 124 |
# File 'app/models/scimitar/resources/base.rb', line 118 def complex_type_from_hash(scim_attribute, attr_value) if attr_value.is_a?(Hash) scim_attribute.complexType.new(attr_value) else attr_value end end |
#constantize_complex_types(hash) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'app/models/scimitar/resources/base.rb', line 126 def constantize_complex_types(hash) hash.with_indifferent_access.each_pair do |attr_name, attr_value| scim_attribute = self.class.complex_scim_attributes[attr_name].try(:first) if scim_attribute && scim_attribute.complexType if scim_attribute.multiValued self.send("#{attr_name}=", attr_value&.map {|attr_for_each_item| complex_type_from_hash(scim_attribute, attr_for_each_item)}) else self.send("#{attr_name}=", complex_type_from_hash(scim_attribute, attr_value)) end end end end |
#flatten_extension_attributes(options) ⇒ Object
38 39 40 41 42 43 44 45 46 |
# File 'app/models/scimitar/resources/base.rb', line 38 def flatten_extension_attributes() flattened = .dup self.class.extended_schemas.each do |extended_schema| if extension_attrs = flattened.delete(extended_schema.id) flattened.merge!(extension_attrs) end end flattened end |
#validate_resource ⇒ Object
182 183 184 185 186 187 |
# File 'app/models/scimitar/resources/base.rb', line 182 def validate_resource self.class.schema.valid?(self) self.class.extended_schemas.each do |extended_schema| extended_schema.valid?(self) end end |