aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-03-14 02:13:42 +0100
committerGitHub <noreply@github.com>2019-03-14 02:13:42 +0100
commit9e33174604952490136a6f8cce2c9bd3ca03a26c (patch)
tree251eb7e328924f4bedcbca7d60e834647500eb18
parentdfb9efae81d029d26a9ef09acd891254529a0f53 (diff)
downloadmastodon-9e33174604952490136a6f8cce2c9bd3ca03a26c.tar
mastodon-9e33174604952490136a6f8cce2c9bd3ca03a26c.tar.gz
mastodon-9e33174604952490136a6f8cce2c9bd3ca03a26c.tar.bz2
mastodon-9e33174604952490136a6f8cce2c9bd3ca03a26c.zip
Refactor User model, extract PamAuthenticable, LdapAuthenticable (#10217)
-rw-r--r--app/models/concerns/ldap_authenticable.rb25
-rw-r--r--app/models/concerns/omniauthable.rb2
-rw-r--r--app/models/concerns/pam_authenticable.rb68
-rw-r--r--app/models/concerns/user_roles.rb54
-rw-r--r--app/models/user.rb126
5 files changed, 155 insertions, 120 deletions
diff --git a/app/models/concerns/ldap_authenticable.rb b/app/models/concerns/ldap_authenticable.rb
new file mode 100644
index 000000000..e1b5e3832
--- /dev/null
+++ b/app/models/concerns/ldap_authenticable.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
diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb
index 4dd2e9383..1b28b8162 100644
--- a/app/models/concerns/omniauthable.rb
+++ b/app/models/concerns/omniauthable.rb
@@ -7,6 +7,8 @@ module Omniauthable
TEMP_EMAIL_REGEX = /\Achange@me/
included do
+ devise :omniauthable
+
def omniauth_providers
Devise.omniauth_configs.keys
end
diff --git a/app/models/concerns/pam_authenticable.rb b/app/models/concerns/pam_authenticable.rb
new file mode 100644
index 000000000..2f651c1a3
--- /dev/null
+++ b/app/models/concerns/pam_authenticable.rb
@@ -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
diff --git a/app/models/concerns/user_roles.rb b/app/models/concerns/user_roles.rb
new file mode 100644
index 000000000..58dffdc46
--- /dev/null
+++ b/app/models/concerns/user_roles.rb
@@ -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
diff --git a/app/models/user.rb b/app/models/user.rb
index 83816def5..a9d6adf70 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -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