summaryrefslogtreecommitdiff
path: root/app/services/spam/spam_check_service.rb
blob: 3269f9d687af9678d8e80d3dc4b615a517dcc508 (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
# frozen_string_literal: true

module Spam
  class SpamCheckService
    include AkismetMethods

    attr_accessor :target, :request, :options
    attr_reader :spam_log

    def initialize(spammable:, request:)
      @target = spammable
      @request = request
      @options = {}

      if @request
        @options[:ip_address] = @request.env['action_dispatch.remote_ip'].to_s
        @options[:user_agent] = @request.env['HTTP_USER_AGENT']
        @options[:referrer] = @request.env['HTTP_REFERRER']
      else
        @options[:ip_address] = @target.ip_address
        @options[:user_agent] = @target.user_agent
      end
    end

    def execute(api: false, recaptcha_verified:, spam_log_id:, user_id:)
      if recaptcha_verified
        # If it's a request which is already verified through recaptcha,
        # update the spam log accordingly.
        SpamLog.verify_recaptcha!(user_id: user_id, id: spam_log_id)
      else
        # Otherwise, it goes to Akismet for spam check.
        # If so, it assigns spammable object as "spam" and creates a SpamLog record.
        possible_spam = check(api)
        target.spam = possible_spam unless target.allow_possible_spam?
        target.spam_log = spam_log
      end
    end

    private

    def check(api)
      return unless request
      return unless check_for_spam?
      return unless akismet.spam?

      create_spam_log(api)
      true
    end

    def check_for_spam?
      target.check_for_spam?
    end

    def create_spam_log(api)
      @spam_log = SpamLog.create!(
        {
          user_id: target.author_id,
          title: target.spam_title,
          description: target.spam_description,
          source_ip: options[:ip_address],
          user_agent: options[:user_agent],
          noteable_type: target.class.to_s,
          via_api: api
        }
      )
    end
  end
end