mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 12:04:08 +00:00
Add security measures for SSO-only users: block password resets, enforce SSO authentication, and refactor validations for JIT provisioning. (#569)
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
class User < ApplicationRecord
|
||||
has_secure_password
|
||||
# Allow nil password for SSO-only users (JIT provisioning).
|
||||
# Custom validation ensures password is present for non-SSO registration.
|
||||
has_secure_password validations: false
|
||||
|
||||
belongs_to :family
|
||||
belongs_to :last_viewed_chat, class_name: "Chat", optional: true
|
||||
@@ -17,6 +19,11 @@ class User < ApplicationRecord
|
||||
validate :ensure_valid_profile_image
|
||||
validates :default_period, inclusion: { in: Period::PERIODS.keys }
|
||||
validates :default_account_order, inclusion: { in: AccountOrder::ORDERS.keys }
|
||||
|
||||
# Password is required on create unless the user is being created via SSO JIT.
|
||||
# SSO JIT users have password_digest = nil and authenticate via OIDC only.
|
||||
validates :password, presence: true, on: :create, unless: :skip_password_validation?
|
||||
validates :password, length: { minimum: 8 }, allow_nil: true
|
||||
normalizes :email, with: ->(email) { email.strip.downcase }
|
||||
normalizes :unconfirmed_email, with: ->(email) { email&.strip&.downcase }
|
||||
|
||||
@@ -104,6 +111,20 @@ class User < ApplicationRecord
|
||||
ai_enabled && ai_available?
|
||||
end
|
||||
|
||||
# SSO-only users have OIDC identities but no local password.
|
||||
# They cannot use password reset or local login.
|
||||
def sso_only?
|
||||
password_digest.nil? && oidc_identities.exists?
|
||||
end
|
||||
|
||||
# Check if user has a local password set (can authenticate locally)
|
||||
def has_local_password?
|
||||
password_digest.present?
|
||||
end
|
||||
|
||||
# Attribute to skip password validation during SSO JIT provisioning
|
||||
attr_accessor :skip_password_validation
|
||||
|
||||
# Deactivation
|
||||
validate :can_deactivate, if: -> { active_changed? && !active }
|
||||
after_update_commit :purge_later, if: -> { saved_change_to_active?(from: true, to: false) }
|
||||
@@ -258,6 +279,10 @@ class User < ApplicationRecord
|
||||
end
|
||||
|
||||
private
|
||||
def skip_password_validation?
|
||||
skip_password_validation == true
|
||||
end
|
||||
|
||||
def default_dashboard_section_order
|
||||
%w[cashflow_sankey outflows_donut net_worth_chart balance_sheet]
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user