app/models/user.rb
# frozen_string_literal: true
# The User class representers a user account, controlling
# authentication and authorization
class User < ApplicationRecord
# All Users must belong to a {UserGroup}
belongs_to :group, class_name: 'UserGroup'
# Users do not have their own label, so it is delegated to the {UserGroup} it belongs to
delegate :study, to: :group
# Others available are:
# :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:lockable
# Enum holding the possible roles for any User
enum role: [:reader, :editor, :admin]
delegate :label, to: :group, prefix: true
validates :email, uniqueness: true
# Used to create the first {User} when the app is first
# initialized
#
# @param [Hash] params First User parameters
def self.setup_initial_superuser(params)
begin
if params['su-password'] == params['su-confirm'] && params['su-password'].length > 7
g = Group.create label: params['su-group'], group_type: 'Centre', study: '*'
u = User.new email: params['su-email'],
first_name: params['su-fname'],
last_name: params['su-lname']
u.password = params['su-password']
u.group = g
u.save!
u.admin!
u.confirm
end
rescue
Rails.logger.error 'Could not create the initial superuser.'
end
end
# Sets the password without knowing the current
# password used in our confirmation controller.
#
# @param [Hash] params New password and confirmation
def attempt_set_password(params)
p = {}
p[:password] = params[:password]
p[:password_confirmation] = params[:password_confirmation]
update(p)
end
# Returns whether a password has been set
#
# @return [Boolean] True if no password has been set
def has_no_password?
self.encrypted_password.blank?
end
# Method wrapper for performing if the User has not
# be confirmed
#
# @yield Method to be executed only if User is not confirmed
def only_if_unconfirmed
pending_any_confirmation { yield }
end
# Checks whether the password is suitable and matches
# the confirmation
#
# @return [Boolean] True if the password is good for use
def password_match?
self.errors[:password] << "can't be blank" if password.blank?
self.errors[:password_confirmation] << "can't be blank" if password_confirmation.blank?
self.errors[:password_confirmation] << 'does not match password' if password != password_confirmation
password == password_confirmation && !password.blank?
end
# Checks whether a password is required
#
# @return [Boolean] True if a password is required
def password_required?
# Password is required if it is being set, but not for new records
if !persisted?
false
else
!password.nil? || !password_confirmation.nil?
end
end
# Returns pretty label of the current User status
#
# @return [String] Pretty status label
def status
return 'locked' if self.access_locked?
'active'
end
def after_database_authentication
update_column(:api_key, SecureRandom.hex(10))
end
end