# @note When we destroy the related user, it's using dependent: # :delete for the relationship. That means no before/after # destroy callbacks will be called on this object. class Identity < ApplicationRecord belongs_to :user scope :enabled, -> { where(provider: Authentication::Providers.enabled) } Authentication::Providers.available.each do |provider_name| scope provider_name, -> { where(provider: provider_name) } end validates :provider, inclusion: { in: Authentication::Providers.available.map(&:to_s) } validates :uid, :provider, presence: true validates :uid, uniqueness: { scope: :provider }, if: proc { |identity| identity.uid_changed? || identity.provider_changed? } validates :user_id, uniqueness: { scope: :provider }, if: proc { |identity| identity.user_id_changed? || identity.provider_changed? } # TODO: [@forem/oss] should this be transitioned to JSON? serialize :auth_data_dump # Builds an identity from OmniAuth's authentication payload def self.build_from_omniauth(provider) payload = provider.payload identity = find_or_initialize_by( provider: payload.provider, uid: payload.uid, ) identity.assign_attributes( token: payload.credentials.token, secret: payload.credentials.secret, auth_data_dump: payload, ) identity end def email auth_data_dump&.info&.email || I18n.t("models.identity.no_email_msg", provider: provider) end end