Class: Authentication

Inherits:
ApplicationRecord show all
Includes:
Models::Auditable
Defined in:
app/models/authentication.rb

Overview

== Schema Information

Table name: authentications
Database name: primary

id :integer not null, primary key
google_auth_access_token :text
google_auth_refresh_token :text
google_calendar_status :string
google_calendar_status_checked_at :datetime
provider :string(255)
uid :string(255)
created_at :datetime not null
updated_at :datetime not null
account_id :integer

Indexes

index_authentications_on_account_id (account_id)
index_authentications_on_uid (uid)
provider_account_id (provider,account_id)
provider_uid (provider,uid)

Constant Summary collapse

PROVIDERS =

Providers.

{
"facebook" => { icon: "facebook", name: "facebook" },
"google_oauth2" => { icon: "google", name: "google" },
"linkedin" => { icon: "linkedin", name: "linkedin" },
"apple" => { icon: "apple", name: "apple" },
"zoom" => { icon: "video", name: "zoom" }
}.freeze
SUPPORTED_PROVIDERS =

Sign In with Apple is temporarily deferred pending an Apple Developer
Program membership renewal. The strategy code in
config/initializers/130_devise.rb and app/models/account.rb (avatar
extraction, monkey-patches) stays in place — re-enable by adding
'apple' back to this list and uncommenting the config.omniauth :apple, …
block. See doc/development/SOCIAL_LOGIN_SETUP.md.

%w[facebook google_oauth2 linkedin zoom].freeze
GOOGLE_REFRESH_SKEW =

Refresh a Google access token this far ahead of its stated expiry, so a
request can't start with seconds of validity left and 401 mid-flight.

2.minutes

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Belongs to collapse

Methods included from Models::Auditable

#creator, #updater

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#providerString (readonly)

Returns:

  • (String)


36
# File 'app/models/authentication.rb', line 36

validates :provider, presence: true

#uidString (readonly)

Returns:

  • (String)

Validations:



38
# File 'app/models/authentication.rb', line 38

validates :uid, presence: true

Class Method Details

.extract_email_from_omniauth_hash(omniauth) ⇒ String?

Parameters:

  • omniauth (Hash)

    OmniAuth auth hash

Returns:

  • (String, nil)


73
74
75
# File 'app/models/authentication.rb', line 73

def self.extract_email_from_omniauth_hash(omniauth)
  omniauth.try(:[], 'user_info').try(:[], 'email') || omniauth.try(:[], 'info').try(:[], 'email')
end

.extract_name_from_omniauth_hash(omniauth) ⇒ String?

Parameters:

  • omniauth (Hash)

    OmniAuth auth hash

Returns:

  • (String, nil)


92
93
94
95
96
97
98
99
# File 'app/models/authentication.rb', line 92

def self.extract_name_from_omniauth_hash(omniauth)
  omniauth.try(:[], 'user_info').try(:[],
'name') || omniauth.try(:[], 'info').try(:[],
'name') || (if omniauth.try(:[], 'info').try(:[],
'first_name').present? || omniauth.try(:[], 'info').try(:[], 'last_name').present?
            [omniauth.try(:[], 'info').try(:[], 'first_name'), omniauth.try(:[], 'info').try(:[], 'last_name')].compact.join(' ')
          end)
end

.extract_picture_url_from_omniauth_hash(omniauth) ⇒ String?

Extract the profile picture URL across providers. Facebook /
Google use info.image; LinkedIn OIDC uses info.picture_url;
Apple does not return one. Returns nil when absent so callers can
skip the fetch.

Parameters:

  • omniauth (Hash)

    OmniAuth auth hash

Returns:

  • (String, nil)


83
84
85
86
87
88
# File 'app/models/authentication.rb', line 83

def self.extract_picture_url_from_omniauth_hash(omniauth)
  info = omniauth.try(:[], 'info') || omniauth.try(:[], 'user_info')
  return nil unless info

  info['image'].presence || info['picture_url'].presence || info['picture'].presence
end

.google_authActiveRecord::Relation<Authentication>

A relation of Authentications that are google auth. Active Record Scope

Returns:

See Also:



32
# File 'app/models/authentication.rb', line 32

scope :google_auth, -> { where(provider: 'google_oauth2') }

.zoom_authActiveRecord::Relation<Authentication>

A relation of Authentications that are zoom auth. Active Record Scope

Returns:

See Also:



33
# File 'app/models/authentication.rb', line 33

scope :zoom_auth, -> { where(provider: 'zoom') }

Instance Method Details

#accountAccount?

Returns:

Validations:



30
# File 'app/models/authentication.rb', line 30

belongs_to :account, optional: true

#google_auth_needs_refresh?Boolean

True when the stored Google access token is expired, about to expire, or of
unknown age. Unknown counts as stale on purpose: rows predating
+google_auth_expires_at+ refresh once and record their expiry from then on.

Returns:

  • (Boolean)


67
68
69
# File 'app/models/authentication.rb', line 67

def google_auth_needs_refresh?
  google_auth_expires_at.blank? || google_auth_expires_at <= Time.current + GOOGLE_REFRESH_SKEW
end