It is now possible to report comments
* Renamed PostReport to Report * Added report button to SPV * Updated rspec refs diaspora/diaspora#4732 refs diaspora/diaspora#4710 refs diaspora/diaspora#4711 refs diaspora/diaspora#4517
This commit is contained in:
parent
ee6212c635
commit
1748d3b940
35 changed files with 406 additions and 239 deletions
|
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 173 B |
|
|
@ -1,3 +0,0 @@
|
||||||
app.models.PostReport = Backbone.Model.extend({
|
|
||||||
urlRoot: '/post_report'
|
|
||||||
});
|
|
||||||
8
app/assets/javascripts/app/models/report.js
Normal file
8
app/assets/javascripts/app/models/report.js
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
app.models.Report = Backbone.Model.extend({
|
||||||
|
urlRoot: '/report',
|
||||||
|
|
||||||
|
getReason: function() {
|
||||||
|
return prompt(Diaspora.I18n.t('report_prompt'), Diaspora.I18n.t('report_prompt_default'));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -5,7 +5,8 @@ app.views.Comment = app.views.Content.extend({
|
||||||
|
|
||||||
events : function() {
|
events : function() {
|
||||||
return _.extend({}, app.views.Content.prototype.events, {
|
return _.extend({}, app.views.Content.prototype.events, {
|
||||||
"click .comment_delete": "destroyModel"
|
"click .comment_delete": "destroyModel",
|
||||||
|
"click .comment_report": "report"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -31,6 +32,20 @@ app.views.Comment = app.views.Content.extend({
|
||||||
|
|
||||||
canRemove : function() {
|
canRemove : function() {
|
||||||
return app.currentUser.authenticated() && (this.ownComment() || this.postOwner())
|
return app.currentUser.authenticated() && (this.ownComment() || this.postOwner())
|
||||||
|
},
|
||||||
|
|
||||||
|
report: function(evt) {
|
||||||
|
if(evt) { evt.preventDefault(); }
|
||||||
|
var report = new app.models.Report();
|
||||||
|
var msg = report.getReason();
|
||||||
|
if (msg !== null) {
|
||||||
|
var id = this.model.id;
|
||||||
|
var type = $(evt.currentTarget).data("type");
|
||||||
|
report.fetch({
|
||||||
|
data: { id: id, type: type, text: msg },
|
||||||
|
type: 'POST'
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ app.views.Feedback = app.views.Base.extend({
|
||||||
events: {
|
events: {
|
||||||
"click *[rel='auth-required']" : "requireAuth",
|
"click *[rel='auth-required']" : "requireAuth",
|
||||||
"click .like" : "toggleLike",
|
"click .like" : "toggleLike",
|
||||||
"click .reshare" : "resharePost"
|
"click .reshare" : "resharePost",
|
||||||
|
"click .post_report" : "report"
|
||||||
},
|
},
|
||||||
|
|
||||||
tooltipSelector : ".label",
|
tooltipSelector : ".label",
|
||||||
|
|
@ -44,5 +45,19 @@ app.views.Feedback = app.views.Base.extend({
|
||||||
if( app.currentUser.authenticated() ) { return }
|
if( app.currentUser.authenticated() ) { return }
|
||||||
alert("you must be logged in to do that!")
|
alert("you must be logged in to do that!")
|
||||||
return false;
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
report: function(evt) {
|
||||||
|
if(evt) { evt.preventDefault(); }
|
||||||
|
var report = new app.models.Report();
|
||||||
|
var msg = report.getReason();
|
||||||
|
if (msg !== null) {
|
||||||
|
var id = this.model.id;
|
||||||
|
var type = $(evt.currentTarget).data("type");
|
||||||
|
report.fetch({
|
||||||
|
data: { id: id, type: type, text: msg },
|
||||||
|
type: 'POST'
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,20 @@ app.views.Post = app.views.Base.extend({
|
||||||
|
|
||||||
showPost : function() {
|
showPost : function() {
|
||||||
return (app.currentUser.get("showNsfw")) || !this.model.get("nsfw")
|
return (app.currentUser.get("showNsfw")) || !this.model.get("nsfw")
|
||||||
}
|
},
|
||||||
|
|
||||||
|
report: function(evt) {
|
||||||
|
if(evt) { evt.preventDefault(); }
|
||||||
|
var report = new app.models.Report();
|
||||||
|
var msg = report.getReason();
|
||||||
|
if (msg !== null) {
|
||||||
|
var id = this.model.id;
|
||||||
|
var type = $(evt.currentTarget).data("type");
|
||||||
|
report.fetch({
|
||||||
|
data: { id: id, type: type, text: msg },
|
||||||
|
type: 'POST'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ app.views.StreamPost = app.views.Post.extend({
|
||||||
|
|
||||||
"click .remove_post": "destroyModel",
|
"click .remove_post": "destroyModel",
|
||||||
"click .hide_post": "hidePost",
|
"click .hide_post": "hidePost",
|
||||||
"click .post_report": "postReport",
|
"click .post_report": "report",
|
||||||
"click .block_user": "blockUser"
|
"click .block_user": "blockUser"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -108,21 +108,6 @@ app.views.StreamPost = app.views.Post.extend({
|
||||||
this.remove();
|
this.remove();
|
||||||
},
|
},
|
||||||
|
|
||||||
postReport : function(evt) {
|
|
||||||
if(evt) { evt.preventDefault(); }
|
|
||||||
var text = prompt(Diaspora.I18n.t('post_report_prompt'),
|
|
||||||
Diaspora.I18n.t('post_report_prompt_default'));
|
|
||||||
|
|
||||||
var postReport = new app.models.PostReport();
|
|
||||||
postReport.fetch({
|
|
||||||
data: {
|
|
||||||
post_id: this.model.id,
|
|
||||||
text: text
|
|
||||||
},
|
|
||||||
type: 'POST'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
focusCommentTextarea: function(evt){
|
focusCommentTextarea: function(evt){
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
this.$(".new_comment_form_wrapper").removeClass("hidden");
|
this.$(".new_comment_form_wrapper").removeClass("hidden");
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
@import 'facebox'
|
@import 'facebox'
|
||||||
@import 'aspects'
|
@import 'aspects'
|
||||||
@import 'popover'
|
@import 'popover'
|
||||||
@import 'post_report'
|
|
||||||
@import 'stream_element'
|
@import 'stream_element'
|
||||||
|
@import 'report'
|
||||||
|
|
||||||
/* ====== media ====== */
|
/* ====== media ====== */
|
||||||
.media
|
.media
|
||||||
|
|
@ -211,10 +211,10 @@ ul.as-selections
|
||||||
:z-index 6
|
:z-index 6
|
||||||
:float right
|
:float right
|
||||||
|
|
||||||
.post_report
|
.post_report, .comment_report
|
||||||
:display inline-block
|
:display inline-block
|
||||||
|
|
||||||
.icons-postreport
|
.icons-report
|
||||||
:height 14px
|
:height 14px
|
||||||
:width 14px
|
:width 14px
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@
|
||||||
&.globe:before { content: '\1f30e'; } /* 1f30e */
|
&.globe:before { content: '\1f30e'; } /* 1f30e */
|
||||||
&.graduation-cap:before { content: '\1f393 '; } /* 1f393 */
|
&.graduation-cap:before { content: '\1f393 '; } /* 1f393 */
|
||||||
&.heart-empty:before { content: '\2661'; } /* 2661 */
|
&.heart-empty:before { content: '\2661'; } /* 2661 */
|
||||||
|
&.report:before { content: '\21'; } /* 21 */
|
||||||
&.heart:before { content: '\2665'; } /* 2665 */
|
&.heart:before { content: '\2665'; } /* 2665 */
|
||||||
&.help:before { content: '\2753'; } /* 2753 */
|
&.help:before { content: '\2753'; } /* 2753 */
|
||||||
&.home:before { content: '\2302'; } /* 2302 */
|
&.home:before { content: '\2302'; } /* 2302 */
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#post_report {
|
#report {
|
||||||
padding-top: 2em;
|
padding-top: 2em;
|
||||||
span {
|
span {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
}
|
}
|
||||||
.clear {
|
.clear {
|
||||||
clear: both;
|
clear: both;
|
||||||
|
border-bottom: 1px solid #808080;
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -61,6 +61,12 @@
|
||||||
i.comment:hover {
|
i.comment:hover {
|
||||||
color: #424242;
|
color: #424242;
|
||||||
}
|
}
|
||||||
|
i.report.gray:hover {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
i.report.red:hover {
|
||||||
|
color: #f55f5a;
|
||||||
|
}
|
||||||
i.heart.gray:hover {
|
i.heart.gray:hover {
|
||||||
color: $red;
|
color: $red;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,17 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bd">
|
<div class="bd">
|
||||||
{{#if canRemove}}
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
{{#if canRemove}}
|
||||||
<a href="#" class="delete comment_delete" title="{{t "delete"}}">
|
<a href="#" class="delete comment_delete" title="{{t "delete"}}">
|
||||||
<div alt="Deletelabel" class="icons-deletelabel" />
|
<div alt="Deletelabel" class="icons-deletelabel" />
|
||||||
<a/>
|
<a/>
|
||||||
</div>
|
{{else}}
|
||||||
|
<a href="#" data-type="comment" class="comment_report" title="{{t "report"}}">
|
||||||
|
<div class="icons-report control_icon"/>
|
||||||
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{#with author}}
|
{{#with author}}
|
||||||
<a href="/people/{{guid}}" class="author author-name {{hovercardable this}}">
|
<a href="/people/{{guid}}" class="author author-name {{hovercardable this}}">
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,9 @@
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
<a href="#" rel="auth-required" data-type="post" class="post_report" title="{{t "report"}}">
|
||||||
|
<i class="entypo report gray large"/>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
{{#if loggedIn}}
|
{{#if loggedIn}}
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{#unless authorIsCurrentUser}}
|
{{#unless authorIsCurrentUser}}
|
||||||
<a href="#" rel="nofollow" class="post_report" title="{{t "post_report"}}">
|
<a href="#" rel="nofollow" data-type="post" class="post_report" title="{{t "report"}}">
|
||||||
<div class="icons-postreport control_icon"/>
|
<div class="icons-report control_icon"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="#" rel="nofollow" class="block_user" title="{{t "ignore"}}">
|
<a href="#" rel="nofollow" class="block_user" title="{{t "ignore"}}">
|
||||||
<div class="icons-ignoreuser control_icon"></div>
|
<div class="icons-ignoreuser control_icon"></div>
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
class PostReportController < ApplicationController
|
|
||||||
before_filter :authenticate_user!
|
|
||||||
before_filter :redirect_unless_admin, :except => [:create]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@post_report = PostReport.where(reviewed: false).all
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if PostReport.exists?(post_id: params[:id])
|
|
||||||
mark_as_reviewed
|
|
||||||
end
|
|
||||||
redirect_to :action => :index and return
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if Post.exists?(params[:id])
|
|
||||||
delete_post
|
|
||||||
mark_as_reviewed
|
|
||||||
end
|
|
||||||
redirect_to :action => :index and return
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
username = current_user.username
|
|
||||||
unless PostReport.where(post_id: params[:post_id]).exists?(user_id: username)
|
|
||||||
post = PostReport.new(
|
|
||||||
:post_id => params[:post_id],
|
|
||||||
:user_id => username,
|
|
||||||
:text => params[:text])
|
|
||||||
result = post.save
|
|
||||||
status(( 200 if result ) || ( 422 if !result ))
|
|
||||||
else
|
|
||||||
status(409)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def delete_post
|
|
||||||
post = Post.find(params[:id])
|
|
||||||
current_user.retract(post)
|
|
||||||
flash[:notice] = I18n.t 'post_report.status.destroyed'
|
|
||||||
end
|
|
||||||
|
|
||||||
def mark_as_reviewed id = params[:id]
|
|
||||||
posts = PostReport.where(post_id: id)
|
|
||||||
posts.each do |post|
|
|
||||||
post.update_attributes(reviewed: true)
|
|
||||||
end
|
|
||||||
flash[:notice] = I18n.t 'post_report.status.marked'
|
|
||||||
end
|
|
||||||
|
|
||||||
def status(code)
|
|
||||||
if code == 200
|
|
||||||
flash[:notice] = I18n.t 'post_report.status.created'
|
|
||||||
else
|
|
||||||
flash[:error] = I18n.t 'post_report.status.failed'
|
|
||||||
end
|
|
||||||
render :nothing => true, :status => code
|
|
||||||
end
|
|
||||||
end
|
|
||||||
67
app/controllers/report_controller.rb
Normal file
67
app/controllers/report_controller.rb
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
class ReportController < ApplicationController
|
||||||
|
before_filter :authenticate_user!
|
||||||
|
before_filter :redirect_unless_admin, :except => [:create]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@report = Report.where(reviewed: false).all
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if Report.where(post_type: params[:type]).exists?(post_id: params[:id])
|
||||||
|
mark_as_reviewed
|
||||||
|
end
|
||||||
|
redirect_to :action => :index and return
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if (params[:type].eql? "post")
|
||||||
|
if Post.exists?(params[:id])
|
||||||
|
delete_post
|
||||||
|
end
|
||||||
|
elsif (params[:type].eql? "comment")
|
||||||
|
if Comment.exists?(params[:id])
|
||||||
|
delete_comment
|
||||||
|
end
|
||||||
|
end
|
||||||
|
redirect_to :action => :index and return
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
code = 400
|
||||||
|
username = current_user.username
|
||||||
|
post = Report.new(
|
||||||
|
:post_id => params[:id],
|
||||||
|
:post_type => params[:type],
|
||||||
|
:user_id => username,
|
||||||
|
:text => params[:text])
|
||||||
|
unless Report.where("post_id = ? AND post_type = ?", params[:id], params[:type]).exists?(user_id: username)
|
||||||
|
result = post.save
|
||||||
|
code = 200 if result
|
||||||
|
end
|
||||||
|
render :nothing => true, :status => code
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def delete_post
|
||||||
|
post = Post.find(params[:id])
|
||||||
|
current_user.retract(post)
|
||||||
|
mark_as_reviewed
|
||||||
|
flash[:notice] = I18n.t 'report.status.destroyed'
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_comment
|
||||||
|
comment = Comment.find(params[:id])
|
||||||
|
#current_user.retract(comment)
|
||||||
|
comment.destroy
|
||||||
|
mark_as_reviewed
|
||||||
|
flash[:notice] = I18n.t 'report.status.destroyed'
|
||||||
|
end
|
||||||
|
|
||||||
|
def mark_as_reviewed
|
||||||
|
posts = Report.where("post_id = ? AND post_type = ?", params[:id], params[:type])
|
||||||
|
posts.each do |post|
|
||||||
|
post.update_attributes(reviewed: true)
|
||||||
|
end
|
||||||
|
flash[:notice] = I18n.t 'report.status.marked'
|
||||||
|
end
|
||||||
|
end
|
||||||
13
app/helpers/report_helper.rb
Normal file
13
app/helpers/report_helper.rb
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Copyright (c) 2012, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
module ReportHelper
|
||||||
|
def report_content(id, type)
|
||||||
|
if type.eql? "post"
|
||||||
|
raw t('report.post_label', title: link_to(post_page_title(Post.find_by_id(id)), post_path(id)))
|
||||||
|
elsif type.eql? "comment"
|
||||||
|
raw t('report.comment_label', data: comment_message(Comment.find_by_id(id)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
class PostReportMailer < ActionMailer::Base
|
|
||||||
default :from => AppConfig.mail.sender_address
|
|
||||||
|
|
||||||
def new_report
|
|
||||||
Role.admins.each do |role|
|
|
||||||
email = User.find_by_id(role.person_id).email
|
|
||||||
format(email).deliver
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def format(email)
|
|
||||||
mail(to: email, subject: I18n.t('notifier.post_report_email.subject')) do |format|
|
|
||||||
format.text { render 'post_report/post_report_email' }
|
|
||||||
format.html { render 'post_report/post_report_email' }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
26
app/mailers/report_mailer.rb
Normal file
26
app/mailers/report_mailer.rb
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
class ReportMailer < ActionMailer::Base
|
||||||
|
default :from => AppConfig.mail.sender_address
|
||||||
|
|
||||||
|
def new_report(type, id)
|
||||||
|
url = AppConfig.pod_uri.to_s
|
||||||
|
url << report_index_path
|
||||||
|
resource = Hash[
|
||||||
|
:subject => I18n.t('notifier.report_email.subject', :type => type),
|
||||||
|
:url => url,
|
||||||
|
:type => type,
|
||||||
|
:id => id
|
||||||
|
]
|
||||||
|
Role.admins.each do |role|
|
||||||
|
resource[:email] = User.find_by_id(role.person_id).email
|
||||||
|
format(resource).deliver
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def format(resource)
|
||||||
|
mail(to: resource[:email], subject: resource[:subject]) do |format|
|
||||||
|
format.html { render 'report/report_email', :locals => { :resource => resource } }
|
||||||
|
format.text { render 'report/report_email', :locals => { :resource => resource } }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
class PostReport < ActiveRecord::Base
|
class Report < ActiveRecord::Base
|
||||||
validates :user_id, presence: true
|
validates :user_id, presence: true
|
||||||
validates :post_id, presence: true
|
validates :post_id, presence: true
|
||||||
|
validates :post_type, presence: true
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :post
|
belongs_to :post
|
||||||
|
|
||||||
has_many :post_reports
|
has_many :reports
|
||||||
|
|
||||||
after_create :send_report_notification
|
after_create :send_report_notification
|
||||||
|
|
||||||
def send_report_notification
|
def send_report_notification
|
||||||
Workers::Mail::PostReportWorker.perform_async
|
Workers::Mail::ReportWorker.perform_async(self.post_type, self.post_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
%li= link_to t('.user_search'), user_search_path
|
%li= link_to t('.user_search'), user_search_path
|
||||||
%li= link_to t('.weekly_user_stats'), weekly_user_stats_path
|
%li= link_to t('.weekly_user_stats'), weekly_user_stats_path
|
||||||
%li= link_to t('.pod_stats'), pod_stats_path
|
%li= link_to t('.pod_stats'), pod_stats_path
|
||||||
%li= link_to t('.post_report'), post_report_index_path
|
%li= link_to t('.report'), report_index_path
|
||||||
%li= link_to t('.correlations'), correlations_path
|
%li= link_to t('.correlations'), correlations_path
|
||||||
%li= link_to t('.sidekiq_monitor'), sidekiq_path
|
%li= link_to t('.sidekiq_monitor'), sidekiq_path
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
.span-24
|
|
||||||
= render :partial => 'admins/admin_bar'
|
|
||||||
|
|
||||||
.span-24.last
|
|
||||||
%h1
|
|
||||||
= t('post_report.title')
|
|
||||||
%div#post_report
|
|
||||||
- @post_report.each do |report|
|
|
||||||
%div.content
|
|
||||||
%span
|
|
||||||
= raw t('post_report.post_label', title: link_to(post_page_title(Post.find_by_id(report.post_id)), post_path(report.post_id)))
|
|
||||||
%span
|
|
||||||
= raw t('post_report.reported_label', person: link_to(report.user_id, user_profile_path(report.user_id)))
|
|
||||||
%span
|
|
||||||
= t('post_report.reason_label', text: report.text)
|
|
||||||
%div.options
|
|
||||||
%span
|
|
||||||
= link_to t('post_report.review_link'), post_report_path(report.post_id), method: :put
|
|
||||||
%span
|
|
||||||
= link_to t('post_report.delete_link'), post_report_path(report.post_id), method: :delete
|
|
||||||
%div.clear
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
<%= t('notifier.post_report_email.body') %>
|
|
||||||
|
|
||||||
21
app/views/report/index.html.haml
Normal file
21
app/views/report/index.html.haml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
.span-24
|
||||||
|
= render :partial => 'admins/admin_bar'
|
||||||
|
|
||||||
|
.span-24.last
|
||||||
|
%h1
|
||||||
|
= t('report.title')
|
||||||
|
%div#report
|
||||||
|
- @report.each do |r|
|
||||||
|
%div.content
|
||||||
|
%span
|
||||||
|
= report_content(r.post_id, r.post_type)
|
||||||
|
%span
|
||||||
|
= raw t('report.reported_label', person: link_to(r.user_id, user_profile_path(r.user_id)))
|
||||||
|
%span
|
||||||
|
= t('report.reason_label', text: r.text)
|
||||||
|
%div.options
|
||||||
|
%span
|
||||||
|
= link_to t('report.review_link'), report_path(r.post_id, :type => r.post_type), method: :put
|
||||||
|
%span
|
||||||
|
= link_to t('report.delete_link'), report_path(r.post_id, :type => r.post_type), method: :delete
|
||||||
|
%div.clear
|
||||||
2
app/views/report/report_email.markerb
Normal file
2
app/views/report/report_email.markerb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
<%= t('notifier.report_email.body', url: resource[:url], type: resource[:type], id: resource[:id]) %>
|
||||||
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
module Workers
|
|
||||||
module Mail
|
|
||||||
class PostReportWorker < Base
|
|
||||||
sidekiq_options queue: :mail
|
|
||||||
|
|
||||||
def perform
|
|
||||||
PostReportMailer.new_report
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
12
app/workers/mail/report_worker.rb
Normal file
12
app/workers/mail/report_worker.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
module Workers
|
||||||
|
module Mail
|
||||||
|
class ReportWorker < Base
|
||||||
|
sidekiq_options queue: :mail
|
||||||
|
|
||||||
|
def perform(type, id)
|
||||||
|
ReportMailer.new_report(type, id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ en:
|
||||||
user_search: "User Search"
|
user_search: "User Search"
|
||||||
weekly_user_stats: "Weekly User Stats"
|
weekly_user_stats: "Weekly User Stats"
|
||||||
pod_stats: "Pod Stats"
|
pod_stats: "Pod Stats"
|
||||||
post_report: "Reported Posts"
|
report: "Reports"
|
||||||
correlations: "Correlations"
|
correlations: "Correlations"
|
||||||
sidekiq_monitor: "Sidekiq monitor"
|
sidekiq_monitor: "Sidekiq monitor"
|
||||||
correlations:
|
correlations:
|
||||||
|
|
@ -736,9 +736,23 @@ en:
|
||||||
confirm_email:
|
confirm_email:
|
||||||
subject: "Please activate your new email address %{unconfirmed_email}"
|
subject: "Please activate your new email address %{unconfirmed_email}"
|
||||||
click_link: "To activate your new email address %{unconfirmed_email}, please follow this link:"
|
click_link: "To activate your new email address %{unconfirmed_email}, please follow this link:"
|
||||||
post_report_email:
|
report_email:
|
||||||
subject: "A new post was marked as offensive"
|
subject: "A new %{type} was marked as offensive"
|
||||||
body: "Please review as soon as possible!"
|
body: |-
|
||||||
|
Hello,
|
||||||
|
|
||||||
|
the %{type} with ID %{id} was marked as offensive.
|
||||||
|
|
||||||
|
[%{url}][1]
|
||||||
|
|
||||||
|
Please review as soon as possible!
|
||||||
|
|
||||||
|
|
||||||
|
Cheers,
|
||||||
|
|
||||||
|
The diaspora* email robot!
|
||||||
|
|
||||||
|
[1]: %{url}
|
||||||
accept_invite: "Accept Your diaspora* invite!"
|
accept_invite: "Accept Your diaspora* invite!"
|
||||||
invited_you: "%{name} invited you to diaspora*"
|
invited_you: "%{name} invited you to diaspora*"
|
||||||
invite:
|
invite:
|
||||||
|
|
@ -868,9 +882,10 @@ en:
|
||||||
other: "%{count} photos by %{author}"
|
other: "%{count} photos by %{author}"
|
||||||
reshare_by: "Reshare by %{author}"
|
reshare_by: "Reshare by %{author}"
|
||||||
|
|
||||||
post_report:
|
report:
|
||||||
title: "Marked Reports Overview"
|
title: "Reports Overview"
|
||||||
post_label: "<b>Post</b>: %{title}"
|
post_label: "<b>Post</b>: %{title}"
|
||||||
|
comment_label: "<b>Comment</b>:<br>%{data}"
|
||||||
reported_label: "<b>Reported by</b> %{person}"
|
reported_label: "<b>Reported by</b> %{person}"
|
||||||
reason_label: "Reason: %{text}"
|
reason_label: "Reason: %{text}"
|
||||||
review_link: "Mark as reviewed"
|
review_link: "Mark as reviewed"
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@
|
||||||
en:
|
en:
|
||||||
javascripts:
|
javascripts:
|
||||||
confirm_dialog: "Are you sure?"
|
confirm_dialog: "Are you sure?"
|
||||||
post_report_prompt: "Please enter a reason:"
|
report_prompt: "Please enter a reason:"
|
||||||
post_report_prompt_default: "offensive content"
|
report_prompt_default: "offensive content"
|
||||||
delete: "Delete"
|
delete: "Delete"
|
||||||
ignore: "Ignore"
|
ignore: "Ignore"
|
||||||
post_report: "Report"
|
report: "Report"
|
||||||
ignore_user: "Ignore this user?"
|
ignore_user: "Ignore this user?"
|
||||||
and: "and"
|
and: "and"
|
||||||
comma: ","
|
comma: ","
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
require 'sidekiq/web'
|
require 'sidekiq/web'
|
||||||
|
|
||||||
Diaspora::Application.routes.draw do
|
Diaspora::Application.routes.draw do
|
||||||
resources :post_report, :except => [:edit]
|
resources :report, :except => [:edit, :new]
|
||||||
|
|
||||||
if Rails.env.production?
|
if Rails.env.production?
|
||||||
mount RailsAdmin::Engine => '/admin_panel', :as => 'rails_admin'
|
mount RailsAdmin::Engine => '/admin_panel', :as => 'rails_admin'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddPostTypeToPostReport < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :post_reports, :post_type, :string, :null => false, :after => :post_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
class RenamePostReportToReport < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
rename_table :post_reports, :reports
|
||||||
|
end
|
||||||
|
def self.down
|
||||||
|
rename_table :reports, :post_reports
|
||||||
|
end
|
||||||
|
end
|
||||||
12
db/schema.rb
12
db/schema.rb
|
|
@ -410,6 +410,18 @@ ActiveRecord::Schema.define(:version => 20140308154022) do
|
||||||
|
|
||||||
add_index "rails_admin_histories", ["item", "table", "month", "year"], :name => "index_rails_admin_histories"
|
add_index "rails_admin_histories", ["item", "table", "month", "year"], :name => "index_rails_admin_histories"
|
||||||
|
|
||||||
|
create_table "reports", :force => true do |t|
|
||||||
|
t.integer "post_id", :null => false
|
||||||
|
t.string "post_type", :null => false
|
||||||
|
t.string "user_id"
|
||||||
|
t.boolean "reviewed", :default => false
|
||||||
|
t.text "text"
|
||||||
|
t.datetime "created_at", :null => false
|
||||||
|
t.datetime "updated_at", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "reports", ["post_id"], :name => "index_post_reports_on_post_id"
|
||||||
|
|
||||||
create_table "roles", :force => true do |t|
|
create_table "roles", :force => true do |t|
|
||||||
t.integer "person_id"
|
t.integer "person_id"
|
||||||
t.string "name"
|
t.string "name"
|
||||||
|
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe PostReportController do
|
|
||||||
before do
|
|
||||||
sign_in alice
|
|
||||||
@message = alice.post(:status_message, :text => "hey", :to => alice.aspects.first.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#index' do
|
|
||||||
context 'admin not signed in' do
|
|
||||||
it 'is behind redirect_unless_admin' do
|
|
||||||
get :index
|
|
||||||
response.should redirect_to stream_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'admin signed in' do
|
|
||||||
before do
|
|
||||||
Role.add_admin(alice.person)
|
|
||||||
end
|
|
||||||
it 'succeeds and renders index' do
|
|
||||||
get :index
|
|
||||||
response.should render_template('index')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#create' do
|
|
||||||
context 'report offensive content' do
|
|
||||||
it 'succeeds' do
|
|
||||||
put :create, :post_id => @message.id, :text => 'offensive content'
|
|
||||||
response.status.should == 200
|
|
||||||
PostReport.exists?(:post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#update' do
|
|
||||||
context 'mark report as user' do
|
|
||||||
it 'is behind redirect_unless_admin' do
|
|
||||||
put :update, :id => @message.id
|
|
||||||
response.should redirect_to stream_path
|
|
||||||
PostReport.where(:reviewed => false, :post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'mark report as admin' do
|
|
||||||
before do
|
|
||||||
Role.add_admin(alice.person)
|
|
||||||
end
|
|
||||||
it 'succeeds' do
|
|
||||||
put :update, :id => @message.id
|
|
||||||
response.status.should == 302
|
|
||||||
PostReport.where(:reviewed => true, :post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#destroy' do
|
|
||||||
context 'destroy post as user' do
|
|
||||||
it 'is behind redirect_unless_admin' do
|
|
||||||
delete :destroy, :id => @message.id
|
|
||||||
response.should redirect_to stream_path
|
|
||||||
PostReport.where(:reviewed => false, :post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'destroy post as admin' do
|
|
||||||
before do
|
|
||||||
Role.add_admin(alice.person)
|
|
||||||
end
|
|
||||||
it 'succeeds' do
|
|
||||||
delete :destroy, :id => @message.id
|
|
||||||
response.status.should == 302
|
|
||||||
PostReport.where(:reviewed => true, :post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
126
spec/controllers/report_controller_spec.rb
Normal file
126
spec/controllers/report_controller_spec.rb
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe ReportController do
|
||||||
|
before do
|
||||||
|
sign_in alice
|
||||||
|
@message = alice.post(:status_message, :text => "hey", :to => alice.aspects.first.id)
|
||||||
|
@comment = alice.comment!(@message, "flying pigs, everywhere")
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#index' do
|
||||||
|
context 'admin not signed in' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
get :index
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'admin signed in' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds and renders index' do
|
||||||
|
get :index
|
||||||
|
response.should render_template('index')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#create' do
|
||||||
|
let(:comment_hash) {
|
||||||
|
{:text =>"facebook, is that you?",
|
||||||
|
:post_id =>"#{@post.id}"}
|
||||||
|
}
|
||||||
|
|
||||||
|
context 'report offensive post' do
|
||||||
|
it 'succeeds' do
|
||||||
|
put :create, :id => @message.id, :type => 'post', :text => 'offensive content'
|
||||||
|
response.status.should == 200
|
||||||
|
Report.exists?(:post_id => @message.id, :post_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'report offensive comment' do
|
||||||
|
it 'succeeds' do
|
||||||
|
put :create, :id => @comment.id, :type => 'comment', :text => 'offensive content'
|
||||||
|
response.status.should == 200
|
||||||
|
Report.exists?(:post_id => @comment.id, :post_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#update' do
|
||||||
|
context 'mark post report as user' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
put :update, :id => @message.id, :type => 'post'
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
Report.where(:reviewed => false, :post_id => @message.id, :post_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'mark comment report as user' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
put :update, :id => @comment.id, :type => 'comment'
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
Report.where(:reviewed => false, :post_id => @comment.id, :post_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'mark post report as admin' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds' do
|
||||||
|
put :update, :id => @message.id, :type => 'post'
|
||||||
|
response.status.should == 302
|
||||||
|
Report.where(:reviewed => true, :post_id => @message.id, :post_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'mark comment report as admin' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds' do
|
||||||
|
put :update, :id => @comment.id, :type => 'comment'
|
||||||
|
response.status.should == 302
|
||||||
|
Report.where(:reviewed => true, :post_id => @comment.id, :post_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#destroy' do
|
||||||
|
context 'destroy post as user' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
delete :destroy, :id => @message.id, :type => 'post'
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
Report.where(:reviewed => false, :post_id => @message.id, :post_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'destroy comment as user' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
delete :destroy, :id => @comment.id, :type => 'comment'
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
Report.where(:reviewed => false, :post_id => @comment.id, :post_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'destroy post as admin' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds' do
|
||||||
|
delete :destroy, :id => @message.id, :type => 'post'
|
||||||
|
response.status.should == 302
|
||||||
|
Report.where(:reviewed => true, :post_id => @message.id, :post_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'destroy comment as admin' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds' do
|
||||||
|
delete :destroy, :id => @comment.id, :type => 'comment'
|
||||||
|
response.status.should == 302
|
||||||
|
Report.where(:reviewed => true, :post_id => @comment.id, :post_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue