module ActiveRecord module Acts #:nodoc: module MuckUser #:nodoc: def self.included(base) base.extend(ClassMethods) end module ClassMethods def acts_as_muck_user(options = {}) has_many :permissions has_many :roles, :through => :permissions named_scope :by_newest, :order => "created_at DESC" named_scope :active, :conditions => "activated_at IS NOT NULL" named_scope :inactive, :conditions => "activated_at IS NULL" named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } } email_name_regex = '[\w\.%\+\-]+'.freeze domain_head_regex = '(?:[A-Z0-9\-]+\.)+'.freeze domain_tld_regex = '(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum)'.freeze email_regex = /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i before_save :lower_login class_eval <<-EOV validates_format_of :login, :with => /^[a-z0-9-]+$/i, :message => 'may only contain letters, numbers or a hyphen.' validates_format_of :email, :with => email_regex, :message => 'does not look like a valid email address.' # prevents a user from submitting a crafted form that bypasses activation attr_protected :crypted_password, :password_salt, :persistence_token, :single_access_token, :perishable_token, :login_count, :failed_login_count, :last_request_at, :last_login_at, :current_login_at, :current_login_ip, :last_login_ip, :terms_of_service, :time_zone, :disabled_at, :activated_at, :created_at, :updated_at EOV include ActiveRecord::Acts::MuckUser::InstanceMethods extend ActiveRecord::Acts::MuckUser::SingletonMethods end end # class methods module SingletonMethods def do_search(query) User.search(query) end def inactive_count User.count :conditions => "activated_at is null" end def activate_all User.update_all("activated_at = '#{Time.now}'", 'activated_at IS NULL') end # Finds the user with the corresponding activation code, activates their account and returns the user. # # Raises: # +User::ActivationCodeNotFound+ if there is no user with the corresponding activation code # +User::AlreadyActivated+ if the user with the corresponding activation code has already activated their account def find_and_activate!(activation_code) raise ArgumentError if activation_code.nil? user = find_by_activation_code(activation_code) raise ActivationCodeNotFound if !user raise AlreadyActivated.new(user) if user.active? user.send(:activate!) user end # checks to see if a given login is already in the database def login_exists?(login) if User.find_by_login(login).nil? false else true end end # checks to see if a given email is already in the database def email_exists?(email) if User.find_by_email(email).nil? false else true end end end # All the methods available to a record that has had acts_as_muck_user specified. module InstanceMethods def deliver_welcome_email UserMailer.deliver_welcome_notification(self) if GlobalConfig.send_welcome end def deliver_activation_confirmation! reset_perishable_token! UserMailer.deliver_activation_confirmation(self) end def deliver_activation_instructions! reset_perishable_token! UserMailer.deliver_activation_instructions(self) end def deliver_password_reset_instructions! if self.active? reset_perishable_token! UserMailer.deliver_password_reset_instructions(self) else UserMailer.deliver_password_not_active_instructions(self) end end def deliver_username_request! UserMailer.deliver_username_request(self) end # Since password reset doesn't need to change openid_identifier, # we save without block as usual. def reset_password!(user) self.password = user[:password] self.password_confirmation = user[:password_confirmation] save end def has_role?(rolename) @roles ||= self.roles.map{|role| role.rolename} return false unless @roles @roles.include?(rolename) end def admin? has_role?('administrator') end def can_edit?(user) return false if user.nil? self.id == user.id || user.admin? end def to_xml(options = {}) options[:except] ||= [] options[:except] << :email << :crypted_password << :salt << :remember_token << :remember_token_expires_at << :activation_code options[:except] << :activated_at << :password_reset_code << :enabled << :terms_of_service << :can_send_messages << :identity_url options[:except] << :tmp_password << :protected_profile << :public_profile super end # Authlogic automatically executes the following methods def active? !activated_at.blank? end # def approved? # end # # def confirmed? # end #lowercase all logins def lower_login self.login = self.login.nil? ? nil : self.login.downcase end def activate! self.update_attribute(:activated_at, Time.now.utc) end def short_name CGI::escapeHTML(self.first_name) || self.display_name end def full_name if self.first_name.blank? && self.last_name.blank? self.display_name rescue 'Deleted user' else ((CGI::escapeHTML(self.first_name) || '') + ' ' + (CGI::escapeHTML(self.last_name) || '')).strip end end def display_name CGI::escapeHTML(self.login) end end end end end