jam-cloud/ruby/lib/jam_ruby/models/invited_user.rb

138 lines
4.5 KiB
Ruby

module JamRuby
class InvitedUser < ActiveRecord::Base
include HtmlSanitize
html_sanitize strict: [:note]
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
attr_accessor :accepted_twice
self.primary_key = 'id'
### Who sent this invitatio?
# either admin_sender or user_sender is not null. If an administrator sends the invitation, then
belongs_to :sender , :inverse_of => :invited_users, :class_name => "JamRuby::User", :foreign_key => "sender_id"
belongs_to :receiver, :inverse_of => :receiver_users, :class_name => "JamRuby::User", :foreign_key => "receiver_id"
# who is the invitation sent to?
validates :email, format: {with: VALID_EMAIL_REGEX}, :if => lambda { |iu| iu.email_required? }
validates :autofriend, :inclusion => {:in => [nil, true, false]}
validates :invitation_code, :presence => true
validates :note, length: {maximum: 1000}, no_profanity: true # 1000 == arbitrary.
validate :one_facebook_invite_per_user, :if => lambda { |iu| iu.facebook_invite? }
validate :valid_personalized_invitation
# validate :not_accepted_twice
validate :not_accepted_twice, :if => lambda { |iu| iu.email_required? }
validate :spammer
validate :can_invite?
after_save :track_user_progression
# ensure invitation code is always created
before_validation(:on => :create) do
self.invitation_code = SecureRandom.urlsafe_base64 if self.invitation_code.nil?
self.sender_id = nil if self.sender_id.blank? # this coercion was done just to make activeadmin work
self.receiver = User.find_by_email(self.email) unless self.email.nil?
end
FB_MEDIUM = 'facebook'
def self.facebook_invite(user)
where(:sender_id => user.id, :invite_medium => FB_MEDIUM).limit(1).first
end
def track_user_progression
self.sender.update_progression_field(:first_invited_at) unless self.sender.nil?
end
def self.index(user)
return InvitedUser.where(:sender_id => user).order(:updated_at)
end
def sender_display_name
return sender.name
end
def accept!
if self.accepted
accepted_twice = true
end
self.accepted = true
end
def invited_by_administrator?
sender.nil? || sender.admin # a nil sender can only be created by someone using jam-admin
end
def generate_signup_url
url = "#{APP_CONFIG.external_root_url}/signup?invitation_code=#{self.invitation_code}"
if APP_CONFIG.external_hostname == 'localhost'
# the feed widget in facebook will not accept localhost. external_host name should be localhost only in dev environments
url["localhost"] = "127.0.0.1"
end
url
end
def facebook_invite?
FB_MEDIUM == self.invite_medium
end
def email_required?
!self.facebook_invite?
end
def has_required_email?
self.email.present? && self.email_required?
end
private
def can_invite?
errors.add(:sender, "can not invite others") if !invited_by_administrator? && !sender.can_invite?
end
def valid_personalized_invitation
errors.add(:autofriend, "must be true if sender is specified") if autofriend && sender.nil?
end
def not_accepted_twice
errors.add(:accepted, "you can only accept an invitation once") if accepted_twice
end
# the same account should not receive emails within the same day
def spammer
max_invites_ever_per_sender
max_invites_per_day_per_sender
max_invites_to_receiver_per_day
end
def max_invites_ever_per_sender
if InvitedUser.where(:sender => self.sender).count > APP_CONFIG.max_invites_ever_per_sender
errors.add(:base, "max invites sent by this account")
end
end
def max_invites_per_day_per_sender
if InvitedUser.where(:sender => self.sender).where("created_at > ?", Time.now - 1.days).count > APP_CONFIG.max_invites_per_day_per_sender
errors.add(:base, "maximum number of invites sent in past 24 hours")
end
end
def max_invites_to_receiver_per_day
if InvitedUser.where(:email => self.email).where("created_at > ?", Time.now - 1.days).count > APP_CONFIG.max_invites_to_receiver_per_day - 1
errors.add(:base, "someone has already sent to #{self.email} in past 24 hours")
end
end
def one_facebook_invite_per_user
rel = InvitedUser.where(:invite_medium => FB_MEDIUM, :sender_id => self.sender_id)
rel = rel.where(['id != ?',self.id]) if self.id
errors.add(:invite_medium, "one facebook invite allowed per user") if 0 < rel.count
end
end
end