From 4cef0e45c2b143064d455e1a0a8e87c576a5c87c Mon Sep 17 00:00:00 2001 From: BrokenEagle Date: Sat, 18 Jan 2020 05:34:46 +0000 Subject: [PATCH] Create the ability to send reports to moderators - Limited to Builders+ -- Moderator+ can also use as they may be too busy ATM - Only on users, comments, and forum posts - Multiple reports can be generated per instance - Primarily posts to a moderator-only topic for viewability - Secondarily has a table for searchability -- Viewable only by moderators --- .../moderation_reports_controller.rb | 49 ++++++++++++++ app/models/comment.rb | 5 ++ app/models/forum_post.rb | 5 ++ app/models/moderation_report.rb | 57 +++++++++++++++++ app/models/user.rb | 5 ++ .../comments/partials/show/_comment.html.erb | 3 + app/views/forum_posts/_forum_post.html.erb | 3 + app/views/moderation_reports/_new.html.erb | 14 ++++ app/views/moderation_reports/create.js.erb | 1 + app/views/moderation_reports/index.html.erb | 27 ++++++++ app/views/moderation_reports/new.js.erb | 1 + app/views/static/site_map.html.erb | 1 + app/views/users/_secondary_links.html.erb | 3 + config/danbooru_default_config.rb | 4 ++ config/routes.rb | 1 + ...0200117220602_create_moderation_reports.rb | 12 ++++ db/structure.sql | 64 +++++++++++++++++++ 17 files changed, 255 insertions(+) create mode 100644 app/controllers/moderation_reports_controller.rb create mode 100644 app/models/moderation_report.rb create mode 100644 app/views/moderation_reports/_new.html.erb create mode 100644 app/views/moderation_reports/create.js.erb create mode 100644 app/views/moderation_reports/index.html.erb create mode 100644 app/views/moderation_reports/new.js.erb create mode 100644 db/migrate/20200117220602_create_moderation_reports.rb diff --git a/app/controllers/moderation_reports_controller.rb b/app/controllers/moderation_reports_controller.rb new file mode 100644 index 000000000..906ff9e36 --- /dev/null +++ b/app/controllers/moderation_reports_controller.rb @@ -0,0 +1,49 @@ +class ModerationReportsController < ApplicationController + respond_to :html, :xml, :json, :js + before_action :builder_only, only: [:new, :create] + before_action :moderator_only, only: [:index] + + def new + check_privilege + @moderation_report = ModerationReport.new(moderation_report_params) + respond_with(@moderation_report) + end + + def index + @moderation_reports = ModerationReport.paginated_search(params).includes(:creator, :model) + respond_with(@moderation_reports) + end + + def create + check_privilege + @moderation_report = ModerationReport.create(moderation_report_params) + @moderation_report.create_forum_post! + respond_with(@moderation_report) + end + + private + + def model_type + params.fetch(:moderation_report, {}).fetch(:model_type) + end + + def model_id + params.fetch(:moderation_report, {}).fetch(:model_id) + end + + def check_privilege + case model_type + when "User" + return if User.find(model_id).reportable_by?(CurrentUser.user) + when "Comment" + return if Comment.find(model_id).reportable_by?(CurrentUser.user) + when "ForumPost" + return if ForumPost.find(model_id).reportable_by?(CurrentUser.user) + end + raise User::PrivilegeError + end + + def moderation_report_params + params.fetch(:moderation_report, {}).permit(%i[model_type model_id reason]) + end +end diff --git a/app/models/comment.rb b/app/models/comment.rb index c9111dd16..005e3c68d 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -7,6 +7,7 @@ class Comment < ApplicationRecord belongs_to :post belongs_to_creator belongs_to_updater + has_many :moderation_reports, as: :model has_many :votes, :class_name => "CommentVote", :dependent => :destroy after_create :update_last_commented_at_on_create after_update(:if => ->(rec) {(!rec.is_deleted? || !rec.saved_change_to_is_deleted?) && CurrentUser.id != rec.creator_id}) do |rec| @@ -127,6 +128,10 @@ class Comment < ApplicationRecord updater_id == user.id || user.is_moderator? end + def reportable_by?(user) + user.is_builder? && creator_id != user.id && !creator.is_moderator? + end + def voted_by?(user) return false if user.is_anonymous? user.id.in?(votes.map(&:user_id)) diff --git a/app/models/forum_post.rb b/app/models/forum_post.rb index 6c797731b..860f3791c 100644 --- a/app/models/forum_post.rb +++ b/app/models/forum_post.rb @@ -6,6 +6,7 @@ class ForumPost < ApplicationRecord belongs_to_updater belongs_to :topic, :class_name => "ForumTopic" has_many :dtext_links, as: :model, dependent: :destroy + has_many :moderation_reports, as: :model has_many :votes, class_name: "ForumPostVote" has_one :tag_alias has_one :tag_implication @@ -93,6 +94,10 @@ class ForumPost < ApplicationRecord bulk_update_request || tag_alias || tag_implication end + def reportable_by?(user) + user.is_builder? && creator_id != user.id && !creator.is_moderator? + end + def votable? TagAlias.where(forum_post_id: id).exists? || TagImplication.where(forum_post_id: id).exists? || diff --git a/app/models/moderation_report.rb b/app/models/moderation_report.rb new file mode 100644 index 000000000..fb0a1aa61 --- /dev/null +++ b/app/models/moderation_report.rb @@ -0,0 +1,57 @@ +class ModerationReport < ApplicationRecord + belongs_to :model, polymorphic: true + belongs_to_creator + + scope :user, -> { where(model_type: "User") } + scope :comment, -> { where(model_type: "Comment") } + scope :forum_post, -> { where(model_type: "ForumPost") } + + def forum_topic_title + "Reports requiring moderation" + end + + def forum_topic_body + "This topic deals with moderation events as reported by Builders. Reports can be filed against users, comments, or forum posts." + end + + def forum_topic + topic = ForumTopic.find_by_title(forum_topic_title) + if topic.nil? + topic = CurrentUser.as_system do + ForumTopic.create(title: forum_topic_title, category_id: 0, min_level: User::Levels::MODERATOR, original_post_attributes: {body: forum_topic_body}) + end + end + topic + end + + def forum_post_message + messages = ["[b]Submitted by:[/b] @#{creator.name}"] + case model_type + when "User" + messages << "[b]Submitted against:[/b] @#{model.name}" + when "Comment" + messages << "[b]Submitted against[/b]: comment ##{model_id}" + when "ForumPost" + messages << "[b]Submitted against[/b]: forum ##{model_id}" + end + messages << "" + messages << "[quote]" + messages << "[b]Reason:[/b]" + messages << "" + messages << reason + messages << "[/quote]" + messages.join("\n") + end + + def create_forum_post! + updater = ForumUpdater.new(forum_topic) + updater.update(forum_post_message) + end + + def self.search(params) + q = super + q = q.search_attributes(params, :model_type, :model_id, :creator_id) + + q.apply_default_order(params) + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 411d29799..6733a8b15 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -93,6 +93,7 @@ class User < ApplicationRecord has_many :wiki_page_versions, foreign_key: :updater_id has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy has_many :forum_post_votes, dependent: :destroy, foreign_key: :creator_id + has_many :moderation_reports, as: :model has_many :posts, :foreign_key => "uploader_id" has_many :post_appeals, foreign_key: :creator_id has_many :post_approvals, :dependent => :destroy @@ -791,6 +792,10 @@ class User < ApplicationRecord end end + def reportable_by?(user) + user.is_builder? && id != user.id && !is_moderator? + end + def hide_favorites? !CurrentUser.is_admin? && enable_private_favorites? && CurrentUser.user.id != id end diff --git a/app/views/comments/partials/show/_comment.html.erb b/app/views/comments/partials/show/_comment.html.erb index f08b42014..acf2c60ad 100644 --- a/app/views/comments/partials/show/_comment.html.erb +++ b/app/views/comments/partials/show/_comment.html.erb @@ -53,6 +53,9 @@ + <% if comment.reportable_by?(CurrentUser.user) %> +
  • <%= link_to "Report comment", new_moderation_report_path(moderation_report: { model_type: "Comment", model_id: comment.id }), remote: true %>
  • + <% end %> <% if comment.editable_by?(CurrentUser.user) %> <%= render "comments/form", comment: comment, hidden: true %> diff --git a/app/views/forum_posts/_forum_post.html.erb b/app/views/forum_posts/_forum_post.html.erb index 88cacfef8..73726f3bd 100644 --- a/app/views/forum_posts/_forum_post.html.erb +++ b/app/views/forum_posts/_forum_post.html.erb @@ -32,6 +32,9 @@
  • <%= link_to "Edit", edit_forum_post_path(forum_post.id), :id => "edit_forum_post_link_#{forum_post.id}", :class => "edit_forum_post_link" %>
  • <% end %> <% end %> + <% if forum_post.reportable_by?(CurrentUser.user) %> +
  • <%= link_to "Report forum", new_moderation_report_path(moderation_report: { model_type: "ForumPost", model_id: forum_post.id }), remote: true %>
  • + <% end %> <% if forum_post.votable? %>