Welcome to mirror list, hosted at ThFree Co, Russian Federation.

client.rb « spamcheck « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 925ca44dfc94f94ded5cb5226fcf16f36c062e96 (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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# frozen_string_literal: true
require 'spamcheck'

module Gitlab
  module Spamcheck
    class Client
      include ::Spam::SpamConstants

      DEFAULT_TIMEOUT_SECS = 2

      VERDICT_MAPPING = {
        ::Spamcheck::SpamVerdict::Verdict::ALLOW => ALLOW,
        ::Spamcheck::SpamVerdict::Verdict::CONDITIONAL_ALLOW => CONDITIONAL_ALLOW,
        ::Spamcheck::SpamVerdict::Verdict::DISALLOW => DISALLOW,
        ::Spamcheck::SpamVerdict::Verdict::BLOCK => BLOCK_USER,
        ::Spamcheck::SpamVerdict::Verdict::NOOP => NOOP
      }.freeze

      ACTION_MAPPING = {
        create: ::Spamcheck::Action::CREATE,
        update: ::Spamcheck::Action::UPDATE
      }.freeze

      def initialize
        @endpoint_url = Gitlab::CurrentSettings.current_application_settings.spam_check_endpoint_url

        # remove the `grpc://` as it's only useful to ensure we're expecting to
        # connect with Spamcheck
        @endpoint_url = @endpoint_url.gsub(%r(^grpc:\/\/), '')

        @creds = stub_creds
      end

      def issue_spam?(spam_issue:, user:, context: {})
        issue = build_issue_protobuf(issue: spam_issue, user: user, context: context)

        response = grpc_client.check_for_spam_issue(issue,
                                              metadata: { 'authorization' =>
                                                           Gitlab::CurrentSettings.spam_check_api_key })
        verdict = convert_verdict_to_gitlab_constant(response.verdict)
        [verdict, response.extra_attributes.to_h, response.error]
      end

      private

      def convert_verdict_to_gitlab_constant(verdict)
        VERDICT_MAPPING.fetch(::Spamcheck::SpamVerdict::Verdict.resolve(verdict), verdict)
      end

      def build_issue_protobuf(issue:, user:, context:)
        issue_pb = ::Spamcheck::Issue.new
        issue_pb.title = issue.spam_title || ''
        issue_pb.description = issue.spam_description || ''
        issue_pb.created_at = convert_to_pb_timestamp(issue.created_at) if issue.created_at
        issue_pb.updated_at = convert_to_pb_timestamp(issue.updated_at) if issue.updated_at
        issue_pb.user_in_project = user.authorized_project?(issue.project)
        issue_pb.project = build_project_protobuf(issue)
        issue_pb.action = ACTION_MAPPING.fetch(context.fetch(:action)) if context.has_key?(:action)
        issue_pb.user = build_user_protobuf(user)
        issue_pb
      end

      def build_user_protobuf(user)
        user_pb = ::Spamcheck::User.new
        user_pb.username = user.username
        user_pb.org = user.organization || ''
        user_pb.created_at = convert_to_pb_timestamp(user.created_at)

        user_pb.emails << build_email(user.email, user.confirmed?)

        user.emails.each do |email|
          next if email.user_primary_email?

          user_pb.emails << build_email(email.email, email.confirmed?)
        end

        user_pb
      end

      def build_email(email, verified)
        email_pb = ::Spamcheck::User::Email.new
        email_pb.email = email
        email_pb.verified = verified
        email_pb
      end

      def build_project_protobuf(issue)
        project_pb = ::Spamcheck::Project.new
        project_pb.project_id = issue.project_id
        project_pb.project_path = issue.project.full_path
        project_pb
      end

      def convert_to_pb_timestamp(ar_timestamp)
        Google::Protobuf::Timestamp.new(seconds: ar_timestamp.to_time.to_i,
                                        nanos: ar_timestamp.to_time.nsec)
      end

      def stub_creds
        if Rails.env.development? || Rails.env.test?
          :this_channel_is_insecure
        else
          GRPC::Core::ChannelCredentials.new ::Gitlab::X509::Certificate.ca_certs_bundle
        end
      end

      def grpc_client
        @grpc_client ||= ::Spamcheck::SpamcheckService::Stub.new(@endpoint_url, @creds,
                                                        interceptors: interceptors,
                                                        timeout: DEFAULT_TIMEOUT_SECS)
      end

      def interceptors
        [Labkit::Correlation::GRPC::ClientInterceptor.instance]
      end
    end
  end
end