From ccf501a420d12d79b803ccf7334d0db978e4724e Mon Sep 17 00:00:00 2001
From: Nyaaori <+@nyaaori.cat>
Date: Mon, 18 Oct 2021 04:51:11 +0000
Subject: [PATCH 1/3] Initial implementation of /report, fixing #13
---
src/client_server/mod.rs | 2 +
src/client_server/report.rs | 75 +++++++++++++++++++++++++++++++++++++
src/main.rs | 1 +
3 files changed, 78 insertions(+)
create mode 100644 src/client_server/report.rs
diff --git a/src/client_server/mod.rs b/src/client_server/mod.rs
index e0c340f..115ddaf 100644
--- a/src/client_server/mod.rs
+++ b/src/client_server/mod.rs
@@ -16,6 +16,7 @@ mod profile;
mod push;
mod read_marker;
mod redact;
+mod report;
mod room;
mod search;
mod session;
@@ -47,6 +48,7 @@ pub use profile::*;
pub use push::*;
pub use read_marker::*;
pub use redact::*;
+pub use report::*;
pub use room::*;
pub use search::*;
pub use session::*;
diff --git a/src/client_server/report.rs b/src/client_server/report.rs
new file mode 100644
index 0000000..e56cbc9
--- /dev/null
+++ b/src/client_server/report.rs
@@ -0,0 +1,75 @@
+use std::sync::Arc;
+
+use crate::{database::admin::AdminCommand, database::DatabaseGuard, ConduitResult, Error, Ruma};
+use ruma::{
+ api::client::{error::ErrorKind, r0::room::report_content},
+ events::room::message,
+ Int,
+};
+
+#[cfg(feature = "conduit_bin")]
+use rocket::post;
+
+/// # `POST /_matrix/client/r0/rooms/{roomId}/report/{eventId}`
+///
+/// Reports an inappropriate event to homeserver admins
+///
+#[cfg_attr(
+ feature = "conduit_bin",
+ post("/_matrix/client/r0/rooms/<_>/report/<_>", data = "
")
+)]
+#[tracing::instrument(skip(db, body))]
+pub async fn report_event_route(
+ db: DatabaseGuard,
+ body: Ruma>,
+) -> ConduitResult {
+ let sender_user = body.sender_user.as_ref().expect("user is authenticated");
+
+ let pdu = match db.rooms.get_pdu(&body.event_id) {
+ Ok(pdu) if !pdu.is_none() => pdu,
+ _ => {
+ return Err(Error::BadRequest(
+ ErrorKind::InvalidParam,
+ "Invalid Event ID",
+ ))
+ }
+ }
+ .unwrap();
+
+ if body.score >= Int::from(0) && body.score <= Int::from(-100) {
+ return Err(Error::BadRequest(
+ ErrorKind::InvalidParam,
+ "Invalid score, must be within 0 to -100",
+ ));
+ };
+
+ if body.reason.chars().count() > 160 {
+ return Err(Error::BadRequest(
+ ErrorKind::InvalidParam,
+ "Reason too long, should be 160 characters or fewer",
+ ));
+ };
+
+ let mutex_state = Arc::clone(
+ db.globals
+ .roomid_mutex_state
+ .write()
+ .unwrap()
+ .entry(body.room_id.clone())
+ .or_default(),
+ );
+ let state_lock = mutex_state.lock().await;
+
+ db.admin.send(AdminCommand::SendMessage(
+ message::RoomMessageEventContent::text_plain(format!(
+ "Report received from: {}\r\n\r\nEvent ID: {}\r\nRoom ID: {}\r\nSent By: {}\r\n\r\nReport Score: {}\r\nReport Reason: {}",
+ sender_user, pdu.event_id, pdu.room_id, pdu.sender, body.score, body.reason,
+ )),
+ ));
+
+ drop(state_lock);
+
+ db.flush()?;
+
+ Ok(report_content::Response {}.into())
+}
diff --git a/src/main.rs b/src/main.rs
index 84dfb1f..56faa3e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -101,6 +101,7 @@ fn setup_rocket(config: Figment, data: Arc>) -> rocket::Rocket<
client_server::create_typing_event_route,
client_server::create_room_route,
client_server::redact_event_route,
+ client_server::report_event_route,
client_server::create_alias_route,
client_server::delete_alias_route,
client_server::get_alias_route,
From 1541b93f457de2d5fb8c37739d6791fa3f60312b Mon Sep 17 00:00:00 2001
From: Nyaaori <+@nyaaori.cat>
Date: Mon, 18 Oct 2021 05:38:41 +0000
Subject: [PATCH 2/3] Make reports look nicer and reduce spam potential,
increase max report length to 1000 characters
---
src/client_server/report.rs | 39 ++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/src/client_server/report.rs b/src/client_server/report.rs
index e56cbc9..7f66fa1 100644
--- a/src/client_server/report.rs
+++ b/src/client_server/report.rs
@@ -8,7 +8,7 @@ use ruma::{
};
#[cfg(feature = "conduit_bin")]
-use rocket::post;
+use rocket::{http::RawStr, post};
/// # `POST /_matrix/client/r0/rooms/{roomId}/report/{eventId}`
///
@@ -43,10 +43,10 @@ pub async fn report_event_route(
));
};
- if body.reason.chars().count() > 160 {
+ if body.reason.chars().count() > 1000 {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
- "Reason too long, should be 160 characters or fewer",
+ "Reason too long, should be 1000 characters or fewer",
));
};
@@ -61,10 +61,35 @@ pub async fn report_event_route(
let state_lock = mutex_state.lock().await;
db.admin.send(AdminCommand::SendMessage(
- message::RoomMessageEventContent::text_plain(format!(
- "Report received from: {}\r\n\r\nEvent ID: {}\r\nRoom ID: {}\r\nSent By: {}\r\n\r\nReport Score: {}\r\nReport Reason: {}",
- sender_user, pdu.event_id, pdu.room_id, pdu.sender, body.score, body.reason,
- )),
+ message::RoomMessageEventContent::text_html(
+ format!(
+ concat!(
+ "Report received from: {}\r\n\r\n",
+ "Event ID: {}\r\n",
+ "Room ID: {}\r\n",
+ "Sent By: {}\r\n\r\n",
+ "Report Score: {}\r\n",
+ "Report Reason: {}"
+ ),
+ sender_user, pdu.event_id, pdu.room_id, pdu.sender, body.score, body.reason
+ )
+ .to_owned(),
+ format!(
+ concat!(
+ "Report received from: {}
",
+ "Event Info
Event ID: {}
Room ID: {}
Sent By: {}",
+ "
Report Info
Report Score: {}",
+ "Report Reason: {}
"
+ ),
+ sender_user,
+ pdu.event_id,
+ pdu.room_id,
+ pdu.sender,
+ body.score,
+ RawStr::new(&body.reason).html_escape()
+ )
+ .to_owned(),
+ ),
));
drop(state_lock);
From 50f931a2fda72d94a6190092dac18f2268c96af1 Mon Sep 17 00:00:00 2001
From: Nyaaori <+@nyaaori.cat>
Date: Wed, 20 Oct 2021 11:12:06 +0000
Subject: [PATCH 3/3] Cleanup and fix validation in report.rs, lower max report
length, better html
---
src/client_server/report.rs | 53 +++++++++++++------------------------
1 file changed, 18 insertions(+), 35 deletions(-)
diff --git a/src/client_server/report.rs b/src/client_server/report.rs
index 7f66fa1..3dcb4d1 100644
--- a/src/client_server/report.rs
+++ b/src/client_server/report.rs
@@ -1,5 +1,3 @@
-use std::sync::Arc;
-
use crate::{database::admin::AdminCommand, database::DatabaseGuard, ConduitResult, Error, Ruma};
use ruma::{
api::client::{error::ErrorKind, r0::room::report_content},
@@ -25,62 +23,49 @@ pub async fn report_event_route(
) -> ConduitResult {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
- let pdu = match db.rooms.get_pdu(&body.event_id) {
- Ok(pdu) if !pdu.is_none() => pdu,
+ let pdu = match db.rooms.get_pdu(&body.event_id)? {
+ Some(pdu) => pdu,
_ => {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid Event ID",
))
}
- }
- .unwrap();
+ };
- if body.score >= Int::from(0) && body.score <= Int::from(-100) {
+ if body.score > Int::from(0) || body.score < Int::from(-100) {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid score, must be within 0 to -100",
));
};
- if body.reason.chars().count() > 1000 {
+ if body.reason.chars().count() > 250 {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
- "Reason too long, should be 1000 characters or fewer",
+ "Reason too long, should be 250 characters or fewer",
));
};
- let mutex_state = Arc::clone(
- db.globals
- .roomid_mutex_state
- .write()
- .unwrap()
- .entry(body.room_id.clone())
- .or_default(),
- );
- let state_lock = mutex_state.lock().await;
-
db.admin.send(AdminCommand::SendMessage(
message::RoomMessageEventContent::text_html(
format!(
- concat!(
- "Report received from: {}\r\n\r\n",
- "Event ID: {}\r\n",
- "Room ID: {}\r\n",
- "Sent By: {}\r\n\r\n",
- "Report Score: {}\r\n",
- "Report Reason: {}"
- ),
+ "Report received from: {}\n\n\
+ Event ID: {}\n\
+ Room ID: {}\n\
+ Sent By: {}\n\n\
+ Report Score: {}\n\
+ Report Reason: {}",
sender_user, pdu.event_id, pdu.room_id, pdu.sender, body.score, body.reason
)
.to_owned(),
format!(
- concat!(
- "Report received from: {}
",
- "Event Info
Event ID: {}
Room ID: {}
Sent By: {}",
- "
Report Info
Report Score: {}",
- "Report Reason: {}
"
- ),
+ "Report received from: {0}\
+
- Event Info
- Event ID:
{1}
\
+ 🔗 - Room ID:
{2}
\
+ - Sent By: {3}
- \
+ Report Info
- Report Score: {4}
- Report Reason: {5}
\
+
",
sender_user,
pdu.event_id,
pdu.room_id,
@@ -92,8 +77,6 @@ pub async fn report_event_route(
),
));
- drop(state_lock);
-
db.flush()?;
Ok(report_content::Response {}.into())