--- /dev/null
+# frozen_string_literal: true
+
+module PamAuthenticable
+ extend ActiveSupport::Concern
+
+ included do
+ devise :pam_authenticatable if ENV['PAM_ENABLED'] == 'true'
+
+ def pam_conflict(_attributes)
+ # Block pam login tries on traditional account
+ end
+
+ def pam_conflict?
+ if Devise.pam_authentication
+ encrypted_password.present? && pam_managed_user?
+ else
+ false
+ end
+ end
+
+ def pam_get_name
+ if account.present?
+ account.username
+ else
+ super
+ end
+ end
+
+ def pam_setup(_attributes)
+ account = Account.new(username: pam_get_name)
+ account.save!(validate: false)
+
+ self.email = "#{account.username}@#{find_pam_suffix}" if email.nil? && find_pam_suffix
+ self.confirmed_at = Time.now.utc
+ self.admin = false
+ self.account = account
+
+ account.destroy! unless save
+ end
+
+ def self.pam_get_user(attributes = {})
+ return nil unless attributes[:email]
+
+ resource = begin
+ if Devise.check_at_sign && !attributes[:email].index('@')
+ joins(:account).find_by(accounts: { username: attributes[:email] })
+ else
+ find_by(email: attributes[:email])
+ end
+ end
+
+ if resource.nil?
+ resource = new(email: attributes[:email], agreement: true)
+
+ if Devise.check_at_sign && !resource[:email].index('@')
+ resource[:email] = Rpam2.getenv(resource.find_pam_service, attributes[:email], attributes[:password], 'email', false)
+ resource[:email] = "#{attributes[:email]}@#{resource.find_pam_suffix}" unless resource[:email]
+ end
+ end
+
+ resource
+ end
+
+ def self.authenticate_with_pam(attributes = {})
+ super if Devise.pam_authentication
+ end
+ end
+end
class User < ApplicationRecord
include Settings::Extend
- include Omniauthable
+ include UserRoles
# The home and list feeds will be stored in Redis for this amount
# of time, and status fan-out to followers will include only people
devise :registerable, :recoverable, :rememberable, :trackable, :validatable,
:confirmable
- devise :pam_authenticatable if ENV['PAM_ENABLED'] == 'true'
-
- devise :omniauthable
+ include Omniauthable
+ include PamAuthenticable
+ include LdapAuthenticable
belongs_to :account, inverse_of: :user
belongs_to :invite, counter_cache: :uses, optional: true
validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create
scope :recent, -> { order(id: :desc) }
- scope :admins, -> { where(admin: true) }
- scope :moderators, -> { where(moderator: true) }
- scope :staff, -> { admins.or(moderators) }
scope :confirmed, -> { where.not(confirmed_at: nil) }
scope :enabled, -> { where(disabled: false) }
scope :inactive, -> { where(arel_table[:current_sign_in_at].lt(ACTIVE_DURATION.ago)) }
attr_reader :invite_code
- def pam_conflict(_)
- # block pam login tries on traditional account
- nil
- end
-
- def pam_conflict?
- return false unless Devise.pam_authentication
- encrypted_password.present? && pam_managed_user?
- end
-
- def pam_get_name
- return account.username if account.present?
- super
- end
-
- def pam_setup(_attributes)
- acc = Account.new(username: pam_get_name)
- acc.save!(validate: false)
-
- self.email = "#{acc.username}@#{find_pam_suffix}" if email.nil? && find_pam_suffix
- self.confirmed_at = Time.now.utc
- self.admin = false
- self.account = acc
-
- acc.destroy! unless save
- end
-
- def ldap_setup(_attributes)
- self.confirmed_at = Time.now.utc
- self.admin = false
- save!
- end
-
def confirmed?
confirmed_at.present?
end
invite_id.present?
end
- def staff?
- admin? || moderator?
- end
-
- def role
- if admin?
- 'admin'
- elsif moderator?
- 'moderator'
- else
- 'user'
- end
- end
-
- def role?(role)
- case role
- when 'user'
- true
- when 'moderator'
- staff?
- when 'admin'
- admin?
- else
- false
- end
- end
-
def disable!
update!(disabled: true,
last_sign_in_at: current_sign_in_at,
new_user = !confirmed?
super
+
prepare_new_user! if new_user
end
skip_confirmation!
save!
+
prepare_new_user! if new_user
end
prepare_returning_user!
end
- def promote!
- if moderator?
- update!(moderator: false, admin: true)
- elsif !admin?
- update!(moderator: true)
- end
- end
-
- def demote!
- if admin?
- update!(admin: false, moderator: true)
- elsif moderator?
- update!(moderator: false)
- end
- end
-
def disable_two_factor!
self.otp_required_for_login = false
otp_backup_codes&.clear
super
end
- def self.pam_get_user(attributes = {})
- return nil unless attributes[:email]
-
- resource =
- if Devise.check_at_sign && !attributes[:email].index('@')
- joins(:account).find_by(accounts: { username: attributes[:email] })
- else
- find_by(email: attributes[:email])
- end
-
- if resource.blank?
- resource = new(email: attributes[:email], agreement: true)
-
- if Devise.check_at_sign && !resource[:email].index('@')
- resource[:email] = Rpam2.getenv(resource.find_pam_service, attributes[:email], attributes[:password], 'email', false)
- resource[:email] = "#{attributes[:email]}@#{resource.find_pam_suffix}" unless resource[:email]
- end
- end
- resource
- end
-
- def self.ldap_get_user(attributes = {})
- resource = joins(:account).find_by(accounts: { username: attributes[Devise.ldap_uid.to_sym].first })
-
- if resource.blank?
- resource = new(email: attributes[:mail].first, agreement: true, account_attributes: { username: attributes[Devise.ldap_uid.to_sym].first })
- resource.ldap_setup(attributes)
- end
-
- resource
- end
-
- def self.authenticate_with_pam(attributes = {})
- return nil unless Devise.pam_authentication
- super
- end
-
def show_all_media?
setting_display_media == 'show_all'
end