class Spud::SpudUserModel < ActiveRecord::Base self.table_name = 'spud_users' self.abstract_class = true acts_as_authentic do |c| c.transition_from_crypto_providers = Authlogic::CryptoProviders::Sha512 c.crypto_provider = Authlogic::CryptoProviders::SCrypt c.logged_in_timeout = 24.hours if Spud::Core.config.use_email_as_login c.login_field = :email end end belongs_to :role, class_name: 'SpudRole', foreign_key: 'spud_role_id' has_many :spud_user_settings validates :first_name, :last_name, presence: true before_validation :set_login_to_email, if: ->{ Spud::Core.config.use_email_as_login } before_update :unset_requires_password_change scope :admins, ->{ where('super_admin = 1 OR role_id IS NOT NULL') } scope :ordered, ->{ order('last_name asc, first_name asc, email asc') } def full_name if first_name.blank? && last_name.blank? return self.login end if self.first_name.blank? return self.last_name elsif self.last_name.blank? return self.first_name end return "#{self.first_name} #{self.last_name}" end def full_name_with_email return "#{full_name} (#{email})" end # Returns true if user can view at least one dashboard app def has_admin_rights? if self.super_admin? return true else return Spud::Core.admin_applications.find{ |app| self.can_view_app?(app) }.present? end end # Returns true if the user can view a spud app based on it's key def can_view_app?(admin_application) if self.super_admin? return true else key = admin_application[:key] return self.permissions.find{ |p| p.apps.include?(key) }.present? end end # Check if a user has a given list of permissions # # * if one tag is supplied, return true if the tag matches # * if multiple tags are supplied, return true if ALL tags match def has_permission?(*tags) if self.super_admin? return true else my_tags = self.permissions.collect(&:tag) return tags.find{ |tag| !my_tags.include?(tag) }.blank? end end # Check if a user has at least one out of a given list of permissions # # * if one tag is supplied, return true if the tag matches # * if multiple tags are supplied, return true if ANY tag matches def has_any_permission?(*tags) if self.super_admin? return true else return self.permissions.find{ |p| tags.include?(p.tag) }.present? end end # Return a list of SpudPermission objects for the user's SpudRole def permissions if !self.role return [] else return self.role.permissions end end # Returns an ActiveRecord::Relation performing a LIKE query against name columns def self.where_name_like(string) full_name = Arel::Nodes::NamedFunction.new( 'concat', [arel_table[:first_name], Arel::Nodes.build_quoted(' '), arel_table[:last_name]] ) search = '%' + string + '%' where(full_name.matches(search)) end # Return an array of users who have the requested permission # # * tag - Desired permission tag string (required) # * include_supers - Whether to include super user (default: true) def self.with_permission(tag, include_supers: true) role_ids = SpudRolePermission.where(spud_permission_tag: tag).pluck(:spud_role_id).uniq() if include_supers where(super_admin: true).or(where(spud_role_id: role_ids)) else where(spud_role_id: role_ids) end end def self.as_csv(column_names, options = {}) CSV.generate do |csv| csv << column_names all.each do |item| csv << item.attributes.values_at(*column_names) end end end private def set_login_to_email if self.email.present? self.login = self.email end return true end def unset_requires_password_change if password_changed? && !requires_password_change_changed?(to: true) self.requires_password_change = false end return true end end