Module: Studio::OauthIdentity
- Defined in:
- lib/studio/oauth_identity.rb
Constant Summary collapse
- GOOGLE_PROVIDERS =
Both spellings appear across the ecosystem:
google_oauth2is the OmniAuth strategy name that lands in users.provider, andgoogleis what Studio.auth_methods calls the same thing. Matching both means a host that stored either is read correctly rather than reported as unlinked. %w[google google_oauth2].freeze
Class Method Summary collapse
- .google_linked?(user) ⇒ Boolean
- .present?(user, attribute) ⇒ Boolean
-
.remaining_sign_ins(user, auth_methods: Studio.auth_methods) ⇒ Object
Every way this account could sign in if Google were gone.
-
.unlink_orphans_account?(user, auth_methods: Studio.auth_methods) ⇒ Boolean
The question the controller actually asks before unlinking.
-
.wallet_present?(user) ⇒ Boolean
ONLY the explicitly configured wallet column — no fallback to a conventional name, deliberately.
Class Method Details
.google_linked?(user) ⇒ Boolean
31 32 33 34 35 |
# File 'lib/studio/oauth_identity.rb', line 31 def google_linked?(user) return false unless user.respond_to?(:provider) && user.respond_to?(:uid) GOOGLE_PROVIDERS.include?(user.provider.to_s) && user.uid.present? end |
.present?(user, attribute) ⇒ Boolean
68 69 70 |
# File 'lib/studio/oauth_identity.rb', line 68 def present?(user, attribute) user.respond_to?(attribute) && user.public_send(attribute).present? end |
.remaining_sign_ins(user, auth_methods: Studio.auth_methods) ⇒ Object
Every way this account could sign in if Google were gone. Returns symbols so a caller can name what is left in a message rather than just refusing.
Gated on Studio.auth_methods, not just on the column: an app that has an email column but does not offer magic-link sign-in cannot use it to get back in, and counting it would be exactly the wrong answer.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/studio/oauth_identity.rb', line 43 def remaining_sign_ins(user, auth_methods: Studio.auth_methods) methods = Array(auth_methods).map(&:to_sym) remaining = [] remaining << :magic_link if methods.include?(:magic_link) && present?(user, :email) remaining << :wallet if methods.include?(:wallet) && wallet_present?(user) # `Studio.password_login_available?` — NOT a bare password_digest check. # A digest can be a FOSSIL: turf-monster removed `has_secure_password` and # kept the column, so rows still carry digests no code can authenticate # against. Counting one as a way back in is a false positive in the # dangerous direction — it would permit an unlink that orphans the account. # The engine already ships the correct composite predicate # (auth_method?(:password) && the User answering `authenticate`). remaining << :password if methods.include?(:password) && Studio.password_login_available? && present?(user, :password_digest) remaining end |
.unlink_orphans_account?(user, auth_methods: Studio.auth_methods) ⇒ Boolean
The question the controller actually asks before unlinking.
64 65 66 |
# File 'lib/studio/oauth_identity.rb', line 64 def unlink_orphans_account?(user, auth_methods: Studio.auth_methods) remaining_sign_ins(user, auth_methods: auth_methods).empty? end |
.wallet_present?(user) ⇒ Boolean
ONLY the explicitly configured wallet column — no fallback to a conventional name, deliberately.
A convention-guessed reader is a false positive waiting to happen, and
turf-monster is the live example: its User#solana_address returns
web3_solana_address || web2_solana_address, and only the WEB3 address can
actually sign in (SolanaSessionsController verifies a wallet signature; the
web2 address is a custodial account with no signer). Guessing that reader
would count a custodial address as a way back in and permit an unlink that
orphans the account.
So an app that has not named its signing-wallet column is treated as having
no wallet sign-in. That errs toward REFUSING an unlink, which is the safe
direction: the cost is an occasional refusal the operator can resolve by
configuring Studio.wallet_address_method; the cost of the other direction
is someone locked out of their account.
88 89 90 91 92 93 |
# File 'lib/studio/oauth_identity.rb', line 88 def wallet_present?(user) configured = Studio.wallet_address_method return false if configured.blank? present?(user, configured) end |