Files
baffle-hub/app/models/user.rb

74 lines
2.0 KiB
Ruby

class User < ApplicationRecord
has_secure_password
has_many :sessions, dependent: :destroy
normalizes :email_address, with: ->(e) { e.strip.downcase }
enum :role, { admin: 0, user: 1, viewer: 2 }, default: :user
generates_token_for :password_reset, expires_in: 1.hour do
updated_at
end
validates :email_address, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :role, presence: true
before_validation :set_first_user_as_admin, on: :create
def self.from_oidc(auth_hash)
# Extract user info from OIDC auth hash
email = auth_hash.dig('info', 'email')
return nil unless email
user = find_or_initialize_by(email_address: email)
# Map OIDC groups to role for new users or update existing user's role
if auth_hash.dig('extra', 'raw_info', 'groups')
user.role = map_oidc_groups_to_role(auth_hash.dig('extra', 'raw_info', 'groups'))
end
# For OIDC users, set a random password if they don't have one
if user.new_record? && !user.password_digest?
user.password = SecureRandom.hex(32) # OIDC users won't use this
end
# Save the user (skip password validation for OIDC users)
user.save!(validate: false) if user.changed?
user
end
def admin?
role == 'admin'
end
def viewer?
role == 'viewer'
end
private
def set_first_user_as_admin
return if User.any?
self.role = 'admin'
end
def self.map_oidc_groups_to_role(groups)
groups = Array(groups)
# Check admin groups first
admin_groups = ENV['OIDC_ADMIN_GROUPS']&.split(',')&.map(&:strip)
return 'admin' if admin_groups && (admin_groups & groups).any?
# Check user groups
user_groups = ENV['OIDC_USER_GROUPS']&.split(',')&.map(&:strip)
return 'user' if user_groups && (user_groups & groups).any?
# Check viewer groups
viewer_groups = ENV['OIDC_VIEWER_GROUPS']&.split(',')&.map(&:strip)
return 'viewer' if viewer_groups && (viewer_groups & groups).any?
# Default to user if no group matches
'user'
end
end