Refactor User model, extract PamAuthenticable, LdapAuthenticable (#10217)

master
Eugen Rochko 5 years ago committed by GitHub
parent dfb9efae81
commit 9e33174604
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      app/models/concerns/ldap_authenticable.rb
  2. 2
      app/models/concerns/omniauthable.rb
  3. 68
      app/models/concerns/pam_authenticable.rb
  4. 54
      app/models/concerns/user_roles.rb
  5. 126
      app/models/user.rb

@ -0,0 +1,25 @@
# frozen_string_literal: true
module LdapAuthenticable
extend ActiveSupport::Concern
def ldap_setup(_attributes)
self.confirmed_at = Time.now.utc
self.admin = false
save!
end
class_methods do
def 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
end
end

@ -7,6 +7,8 @@ module Omniauthable
TEMP_EMAIL_REGEX = /\Achange@me/
included do
devise :omniauthable
def omniauth_providers
Devise.omniauth_configs.keys
end

@ -0,0 +1,68 @@
# 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

@ -0,0 +1,54 @@
# frozen_string_literal: true
module UserRoles
extend ActiveSupport::Concern
included do
scope :admins, -> { where(admin: true) }
scope :moderators, -> { where(moderator: true) }
scope :staff, -> { admins.or(moderators) }
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 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
end

@ -41,7 +41,7 @@
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
@ -61,9 +61,9 @@ class User < ApplicationRecord
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
@ -79,9 +79,6 @@ class User < ApplicationRecord
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)) }
@ -104,39 +101,6 @@ class User < ApplicationRecord
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
@ -145,33 +109,6 @@ class User < ApplicationRecord
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,
@ -186,6 +123,7 @@ class User < ApplicationRecord
new_user = !confirmed?
super
prepare_new_user! if new_user
end
@ -194,6 +132,7 @@ class User < ApplicationRecord
skip_confirmation!
save!
prepare_new_user! if new_user
end
@ -202,22 +141,6 @@ class User < ApplicationRecord
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
@ -297,43 +220,6 @@ class User < ApplicationRecord
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

Loading…
Cancel
Save