1class AdminUser < ActiveRecord::Base
 
2  DISABLED_LOGIN_COUNT = 5
 
3  SYSADMIN_ROLE = 'sysadmin'
 
4  MODERATOR_ROLE = 'moderator'
 
5  ROLES = [SYSADMIN_ROLE, MODERATOR_ROLE]
 
6  PASSWORD_REGEX = /\A.*(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\W_]).*\z/
 
7
 
8  class CannotDeleteCurrentUser < RuntimeError; end
 
 9  class MustBeAtLeastOneAdminUser < RuntimeError; end
 
 
11  acts_as_authentic do |config|
 
12    config.check_passwords_against_database = true
 
13    config.ignore_blank_passwords = true
 
14    config.logged_in_timeout = Site.login_timeout
 
15    config.require_password_confirmation = true
 
 
17    config.merge_validates_length_of_password_field_options minimum: 8
 
18    config.merge_validates_uniqueness_of_email_field_options case_sensitive: false
 
19    config.merge_validates_format_of_email_field_options unless: ->(u) { u.email.blank? }
 
20    config.merge_validates_length_of_email_field_options unless: ->(u) { u.email.blank? }
 
21    config.merge_validates_length_of_password_field_options unless: ->(u) { u.password.blank? }
 
22    config.merge_validates_confirmation_of_password_field_options unless: ->(u) { u.password.blank? }
 
23  end
 
 
25  # = Validations =
 
26  validates_presence_of :email, :first_name, :last_name
 
27  validates_presence_of :password, on: :create
 
28  validates_format_of :password, with: PASSWORD_REGEX, allow_blank: true
 
29  validates_inclusion_of :role, in: ROLES
 
 
31  # = Callbacks =
 
32  before_update if: :crypted_password_changed? do
 
33    self.force_password_reset = false
 
34    self.password_changed_at = Time.current
 
35  end
 
 
37  # = Finders =
 
38  scope :by_name, -> { order(:last_name, :first_name) }
 
39  scope :by_role, ->(role) { where(role: role).order(:id) }
 
 
41  # = Methods =
  • Complexity 2 » saikuro
42  def current_password
 
43    defined?(@current_password) ? @current_password : nil
 
44  end
 
  • Complexity 1 » saikuro
46  def current_password=(value)
 
47    @current_password = value
 
48  end
 
  • TooManyStatements - has approx 8 statements » reek
  • Complexity 6 » saikuro
50  def update_with_password(attrs)
 
51    if attrs[:password].blank?
 
52      attrs.delete(:password)
 
53      attrs.delete(:password_confirmation) if attrs[:password_confirmation].blank?
 
54    end
 
 
56    self.attributes = attrs
 
57    self.valid?
 
 
59    if current_password.blank?
 
60      errors.add(:current_password, :blank)
 
61    elsif !valid_password?(current_password)
 
62      errors.add(:current_password, :invalid)
 
63    elsif current_password == password
 
64      errors.add(:password, :taken)
 
65    end
 
 
67    errors.empty? && save(validate: false)
 
68  end
 
  • ControlParameter - is controlled by argument 'current_user' » reek
  • Complexity 3 » saikuro
70  def destroy(current_user: nil)
 
71    if self == current_user
 
72      raise CannotDeleteCurrentUser, "Cannot delete current user"
 
73    elsif self.class.count < 2
 
74      raise MustBeAtLeastOneAdminUser, "There must be at least one admin user"
 
75    else
 
76      super()
 
77    end
 
78  end
 
  • Complexity 1 » saikuro
80  def name
 
81    "#{last_name}, #{first_name}"
 
82  end
 
  • Complexity 1 » saikuro
84  def pretty_name
 
85    "#{first_name} #{last_name}"
 
86  end
 
  • Complexity 1 » saikuro
88  def is_a_sysadmin?
 
89    self.role == 'sysadmin'
 
90  end
 
  • Complexity 1 » saikuro
92  def is_a_moderator?
 
93    self.role == 'moderator'
 
94  end
 
  • DuplicateMethodCall - calls 'self.password_changed_at' 2 times » reek
  • Complexity 1 » saikuro
96  def has_to_change_password?
 
97    self.force_password_reset or (self.password_changed_at and self.password_changed_at < 9.months.ago)
 
98  end
 
 99
  • Complexity 1 » saikuro
100  def can_take_petitions_down?
 
101    is_a_sysadmin? || is_a_moderator?
 
102  end
 
  • Complexity 1 » saikuro
104  def can_edit_responses?
 
105    is_a_sysadmin? || is_a_moderator?
 
106  end
 
  • Complexity 1 » saikuro
108  def account_disabled
 
109    self.failed_login_count >= DISABLED_LOGIN_COUNT
 
110  end
 
  • Complexity 2 » saikuro
112  def account_disabled=(flag)
 
113    self.failed_login_count = (flag == "0" or !flag) ? 0 : DISABLED_LOGIN_COUNT
 
114  end
 
  • Complexity 1 » saikuro
116  def elapsed_time(now = Time.current)
 
117    (now - last_request_at).floor
 
118  end
 
  • Complexity 1 » saikuro
120  def time_remaining(now = Time.current)
 
121    [Site.login_timeout - elapsed_time(now), 0].max
 
122  end
 
123end