Class: TwoPercent::ScimUser
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- TwoPercent::ScimUser
- Defined in:
- app/models/two_percent/scim_user.rb
Class Method Summary collapse
- .destroy_by_scim_id(scim_id) ⇒ Object
- .exists_by_scim_id?(scim_id) ⇒ Boolean
- .find_by_scim_id(scim_id) ⇒ Object
-
.upsert_from_scim(scim_hash, correlation_id: nil) ⇒ TwoPercent::ScimUser
Creates or updates a user from SCIM data.
Instance Method Summary collapse
- #extension_attributes(schema_urn = nil) ⇒ Object
-
#scim_attribute(path) ⇒ Object?
Extracts a nested attribute from the scim_data JSON.
- #sync_groups(groups_data) ⇒ Object
-
#to_domain_attributes ⇒ Hash
Extracts domain attributes for publishing in domain events.
-
#to_scim_representation ⇒ Hash
Returns full SCIM representation for HTTP responses.
- #update_from_scim!(validated_data, correlation_id: nil) ⇒ Object
Class Method Details
.destroy_by_scim_id(scim_id) ⇒ Object
47 48 49 |
# File 'app/models/two_percent/scim_user.rb', line 47 def self.destroy_by_scim_id(scim_id) find_by_scim_id(scim_id)&.destroy end |
.exists_by_scim_id?(scim_id) ⇒ Boolean
43 44 45 |
# File 'app/models/two_percent/scim_user.rb', line 43 def self.exists_by_scim_id?(scim_id) exists?(scim_id: scim_id) end |
.find_by_scim_id(scim_id) ⇒ Object
39 40 41 |
# File 'app/models/two_percent/scim_user.rb', line 39 def self.find_by_scim_id(scim_id) find_by(scim_id: scim_id) end |
.upsert_from_scim(scim_hash, correlation_id: nil) ⇒ TwoPercent::ScimUser
Creates or updates a user from SCIM data
Generates a UUID for the id field if not present (for POST/create operations). Validates the SCIM data against the User schema before persisting.
28 29 30 31 32 33 34 35 36 37 |
# File 'app/models/two_percent/scim_user.rb', line 28 def self.upsert_from_scim(scim_hash, correlation_id: nil) # Generate ID if not present (for POST/create operations) scim_hash = scim_hash.dup scim_hash["id"] ||= SecureRandom.uuid validated_data = TwoPercent::Scim::Schema.validate_user(scim_hash, require_id: true) scim_user = find_or_initialize_by(scim_id: scim_hash["id"]) scim_user.update_from_scim!(validated_data, correlation_id: correlation_id) scim_user end |
Instance Method Details
#extension_attributes(schema_urn = nil) ⇒ Object
118 119 120 121 122 123 124 |
# File 'app/models/two_percent/scim_user.rb', line 118 def extension_attributes(schema_urn = nil) if schema_urn scim_data[schema_urn] || {} else scim_data.select { |k, _| k.start_with?("urn:ietf:params:scim:schemas:extension:") } end end |
#scim_attribute(path) ⇒ Object?
Extracts a nested attribute from the scim_data JSON
113 114 115 116 |
# File 'app/models/two_percent/scim_user.rb', line 113 def scim_attribute(path) keys = path.split(".") scim_data.dig(*keys) end |
#sync_groups(groups_data) ⇒ Object
99 100 101 102 103 104 105 |
# File 'app/models/two_percent/scim_user.rb', line 99 def sync_groups(groups_data) return if groups_data.blank? group_ids = groups_data.filter_map { |g| g["value"] } groups = TwoPercent::ScimGroup.where(scim_id: group_ids) self.scim_groups = groups end |
#to_domain_attributes ⇒ Hash
Extracts domain attributes for publishing in domain events
Returns key attributes for event payloads. Includes associated group memberships if loaded.
57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'app/models/two_percent/scim_user.rb', line 57 def to_domain_attributes attributes = { scim_id: scim_id, external_id: external_id, user_name: user_name, display_name: display_name, email: email, active: active, } attributes[:groups] = group_memberships_attributes if scim_groups.loaded? || scim_groups.any? attributes.compact end |
#to_scim_representation ⇒ Hash
Returns full SCIM representation for HTTP responses
74 75 76 77 78 79 80 81 82 83 |
# File 'app/models/two_percent/scim_user.rb', line 74 def to_scim_representation scim_data.merge( "id" => scim_id, "meta" => { "resourceType" => "User", "created" => created_at.iso8601, "lastModified" => updated_at.iso8601, } ) end |
#update_from_scim!(validated_data, correlation_id: nil) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'app/models/two_percent/scim_user.rb', line 85 def update_from_scim!(validated_data, correlation_id: nil) core_data = validated_data[:core] self.scim_data = core_data.merge(validated_data[:extensions]) self.scim_id = core_data["id"] self.external_id = core_data["externalId"] self.user_name = core_data["userName"] self.display_name = core_data["displayName"] self.email = core_data.dig("emails", 0, "value") self.active = core_data.fetch("active", true) self.correlation_id = correlation_id save! sync_groups(core_data["groups"]) if core_data["groups"] end |