Refactor spam validation to a concern that can be easily reused and improve legibility in `SpamCheckService`
This commit is contained in:
parent
8f04cf0ead
commit
f01fce7f46
|
@ -10,6 +10,7 @@ v 8.11.0 (unreleased)
|
|||
- Retrieve rendered HTML from cache in one request
|
||||
- Nokogiri's various parsing methods are now instrumented
|
||||
- Make fork counter always clickable. !5463 (winniehell)
|
||||
- All created issues, API or WebUI, can be submitted to Akismet for spam check !5333
|
||||
- Remove `search_id` of labels dropdown filter to fix 'Missleading URI for labels in Merge Requests and Issues view'. !5368 (Scott Le)
|
||||
- Load project invited groups and members eagerly in `ProjectTeam#fetch_members`
|
||||
- Add GitLab Workhorse version to admin dashboard (Katarzyna Kobierska Ula Budziszewska)
|
||||
|
@ -93,7 +94,6 @@ v 8.10.0
|
|||
- Fix viewing notification settings when a project is pending deletion
|
||||
- Updated compare dropdown menus to use GL dropdown
|
||||
- Redirects back to issue after clicking login link
|
||||
- All created issues, API or WebUI, can be submitted to Akismet for spam check !5333
|
||||
- Eager load award emoji on notes
|
||||
- Allow to define manual actions/builds on Pipelines and Environments
|
||||
- Fix pagination when sorting by columns with lots of ties (like priority)
|
||||
|
|
|
@ -79,11 +79,11 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
@issue = Issues::CreateService.new(project, current_user, issue_params.merge({ request: request })).execute
|
||||
@issue = Issues::CreateService.new(project, current_user, issue_params.merge(request: request)).execute
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
if @issue.errors.empty? && @issue.valid?
|
||||
if @issue.valid?
|
||||
redirect_to issue_path(@issue)
|
||||
else
|
||||
render :new
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
module Spammable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
attr_accessor :spam
|
||||
after_validation :check_for_spam, on: :create
|
||||
end
|
||||
|
||||
def spam?
|
||||
@spam
|
||||
end
|
||||
|
||||
def check_for_spam
|
||||
self.errors.add(:base, "Your #{self.class.name.underscore} has been recognized as spam and has been discarded.") if spam?
|
||||
end
|
||||
end
|
|
@ -6,6 +6,7 @@ class Issue < ActiveRecord::Base
|
|||
include Referable
|
||||
include Sortable
|
||||
include Taskable
|
||||
include Spammable
|
||||
|
||||
DueDateStruct = Struct.new(:title, :name).freeze
|
||||
NoDueDate = DueDateStruct.new('No Due Date', '0').freeze
|
||||
|
|
|
@ -2,14 +2,13 @@ module Issues
|
|||
class CreateService < Issues::BaseService
|
||||
def execute
|
||||
filter_params
|
||||
label_params = params[:label_ids]
|
||||
issue = project.issues.new(params.except(:label_ids, :request))
|
||||
label_params = params.delete(:label_ids)
|
||||
request = params.delete(:request)
|
||||
api = params.delete(:api)
|
||||
issue = project.issues.new(params)
|
||||
issue.author = params[:author] || current_user
|
||||
|
||||
if SpamCheckService.new(project, current_user, params).spam_detected?
|
||||
issue.errors.add(:base, 'Your issue has been recognized as spam and has been discarded.')
|
||||
return issue
|
||||
end
|
||||
issue.spam = spam_check_service.execute(request, api)
|
||||
|
||||
if issue.save
|
||||
issue.update_attributes(label_ids: label_params)
|
||||
|
@ -22,5 +21,11 @@ module Issues
|
|||
|
||||
issue
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def spam_check_service
|
||||
SpamCheckService.new(project, current_user, params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,28 +1,38 @@
|
|||
class SpamCheckService
|
||||
class SpamCheckService < BaseService
|
||||
include Gitlab::AkismetHelper
|
||||
|
||||
attr_accessor :subject, :current_user, :params
|
||||
|
||||
def initialize(subject, user, params = {})
|
||||
@subject, @current_user, @params = subject, user, params.dup
|
||||
end
|
||||
|
||||
def spam_detected?
|
||||
request = params[:request]
|
||||
return false unless request || check_for_spam?(subject)
|
||||
|
||||
text = [params[:title], params[:description]].reject(&:blank?).join("\n")
|
||||
attr_accessor :request, :api
|
||||
|
||||
def execute(request, api)
|
||||
@request, @api = request, api
|
||||
return false unless request || check_for_spam?(project)
|
||||
return false unless is_spam?(request.env, current_user, text)
|
||||
|
||||
attrs = {
|
||||
user_id: current_user.id,
|
||||
project_id: subject.id,
|
||||
title: params[:title],
|
||||
description: params[:description]
|
||||
}
|
||||
create_spam_log(subject, current_user, attrs, request.env, api: false)
|
||||
|
||||
create_spam_log
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def text
|
||||
[params[:title], params[:description]].reject(&:blank?).join("\n")
|
||||
end
|
||||
|
||||
def spam_log_attrs
|
||||
{
|
||||
user_id: current_user.id,
|
||||
project_id: project.id,
|
||||
title: params[:title],
|
||||
description: params[:description],
|
||||
source_ip: client_ip(request.env),
|
||||
user_agent: user_agent(request.env),
|
||||
noteable_type: 'Issue',
|
||||
via_api: api
|
||||
}
|
||||
end
|
||||
|
||||
def create_spam_log
|
||||
CreateSpamLogService.new(project, current_user, spam_log_attrs).execute
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Akismet
|
||||
|
||||
> *Note:* Before 8.10 only issues submitted via the API and for non-project
|
||||
> *Note:* Before 8.11 only issues submitted via the API and for non-project
|
||||
members were submitted to Akismet.
|
||||
|
||||
GitLab leverages [Akismet](http://akismet.com) to protect against spam. Currently
|
||||
|
|
|
@ -158,15 +158,13 @@ module API
|
|||
|
||||
project = user_project
|
||||
|
||||
issue = ::Issues::CreateService.new(project, current_user, attrs.merge({ request: request })).execute
|
||||
issue = ::Issues::CreateService.new(project, current_user, attrs.merge(request: request, api: true)).execute
|
||||
|
||||
if issue.spam?
|
||||
render_api_error!({ error: 'Spam detected' }, 400)
|
||||
end
|
||||
|
||||
if issue.valid?
|
||||
# Need to check if id is nil here, because if issue is spam, errors
|
||||
# get added, but Rails still thinks it's valid, but it is never saved
|
||||
# so id will be nil
|
||||
if issue.id.nil?
|
||||
render_api_error!({ error: 'Spam detected' }, 400)
|
||||
end
|
||||
# Find or create labels and attach to issue. Labels are valid because
|
||||
# we already checked its name, so there can't be an error here
|
||||
if params[:labels].present?
|
||||
|
|
|
@ -43,16 +43,5 @@ module Gitlab
|
|||
false
|
||||
end
|
||||
end
|
||||
|
||||
def create_spam_log(project, current_user, attrs, env, api: true)
|
||||
params = attrs.merge({
|
||||
source_ip: client_ip(env),
|
||||
user_agent: user_agent(env),
|
||||
noteable_type: 'Issue',
|
||||
via_api: api
|
||||
})
|
||||
|
||||
::CreateSpamLogService.new(project, current_user, params).execute
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue