BigW Consortium Gitlab

spammable.rb 1.98 KB
Newer Older
1 2
module Spammable
  extend ActiveSupport::Concern
3 4

  module ClassMethods
5 6
    def attr_spammable(attr, options = {})
      spammable_attrs << [attr.to_s, options]
7 8
    end
  end
9 10

  included do
11
    has_one :user_agent_detail, as: :subject, dependent: :destroy
12

13
    attr_accessor :spam
14
    attr_accessor :spam_log
15

16
    after_validation :check_for_spam, on: [:create, :update]
17 18 19 20

    cattr_accessor :spammable_attrs, instance_accessor: false do
      []
    end
21 22

    delegate :ip_address, :user_agent, to: :user_agent_detail, allow_nil: true
23 24
  end

25 26 27 28
  def submittable_as_spam_by?(current_user)
    current_user && current_user.admin? && submittable_as_spam?
  end

29
  def submittable_as_spam?
30
    if user_agent_detail
31
      user_agent_detail.submittable? && current_application_settings.akismet_enabled
32 33 34 35 36
    else
      false
    end
  end

37
  def spam?
38 39 40
    @spam
  end

41
  def check_for_spam
42 43
    error_msg = if Gitlab::Recaptcha.enabled?
                  "Your #{spammable_entity_type} has been recognized as spam. "\
44
                  "Please, change the content or solve the reCAPTCHA to proceed."
45 46 47 48 49
                else
                  "Your #{spammable_entity_type} has been recognized as spam and has been discarded."
                end

    self.errors.add(:base, error_msg) if spam?
50 51 52 53
  end

  def spammable_entity_type
    self.class.name.underscore
54 55 56
  end

  def spam_title
57
    attr = self.class.spammable_attrs.find do |_, options|
58 59 60
      options.fetch(:spam_title, false)
    end

61
    public_send(attr.first) if attr && respond_to?(attr.first.to_sym)
62 63 64
  end

  def spam_description
65
    attr = self.class.spammable_attrs.find do |_, options|
66 67
      options.fetch(:spam_description, false)
    end
68

69
    public_send(attr.first) if attr && respond_to?(attr.first.to_sym)
70
  end
71 72

  def spammable_text
73 74
    result = self.class.spammable_attrs.map do |attr|
      public_send(attr.first)
75
    end
76

77 78 79
    result.reject(&:blank?).join("\n")
  end

80 81
  # Override in Spammable if further checks are necessary
  def check_for_spam?
82
    true
83 84
  end
end