Commit b05c6c7f authored by Max Woolf's avatar Max Woolf

Merge branch '16240-fix-project-bot-captcha' into 'master'

Resolve "Project bots can get CAPTCHA even on a private project"

See merge request gitlab-org/gitlab!65661
parents 1a0e5e06 bf0bad9d
...@@ -426,8 +426,15 @@ class Issue < ApplicationRecord ...@@ -426,8 +426,15 @@ class Issue < ApplicationRecord
end end
def check_for_spam? def check_for_spam?
publicly_visible? && # content created via support bots is always checked for spam, EVEN if
(title_changed? || description_changed? || confidential_changed?) # the issue is not publicly visible and/or confidential
return true if author.support_bot? && spammable_attribute_changed?
# Only check for spam on issues which are publicly visible (and thus indexed in search engines)
return false unless publicly_visible?
# Only check for spam if certain attributes have changed
spammable_attribute_changed?
end end
def as_json(options = {}) def as_json(options = {})
...@@ -515,6 +522,14 @@ class Issue < ApplicationRecord ...@@ -515,6 +522,14 @@ class Issue < ApplicationRecord
private private
def spammable_attribute_changed?
title_changed? ||
description_changed? ||
# NOTE: We need to check them for spam when issues are made non-confidential, because spam
# may have been added while they were confidential and thus not being checked for spam.
confidential_changed?(from: true, to: false)
end
# Ensure that the metrics association is safely created and respecting the unique constraint on issue_id # Ensure that the metrics association is safely created and respecting the unique constraint on issue_id
override :ensure_metrics override :ensure_metrics
def ensure_metrics def ensure_metrics
......
...@@ -91,11 +91,6 @@ module EE ...@@ -91,11 +91,6 @@ module EE
end end
end end
# override
def check_for_spam?
author.bot? && (title_changed? || description_changed? || confidential_changed?) || super
end
# override # override
def allows_multiple_assignees? def allows_multiple_assignees?
project.feature_available?(:multiple_issue_assignees) project.feature_available?(:multiple_issue_assignees)
......
...@@ -453,38 +453,6 @@ RSpec.describe Issue do ...@@ -453,38 +453,6 @@ RSpec.describe Issue do
end end
end end
describe '#check_for_spam?' do
using RSpec::Parameterized::TableSyntax
let_it_be(:reusable_project) { create(:project) }
let_it_be(:author) { ::User.support_bot }
where(:visibility_level, :confidential, :new_attributes, :check_for_spam?) do
Gitlab::VisibilityLevel::PUBLIC | false | { description: 'woo' } | true
Gitlab::VisibilityLevel::PUBLIC | false | { title: 'woo' } | true
Gitlab::VisibilityLevel::PUBLIC | true | { confidential: false } | true
Gitlab::VisibilityLevel::PUBLIC | true | { description: 'woo' } | true
Gitlab::VisibilityLevel::PUBLIC | false | { title: 'woo', confidential: true } | true
Gitlab::VisibilityLevel::INTERNAL | false | { description: 'woo' } | true
Gitlab::VisibilityLevel::PRIVATE | true | { description: 'woo' } | true
Gitlab::VisibilityLevel::PUBLIC | false | { description: 'original description' } | false
Gitlab::VisibilityLevel::PRIVATE | true | { weight: 3 } | false
end
with_them do
context 'when author is a bot' do
it 'only checks for spam when description, title, or confidential status is updated' do
project = reusable_project
project.update(visibility_level: visibility_level)
issue = create(:issue, project: project, confidential: confidential, description: 'original description', author: author)
issue.assign_attributes(new_attributes)
expect(issue.check_for_spam?).to eq(check_for_spam?)
end
end
end
end
describe '#weight' do describe '#weight' do
where(:license_value, :database_value, :expected) do where(:license_value, :database_value, :expected) do
true | 5 | 5 true | 5 | 5
......
...@@ -1051,23 +1051,53 @@ RSpec.describe Issue do ...@@ -1051,23 +1051,53 @@ RSpec.describe Issue do
describe '#check_for_spam?' do describe '#check_for_spam?' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
let_it_be(:support_bot) { ::User.support_bot }
where(:visibility_level, :confidential, :new_attributes, :check_for_spam?) do
Gitlab::VisibilityLevel::PUBLIC | false | { description: 'woo' } | true where(:support_bot?, :visibility_level, :confidential, :new_attributes, :check_for_spam?) do
Gitlab::VisibilityLevel::PUBLIC | false | { title: 'woo' } | true ### non-support-bot cases
Gitlab::VisibilityLevel::PUBLIC | true | { confidential: false } | true # spammable attributes changing
Gitlab::VisibilityLevel::PUBLIC | true | { description: 'woo' } | false false | Gitlab::VisibilityLevel::PUBLIC | false | { description: 'new' } | true
Gitlab::VisibilityLevel::PUBLIC | false | { title: 'woo', confidential: true } | false false | Gitlab::VisibilityLevel::PUBLIC | false | { title: 'new' } | true
Gitlab::VisibilityLevel::PUBLIC | false | { description: 'original description' } | false # confidential to non-confidential
Gitlab::VisibilityLevel::INTERNAL | false | { description: 'woo' } | false false | Gitlab::VisibilityLevel::PUBLIC | true | { confidential: false } | true
Gitlab::VisibilityLevel::PRIVATE | false | { description: 'woo' } | false # non-confidential to confidential
false | Gitlab::VisibilityLevel::PUBLIC | false | { confidential: true } | false
# spammable attributes changing on confidential
false | Gitlab::VisibilityLevel::PUBLIC | true | { description: 'new' } | false
# spammable attributes changing while changing to confidential
false | Gitlab::VisibilityLevel::PUBLIC | false | { title: 'new', confidential: true } | false
# spammable attribute not changing
false | Gitlab::VisibilityLevel::PUBLIC | false | { description: 'original description' } | false
# non-spammable attribute changing
false | Gitlab::VisibilityLevel::PUBLIC | false | { weight: 3 } | false
# spammable attributes changing on non-public
false | Gitlab::VisibilityLevel::INTERNAL | false | { description: 'new' } | false
false | Gitlab::VisibilityLevel::PRIVATE | false | { description: 'new' } | false
### support-bot cases
# confidential to non-confidential
true | Gitlab::VisibilityLevel::PUBLIC | true | { confidential: false } | true
# non-confidential to confidential
true | Gitlab::VisibilityLevel::PUBLIC | false | { confidential: true } | false
# spammable attributes changing on confidential
true | Gitlab::VisibilityLevel::PUBLIC | true | { description: 'new' } | true
# spammable attributes changing while changing to confidential
true | Gitlab::VisibilityLevel::PUBLIC | false | { title: 'new', confidential: true } | true
# spammable attributes changing on non-public
true | Gitlab::VisibilityLevel::INTERNAL | false | { description: 'new' } | true
true | Gitlab::VisibilityLevel::PRIVATE | false | { title: 'new' } | true
# spammable attribute not changing
true | Gitlab::VisibilityLevel::PUBLIC | false | { description: 'original description' } | false
# non-spammable attribute changing
true | Gitlab::VisibilityLevel::PRIVATE | true | { weight: 3 } | false
end end
with_them do with_them do
it 'checks for spam on issues that can be seen anonymously' do it 'checks for spam when necessary' do
author = support_bot? ? support_bot : user
project = reusable_project project = reusable_project
project.update!(visibility_level: visibility_level) project.update!(visibility_level: visibility_level)
issue = create(:issue, project: project, confidential: confidential, description: 'original description') issue = create(:issue, project: project, confidential: confidential, description: 'original description', author: author)
issue.assign_attributes(new_attributes) issue.assign_attributes(new_attributes)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment