diff --git a/Changelog.md b/Changelog.md
index d842663db..1d886ee17 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -49,7 +49,7 @@ Read more in [#4249](https://github.com/diaspora/diaspora/pull/4249) and [#4883]
* Redirect to the stream when switching the mobile publisher to desktop [#4806](https://github.com/diaspora/diaspora/issues/4806)
## Features
-* You can report a single post by clicking the correct icon in the controler section [#4517](https://github.com/diaspora/diaspora/pull/4517)
+* You can report a single post or comment by clicking the correct icon in the controler section [#4517](https://github.com/diaspora/diaspora/pull/4517) [#4781](https://github.com/diaspora/diaspora/pull/4781)
* Add permalinks for comments [#4577](https://github.com/diaspora/diaspora/pull/4577)
* New menu for the mobile version [#4673](https://github.com/diaspora/diaspora/pull/4673)
* Added comment count to statistic to enable calculations of posts/comments ratios [#4799](https://github.com/diaspora/diaspora/pull/4799)
diff --git a/app/assets/images/icons/postreport.png b/app/assets/images/icons/report.png
similarity index 100%
rename from app/assets/images/icons/postreport.png
rename to app/assets/images/icons/report.png
diff --git a/app/assets/javascripts/app/models/post_report.js b/app/assets/javascripts/app/models/post_report.js
deleted file mode 100644
index 7a9705bb5..000000000
--- a/app/assets/javascripts/app/models/post_report.js
+++ /dev/null
@@ -1,3 +0,0 @@
-app.models.PostReport = Backbone.Model.extend({
- urlRoot: '/post_report'
-});
diff --git a/app/assets/javascripts/app/models/report.js b/app/assets/javascripts/app/models/report.js
new file mode 100644
index 000000000..d2d734221
--- /dev/null
+++ b/app/assets/javascripts/app/models/report.js
@@ -0,0 +1,4 @@
+app.models.Report = Backbone.Model.extend({
+ urlRoot: '/report',
+ type: 'POST'
+});
diff --git a/app/assets/javascripts/app/views.js b/app/assets/javascripts/app/views.js
index f5c17c0f9..78baa19b7 100644
--- a/app/assets/javascripts/app/views.js
+++ b/app/assets/javascripts/app/views.js
@@ -81,6 +81,37 @@ app.views.Base = Backbone.View.extend({
}
},
+ report: function(evt) {
+ if(evt) { evt.preventDefault(); }
+ var msg = prompt(Diaspora.I18n.t('report.prompt'), Diaspora.I18n.t('report.prompt_default'));
+ if (msg == null) {
+ return;
+ }
+ var data = {
+ report: {
+ item_id: this.model.id,
+ item_type: $(evt.currentTarget).data("type"),
+ text: msg
+ }
+ };
+
+ var report = new app.models.Report();
+ report.save(data, {
+ success: function(model, response) {
+ Diaspora.page.flashMessages.render({
+ success: true,
+ notice: Diaspora.I18n.t('report.status.created')
+ });
+ },
+ error: function(model, response) {
+ Diaspora.page.flashMessages.render({
+ success: false,
+ notice: Diaspora.I18n.t('report.status.exists')
+ });
+ }
+ });
+ },
+
destroyModel: function(evt) {
evt && evt.preventDefault();
var self = this;
@@ -114,4 +145,4 @@ app.views.StaticContentView = app.views.Base.extend({
presenter : function(){
return this.data;
},
-});
\ No newline at end of file
+});
diff --git a/app/assets/javascripts/app/views/comment_view.js b/app/assets/javascripts/app/views/comment_view.js
index 8ed7ff48a..540c54b99 100644
--- a/app/assets/javascripts/app/views/comment_view.js
+++ b/app/assets/javascripts/app/views/comment_view.js
@@ -5,7 +5,8 @@ app.views.Comment = app.views.Content.extend({
events : function() {
return _.extend({}, app.views.Content.prototype.events, {
- "click .comment_delete": "destroyModel"
+ "click .comment_delete": "destroyModel",
+ "click .comment_report": "report"
});
},
diff --git a/app/assets/javascripts/app/views/feedback_view.js b/app/assets/javascripts/app/views/feedback_view.js
index d7f84a653..41e957c89 100644
--- a/app/assets/javascripts/app/views/feedback_view.js
+++ b/app/assets/javascripts/app/views/feedback_view.js
@@ -6,7 +6,8 @@ app.views.Feedback = app.views.Base.extend({
events: {
"click *[rel='auth-required']" : "requireAuth",
"click .like" : "toggleLike",
- "click .reshare" : "resharePost"
+ "click .reshare" : "resharePost",
+ "click .post_report" : "report"
},
tooltipSelector : ".label",
diff --git a/app/assets/javascripts/app/views/stream_post_views.js b/app/assets/javascripts/app/views/stream_post_views.js
index fb1d846d4..ef557362d 100644
--- a/app/assets/javascripts/app/views/stream_post_views.js
+++ b/app/assets/javascripts/app/views/stream_post_views.js
@@ -20,7 +20,7 @@ app.views.StreamPost = app.views.Post.extend({
"click .remove_post": "destroyModel",
"click .hide_post": "hidePost",
- "click .post_report": "postReport",
+ "click .post_report": "report",
"click .block_user": "blockUser"
},
@@ -108,21 +108,6 @@ app.views.StreamPost = app.views.Post.extend({
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){
evt.preventDefault();
this.$(".new_comment_form_wrapper").removeClass("hidden");
diff --git a/app/assets/stylesheets/application.css.sass b/app/assets/stylesheets/application.css.sass
index 96184c315..52199d047 100644
--- a/app/assets/stylesheets/application.css.sass
+++ b/app/assets/stylesheets/application.css.sass
@@ -17,8 +17,8 @@
@import 'facebox'
@import 'aspects'
@import 'popover'
-@import 'post_report'
@import 'stream_element'
+@import 'report'
/* ====== media ====== */
.media
@@ -211,10 +211,10 @@ ul.as-selections
:z-index 6
:float right
- .post_report
+ .post_report, .comment_report
:display inline-block
- .icons-postreport
+ .icons-report
:height 14px
:width 14px
diff --git a/app/assets/stylesheets/post_report.css.scss b/app/assets/stylesheets/report.css.scss
similarity index 56%
rename from app/assets/stylesheets/post_report.css.scss
rename to app/assets/stylesheets/report.css.scss
index ba865f9da..2ee1789e7 100644
--- a/app/assets/stylesheets/post_report.css.scss
+++ b/app/assets/stylesheets/report.css.scss
@@ -1,16 +1,18 @@
-#post_report {
+#reports {
padding-top: 2em;
- span {
- display: block;
- }
.content {
float: left;
+ span {
+ display: block;
+ }
}
.options {
float: right;
}
.clear {
clear: both;
+ border-bottom: 1px solid #808080;
padding-bottom: 1em;
+ margin-bottom: 1em;
}
}
diff --git a/app/assets/stylesheets/single-post-view.css.scss b/app/assets/stylesheets/single-post-view.css.scss
index 2fd30c888..cf6ffa3d6 100644
--- a/app/assets/stylesheets/single-post-view.css.scss
+++ b/app/assets/stylesheets/single-post-view.css.scss
@@ -61,6 +61,9 @@
i.comment:hover {
color: #424242;
}
+ .post_report i.gray:hover {
+ color: $red;
+ }
i.heart.gray:hover {
color: $red;
}
@@ -204,6 +207,13 @@
&:hover {
@include opacity(1);
}
+ .comment_report {
+ display: inline-block;
+ .icons-report {
+ height: 14px;
+ width: 14px;
+ }
+ }
.delete {
display: inline-block;
.icons-deletelabel {
diff --git a/app/assets/stylesheets/stream_element.css.scss b/app/assets/stylesheets/stream_element.css.scss
index ac7f35c66..b7cfe0708 100644
--- a/app/assets/stylesheets/stream_element.css.scss
+++ b/app/assets/stylesheets/stream_element.css.scss
@@ -133,17 +133,17 @@
padding-top: 10px;
.controls {
- .comment_delete {
+ .comment_delete, .comment_report {
@include transition(opacity);
@include opacity(0);
}
}
&:hover {
.controls {
- .comment_delete {
+ .comment_delete, .comment_report {
@include opacity(0.3);
}
- .comment_delete:hover {
+ .comment_delete:hover, .comment_report:hover {
@include opacity(1);
}
}
diff --git a/app/assets/templates/comment_tpl.jst.hbs b/app/assets/templates/comment_tpl.jst.hbs
index e87eb2eeb..5d5c7c1cf 100644
--- a/app/assets/templates/comment_tpl.jst.hbs
+++ b/app/assets/templates/comment_tpl.jst.hbs
@@ -6,13 +6,17 @@
diff --git a/app/assets/templates/stream-element_tpl.jst.hbs b/app/assets/templates/stream-element_tpl.jst.hbs
index 21ed75fd4..9a6952808 100644
--- a/app/assets/templates/stream-element_tpl.jst.hbs
+++ b/app/assets/templates/stream-element_tpl.jst.hbs
@@ -10,8 +10,8 @@
{{#if loggedIn}}
{{#unless authorIsCurrentUser}}
-
-
+
+
diff --git a/app/controllers/post_report_controller.rb b/app/controllers/post_report_controller.rb
deleted file mode 100644
index cd8dba827..000000000
--- a/app/controllers/post_report_controller.rb
+++ /dev/null
@@ -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
diff --git a/app/controllers/report_controller.rb b/app/controllers/report_controller.rb
new file mode 100644
index 000000000..64022d988
--- /dev/null
+++ b/app/controllers/report_controller.rb
@@ -0,0 +1,42 @@
+# Copyright (c) 2010-2011, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+class ReportController < ApplicationController
+ before_filter :authenticate_user!
+ before_filter :redirect_unless_admin, :except => [:create]
+
+ def index
+ @reports = Report.where(reviewed: false).all
+ end
+
+ def update
+ if report = Report.where(id: params[:id]).first
+ report.mark_as_reviewed
+ end
+ redirect_to :action => :index
+ end
+
+ def destroy
+ if (report = Report.where(id: params[:id]).first) && report.destroy_reported_item
+ flash[:notice] = I18n.t 'report.status.destroyed'
+ else
+ flash[:error] = I18n.t 'report.status.failed'
+ end
+ redirect_to :action => :index
+ end
+
+ def create
+ report = current_user.reports.new(report_params)
+ if report.save
+ render :json => true, :status => 200
+ else
+ render :nothing => true, :status => 409
+ end
+ end
+
+ private
+ def report_params
+ params.require(:report).permit(:item_id, :item_type, :text)
+ end
+end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 886b905b1..b893621c5 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -179,6 +179,7 @@ class UsersController < ApplicationController
:remember_me,
:getting_started,
email_preferences: [
+ :someone_reported,
:also_commented,
:mentioned,
:comment_on_post,
diff --git a/app/helpers/report_helper.rb b/app/helpers/report_helper.rb
new file mode 100644
index 000000000..370981314
--- /dev/null
+++ b/app/helpers/report_helper.rb
@@ -0,0 +1,16 @@
+# 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)
+ raw case type
+ when 'post'
+ t('report.post_label', title: link_to(post_page_title(Post.find_by_id(id)), post_path(id)))
+ when 'comment'
+ # comment_message is not html_safe. To prevent
+ # cross-site-scripting we have to escape html
+ t('report.comment_label', data: h(comment_message(Comment.find_by_id(id))))
+ end
+ end
+end
diff --git a/app/mailers/post_report_mailer.rb b/app/mailers/post_report_mailer.rb
deleted file mode 100644
index 46b6737cc..000000000
--- a/app/mailers/post_report_mailer.rb
+++ /dev/null
@@ -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
diff --git a/app/mailers/report_mailer.rb b/app/mailers/report_mailer.rb
new file mode 100644
index 000000000..5438bd9a7
--- /dev/null
+++ b/app/mailers/report_mailer.rb
@@ -0,0 +1,26 @@
+class ReportMailer < ActionMailer::Base
+ default :from => AppConfig.mail.sender_address
+
+ def new_report(type, id)
+ resource = {
+ :url => report_index_url,
+ :type => I18n.t('notifier.report_email.type.' + type),
+ :id => id
+ }
+ Role.admins.each do |role|
+ user = User.find_by_id(role.person_id)
+ unless user.user_preferences.exists?(:email_type => :someone_reported)
+ resource[:email] = user.email
+ format(resource).deliver
+ end
+ end
+ end
+
+ private
+ def format(resource)
+ mail(to: resource[:email], subject: I18n.t('notifier.report_email.subject', :type => resource[:type])) do |format|
+ format.html { render 'report/report_email', :locals => { :resource => resource } }
+ format.text { render 'report/report_email', :locals => { :resource => resource } }
+ end
+ end
+end
diff --git a/app/models/post_report.rb b/app/models/post_report.rb
deleted file mode 100644
index a521162ad..000000000
--- a/app/models/post_report.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class PostReport < ActiveRecord::Base
- validates :user_id, presence: true
- validates :post_id, presence: true
-
- belongs_to :user
- belongs_to :post
-
- has_many :post_reports
-
- after_create :send_report_notification
-
- def send_report_notification
- Workers::Mail::PostReportWorker.perform_async
- end
-end
diff --git a/app/models/report.rb b/app/models/report.rb
new file mode 100644
index 000000000..6ee562293
--- /dev/null
+++ b/app/models/report.rb
@@ -0,0 +1,60 @@
+class Report < ActiveRecord::Base
+ validates :user_id, presence: true
+ validates :item_id, presence: true
+ validates :item_type, presence: true, :inclusion => { :in => %w(post comment),
+ :message => 'Type should match `post` or `comment`!'}
+ validates :text, presence: true
+
+ validate :entry_does_not_exist, :on => :create
+
+ belongs_to :user
+ belongs_to :post
+ belongs_to :comment
+
+ after_commit :send_report_notification, :on => :create
+
+ def entry_does_not_exist
+ if Report.where(item_id: item_id, item_type: item_type).exists?(user_id: user_id)
+ errors[:base] << 'You cannot report the same post twice.'
+ end
+ end
+
+ def destroy_reported_item
+ if item_type == 'post'
+ delete_post
+ elsif item_type == 'comment'
+ delete_comment
+ end
+ mark_as_reviewed
+ end
+
+ def delete_post
+ if post = Post.where(id: item_id).first
+ if post.author.local?
+ post.author.owner.retract(post)
+ else
+ post.destroy
+ end
+ end
+ end
+
+ def delete_comment
+ if comment = Comment.where(id: item_id).first
+ if comment.author.local?
+ comment.author.owner.retract(comment)
+ elsif comment.parent.author.local?
+ comment.parent.author.owner.retract(comment)
+ else
+ comment.destroy
+ end
+ end
+ end
+
+ def mark_as_reviewed
+ Report.where(item_id: item_id, item_type: item_type).update_all(reviewed: true)
+ end
+
+ def send_report_notification
+ Workers::Mail::ReportWorker.perform_async(self.item_type, self.item_id)
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 0261857f9..2e9168a80 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -69,6 +69,8 @@ class User < ActiveRecord::Base
has_many :notifications, :foreign_key => :recipient_id
+ has_many :reports
+
before_save :guard_unconfirmed_email,
:save_person!
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index cf73c7d58..354a48400 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -4,7 +4,8 @@ class UserPreference < ActiveRecord::Base
validate :must_be_valid_email_type
VALID_EMAIL_TYPES =
- ["mentioned",
+ ["someone_reported",
+ "mentioned",
"comment_on_post",
"private_message",
"started_sharing",
diff --git a/app/views/admins/_admin_bar.haml b/app/views/admins/_admin_bar.haml
index dff8955fa..cb6ac9b34 100644
--- a/app/views/admins/_admin_bar.haml
+++ b/app/views/admins/_admin_bar.haml
@@ -5,7 +5,7 @@
%li= link_to t('.user_search'), user_search_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('.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('.sidekiq_monitor'), sidekiq_path
diff --git a/app/views/post_report/index.html.haml b/app/views/post_report/index.html.haml
deleted file mode 100644
index 538ff39b0..000000000
--- a/app/views/post_report/index.html.haml
+++ /dev/null
@@ -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
diff --git a/app/views/post_report/post_report_email.markerb b/app/views/post_report/post_report_email.markerb
deleted file mode 100644
index fb4b688f1..000000000
--- a/app/views/post_report/post_report_email.markerb
+++ /dev/null
@@ -1,2 +0,0 @@
-<%= t('notifier.post_report_email.body') %>
-
diff --git a/app/views/report/index.html.haml b/app/views/report/index.html.haml
new file mode 100644
index 000000000..b5026c643
--- /dev/null
+++ b/app/views/report/index.html.haml
@@ -0,0 +1,27 @@
+.span-24
+ = render :partial => 'admins/admin_bar'
+
+.span-24.last
+ %h1
+ = t('report.title')
+ %div#reports
+ - @reports.each do |r|
+ - username = User.find_by_id(r.user_id).username
+ %div.content
+ %span
+ = report_content(r.item_id, r.item_type)
+ %span
+ = raw t('report.reported_label', person: link_to(username, user_profile_path(username)))
+ %span
+ = t('report.reason_label', text: r.text)
+ %div.options
+ %span
+ = button_to t('report.review_link'), report_path(r.id, :type => r.item_type),
+ :class => "button",
+ method: :put
+ %span
+ = button_to t('report.delete_link'), report_path(r.id, :type => r.item_type),
+ :data => { :confirm => t('report.confirm_deletion') },
+ :class => "button delete",
+ method: :delete
+ %div.clear
diff --git a/app/views/report/report_email.markerb b/app/views/report/report_email.markerb
new file mode 100644
index 000000000..ba787d56a
--- /dev/null
+++ b/app/views/report/report_email.markerb
@@ -0,0 +1,2 @@
+<%= t('notifier.report_email.body', url: resource[:url], type: resource[:type], id: resource[:id]) %>
+
diff --git a/app/views/users/edit.html.haml b/app/views/users/edit.html.haml
index 88458c021..55af40b83 100644
--- a/app/views/users/edit.html.haml
+++ b/app/views/users/edit.html.haml
@@ -125,11 +125,22 @@
= f.fields_for :email_preferences do |type|
#email_prefs
+ - if current_user.admin?
+ %p.checkbox_select
+ = type.label :someone_reported, t('.someone_reported')
+ = type.check_box :someone_reported, {:checked => @email_prefs['someone_reported']}, false, true
+
+ %br
%p.checkbox_select
= type.label :started_sharing, t('.started_sharing')
= type.check_box :started_sharing, {:checked => @email_prefs['started_sharing']}, false, true
%br
+ %p.checkbox_select
+ = type.label :also_commented, t('.also_commented')
+ = type.check_box :also_commented, {:checked => @email_prefs['also_commented']}, false, true
+ %br
+
%p.checkbox_select
= type.label :mentioned, t('.mentioned')
= type.check_box :mentioned, {:checked => @email_prefs['mentioned']}, false, true
diff --git a/app/views/users/edit.mobile.haml b/app/views/users/edit.mobile.haml
index a08170ed5..a1bbc08d6 100644
--- a/app/views/users/edit.mobile.haml
+++ b/app/views/users/edit.mobile.haml
@@ -113,14 +113,25 @@
= f.fields_for :email_preferences do |type|
#email_prefs
+ - if current_user.admin?
+ %p.checkbox_select
+ = type.label :someone_reported, t('.someone_reported')
+ = type.check_box :someone_reported, {:checked => @email_prefs['someone_reported']}, false, true
+
+ %br
%p.checkbox_select
= type.label :started_sharing, t('.started_sharing')
= type.check_box :started_sharing, {:checked => @email_prefs['started_sharing']}, false, true
%br
%p.checkbox_select
- = type.label :mentioned, t('.mentioned')
- = type.check_box :mentioned, {:checked => @email_prefs['mentioned']}, false, true
+ = type.label :also_commented, t('.also_commented')
+ = type.check_box :also_commented, {:checked => @email_prefs['also_commented']}, false, true
+ %br
+
+ %p.checkbox_select
+ = type.label :mentioned, t('.mentioned')
+ = type.check_box :mentioned, {:checked => @email_prefs['mentioned']}, false, true
%br
%p.checkbox_select
diff --git a/app/workers/mail/post_report_worker.rb b/app/workers/mail/post_report_worker.rb
deleted file mode 100644
index a3f841942..000000000
--- a/app/workers/mail/post_report_worker.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Workers
- module Mail
- class PostReportWorker < Base
- sidekiq_options queue: :mail
-
- def perform
- PostReportMailer.new_report
- end
- end
- end
-end
-
diff --git a/app/workers/mail/report_worker.rb b/app/workers/mail/report_worker.rb
new file mode 100644
index 000000000..92c201dcb
--- /dev/null
+++ b/app/workers/mail/report_worker.rb
@@ -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
+
diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml
index 60dc8c116..5fc467451 100644
--- a/config/locales/diaspora/en.yml
+++ b/config/locales/diaspora/en.yml
@@ -99,7 +99,7 @@ en:
user_search: "User Search"
weekly_user_stats: "Weekly User Stats"
pod_stats: "Pod Stats"
- post_report: "Reported Posts"
+ report: "Reports"
correlations: "Correlations"
sidekiq_monitor: "Sidekiq monitor"
correlations:
@@ -736,9 +736,26 @@ en:
confirm_email:
subject: "Please activate your new email address %{unconfirmed_email}"
click_link: "To activate your new email address %{unconfirmed_email}, please follow this link:"
- post_report_email:
- subject: "A new post was marked as offensive"
- body: "Please review as soon as possible!"
+ report_email:
+ type:
+ post: "post"
+ comment: "comment"
+ subject: "A new %{type} was marked as offensive"
+ 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!"
invited_you: "%{name} invited you to diaspora*"
invite:
@@ -868,13 +885,15 @@ en:
other: "%{count} photos by %{author}"
reshare_by: "Reshare by %{author}"
- post_report:
- title: "Marked Reports Overview"
+ report:
+ title: "Reports Overview"
post_label: "Post: %{title}"
+ comment_label: "Comment:
%{data}"
reported_label: "Reported by %{person}"
reason_label: "Reason: %{text}"
review_link: "Mark as reviewed"
- delete_link: "Delete post"
+ delete_link: "Delete item"
+ confirm_deletion: "Are you sure to delete the item?"
status:
marked: "The report was marked as reviewed"
destroyed: "The post was destroyed"
@@ -1206,6 +1225,7 @@ en:
edit_account: "Edit account"
receive_email_notifications: "Receive email notifications when:"
started_sharing: "someone starts sharing with you"
+ someone_reported: "someone sent a report"
mentioned: "you are mentioned in a post"
liked: "someone likes your post"
reshared: "someone reshares your post"
diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml
index 5a619206e..a9647a999 100644
--- a/config/locales/javascript/javascript.en.yml
+++ b/config/locales/javascript/javascript.en.yml
@@ -6,11 +6,15 @@
en:
javascripts:
confirm_dialog: "Are you sure?"
- post_report_prompt: "Please enter a reason:"
- post_report_prompt_default: "offensive content"
delete: "Delete"
ignore: "Ignore"
- post_report: "Report"
+ report:
+ prompt: "Please enter a reason:"
+ prompt_default: "offensive content"
+ name: "Report"
+ status:
+ created: "The report was successfully created"
+ exists: "The report already exists"
ignore_user: "Ignore this user?"
and: "and"
comma: ","
diff --git a/config/routes.rb b/config/routes.rb
index 39b66432e..dc659bbbb 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -5,7 +5,7 @@
require 'sidekiq/web'
Diaspora::Application.routes.draw do
- resources :post_report, :except => [:edit]
+ resources :report, :except => [:edit, :new]
if Rails.env.production?
mount RailsAdmin::Engine => '/admin_panel', :as => 'rails_admin'
diff --git a/db/migrate/20140121132816_add_post_type_to_post_report.rb b/db/migrate/20140121132816_add_post_type_to_post_report.rb
new file mode 100644
index 000000000..4d6686eea
--- /dev/null
+++ b/db/migrate/20140121132816_add_post_type_to_post_report.rb
@@ -0,0 +1,6 @@
+class AddPostTypeToPostReport < ActiveRecord::Migration
+ def change
+ add_column :post_reports, :post_type, :string, :null => false, :after => :post_id, :default => 'post'
+ change_column_default :post_reports, :post_type, nil
+ end
+end
diff --git a/db/migrate/20140214104217_rename_post_report_to_report.rb b/db/migrate/20140214104217_rename_post_report_to_report.rb
new file mode 100644
index 000000000..2d477491e
--- /dev/null
+++ b/db/migrate/20140214104217_rename_post_report_to_report.rb
@@ -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
diff --git a/db/migrate/20140422134050_rename_post_columns_to_item.rb b/db/migrate/20140422134050_rename_post_columns_to_item.rb
new file mode 100644
index 000000000..4550eacd7
--- /dev/null
+++ b/db/migrate/20140422134050_rename_post_columns_to_item.rb
@@ -0,0 +1,11 @@
+class RenamePostColumnsToItem < ActiveRecord::Migration
+ def up
+ rename_column :reports, :post_id, :item_id
+ rename_column :reports, :post_type, :item_type
+ end
+
+ def down
+ rename_column :reports, :item_id, :post_id
+ rename_column :reports, :item_type, :post_type
+ end
+end
diff --git a/db/migrate/20140422134627_change_user_id_type_to_integer.rb b/db/migrate/20140422134627_change_user_id_type_to_integer.rb
new file mode 100644
index 000000000..1f4918e8b
--- /dev/null
+++ b/db/migrate/20140422134627_change_user_id_type_to_integer.rb
@@ -0,0 +1,12 @@
+class ChangeUserIdTypeToInteger < ActiveRecord::Migration
+ def up
+ remove_column :reports, :user_id
+ add_column :reports, :user_id, :integer, :null => false, :default => 1
+ change_column_default :reports, :user_id, nil
+ end
+
+ def down
+ remove_column :reports, :user_id
+ add_column :reports, :user_id, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 97f7cb6c2..8ae07e086 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20140308154022) do
+ActiveRecord::Schema.define(:version => 20140422134627) do
create_table "account_deletions", :force => true do |t|
t.string "diaspora_handle"
@@ -316,17 +316,6 @@ ActiveRecord::Schema.define(:version => 20140308154022) do
add_index "polls", ["status_message_id"], :name => "index_polls_on_status_message_id"
- create_table "post_reports", :force => true do |t|
- t.integer "post_id", :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 "post_reports", ["post_id"], :name => "index_post_reports_on_post_id"
-
create_table "posts", :force => true do |t|
t.integer "author_id", :null => false
t.boolean "public", :default => false, :null => false
@@ -410,6 +399,18 @@ ActiveRecord::Schema.define(:version => 20140308154022) do
add_index "rails_admin_histories", ["item", "table", "month", "year"], :name => "index_rails_admin_histories"
+ create_table "reports", :force => true do |t|
+ t.integer "item_id", :null => false
+ t.string "item_type", :null => false
+ t.boolean "reviewed", :default => false
+ t.text "text"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.integer "user_id", :null => false
+ end
+
+ add_index "reports", ["item_id"], :name => "index_post_reports_on_post_id"
+
create_table "roles", :force => true do |t|
t.integer "person_id"
t.string "name"
diff --git a/lib/account_deleter.rb b/lib/account_deleter.rb
index da2d7ba9e..314201f92 100644
--- a/lib/account_deleter.rb
+++ b/lib/account_deleter.rb
@@ -50,7 +50,7 @@ class AccountDeleter
end
def ignored_ar_user_associations
- [:followed_tags, :invited_by, :contact_people, :aspect_memberships, :ignored_people, :conversation_visibilities, :conversations]
+ [:followed_tags, :invited_by, :contact_people, :aspect_memberships, :ignored_people, :conversation_visibilities, :conversations, :reports]
end
def delete_standard_user_associations
diff --git a/spec/controllers/post_report_controller_spec.rb b/spec/controllers/post_report_controller_spec.rb
deleted file mode 100644
index 513e19164..000000000
--- a/spec/controllers/post_report_controller_spec.rb
+++ /dev/null
@@ -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
diff --git a/spec/controllers/report_controller_spec.rb b/spec/controllers/report_controller_spec.rb
new file mode 100644
index 000000000..9c48503c0
--- /dev/null
+++ b/spec/controllers/report_controller_spec.rb
@@ -0,0 +1,130 @@
+# Copyright (c) 2010-2011, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+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?",
+ :item_id =>"#{@post.id}"}
+ }
+
+ context 'report offensive post' do
+ it 'succeeds' do
+ put :create, :report => { :item_id => @message.id, :item_type => 'post', :text => 'offensive content' }
+ response.status.should == 200
+ Report.exists?(:item_id => @message.id, :item_type => 'post').should be_true
+ end
+ end
+ context 'report offensive comment' do
+ it 'succeeds' do
+ put :create, :report => { :item_id => @comment.id, :item_type => 'comment', :text => 'offensive content' }
+ response.status.should == 200
+ Report.exists?(:item_id => @comment.id, :item_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, :item_id => @message.id, :item_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, :item_id => @comment.id, :item_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, :item_id => @message.id, :item_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, :item_id => @comment.id, :item_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, :item_id => @message.id, :item_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, :item_id => @comment.id, :item_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, :item_id => @message.id, :item_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, :item_id => @comment.id, :item_type => 'comment').should be_true
+ end
+ end
+ end
+end
diff --git a/spec/mailers/report_spec.rb b/spec/mailers/report_spec.rb
new file mode 100644
index 000000000..e5d1b1608
--- /dev/null
+++ b/spec/mailers/report_spec.rb
@@ -0,0 +1,26 @@
+# Copyright (c) 2010-2011, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe Report do
+ describe '#make_notification' do
+ before do
+ @user = bob
+ Role.add_admin(@user)
+ end
+
+ it "should deliver successfully" do
+ expect {
+ ReportMailer.new_report('post', 666)
+ }.to_not raise_error
+ end
+
+ it "should be added to the delivery queue" do
+ expect {
+ ReportMailer.new_report('post', 666)
+ }.to change(ActionMailer::Base.deliveries, :size).by(1)
+ end
+ end
+end
diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb
new file mode 100644
index 000000000..82d5d8603
--- /dev/null
+++ b/spec/models/report_spec.rb
@@ -0,0 +1,79 @@
+# Copyright (c) 2010-2011, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe Report do
+ before do
+ #:report => { :item_id => @message.id, :item_type => 'post', :text => 'offensive content' }
+ @user = bob
+ @bob_post = @user.post(:status_message, :text => "hello", :to => @user.aspects.first.id)
+ @bob_comment = @user.comment!(@bob_post, "welcome")
+
+ @valid_post_report = {
+ :item_id => @bob_post.id,
+ :item_type => 'post',
+ :text => 'offensive content'
+ }
+ @valid_comment_report = {
+ :item_id => @bob_comment.id,
+ :item_type => 'comment',
+ :text => 'offensive content'
+ }
+ end
+
+ describe '#validation' do
+ it 'validates that post ID is required' do
+ @user.reports.build(:item_type => 'post', :text => 'blub').should_not be_valid
+ end
+
+ it 'validates that post type is required' do
+ @user.reports.build(:item_id => 666, :text => 'blub').should_not be_valid
+ end
+
+ it 'validates that entry does not exist' do
+ @user.reports.build(@valid_post_report).should be_valid
+ end
+
+ it 'validates that entry does exist' do
+ @user.reports.create(@valid_post_report)
+ @user.reports.build(@valid_post_report).should_not be_valid
+ end
+ end
+
+ describe '#destroy_reported_item' do
+ before(:each) do
+ @post_report = @user.reports.create(@valid_post_report)
+ @comment_report = @user.reports.create(@valid_comment_report)
+ end
+
+ describe '.post' do
+ it 'should destroy it' do
+ expect {
+ @post_report.destroy_reported_item
+ }.to change { Post.count }.by(-1)
+ end
+
+ it 'should be marked' do
+ expect {
+ @post_report.destroy_reported_item
+ }.to change { Report.where(@valid_post_report).first.reviewed }.to(true).from(false)
+ end
+ end
+
+ describe '.comment' do
+ it 'should destroy it' do
+ expect {
+ @comment_report.destroy_reported_item
+ }.to change { Comment.count }.by(-1)
+ end
+
+ it 'should be marked' do
+ expect {
+ @comment_report.destroy_reported_item
+ }.to change { Report.where(@valid_comment_report).first.reviewed }.to(true).from(false)
+ end
+ end
+ end
+end