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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/spam/spam_verdict_service.rb')
-rw-r--r--app/services/spam/spam_verdict_service.rb76
1 files changed, 72 insertions, 4 deletions
diff --git a/app/services/spam/spam_verdict_service.rb b/app/services/spam/spam_verdict_service.rb
index 2b4d5f4a984..68f1135ae28 100644
--- a/app/services/spam/spam_verdict_service.rb
+++ b/app/services/spam/spam_verdict_service.rb
@@ -5,22 +5,90 @@ module Spam
include AkismetMethods
include SpamConstants
- def initialize(target:, request:, options:)
+ def initialize(user:, target:, request:, options:, context: {})
@target = target
@request = request
+ @user = user
@options = options
+ @verdict_params = assemble_verdict_params(context)
end
def execute
+ external_spam_check_result = spam_verdict
+ akismet_result = akismet_verdict
+
+ # filter out anything we don't recognise, including nils.
+ valid_results = [external_spam_check_result, akismet_result].compact.select { |r| SUPPORTED_VERDICTS.key?(r) }
+ # Treat nils - such as service unavailable - as ALLOW
+ return ALLOW unless valid_results.any?
+
+ # Favour the most restrictive result.
+ valid_results.min_by { |v| SUPPORTED_VERDICTS[v][:priority] }
+ end
+
+ private
+
+ attr_reader :user, :target, :request, :options, :verdict_params
+
+ def akismet_verdict
if akismet.spam?
- Gitlab::Recaptcha.enabled? ? REQUIRE_RECAPTCHA : DISALLOW
+ Gitlab::Recaptcha.enabled? ? CONDITIONAL_ALLOW : DISALLOW
else
ALLOW
end
end
- private
+ def spam_verdict
+ return unless Gitlab::CurrentSettings.spam_check_endpoint_enabled
+ return if endpoint_url.blank?
+
+ begin
+ result = Gitlab::HTTP.post(endpoint_url, body: verdict_params.to_json, headers: { 'Content-Type' => 'application/json' })
+ return unless result
+
+ json_result = Gitlab::Json.parse(result).with_indifferent_access
+ # @TODO metrics/logging
+ # Expecting:
+ # error: (string or nil)
+ # result: (string or nil)
+ verdict = json_result[:verdict]
+ return unless SUPPORTED_VERDICTS.include?(verdict)
- attr_reader :target, :request, :options
+ # @TODO log if json_result[:error]
+
+ json_result[:verdict]
+ rescue *Gitlab::HTTP::HTTP_ERRORS => e
+ # @TODO: log error via try_post https://gitlab.com/gitlab-org/gitlab/-/issues/219223
+ Gitlab::ErrorTracking.log_exception(e)
+ return
+ rescue
+ # @TODO log
+ ALLOW
+ end
+ end
+
+ def assemble_verdict_params(context)
+ return {} unless endpoint_url.present?
+
+ project = target.try(:project)
+
+ context.merge({
+ target: {
+ title: target.spam_title,
+ description: target.spam_description,
+ type: target.class.to_s
+ },
+ user: {
+ created_at: user.created_at,
+ email: user.email,
+ username: user.username
+ },
+ user_in_project: user.authorized_project?(project)
+ })
+ end
+
+ def endpoint_url
+ @endpoint_url ||= Gitlab::CurrentSettings.current_application_settings.spam_check_endpoint_url
+ end
end
end