Class: OauthCredential

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

Overview

== Schema Information

Table name: oauth_credentials
Database name: primary

id :bigint not null, primary key
access_token :text not null
expires_at :datetime
metadata :jsonb
provider :string not null
refresh_token :text
token_type :string default("Bearer")
created_at :datetime not null
updated_at :datetime not null
account_id :bigint

Indexes

index_oauth_credentials_on_provider_and_account_id (provider,account_id) UNIQUE

Foreign Keys

fk_rails_... (account_id => accounts.id)

Constant Summary

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

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::EventPublishable

#publish_event

Instance Attribute Details

#access_tokenObject (readonly)



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

validates :access_token, presence: true

#providerObject (readonly)



31
# File 'app/models/oauth_credential.rb', line 31

validates :provider, presence: true, uniqueness: { scope: :account_id }

Class Method Details

.activeActiveRecord::Relation<OauthCredential>

A relation of OauthCredentials that are active. Active Record Scope

Returns:

See Also:



34
# File 'app/models/oauth_credential.rb', line 34

scope :active, -> { where('expires_at IS NULL OR expires_at > ?', Time.current) }

.expiring_withinActiveRecord::Relation<OauthCredential>

A relation of OauthCredentials that are expiring within. Active Record Scope

Returns:

See Also:



35
# File 'app/models/oauth_credential.rb', line 35

scope :expiring_within, ->(duration) { where('expires_at IS NOT NULL AND expires_at <= ?', duration.from_now) }

.for(provider, account: nil) ⇒ OauthCredential?

Fetch the credential for a given provider, optionally scoped to an account.

Parameters:

  • provider (String)

    e.g. "basecamp"

  • account (Account, nil) (defaults to: nil)

    specific account, or nil for system-level

Returns:



41
42
43
# File 'app/models/oauth_credential.rb', line 41

def self.for(provider, account: nil)
  find_by(provider: provider, account_id: &.id)
end

.for!(provider, account: nil) ⇒ OauthCredential

Fetch the credential for a given provider, raising if not found.

Parameters:

  • provider (String)
  • account (Account, nil) (defaults to: nil)

Returns:

Raises:

  • (ActiveRecord::RecordNotFound)


50
51
52
# File 'app/models/oauth_credential.rb', line 50

def self.for!(provider, account: nil)
  find_by!(provider: provider, account_id: &.id)
end

Instance Method Details

#accountAccount

Returns:

See Also:



29
# File 'app/models/oauth_credential.rb', line 29

belongs_to :account, optional: true

#expires_inObject

How many seconds until the token expires. Returns nil if no expiry set.



63
64
65
66
67
# File 'app/models/oauth_credential.rb', line 63

def expires_in
  return nil if expires_at.blank?

  [(expires_at - Time.current).to_i, 0].max
end

#token_expired?Boolean

Returns:

  • (Boolean)


54
55
56
# File 'app/models/oauth_credential.rb', line 54

def token_expired?
  expires_at.present? && expires_at <= Time.current
end

#token_fresh?Boolean

Returns:

  • (Boolean)


58
59
60
# File 'app/models/oauth_credential.rb', line 58

def token_fresh?
  !token_expired?
end

#update_from_oauth2_token!(oauth2_token) ⇒ Object

Update the credential with a new token response from OAuth2::AccessToken.

Parameters:

  • oauth2_token (OAuth2::AccessToken)


71
72
73
74
75
76
77
78
# File 'app/models/oauth_credential.rb', line 71

def update_from_oauth2_token!(oauth2_token)
  update!(
    access_token: oauth2_token.token,
    refresh_token: oauth2_token.refresh_token || refresh_token, # Keep old if not returned
    expires_at: oauth2_token.expires_at ? Time.at(oauth2_token.expires_at) : nil,
    token_type: oauth2_token.params['token_type'] || 'Bearer'
  )
end