diff --git a/app/models/comment.rb b/app/models/comment.rb index 7a373b0068..7b882c3178 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -37,6 +37,12 @@ class Comment < ApplicationRecord instance_accessor: false, default: DEFAULT_CREATION_RATE_LIMITS + cattr_accessor :old_age_in_days, + instance_reader: false, + instance_writer: false, + instance_accessor: false, + default: 30 + strip_attributes allow_empty: true belongs_to :user, @@ -52,7 +58,7 @@ class Comment < ApplicationRecord # validates_presence_of :user # breaks during construction of new ones :( validate :check_body_has_content, - :check_body_uses_mixed_capitals + :check_body_uses_mixed_capitals, unless: :hidden? scope :visible, -> { joins(:info_request). @@ -60,6 +66,8 @@ class Comment < ApplicationRecord where(visible: true) } + scope :hidden, -> { where(visible: false) } + scope :embargoed, -> { joins(info_request: :embargo). where('embargoes.id IS NOT NULL'). @@ -79,6 +87,15 @@ class Comment < ApplicationRecord default_url_options[:host] = AlaveteliConfiguration.domain + def self.erase_old_hidden(editor: User.internal_admin_user) + old_hidden = hidden.where('updated_at > ?', old_age_in_days.days.ago) + reason = "Hidden for longer than #{old_age_in_days} days" + + old_hidden.find_each do |comment| + comment.erase(editor: editor, reason: reason) + end + end + # When posting a new comment, use this to check user hasn't double # submitted. def self.find_existing(info_request_id, body) @@ -194,6 +211,11 @@ def hide(editor:) end end + def erase(**kwargs) + return false unless hidden? + Comment::Erasure.new(self, **kwargs).erase + end + def cached_urls [ request_path(info_request), diff --git a/app/models/comment/erasure.rb b/app/models/comment/erasure.rb new file mode 100644 index 0000000000..fc8e5e24be --- /dev/null +++ b/app/models/comment/erasure.rb @@ -0,0 +1,43 @@ +class Comment::Erasure + def initialize(comment, editor: User.internal_admin_user, reason:) + @comment = comment + @editor = editor + @reason = reason + end + + def erase + ActiveRecord::Base.transaction do + erase_comment + erase_comment_events + end + end + + protected + + attr_reader :comment, :editor, :reason + + private + + def erase_comment + event_params = { + comment_id: comment.id, + editor: editor.url_name, + reason: "Erased: #{reason}" + } + + comment.update!(body: '') + comment.info_request.log_event('erase_comment', event_params) + end + + def erase_comment_events + comment.info_request_events.edit_comment_events.find_each do |event| + params = event.params.dup + + params.each do |key, _| + params[key] = "[ERASED]" if key =~ /body/ + end + + event.update(params: params) + end + end +end diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb index dc25750a7b..0bf5101e1e 100644 --- a/app/models/info_request_event.rb +++ b/app/models/info_request_event.rb @@ -35,6 +35,7 @@ class InfoRequestEvent < ApplicationRecord 'edit_comment', # comment edited (in admin interface) 'hide_comment', # comment hidden by admin 'report_comment', # comment reported for admin attention by user + 'erase_comment', # comment is erased 'report_request', # a request reported for admin attention by user 'destroy_incoming', # deleted an incoming message (in admin interface) 'destroy_outgoing', # deleted an outgoing message (in admin interface)