Refactor User model, extract PamAuthenticable, LdapAuthenticable (#10217)
This commit is contained in:
		
							
								
								
									
										25
									
								
								app/models/concerns/ldap_authenticable.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/models/concerns/ldap_authenticable.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||
|  | ||||
							
								
								
									
										68
									
								
								app/models/concerns/pam_authenticable.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								app/models/concerns/pam_authenticable.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||
							
								
								
									
										54
									
								
								app/models/concerns/user_roles.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								app/models/concerns/user_roles.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user