Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
3d2954e4
Commit
3d2954e4
authored
Jan 27, 2017
by
Jarka Kadlecova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use reCaptcha when an issue identified as spam
parent
999edc5c
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
400 additions
and
32 deletions
+400
-32
app/assets/stylesheets/pages/issues.scss
app/assets/stylesheets/pages/issues.scss
+4
-0
app/controllers/concerns/spammable_actions.rb
app/controllers/concerns/spammable_actions.rb
+18
-0
app/controllers/projects/issues_controller.rb
app/controllers/projects/issues_controller.rb
+17
-5
app/controllers/registrations_controller.rb
app/controllers/registrations_controller.rb
+2
-2
app/models/concerns/spammable.rb
app/models/concerns/spammable.rb
+9
-3
app/services/issues/create_service.rb
app/services/issues/create_service.rb
+10
-2
app/services/spam_service.rb
app/services/spam_service.rb
+2
-1
app/views/admin/spam_logs/_spam_log.html.haml
app/views/admin/spam_logs/_spam_log.html.haml
+2
-0
app/views/admin/spam_logs/index.html.haml
app/views/admin/spam_logs/index.html.haml
+1
-0
app/views/devise/shared/_signup_box.html.haml
app/views/devise/shared/_signup_box.html.haml
+1
-1
app/views/projects/issues/verify.html.haml
app/views/projects/issues/verify.html.haml
+20
-0
changelogs/unreleased/21518_recaptcha_spam_issues.yml
changelogs/unreleased/21518_recaptcha_spam_issues.yml
+4
-0
db/migrate/20170206071414_add_recaptcha_verified_to_spam_logs.rb
...ate/20170206071414_add_recaptcha_verified_to_spam_logs.rb
+15
-0
db/schema.rb
db/schema.rb
+2
-1
lib/gitlab/recaptcha.rb
lib/gitlab/recaptcha.rb
+4
-0
spec/controllers/projects/issues_controller_spec.rb
spec/controllers/projects/issues_controller_spec.rb
+73
-16
spec/controllers/registrations_controller_spec.rb
spec/controllers/registrations_controller_spec.rb
+1
-1
spec/features/issues/spam_issues_spec.rb
spec/features/issues/spam_issues_spec.rb
+66
-0
spec/services/issues/create_service_spec.rb
spec/services/issues/create_service_spec.rb
+102
-0
spec/services/spam_service_spec.rb
spec/services/spam_service_spec.rb
+47
-0
No files found.
app/assets/stylesheets/pages/issues.scss
View file @
3d2954e4
...
@@ -148,3 +148,7 @@ ul.related-merge-requests > li {
...
@@ -148,3 +148,7 @@ ul.related-merge-requests > li {
border
:
1px
solid
$border-gray-normal
;
border
:
1px
solid
$border-gray-normal
;
}
}
}
}
.recaptcha
{
margin-bottom
:
30px
;
}
app/controllers/concerns/spammable_actions.rb
View file @
3d2954e4
module
SpammableActions
module
SpammableActions
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
include
Recaptcha
::
Verify
included
do
included
do
before_action
:authorize_submit_spammable!
,
only: :mark_as_spam
before_action
:authorize_submit_spammable!
,
only: :mark_as_spam
end
end
...
@@ -15,6 +17,15 @@ module SpammableActions
...
@@ -15,6 +17,15 @@ module SpammableActions
private
private
def
recaptcha_params
return
{}
unless
params
[
:recaptcha_verification
]
&&
Gitlab
::
Recaptcha
.
load_configurations!
&&
verify_recaptcha
{
recaptcha_verified:
true
,
spam_log_id:
params
[
:spam_log_id
]
}
end
def
spammable
def
spammable
raise
NotImplementedError
,
"
#{
self
.
class
}
does not implement
#{
__method__
}
"
raise
NotImplementedError
,
"
#{
self
.
class
}
does not implement
#{
__method__
}
"
end
end
...
@@ -22,4 +33,11 @@ module SpammableActions
...
@@ -22,4 +33,11 @@ module SpammableActions
def
authorize_submit_spammable!
def
authorize_submit_spammable!
access_denied!
unless
current_user
.
admin?
access_denied!
unless
current_user
.
admin?
end
end
def
render_recaptcha?
return
false
if
spammable
.
errors
.
count
>
1
# re-render "new" template in case there are other errors
return
false
unless
Gitlab
::
Recaptcha
.
enabled?
spammable
.
spam
end
end
end
app/controllers/projects/issues_controller.rb
View file @
3d2954e4
...
@@ -93,15 +93,13 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -93,15 +93,13 @@ class Projects::IssuesController < Projects::ApplicationController
def
create
def
create
extra_params
=
{
request:
request
,
extra_params
=
{
request:
request
,
merge_request_for_resolving_discussions:
merge_request_for_resolving_discussions
}
merge_request_for_resolving_discussions:
merge_request_for_resolving_discussions
}
extra_params
.
merge!
(
recaptcha_params
)
@issue
=
Issues
::
CreateService
.
new
(
project
,
current_user
,
issue_params
.
merge
(
extra_params
)).
execute
@issue
=
Issues
::
CreateService
.
new
(
project
,
current_user
,
issue_params
.
merge
(
extra_params
)).
execute
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
html
do
format
.
html
do
if
@issue
.
valid?
html_response_create
redirect_to
issue_path
(
@issue
)
else
render
:new
end
end
end
format
.
js
do
format
.
js
do
@link
=
@issue
.
attachment
.
url
.
to_js
@link
=
@issue
.
attachment
.
url
.
to_js
...
@@ -178,6 +176,20 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -178,6 +176,20 @@ class Projects::IssuesController < Projects::ApplicationController
protected
protected
def
html_response_create
if
@issue
.
valid?
redirect_to
issue_path
(
@issue
)
elsif
render_recaptcha?
if
params
[
:recaptcha_verification
]
flash
[
:alert
]
=
'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
end
render
:verify
else
render
:new
end
end
def
issue
def
issue
# The Sortable default scope causes performance issues when used with find_by
# The Sortable default scope causes performance issues when used with find_by
@noteable
=
@issue
||=
@project
.
issues
.
where
(
iid:
params
[
:id
]).
reorder
(
nil
).
take
||
redirect_old
@noteable
=
@issue
||=
@project
.
issues
.
where
(
iid:
params
[
:id
]).
reorder
(
nil
).
take
||
redirect_old
...
...
app/controllers/registrations_controller.rb
View file @
3d2954e4
...
@@ -17,7 +17,7 @@ class RegistrationsController < Devise::RegistrationsController
...
@@ -17,7 +17,7 @@ class RegistrationsController < Devise::RegistrationsController
if
!
Gitlab
::
Recaptcha
.
load_configurations!
||
verify_recaptcha
if
!
Gitlab
::
Recaptcha
.
load_configurations!
||
verify_recaptcha
super
super
else
else
flash
[
:alert
]
=
'There was an error with the reCAPTCHA. Please
re-solve the reCAPTCHA
.'
flash
[
:alert
]
=
'There was an error with the reCAPTCHA. Please
solve the reCAPTCHA again
.'
flash
.
delete
:recaptcha_error
flash
.
delete
:recaptcha_error
render
action:
'new'
render
action:
'new'
end
end
...
@@ -30,7 +30,7 @@ class RegistrationsController < Devise::RegistrationsController
...
@@ -30,7 +30,7 @@ class RegistrationsController < Devise::RegistrationsController
format
.
html
do
format
.
html
do
session
.
try
(
:destroy
)
session
.
try
(
:destroy
)
redirect_to
new_user_session_path
,
notice:
"Account successfully removed."
redirect_to
new_user_session_path
,
notice:
"Account successfully removed."
end
end
end
end
end
end
...
...
app/models/concerns/spammable.rb
View file @
3d2954e4
...
@@ -11,6 +11,7 @@ module Spammable
...
@@ -11,6 +11,7 @@ module Spammable
has_one
:user_agent_detail
,
as: :subject
,
dependent: :destroy
has_one
:user_agent_detail
,
as: :subject
,
dependent: :destroy
attr_accessor
:spam
attr_accessor
:spam
attr_accessor
:spam_log
after_validation
:check_for_spam
,
on: :create
after_validation
:check_for_spam
,
on: :create
...
@@ -34,9 +35,14 @@ module Spammable
...
@@ -34,9 +35,14 @@ module Spammable
end
end
def
check_for_spam
def
check_for_spam
if
spam?
error_msg
=
if
Gitlab
::
Recaptcha
.
enabled?
self
.
errors
.
add
(
:base
,
"Your
#{
spammable_entity_type
}
has been recognized as spam and has been discarded."
)
"Your
#{
spammable_entity_type
}
has been recognized as spam. "
\
end
"You can still submit it by solving Captcha."
else
"Your
#{
spammable_entity_type
}
has been recognized as spam and has been discarded."
end
self
.
errors
.
add
(
:base
,
error_msg
)
if
spam?
end
end
def
spammable_entity_type
def
spammable_entity_type
...
...
app/services/issues/create_service.rb
View file @
3d2954e4
...
@@ -3,6 +3,8 @@ module Issues
...
@@ -3,6 +3,8 @@ module Issues
def
execute
def
execute
@request
=
params
.
delete
(
:request
)
@request
=
params
.
delete
(
:request
)
@api
=
params
.
delete
(
:api
)
@api
=
params
.
delete
(
:api
)
@recaptcha_verified
=
params
.
delete
(
:recaptcha_verified
)
@spam_log_id
=
params
.
delete
(
:spam_log_id
)
issue_attributes
=
params
.
merge
(
merge_request_for_resolving_discussions:
merge_request_for_resolving_discussions
)
issue_attributes
=
params
.
merge
(
merge_request_for_resolving_discussions:
merge_request_for_resolving_discussions
)
@issue
=
BuildService
.
new
(
project
,
current_user
,
issue_attributes
).
execute
@issue
=
BuildService
.
new
(
project
,
current_user
,
issue_attributes
).
execute
...
@@ -11,7 +13,13 @@ module Issues
...
@@ -11,7 +13,13 @@ module Issues
end
end
def
before_create
(
issuable
)
def
before_create
(
issuable
)
issuable
.
spam
=
spam_service
.
check
(
@api
)
if
@recaptcha_verified
spam_log
=
current_user
.
spam_logs
.
find_by
(
id:
@spam_log_id
,
title:
issuable
.
title
)
spam_log
.
update!
(
recaptcha_verified:
true
)
if
spam_log
else
issuable
.
spam
=
spam_service
.
check
(
@api
)
issuable
.
spam_log
=
spam_service
.
spam_log
end
end
end
def
after_create
(
issuable
)
def
after_create
(
issuable
)
...
@@ -35,7 +43,7 @@ module Issues
...
@@ -35,7 +43,7 @@ module Issues
private
private
def
spam_service
def
spam_service
SpamService
.
new
(
@issue
,
@request
)
@spam_service
||=
SpamService
.
new
(
@issue
,
@request
)
end
end
def
user_agent_detail_service
def
user_agent_detail_service
...
...
app/services/spam_service.rb
View file @
3d2954e4
class
SpamService
class
SpamService
attr_accessor
:spammable
,
:request
,
:options
attr_accessor
:spammable
,
:request
,
:options
attr_reader
:spam_log
def
initialize
(
spammable
,
request
=
nil
)
def
initialize
(
spammable
,
request
=
nil
)
@spammable
=
spammable
@spammable
=
spammable
...
@@ -63,7 +64,7 @@ class SpamService
...
@@ -63,7 +64,7 @@ class SpamService
end
end
def
create_spam_log
(
api
)
def
create_spam_log
(
api
)
SpamLog
.
create
(
@spam_log
=
SpamLog
.
create!
(
{
{
user_id:
spammable_owner_id
,
user_id:
spammable_owner_id
,
title:
spammable
.
spam_title
,
title:
spammable
.
spam_title
,
...
...
app/views/admin/spam_logs/_spam_log.html.haml
View file @
3d2954e4
...
@@ -13,6 +13,8 @@
...
@@ -13,6 +13,8 @@
=
spam_log
.
source_ip
=
spam_log
.
source_ip
%td
%td
=
spam_log
.
via_api?
?
'Y'
:
'N'
=
spam_log
.
via_api?
?
'Y'
:
'N'
%td
=
spam_log
.
recaptcha_verified
?
'Y'
:
'N'
%td
%td
=
spam_log
.
noteable_type
=
spam_log
.
noteable_type
%td
%td
...
...
app/views/admin/spam_logs/index.html.haml
View file @
3d2954e4
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
%th
User
%th
User
%th
Source IP
%th
Source IP
%th
API?
%th
API?
%th
Recaptcha verified?
%th
Type
%th
Type
%th
Title
%th
Title
%th
Description
%th
Description
...
...
app/views/devise/shared/_signup_box.html.haml
View file @
3d2954e4
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
=
f
.
password_field
:password
,
class:
"form-control bottom"
,
required:
true
,
pattern:
".{
#{
@minimum_password_length
}
,}"
,
title:
"Minimum length is
#{
@minimum_password_length
}
characters."
=
f
.
password_field
:password
,
class:
"form-control bottom"
,
required:
true
,
pattern:
".{
#{
@minimum_password_length
}
,}"
,
title:
"Minimum length is
#{
@minimum_password_length
}
characters."
%p
.gl-field-hint
Minimum length is
#{
@minimum_password_length
}
characters
%p
.gl-field-hint
Minimum length is
#{
@minimum_password_length
}
characters
%div
%div
-
if
current_application_settings
.
recaptcha_enabled
-
if
Gitlab
::
Recaptcha
.
enabled?
=
recaptcha_tags
=
recaptcha_tags
%div
%div
=
f
.
submit
"Register"
,
class:
"btn-register btn"
=
f
.
submit
"Register"
,
class:
"btn-register btn"
...
...
app/views/projects/issues/verify.html.haml
0 → 100644
View file @
3d2954e4
-
page_title
"Anti-spam verification"
%h3
.page-title
Anti-spam verification
%hr
%p
We detected potential spam in the issue description. Please verify that you are not a robot to submit the issue.
=
form_for
[
@project
.
namespace
.
becomes
(
Namespace
),
@project
,
@issue
]
do
|
f
|
.recaptcha
-
params
[
:issue
].
each
do
|
field
,
value
|
=
hidden_field
(
:issue
,
field
,
value:
value
)
=
hidden_field_tag
(
:merge_request_for_resolving_discussions
,
params
[
:merge_request_for_resolving_discussions
])
=
hidden_field_tag
(
:spam_log_id
,
@issue
.
spam_log
.
id
)
=
hidden_field_tag
(
:recaptcha_verification
,
true
)
=
recaptcha_tags
.row-content-block.footer-block
=
f
.
submit
"Submit
#{
@issue
.
class
.
model_name
.
human
.
downcase
}
"
,
class:
'btn btn-create'
changelogs/unreleased/21518_recaptcha_spam_issues.yml
0 → 100644
View file @
3d2954e4
---
title
:
Use reCaptcha when an issue is identified as a spam
merge_request
:
8846
author
:
db/migrate/20170206071414_add_recaptcha_verified_to_spam_logs.rb
0 → 100644
View file @
3d2954e4
class
AddRecaptchaVerifiedToSpamLogs
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
disable_ddl_transaction!
DOWNTIME
=
false
def
up
add_column_with_default
(
:spam_logs
,
:recaptcha_verified
,
:boolean
,
default:
false
)
end
def
down
remove_column
(
:spam_logs
,
:recaptcha_verified
)
end
end
db/schema.rb
View file @
3d2954e4
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
#
#
# It's strongly recommended that you check this file into your version control system.
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
2017020
4181513
)
do
ActiveRecord
::
Schema
.
define
(
version:
2017020
6071414
)
do
# These are extensions that must be enabled in order to support this database
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
enable_extension
"plpgsql"
...
@@ -1102,6 +1102,7 @@ ActiveRecord::Schema.define(version: 20170204181513) do
...
@@ -1102,6 +1102,7 @@ ActiveRecord::Schema.define(version: 20170204181513) do
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
boolean
"submitted_as_ham"
,
default:
false
,
null:
false
t
.
boolean
"submitted_as_ham"
,
default:
false
,
null:
false
t
.
boolean
"recaptcha_verified"
,
default:
false
,
null:
false
end
end
create_table
"subscriptions"
,
force: :cascade
do
|
t
|
create_table
"subscriptions"
,
force: :cascade
do
|
t
|
...
...
lib/gitlab/recaptcha.rb
View file @
3d2954e4
...
@@ -10,5 +10,9 @@ module Gitlab
...
@@ -10,5 +10,9 @@ module Gitlab
true
true
end
end
end
end
def
self
.
enabled?
current_application_settings
.
recaptcha_enabled
end
end
end
end
end
spec/controllers/projects/issues_controller_spec.rb
View file @
3d2954e4
...
@@ -326,7 +326,7 @@ describe Projects::IssuesController do
...
@@ -326,7 +326,7 @@ describe Projects::IssuesController do
end
end
describe
'POST #create'
do
describe
'POST #create'
do
def
post_new_issue
(
attr
s
=
{})
def
post_new_issue
(
issue_attrs
=
{},
additional_param
s
=
{})
sign_in
(
user
)
sign_in
(
user
)
project
=
create
(
:empty_project
,
:public
)
project
=
create
(
:empty_project
,
:public
)
project
.
team
<<
[
user
,
:developer
]
project
.
team
<<
[
user
,
:developer
]
...
@@ -334,8 +334,8 @@ describe Projects::IssuesController do
...
@@ -334,8 +334,8 @@ describe Projects::IssuesController do
post
:create
,
{
post
:create
,
{
namespace_id:
project
.
namespace
.
to_param
,
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
.
to_param
,
project_id:
project
.
to_param
,
issue:
{
title:
'Title'
,
description:
'Description'
}.
merge
(
attrs
)
issue:
{
title:
'Title'
,
description:
'Description'
}.
merge
(
issue_
attrs
)
}
}
.
merge
(
additional_params
)
project
.
issues
.
first
project
.
issues
.
first
end
end
...
@@ -378,24 +378,81 @@ describe Projects::IssuesController do
...
@@ -378,24 +378,81 @@ describe Projects::IssuesController do
context
'Akismet is enabled'
do
context
'Akismet is enabled'
do
before
do
before
do
stub_application_setting
(
recaptcha_enabled:
true
)
allow_any_instance_of
(
SpamService
).
to
receive
(
:check_for_spam?
).
and_return
(
true
)
allow_any_instance_of
(
SpamService
).
to
receive
(
:check_for_spam?
).
and_return
(
true
)
allow_any_instance_of
(
AkismetService
).
to
receive
(
:is_spam?
).
and_return
(
true
)
end
end
def
post_spam_issue
context
'when an issue is not identified as a spam'
do
post_new_issue
(
title:
'Spam Title'
,
description:
'Spam lives here'
)
before
do
end
allow_any_instance_of
(
described_class
).
to
receive
(
:verify_recaptcha
).
and_return
(
false
)
allow_any_instance_of
(
AkismetService
).
to
receive
(
:is_spam?
).
and_return
(
false
)
end
it
'rejects an issue recognized as spam
'
do
it
'does not create an issue
'
do
expect
{
post_spam_issue
}.
not_to
change
(
Issue
,
:count
)
expect
{
post_new_issue
(
title:
''
)
}.
not_to
change
(
Issue
,
:count
)
e
xpect
(
response
).
to
render_template
(
:new
)
e
nd
end
end
it
'creates a spam log'
do
context
'when an issue is identified as a spam'
do
post_spam_issue
before
{
allow_any_instance_of
(
AkismetService
).
to
receive
(
:is_spam?
).
and_return
(
true
)
}
spam_logs
=
SpamLog
.
all
expect
(
spam_logs
.
count
).
to
eq
(
1
)
context
'when captcha is not verified'
do
expect
(
spam_logs
[
0
].
title
).
to
eq
(
'Spam Title'
)
def
post_spam_issue
post_new_issue
(
title:
'Spam Title'
,
description:
'Spam lives here'
)
end
before
{
allow_any_instance_of
(
described_class
).
to
receive
(
:verify_recaptcha
).
and_return
(
false
)
}
it
'rejects an issue recognized as a spam'
do
expect
{
post_spam_issue
}.
not_to
change
(
Issue
,
:count
)
end
it
'creates a spam log'
do
post_spam_issue
spam_logs
=
SpamLog
.
all
expect
(
spam_logs
.
count
).
to
eq
(
1
)
expect
(
spam_logs
.
first
.
title
).
to
eq
(
'Spam Title'
)
expect
(
spam_logs
.
first
.
recaptcha_verified
).
to
be_falsey
end
it
'does not create an issue when it is not valid'
do
expect
{
post_new_issue
(
title:
''
)
}.
not_to
change
(
Issue
,
:count
)
end
it
'does not create an issue when recaptcha is not enabled'
do
stub_application_setting
(
recaptcha_enabled:
false
)
expect
{
post_spam_issue
}.
not_to
change
(
Issue
,
:count
)
end
end
context
'when captcha is verified'
do
let!
(
:spam_logs
)
{
create_list
(
:spam_log
,
2
,
user:
user
,
title:
'Title'
)
}
def
post_verified_issue
post_new_issue
({},
{
spam_log_id:
spam_logs
.
last
.
id
,
recaptcha_verification:
true
}
)
end
before
do
allow_any_instance_of
(
described_class
).
to
receive
(
:verify_recaptcha
).
and_return
(
true
)
end
it
'accepts an issue after recaptcha is verified'
do
expect
{
post_verified_issue
}.
to
change
(
Issue
,
:count
)
end
it
'marks spam log as recaptcha_verified'
do
expect
{
post_verified_issue
}.
to
change
{
SpamLog
.
last
.
recaptcha_verified
}.
from
(
false
).
to
(
true
)
end
it
'does not mark spam log as recaptcha_verified when it does not belong to current_user'
do
spam_log
=
create
(
:spam_log
)
expect
{
post_new_issue
({},
{
spam_log_id:
spam_log
.
id
,
recaptcha_verification:
true
}
)
}.
not_to
change
{
SpamLog
.
last
.
recaptcha_verified
}
end
end
end
end
end
end
...
@@ -405,7 +462,7 @@ describe Projects::IssuesController do
...
@@ -405,7 +462,7 @@ describe Projects::IssuesController do
end
end
it
'creates a user agent detail'
do
it
'creates a user agent detail'
do
expect
{
post_new_issue
}.
to
change
(
UserAgentDetail
,
:count
).
by
(
1
)
expect
{
post_new_issue
}.
to
change
(
UserAgentDetail
,
:count
).
by
(
1
)
end
end
end
end
...
...
spec/controllers/registrations_controller_spec.rb
View file @
3d2954e4
...
@@ -44,7 +44,7 @@ describe RegistrationsController do
...
@@ -44,7 +44,7 @@ describe RegistrationsController do
post
(
:create
,
user_params
)
post
(
:create
,
user_params
)
expect
(
response
).
to
render_template
(
:new
)
expect
(
response
).
to
render_template
(
:new
)
expect
(
flash
[
:alert
]).
to
include
'There was an error with the reCAPTCHA. Please
re-solve the reCAPTCHA
.'
expect
(
flash
[
:alert
]).
to
include
'There was an error with the reCAPTCHA. Please
solve the reCAPTCHA again
.'
end
end
it
'redirects to the dashboard when the recaptcha is solved'
do
it
'redirects to the dashboard when the recaptcha is solved'
do
...
...
spec/features/issues/spam_issues_spec.rb
0 → 100644
View file @
3d2954e4
require
'rails_helper'
describe
'New issue'
,
feature:
true
do
include
StubENV
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:user
)
{
create
(
:user
)}
before
do
stub_env
(
'IN_MEMORY_APPLICATION_SETTINGS'
,
'false'
)
current_application_settings
.
update!
(
akismet_enabled:
true
,
akismet_api_key:
'testkey'
,
recaptcha_enabled:
true
,
recaptcha_site_key:
'test site key'
,
recaptcha_private_key:
'test private key'
)
project
.
team
<<
[
user
,
:master
]
login_as
(
user
)
end
context
'when identified as a spam'
do
before
do
WebMock
.
stub_request
(
:any
,
/.*akismet.com.*/
).
to_return
(
body:
"true"
,
status:
200
)
visit
new_namespace_project_issue_path
(
project
.
namespace
,
project
)
end
it
'creates an issue after solving reCaptcha'
do
fill_in
'issue_title'
,
with:
'issue title'
fill_in
'issue_description'
,
with:
'issue description'
click_button
'Submit issue'
# it is impossible to test recaptcha automatically and there is no possibility to fill in recaptcha
# recaptcha verification is skipped in test environment and it always returns true
expect
(
page
).
not_to
have_content
(
'issue title'
)
expect
(
page
).
to
have_css
(
'.recaptcha'
)
click_button
'Submit issue'
expect
(
page
.
find
(
'.issue-details h2.title'
)).
to
have_content
(
'issue title'
)
expect
(
page
.
find
(
'.issue-details .description'
)).
to
have_content
(
'issue description'
)
end
end
context
'when not identified as a spam'
do
before
do
WebMock
.
stub_request
(
:any
,
/.*akismet.com.*/
).
to_return
(
body:
'false'
,
status:
200
)
visit
new_namespace_project_issue_path
(
project
.
namespace
,
project
)
end
it
'creates an issue'
do
fill_in
'issue_title'
,
with:
'issue title'
fill_in
'issue_description'
,
with:
'issue description'
click_button
'Submit issue'
expect
(
page
.
find
(
'.issue-details h2.title'
)).
to
have_content
(
'issue title'
)
expect
(
page
.
find
(
'.issue-details .description'
)).
to
have_content
(
'issue description'
)
end
end
end
spec/services/issues/create_service_spec.rb
View file @
3d2954e4
...
@@ -181,5 +181,107 @@ describe Issues::CreateService, services: true do
...
@@ -181,5 +181,107 @@ describe Issues::CreateService, services: true do
expect
(
issue
.
title
).
to
be_nil
expect
(
issue
.
title
).
to
be_nil
end
end
end
end
context
'checking spam'
do
let
(
:opts
)
do
{
title:
'Awesome issue'
,
description:
'please fix'
,
request:
double
(
:request
,
env:
{})
}
end
before
do
allow_any_instance_of
(
SpamService
).
to
receive
(
:check_for_spam?
).
and_return
(
true
)
end
context
'when recaptcha was verified'
do
let
(
:log_user
)
{
user
}
let
(
:spam_logs
)
{
create_list
(
:spam_log
,
2
,
user:
log_user
,
title:
'Awesome issue'
)
}
before
do
opts
[
:recaptcha_verified
]
=
true
opts
[
:spam_log_id
]
=
spam_logs
.
last
.
id
expect
(
AkismetService
).
not_to
receive
(
:new
)
end
it
'does no mark an issue as a spam '
do
expect
(
issue
).
not_to
be_spam
end
it
'an issue is valid '
do
expect
(
issue
.
valid?
).
to
be_truthy
end
it
'does not assign a spam_log to an issue'
do
expect
(
issue
.
spam_log
).
to
be_nil
end
it
'marks related spam_log as recaptcha_verified'
do
expect
{
issue
}.
to
change
{
SpamLog
.
last
.
recaptcha_verified
}.
from
(
false
).
to
(
true
)
end
context
'when spam log does not belong to a user'
do
let
(
:log_user
)
{
create
(
:user
)
}
it
'does not mark spam_log as recaptcha_verified'
do
expect
{
issue
}.
not_to
change
{
SpamLog
.
last
.
recaptcha_verified
}
end
end
context
'when spam log title does not match the issue title'
do
before
do
opts
[
:title
]
=
'Another issue'
end
it
'does not mark spam_log as recaptcha_verified'
do
expect
{
issue
}.
not_to
change
{
SpamLog
.
last
.
recaptcha_verified
}
end
end
end
context
'when recaptcha was not verified'
do
context
'when akismet detects spam'
do
before
do
allow_any_instance_of
(
AkismetService
).
to
receive
(
:is_spam?
).
and_return
(
true
)
end
it
'marks an issue as a spam '
do
expect
(
issue
).
to
be_spam
end
it
'an issue is not valid '
do
expect
(
issue
.
valid?
).
to
be_falsey
end
it
'creates a new spam_log'
do
expect
{
issue
}.
to
change
{
SpamLog
.
count
}.
from
(
0
).
to
(
1
)
end
it
'assigns a spam_log to an issue'
do
expect
(
issue
.
spam_log
).
to
eq
(
SpamLog
.
last
)
end
end
context
'when akismet does not detect spam'
do
before
do
allow_any_instance_of
(
AkismetService
).
to
receive
(
:is_spam?
).
and_return
(
false
)
end
it
'does not mark an issue as a spam '
do
expect
(
issue
).
not_to
be_spam
end
it
'an issue is valid '
do
expect
(
issue
.
valid?
).
to
be_truthy
end
it
'does not assign a spam_log to an issue'
do
expect
(
issue
.
spam_log
).
to
be_nil
end
end
end
end
end
end
end
end
spec/services/spam_service_spec.rb
0 → 100644
View file @
3d2954e4
require
'spec_helper'
describe
SpamService
,
services:
true
do
describe
'#check'
do
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:request
)
{
double
(
:request
,
env:
{})
}
def
check_spam
(
issue
,
request
)
described_class
.
new
(
issue
,
request
).
check
end
context
'when indicated as spam by akismet'
do
before
{
allow
(
AkismetService
).
to
receive
(
:new
).
and_return
(
double
(
is_spam?:
true
))
}
it
'returns false when request is missing'
do
expect
(
check_spam
(
issue
,
nil
)).
to
be_falsey
end
it
'returns false when issue is not public'
do
issue
=
create
(
:issue
,
project:
create
(
:project
,
:private
))
expect
(
check_spam
(
issue
,
request
)).
to
be_falsey
end
it
'returns true'
do
expect
(
check_spam
(
issue
,
request
)).
to
be_truthy
end
it
'creates a spam log'
do
expect
{
check_spam
(
issue
,
request
)
}.
to
change
{
SpamLog
.
count
}.
from
(
0
).
to
(
1
)
end
end
context
'when not indicated as spam by akismet'
do
before
{
allow
(
AkismetService
).
to
receive
(
:new
).
and_return
(
double
(
is_spam?:
false
))
}
it
'returns false'
do
expect
(
check_spam
(
issue
,
request
)).
to
be_falsey
end
it
'does not create a spam log'
do
expect
{
check_spam
(
issue
,
request
)
}.
not_to
change
{
SpamLog
.
count
}
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment