summaryrefslogtreecommitdiff
path: root/app/services/spam/akismet_service.rb
blob: e9843497dd736b5173e732776813503935642a82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# frozen_string_literal: true

module Spam
  class AkismetService
    attr_accessor :text, :options

    def initialize(owner_name, owner_email, text, options = {})
      @owner_name = owner_name
      @owner_email = owner_email
      @text = text
      @options = options
    end

    def spam?
      return false unless akismet_enabled?

      params = {
        type: 'comment',
        text: text,
        created_at: DateTime.current,
        author: owner_name,
        author_email: owner_email,
        referrer: options[:referer]
      }

      begin
        is_spam, is_blatant = akismet_client.check(options[:ip_address], options[:user_agent], params)
        is_spam || is_blatant
      rescue ArgumentError => e
        Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
        false
      rescue StandardError => e
        Gitlab::ErrorTracking.track_exception(e)
        Gitlab::AppLogger.error("Error during Akismet spam check, flagging as not spam: #{e}")
        false
      end
    end

    def submit_ham
      submit(:ham)
    end

    def submit_spam
      submit(:spam)
    end

    private

    attr_accessor :owner_name, :owner_email

    def akismet_client
      @akismet_client ||= ::Akismet::Client.new(Gitlab::CurrentSettings.akismet_api_key,
                                                Gitlab.config.gitlab.url)
    end

    def akismet_enabled?
      Gitlab::CurrentSettings.akismet_enabled
    end

    def submit(type)
      return false unless akismet_enabled?

      params = {
        type: 'comment',
        text: text,
        author: owner_name,
        author_email: owner_email
      }

      begin
        akismet_client.public_send(type, options[:ip_address], options[:user_agent], params) # rubocop:disable GitlabSecurity/PublicSend
        true
      rescue StandardError => e
        Gitlab::AppLogger.error("Unable to connect to Akismet: #{e}, skipping!")
        false
      end
    end
  end
end