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
0
Merge Requests
0
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
Jérome Perrin
gitlab-ce
Commits
96399a81
Commit
96399a81
authored
Aug 02, 2016
by
Patricio Cano
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow `Issue` to be submitted as spam
- Added controller actions as reusable concerns - Added controller tests
parent
abf2dcd2
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
129 additions
and
10 deletions
+129
-10
app/assets/stylesheets/framework/buttons.scss
app/assets/stylesheets/framework/buttons.scss
+4
-0
app/controllers/concerns/spammable_actions.rb
app/controllers/concerns/spammable_actions.rb
+32
-0
app/controllers/projects/issues_controller.rb
app/controllers/projects/issues_controller.rb
+2
-0
app/models/concerns/spammable.rb
app/models/concerns/spammable.rb
+15
-3
app/services/system_note_service.rb
app/services/system_note_service.rb
+17
-0
app/views/admin/spam_logs/_spam_log.html.haml
app/views/admin/spam_logs/_spam_log.html.haml
+1
-1
app/views/projects/issues/show.html.haml
app/views/projects/issues/show.html.haml
+9
-2
config/routes.rb
config/routes.rb
+1
-0
db/migrate/20160727163552_create_user_agent_details.rb
db/migrate/20160727163552_create_user_agent_details.rb
+1
-0
db/schema.rb
db/schema.rb
+1
-0
spec/controllers/admin/spam_logs_controller_spec.rb
spec/controllers/admin/spam_logs_controller_spec.rb
+12
-0
spec/controllers/projects/issues_controller_spec.rb
spec/controllers/projects/issues_controller_spec.rb
+29
-0
spec/models/concerns/spammable_spec.rb
spec/models/concerns/spammable_spec.rb
+5
-4
No files found.
app/assets/stylesheets/framework/buttons.scss
View file @
96399a81
...
@@ -164,6 +164,10 @@
...
@@ -164,6 +164,10 @@
@include
btn-outline
(
$white-light
,
$orange-normal
,
$orange-normal
,
$orange-light
,
$white-light
,
$orange-light
);
@include
btn-outline
(
$white-light
,
$orange-normal
,
$orange-normal
,
$orange-light
,
$white-light
,
$orange-light
);
}
}
&
.btn-spam
{
@include
btn-outline
(
$white-light
,
$red-normal
,
$red-normal
,
$red-light
,
$white-light
,
$red-light
);
}
&
.btn-danger
,
&
.btn-danger
,
&
.btn-remove
,
&
.btn-remove
,
&
.btn-red
{
&
.btn-red
{
...
...
app/controllers/concerns/spammable_actions.rb
0 → 100644
View file @
96399a81
module
SpammableActions
extend
ActiveSupport
::
Concern
included
do
before_action
:authorize_submit_spammable!
,
only: :mark_as_spam
end
def
mark_as_spam
if
spammable
.
submit_spam
spammable
.
user_agent_detail
.
update_attribute
(
:submitted
,
true
)
if
spammable
.
is_a?
(
Issuable
)
SystemNoteService
.
submit_spam
(
spammable
,
spammable
.
project
,
current_user
)
end
redirect_to
spammable
,
notice:
'Issue was submitted to Akismet successfully.'
else
flash
[
:error
]
=
'Error with Akismet. Please check the logs for more info.'
redirect_to
spammable
end
end
private
def
spammable
raise
NotImplementedError
end
def
authorize_submit_spammable!
access_denied!
unless
current_user
.
admin?
end
end
app/controllers/projects/issues_controller.rb
View file @
96399a81
...
@@ -4,6 +4,7 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -4,6 +4,7 @@ class Projects::IssuesController < Projects::ApplicationController
include
IssuableActions
include
IssuableActions
include
ToggleAwardEmoji
include
ToggleAwardEmoji
include
IssuableCollections
include
IssuableCollections
include
SpammableActions
before_action
:redirect_to_external_issue_tracker
,
only:
[
:index
,
:new
]
before_action
:redirect_to_external_issue_tracker
,
only:
[
:index
,
:new
]
before_action
:module_enabled
before_action
:module_enabled
...
@@ -185,6 +186,7 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -185,6 +186,7 @@ class Projects::IssuesController < Projects::ApplicationController
alias_method
:subscribable_resource
,
:issue
alias_method
:subscribable_resource
,
:issue
alias_method
:issuable
,
:issue
alias_method
:issuable
,
:issue
alias_method
:awardable
,
:issue
alias_method
:awardable
,
:issue
alias_method
:spammable
,
:issue
def
authorize_read_issue!
def
authorize_read_issue!
return
render_404
unless
can?
(
current_user
,
:read_issue
,
@issue
)
return
render_404
unless
can?
(
current_user
,
:read_issue
,
@issue
)
...
...
app/models/concerns/spammable.rb
View file @
96399a81
...
@@ -22,7 +22,7 @@ module Spammable
...
@@ -22,7 +22,7 @@ module Spammable
def
can_be_submitted?
def
can_be_submitted?
if
user_agent_detail
if
user_agent_detail
user_agent_detail
.
submittable?
user_agent_detail
.
submittable?
&&
akismet_enabled?
else
else
false
false
end
end
...
@@ -41,6 +41,14 @@ module Spammable
...
@@ -41,6 +41,14 @@ module Spammable
@spam
@spam
end
end
def
submitted?
if
user_agent_detail
user_agent_detail
.
submitted
else
false
end
end
def
check_for_spam
def
check_for_spam
self
.
errors
.
add
(
:base
,
"Your
#{
self
.
class
.
name
.
underscore
}
has been recognized as spam and has been discarded."
)
if
spam?
self
.
errors
.
add
(
:base
,
"Your
#{
self
.
class
.
name
.
underscore
}
has been recognized as spam and has been discarded."
)
if
spam?
end
end
...
@@ -53,17 +61,21 @@ module Spammable
...
@@ -53,17 +61,21 @@ module Spammable
end
end
end
end
def
to_ability_name
self
.
class
.
to_s
.
underscore
end
# Override this method if an additional check is needed before calling Akismet
# Override this method if an additional check is needed before calling Akismet
def
check_for_spam?
def
check_for_spam?
akismet_enabled?
akismet_enabled?
end
end
def
spam_title
def
spam_title
raise
'Implement in included model!'
raise
NotImplementedError
end
end
def
spam_description
def
spam_description
raise
'Implement in included model!'
raise
NotImplementedError
end
end
private
private
...
...
app/services/system_note_service.rb
View file @
96399a81
...
@@ -395,6 +395,23 @@ module SystemNoteService
...
@@ -395,6 +395,23 @@ module SystemNoteService
create_note
(
noteable:
noteable
,
project:
project
,
author:
author
,
note:
body
)
create_note
(
noteable:
noteable
,
project:
project
,
author:
author
,
note:
body
)
end
end
# Called when the status of a Issuable is submitted as spam
#
# noteable - Noteable object
# project - Project owning noteable
# author - User performing the change
#
# Example Note text:
#
# "Issue submitted as spam."
#
# Returns the created Note object
def
submit_spam
(
noteable
,
project
,
author
)
body
=
"Submitted
#{
noteable
.
class
.
to_s
.
downcase
}
as spam"
create_note
(
noteable:
noteable
,
project:
project
,
author:
author
,
note:
body
)
end
private
private
def
notes_for_mentioner
(
mentioner
,
noteable
,
notes
)
def
notes_for_mentioner
(
mentioner
,
noteable
,
notes
)
...
...
app/views/admin/spam_logs/_spam_log.html.haml
View file @
96399a81
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
%td
%td
-
if
spam_log
.
submitted_as_ham?
-
if
spam_log
.
submitted_as_ham?
.btn.btn-xs.disabled
.btn.btn-xs.disabled
Submitted as
H
am
Submitted as
h
am
-
else
-
else
=
link_to
'Submit as ham'
,
mark_as_ham_admin_spam_log_path
(
spam_log
),
method: :post
,
class:
'btn btn-xs btn-warning'
=
link_to
'Submit as ham'
,
mark_as_ham_admin_spam_log_path
(
spam_log
),
method: :post
,
class:
'btn btn-xs btn-warning'
-
if
user
&&
!
user
.
blocked?
-
if
user
&&
!
user
.
blocked?
...
...
app/views/projects/issues/show.html.haml
View file @
96399a81
...
@@ -37,14 +37,21 @@
...
@@ -37,14 +37,21 @@
=
link_to
'Close issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :close
},
status_only:
true
,
format:
'json'
),
data:
{
no_turbolink:
true
},
class:
"btn-close
#{
issue_button_visibility
(
@issue
,
true
)
}
"
,
title:
'Close issue'
=
link_to
'Close issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :close
},
status_only:
true
,
format:
'json'
),
data:
{
no_turbolink:
true
},
class:
"btn-close
#{
issue_button_visibility
(
@issue
,
true
)
}
"
,
title:
'Close issue'
%li
%li
=
link_to
'Edit'
,
edit_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
)
=
link_to
'Edit'
,
edit_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
)
-
if
@issue
.
can_be_submitted?
&&
current_user
.
admin?
-
unless
@issue
.
submitted?
%li
=
link_to
'Submit as spam'
,
mark_as_spam_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
),
method: :post
,
class:
'btn-spam'
,
title:
'Submit as spam'
-
if
can?
(
current_user
,
:create_issue
,
@project
)
-
if
can?
(
current_user
,
:create_issue
,
@project
)
=
link_to
new_namespace_project_issue_path
(
@project
.
namespace
,
@project
),
class:
'hidden-xs hidden-sm btn btn-grouped new-issue-link btn-new btn-inverted'
,
title:
'New issue'
,
id:
'new_issue_link'
do
=
link_to
new_namespace_project_issue_path
(
@project
.
namespace
,
@project
),
class:
'hidden-xs hidden-sm btn btn-grouped new-issue-link btn-new btn-inverted'
,
title:
'New issue'
,
id:
'new_issue_link'
do
New issue
New issue
-
if
can?
(
current_user
,
:update_issue
,
@issue
)
-
if
can?
(
current_user
,
:update_issue
,
@issue
)
=
link_to
'Reopen issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :reopen
},
status_only:
true
,
format:
'json'
),
data:
{
no_turbolink:
true
},
class:
"hidden-xs hidden-sm btn btn-grouped btn-reopen
#{
issue_button_visibility
(
@issue
,
false
)
}
"
,
title:
'Reopen issue'
=
link_to
'Reopen issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :reopen
},
status_only:
true
,
format:
'json'
),
data:
{
no_turbolink:
true
},
class:
"hidden-xs hidden-sm btn btn-grouped btn-reopen
#{
issue_button_visibility
(
@issue
,
false
)
}
"
,
title:
'Reopen issue'
=
link_to
'Close issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :close
},
status_only:
true
,
format:
'json'
),
data:
{
no_turbolink:
true
},
class:
"hidden-xs hidden-sm btn btn-grouped btn-close
#{
issue_button_visibility
(
@issue
,
true
)
}
"
,
title:
'Close issue'
=
link_to
'Close issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :close
},
status_only:
true
,
format:
'json'
),
data:
{
no_turbolink:
true
},
class:
"hidden-xs hidden-sm btn btn-grouped btn-close
#{
issue_button_visibility
(
@issue
,
true
)
}
"
,
title:
'Close issue'
=
link_to
edit_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
),
class:
'hidden-xs hidden-sm btn btn-grouped issuable-edit'
do
=
link_to
'Edit'
,
edit_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
),
class:
'hidden-xs hidden-sm btn btn-grouped issuable-edit'
Edit
-
if
@issue
.
can_be_submitted?
&&
current_user
.
admin?
-
unless
@issue
.
submitted?
=
link_to
'Submit as spam'
,
mark_as_spam_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
),
method: :post
,
class:
'hidden-xs hidden-sm btn btn-grouped btn-spam'
,
title:
'Submit as spam'
.issue-details.issuable-details
.issue-details.issuable-details
...
...
config/routes.rb
View file @
96399a81
...
@@ -817,6 +817,7 @@ Rails.application.routes.draw do
...
@@ -817,6 +817,7 @@ Rails.application.routes.draw do
member
do
member
do
post
:toggle_subscription
post
:toggle_subscription
post
:toggle_award_emoji
post
:toggle_award_emoji
post
:mark_as_spam
get
:referenced_merge_requests
get
:referenced_merge_requests
get
:related_branches
get
:related_branches
get
:can_create_branch
get
:can_create_branch
...
...
db/migrate/20160727163552_create_user_agent_details.rb
View file @
96399a81
...
@@ -5,6 +5,7 @@ class CreateUserAgentDetails < ActiveRecord::Migration
...
@@ -5,6 +5,7 @@ class CreateUserAgentDetails < ActiveRecord::Migration
t
.
string
:ip_address
,
null:
false
t
.
string
:ip_address
,
null:
false
t
.
integer
:subject_id
,
null:
false
t
.
integer
:subject_id
,
null:
false
t
.
string
:subject_type
,
null:
false
t
.
string
:subject_type
,
null:
false
t
.
boolean
:submitted
,
default:
false
t
.
timestamps
null:
false
t
.
timestamps
null:
false
end
end
...
...
db/schema.rb
View file @
96399a81
...
@@ -1004,6 +1004,7 @@ ActiveRecord::Schema.define(version: 20160810142633) do
...
@@ -1004,6 +1004,7 @@ ActiveRecord::Schema.define(version: 20160810142633) do
t
.
string
"ip_address"
,
null:
false
t
.
string
"ip_address"
,
null:
false
t
.
integer
"subject_id"
,
null:
false
t
.
integer
"subject_id"
,
null:
false
t
.
string
"subject_type"
,
null:
false
t
.
string
"subject_type"
,
null:
false
t
.
boolean
"submitted"
,
default:
false
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
end
end
...
...
spec/controllers/admin/spam_logs_controller_spec.rb
View file @
96399a81
...
@@ -34,4 +34,16 @@ describe Admin::SpamLogsController do
...
@@ -34,4 +34,16 @@ describe Admin::SpamLogsController do
expect
{
User
.
find
(
user
.
id
)
}.
to
raise_error
(
ActiveRecord
::
RecordNotFound
)
expect
{
User
.
find
(
user
.
id
)
}.
to
raise_error
(
ActiveRecord
::
RecordNotFound
)
end
end
end
end
describe
'#mark_as_ham'
do
before
do
allow_any_instance_of
(
Gitlab
::
AkismetHelper
).
to
receive
(
:ham!
).
and_return
(
true
)
end
it
'submits the log as ham'
do
post
:mark_as_ham
,
id:
first_spam
.
id
expect
(
response
).
to
have_http_status
(
302
)
expect
(
SpamLog
.
find
(
first_spam
.
id
).
submitted_as_ham
).
to
be_truthy
end
end
end
end
spec/controllers/projects/issues_controller_spec.rb
View file @
96399a81
...
@@ -322,6 +322,35 @@ describe Projects::IssuesController do
...
@@ -322,6 +322,35 @@ describe Projects::IssuesController do
end
end
end
end
describe
'POST #mark_as_spam'
do
context
'properly submits to Akismet'
do
before
do
allow_any_instance_of
(
Spammable
).
to
receive_messages
(
can_be_submitted?:
true
,
submit_spam:
true
)
end
def
post_spam
admin
=
create
(
:admin
)
create
(
:user_agent_detail
,
subject:
issue
)
project
.
team
<<
[
admin
,
:master
]
sign_in
(
admin
)
post
:mark_as_spam
,
{
namespace_id:
project
.
namespace
.
path
,
project_id:
project
.
path
,
id:
issue
.
iid
}
end
it
'creates a system note'
do
expect
{
post_spam
}.
to
change
(
Note
,
:count
)
end
it
'updates issue'
do
post_spam
expect
(
issue
.
submitted?
).
to
be_truthy
end
end
end
describe
"DELETE #destroy"
do
describe
"DELETE #destroy"
do
context
"when the user is a developer"
do
context
"when the user is a developer"
do
before
{
sign_in
(
user
)
}
before
{
sign_in
(
user
)
}
...
...
spec/models/concerns/spammable_spec.rb
View file @
96399a81
...
@@ -14,6 +14,10 @@ describe Issue, 'Spammable' do
...
@@ -14,6 +14,10 @@ describe Issue, 'Spammable' do
end
end
describe
'InstanceMethods'
do
describe
'InstanceMethods'
do
before
do
allow_any_instance_of
(
Gitlab
::
AkismetHelper
).
to
receive
(
:akismet_enabled?
).
and_return
(
true
)
end
it
'should return the correct creator'
do
it
'should return the correct creator'
do
expect
(
issue
.
send
(
:owner
).
id
).
to
eq
(
issue
.
author_id
)
expect
(
issue
.
send
(
:owner
).
id
).
to
eq
(
issue
.
author_id
)
end
end
...
@@ -24,14 +28,11 @@ describe Issue, 'Spammable' do
...
@@ -24,14 +28,11 @@ describe Issue, 'Spammable' do
end
end
it
'should be submittable'
do
it
'should be submittable'
do
create
(
:user_agent_detail
,
subject
_id:
issue
.
id
,
subject_type:
issue
.
class
.
to_s
)
create
(
:user_agent_detail
,
subject
:
issue
)
expect
(
issue
.
can_be_submitted?
).
to
be_truthy
expect
(
issue
.
can_be_submitted?
).
to
be_truthy
end
end
describe
'#check_for_spam?'
do
describe
'#check_for_spam?'
do
before
do
allow_any_instance_of
(
Gitlab
::
AkismetHelper
).
to
receive
(
:akismet_enabled?
).
and_return
(
true
)
end
it
'returns true for public project'
do
it
'returns true for public project'
do
issue
.
project
.
update_attribute
(
:visibility_level
,
Gitlab
::
VisibilityLevel
::
PUBLIC
)
issue
.
project
.
update_attribute
(
:visibility_level
,
Gitlab
::
VisibilityLevel
::
PUBLIC
)
expect
(
issue
.
check_for_spam?
).
to
eq
(
true
)
expect
(
issue
.
check_for_spam?
).
to
eq
(
true
)
...
...
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