ministryofjustice/Claim-for-Crown-Court-Defence

View on GitHub
app/models/user.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
98%
# == Schema Information
#
# Table name: users
#
#  id                     :integer          not null, primary key
#  email                  :string           default(""), not null
#  encrypted_password     :string           default(""), not null
#  reset_password_token   :string
#  reset_password_sent_at :datetime
#  remember_created_at    :datetime
#  sign_in_count          :integer          default(0), not null
#  current_sign_in_at     :datetime
#  last_sign_in_at        :datetime
#  current_sign_in_ip     :inet
#  last_sign_in_ip        :inet
#  persona_id             :integer
#  persona_type           :string
#  created_at             :datetime
#  updated_at             :datetime
#  first_name             :string
#  last_name              :string
#  failed_attempts        :integer          default(0), not null
#  locked_at              :datetime
#  unlock_token           :string
#  settings               :text
#  deleted_at             :datetime
#  api_key                :uuid
#

class User < ApplicationRecord
  include Disablable
  include SoftlyDeletable

  auto_strip_attributes :first_name, :last_name, :email, squish: true, nullify: true

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise  :database_authenticatable,
          :registerable,
          :recoverable,
          :rememberable,
          :trackable,
          :timeoutable,
          :validatable,
          :lockable

  attribute :terms_and_conditions_required, :boolean, default: false
  attribute :terms_and_conditions, :boolean
  attr_accessor :email_confirmation

  belongs_to :persona, polymorphic: true
  has_many :messages_sent, foreign_key: 'sender_id', class_name: 'Message'
  has_many :user_message_statuses

  validates :first_name, :last_name, presence: true, length: { maximum: 40 }
  validates :email, confirmation: { case_sensitive: false }, length: { maximum: 80 }
  validates :terms_and_conditions,
            acceptance: ['1', true],
            allow_nil: false,
            on: :create,
            if: proc { terms_and_conditions_required? }

  # enable current_user to directly call persona methods (in controllers)
  delegate :claims, to: :persona
  delegate :claims_created, to: :persona
  delegate :roles, to: :persona
  delegate :provider, to: :persona

  scope :external_users, -> { where(persona_type: 'ExternalUser') }

  def name
    [first_name, last_name].join(' ')
  end

  def email_with_name
    "#{first_name} #{last_name} <#{email}>"
  end

  def sortable_name
    [last_name, first_name].join(' ')
  end

  def settings
    JSON.parse(read_attribute(:settings)).with_indifferent_access
  rescue StandardError
    {}
  end

  def setting?(name, default = nil)
    settings.fetch(name, default)
  end

  def save_settings!(data)
    update(settings: settings.merge(data).to_json)
  end
  alias save_setting! save_settings!

  def case_worker?
    persona.is_a?(CaseWorker)
  end

  def external_user?
    persona.is_a?(ExternalUser)
  end

  # So we are able to return useful error messages to the user related to the locking of the account,
  # without having to disable Devise paranoid mode globally (security issues).
  #
  def unauthenticated_message
    override_paranoid_setting(false) { super }
  end

  def active_for_authentication?
    super && active? && enabled?
  end

  def inactive_message
    if active? && enabled?
      super
    else
      I18n.t('activerecord.attributes.user.disabled_and_deleted_message')
    end
  end

  def email_notification_of_message
    settings[:email_notification_of_message] || false
  end

  def send_email_notification_of_message?
    email_notification_of_message
  end

  def email_notification_of_message=(value)
    save_settings! email_notification_of_message: value.to_bool
  end

  def before_soft_delete
    self.email = "#{email}.deleted.#{id}"
  end

  def before_un_soft_delete
    self.email = email.gsub(/\.deleted.#{id}$/, '')
  end

  # To enable Devise emails to be delivered in the background.
  # https://github.com/heartcombo/devise#activejob-integration
  #
  def send_devise_notification(notification, *)
    devise_mailer.send(notification, self, *).deliver_later
  end
end