Skip to content

Commit f39e2cf

Browse files
committed
Allow reporting of malicious content
RfCs and Comments on RfCs are user generated content that can be reviewed by other users. This feature can be misused. A simple email based reporting mechanism has been added allow users to report this malicious content. The UI for the RfC comment are part of a separate change. Relates to #2715
1 parent e9d4d79 commit f39e2cf

24 files changed

+287
-64
lines changed

app/controllers/request_for_comments_controller.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
class RequestForCommentsController < ApplicationController
44
include CommonBehavior
5-
before_action :set_request_for_comment, only: %i[show mark_as_solved set_thank_you_note clear_question]
5+
before_action :set_request_for_comment, only: %i[show mark_as_solved set_thank_you_note clear_question report]
66
before_action :set_study_group_grouping,
77
only: %i[index my_comment_requests rfcs_with_my_comments rfcs_for_exercise]
88

@@ -162,6 +162,15 @@ def create
162162
authorize!
163163
end
164164

165+
# POST /request_for_comments/1/report
166+
def report
167+
authorize!
168+
169+
ReportMailer.with(reported_content: @request_for_comment).report_content.deliver_later
170+
171+
redirect_to(@request_for_comment, notice: t('.report.reported'))
172+
end
173+
165174
private
166175

167176
# Use callbacks to share common setup or constraints between actions.

app/mailers/report_mailer.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
3+
class ReportMailer < ApplicationMailer
4+
default to: CodeOcean::Config.new(:code_ocean).read.dig(:content_moderation, :report_emails)
5+
6+
def report_content
7+
@reported_content = params.fetch(:reported_content)
8+
9+
mail(subject: I18n.t('report_mailer.report_content.subject', content_name: @reported_content.model_name.human))
10+
end
11+
end

app/policies/request_for_comment_policy.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ def rfcs_with_my_comments?
4141
everyone
4242
end
4343

44+
def report?
45+
report_receiver_configured? && !author?
46+
end
47+
48+
private
49+
50+
def report_receiver_configured?
51+
CodeOcean::Config.new(:code_ocean).read.dig(:content_moderation, :report_emails).present?
52+
end
53+
4454
def rfc_visibility
4555
# The consumer with the most restricted visibility determines the visibility of the RfC
4656
case [@user.consumer.rfc_visibility, @record.author.consumer.rfc_visibility]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<%= t('.prolog') %>
2+
3+
<% case @reported_content %>
4+
<% when Comment %>
5+
<%= @reported_content.text %>
6+
7+
<%= t('.take_action') %>
8+
9+
<%= rails_admin.show_url(
10+
model_name: 'comment',
11+
id: @reported_content.id) %>
12+
<% when RequestForComment %>
13+
<%= @reported_content.question %>
14+
15+
<%= t('.take_action') %>
16+
17+
<%= request_for_comment_url(@reported_content) %>
18+
<% else %>
19+
<% raise("Unexpected reported content: #{@reported_content.class.name}") %>
20+
<% end %>
21+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- if policy(request_for_comment).report?
2+
.text-end
3+
= button_to t('.report'), report_request_for_comment_path(request_for_comment),
4+
data: {confirm: t('.confirm')},
5+
class: 'btn btn-light btn-sm'

app/views/request_for_comments/show.html.slim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
.text
2929
- question = @request_for_comment.question
3030
= question.presence || t('request_for_comments.no_question')
31+
= render('report', request_for_comment: @request_for_comment)
3132

3233
- if policy(@request_for_comment).mark_as_solved? && !@request_for_comment.solved?
3334
= render('mark_as_solved')

config/code_ocean.yml.ci

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ test:
1414
ca_file: /example/certificates/ca.crt
1515
token: SECRET
1616
unused_runner_expiration_time: 180
17+
content_moderation:
18+
report_emails:
19+

config/code_ocean.yml.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ default: &default
5555
# be truly greater than any permitted execution time of an execution environment.
5656
unused_runner_expiration_time: 180
5757

58+
content_moderation:
59+
# Email address to receive reports about inappropriate content.
60+
report_emails:
61+
5862

5963
development:
6064
<<: *default

config/locales/de/report.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
de:
3+
report_mailer:
4+
report_content:
5+
prolog: 'Die folgenden Inhalte wurden als unangemessen gemeldet:'
6+
subject: 'Spam Report: Ein %{content_name} in CodeOcean wurde als unangemessen markiert.'
7+
take_action: Bitte ergreifen Sie gegebenenfalls Maßnahmen.

config/locales/de/request_for_comment.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ de:
4242
no_output: Keine Ausgabe.
4343
no_question: Der/die Autor:in hat keine Frage zu dieser Anfrage gestellt.
4444
passed: Erfolgreich
45+
report:
46+
confirm: Möchten Sie diesen Inhalt melden?
47+
report: Melden
48+
reported: Vielen Dank, dass Sie uns auf dieses Problem aufmerksam gemacht haben. Wir werden uns in Kürze darum kümmern.
4549
runtime_output: Programmausgabe
4650
send_thank_you_note: Senden
4751
show_all: Alle Anfragen anzeigen

0 commit comments

Comments
 (0)